haiwei-module-admin 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "id": 0,
3
3
  "name": "haiwei-module-admin",
4
4
  "code": "admin",
5
- "version": "1.1.0",
5
+ "version": "1.1.2",
6
6
  "description": "haiwei前端Admin模块组件",
7
7
  "author": "Eric",
8
8
  "license": "ISC",
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "haiwei-skins-classics": "^1.0.2",
22
- "haiwei-ui": "^1.0.9"
22
+ "haiwei-ui": "^1.1.1"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@vue/cli-plugin-babel": "^4.4.4",
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <div :style="{ width, height }" class="nm-file-img-preview">
3
+ <img v-if="url__" :src="url__" />
4
+ <nm-icon class="no-picture" v-else name="photo" />
5
+ </div>
6
+ </template>
7
+ <script>
8
+ export default {
9
+ data() {
10
+ return {
11
+ url_: this.url,
12
+ url__: ''
13
+ }
14
+ },
15
+ props: {
16
+ url: {
17
+ type: String
18
+ },
19
+ //是否私有
20
+ private: Boolean,
21
+ width: {
22
+ type: String,
23
+ default: 'auto'
24
+ },
25
+ height: {
26
+ type: String,
27
+ default: 'auto'
28
+ }
29
+ },
30
+ watch: {
31
+ url: {
32
+ immediate: true,
33
+ handler(val) {
34
+ if (val !== this.url_) {
35
+ if (this.private && this.url) {
36
+ $api.admin.file.preview(this.url).then(url => {
37
+ this.url__ = url
38
+ })
39
+ } else {
40
+ this.url__ = val
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ </script>
48
+ <style lang="scss">
49
+ .nm-file-img-preview {
50
+ display: block;
51
+ img {
52
+ width: 100%;
53
+ }
54
+ }
55
+ </style>
@@ -16,6 +16,10 @@ export default {
16
16
  url: {
17
17
  type: String
18
18
  },
19
+ // 完整路径(公有图片)
20
+ fullPath: {
21
+ type: String
22
+ },
19
23
  //是否私有
20
24
  private: Boolean,
21
25
  width: {
@@ -27,19 +31,89 @@ export default {
27
31
  default: 'auto'
28
32
  }
29
33
  },
34
+ computed: {
35
+ baseUrl() {
36
+ // 优先使用全局变量,否则使用默认值
37
+ return window.__HAIWEI_API_BASE_URL__ || '/api/'
38
+ }
39
+ },
30
40
  watch: {
31
41
  url: {
32
42
  immediate: true,
33
43
  handler(val) {
34
44
  if (val !== this.url_) {
35
- if (this.private && this.url) {
36
- $api.admin.file.preview(this.url).then(url => {
37
- this.url__ = url
38
- })
45
+ this.updatePreviewUrl()
46
+ }
47
+ }
48
+ },
49
+ fullPath: {
50
+ immediate: true,
51
+ handler() {
52
+ this.updatePreviewUrl()
53
+ }
54
+ },
55
+ private: {
56
+ immediate: true,
57
+ handler() {
58
+ this.updatePreviewUrl()
59
+ }
60
+ }
61
+ },
62
+ methods: {
63
+ // 判断是否为绝对 URL
64
+ isAbsoluteUrl(path) {
65
+ return /^(https?:)?\/\//.test(path)
66
+ },
67
+
68
+ // 规范化路径拼接
69
+ normalizePath(base, path) {
70
+ // 如果 path 已经是绝对 URL,直接返回
71
+ if (this.isAbsoluteUrl(path)) {
72
+ return path
73
+ }
74
+ // 确保 base 以 / 结尾,path 不以 / 开头
75
+ let baseUrl = base.endsWith('/') ? base.slice(0, -1) : base
76
+ let fullPath = path.startsWith('/') ? path.slice(1) : path
77
+ return `${baseUrl}/${fullPath}`
78
+ },
79
+
80
+ updatePreviewUrl() {
81
+ // 重置内部状态
82
+ this.url_ = this.url
83
+
84
+ // 优先使用 fullPath
85
+ if (this.fullPath) {
86
+ if (this.private) {
87
+ // 私有图片,调用预览接口
88
+ $api.admin.file.preview(this.fullPath).then(url => {
89
+ this.url__ = url
90
+ }).catch(() => {
91
+ // 如果接口调用失败,使用原始路径
92
+ this.url__ = this.fullPath
93
+ })
94
+ } else {
95
+ // 公有图片,拼接 OSS 路径
96
+ if (this.isAbsoluteUrl(this.fullPath)) {
97
+ // 如果已经是绝对 URL,直接使用
98
+ this.url__ = this.fullPath
39
99
  } else {
40
- this.url__ = val
100
+ // 拼接 OSS 路径
101
+ this.url__ = this.normalizePath(this.baseUrl + '/oss/o', this.fullPath)
41
102
  }
42
103
  }
104
+ } else if (this.url) {
105
+ // 原有逻辑
106
+ if (this.private) {
107
+ $api.admin.file.preview(this.url).then(url => {
108
+ this.url__ = url
109
+ }).catch(() => {
110
+ this.url__ = this.url
111
+ })
112
+ } else {
113
+ this.url__ = this.url
114
+ }
115
+ } else {
116
+ this.url__ = ''
43
117
  }
44
118
  }
45
119
  }
@@ -77,7 +77,7 @@
77
77
  export default {
78
78
  name: 'FilePreview',
79
79
  props: {
80
- fullPath: { type: String, required: true },
80
+ fullPath: { type: String, default: null },
81
81
  isPrivate: { type: Boolean, default: false },
82
82
  downloadText: { type: String, default: '下载' },
83
83
  downloadIcon: { type: String, default: 'download' },
@@ -114,6 +114,27 @@ export default {
114
114
  },
115
115
 
116
116
  computed: {
117
+ // 缓存路径处理结果,避免重复计算
118
+ normalizedPath() {
119
+ if (!this.fullPath) return null
120
+ return this.fullPath.replace(/\\/g, '/')
121
+ },
122
+
123
+ // 缓存文件名,避免重复提取
124
+ fileName() {
125
+ if (!this.normalizedPath) return ''
126
+ const filename = this.normalizedPath.split('/').pop()
127
+ return filename || ''
128
+ },
129
+
130
+ // 缓存文件扩展名
131
+ fileExt() {
132
+ const filename = this.fileName
133
+ if (!filename) return ''
134
+ const dotIndex = filename.lastIndexOf('.')
135
+ return dotIndex > -1 ? filename.slice(dotIndex + 1).toLowerCase() : ''
136
+ },
137
+
117
138
  hasValidFullPath() {
118
139
  // 检查fullPath是否有效:不为空且不是空字符串
119
140
  if (!this.fullPath || this.fullPath.trim() === '') {
@@ -125,9 +146,8 @@ export default {
125
146
  return false
126
147
  }
127
148
 
128
- // 检查是否有文件名(路径的最后一部分)
129
- const path = this.fullPath.replace(/\\/g, '/')
130
- const filename = path.split('/').pop()
149
+ // 使用已计算的文件名
150
+ const filename = this.fileName
131
151
 
132
152
  // 文件名不能为空
133
153
  if (!filename || filename.trim() === '') {
@@ -137,27 +157,12 @@ export default {
137
157
  return true
138
158
  },
139
159
 
140
- fileName() {
141
- // 从fullPath中提取文件名
142
- if (!this.fullPath) return ''
143
- const path = this.fullPath.replace(/\\/g, '/')
144
- const filename = path.split('/').pop()
145
- return filename || ''
146
- },
147
-
148
- fileExt() {
149
- // 从fullPath中提取文件扩展名
150
- const filename = this.fileName
151
- const dotIndex = filename.lastIndexOf('.')
152
- return dotIndex > -1 ? filename.slice(dotIndex + 1).toLowerCase() : ''
153
- },
154
-
155
160
  isImage() {
156
161
  return this.imageExtensions.includes(this.fileExt)
157
162
  },
158
163
 
159
164
  downloadUrl() {
160
- console.log('this.fileInfo?.url ', this.fileInfo?.url)
165
+ // console.log('this.fileInfo?.url ', this.fileInfo?.url)
161
166
  return this.fileInfo?.url || this.fullPath
162
167
  },
163
168
 
@@ -1,573 +0,0 @@
1
- <template>
2
- <div class="file-preview">
3
- <!-- 当fullPath有效时显示内容 -->
4
- <template v-if="hasValidFullPath">
5
- <!-- 图片预览链接 -->
6
- <a v-if="isImage" class="preview-link" @click="showPreviewDialog">
7
- 查看
8
- </a>
9
-
10
- <!-- 非图片文件下载 -->
11
- <nm-file-download v-else :url="downloadUrl" :private="isPrivate" :fileName="fileName" :text="downloadText" :icon="downloadIcon" :size="downloadSize" :type="downloadType" @click="onDownload" />
12
- </template>
13
-
14
- <!-- 图片预览对话框 -->
15
- <nm-dialog
16
- v-if="isImage"
17
- ref="previewDialog"
18
- :visible.sync="previewVisible"
19
- :title="previewTitle"
20
- width="800px"
21
- height="800px"
22
- :fullscreen="false"
23
- :footer="false"
24
- custom-class="image-preview-dialog"
25
- @closed="resetState"
26
- >
27
- <div class="preview-wrapper">
28
- <!-- 使用CSS实现图片居中,而不是JS计算 -->
29
- <div class="preview-container" ref="previewContainer">
30
- <img
31
- :src="previewUrl"
32
- :alt="fileName"
33
- class="preview-image"
34
- ref="previewImage"
35
- @load="handleImageLoad"
36
- @error="handleImageError"
37
- :style="imageStyle"
38
- @mousedown="startDrag"
39
- @wheel="handleWheel"
40
- @dblclick="resetImage"
41
- />
42
- </div>
43
-
44
- <!-- 操作按钮栏 -->
45
- <div class="toolbar">
46
- <button class="toolbar-btn" @click="zoomIn">
47
- <span class="icon">+</span>
48
- <span class="text">放大</span>
49
- </button>
50
- <button class="toolbar-btn" @click="zoomOut">
51
- <span class="icon">-</span>
52
- <span class="text">缩小</span>
53
- </button>
54
- <button class="toolbar-btn" @click="resetImage">
55
- <span class="icon">⟳</span>
56
- <span class="text">重置</span>
57
- </button>
58
- <!-- 非图片文件下载 -->
59
- <nm-file-download
60
- v-if="hasValidFullPath"
61
- :url="downloadUrl"
62
- :private="isPrivate"
63
- :fileName="fileName"
64
- :text="downloadText"
65
- :icon="downloadIcon"
66
- :size="downloadSize"
67
- :type="downloadType"
68
- @click="onDownload"
69
- />
70
- </div>
71
- </div>
72
- </nm-dialog>
73
- </div>
74
- </template>
75
-
76
- <script>
77
- export default {
78
- name: 'FilePreview',
79
- props: {
80
- fullPath: { type: String, required: true },
81
- isPrivate: { type: Boolean, default: false },
82
- downloadText: { type: String, default: '下载' },
83
- downloadIcon: { type: String, default: 'download' },
84
- downloadSize: String,
85
- downloadType: { type: String, default: 'primary' },
86
- previewTitle: { type: String, default: '图片预览' },
87
- imageExtensions: {
88
- type: Array,
89
- default: () => ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'ico']
90
- }
91
- },
92
-
93
- data() {
94
- return {
95
- previewVisible: false,
96
- previewUrl: '',
97
- fileInfo: null,
98
-
99
- // 图片状态
100
- imageLoading: false,
101
- imageError: false,
102
- loadingTimeout: null,
103
-
104
- // 图片位置和缩放(使用CSS transform,但让CSS处理居中)
105
- position: { x: 0, y: 0 },
106
- scale: 1,
107
- minScale: 0.1,
108
- maxScale: 5,
109
-
110
- // 拖拽状态
111
- isDragging: false,
112
- startPosition: { x: 0, y: 0 }
113
- }
114
- },
115
-
116
- computed: {
117
- hasValidFullPath() {
118
- // 检查fullPath是否有效:不为空且不是空字符串
119
- if (!this.fullPath || this.fullPath.trim() === '') {
120
- return false
121
- }
122
-
123
- // 检查是否是目录路径(以斜杠结尾)
124
- if (this.fullPath.endsWith('/') || this.fullPath.endsWith('\\')) {
125
- return false
126
- }
127
-
128
- // 检查是否有文件名(路径的最后一部分)
129
- const path = this.fullPath.replace(/\\/g, '/')
130
- const filename = path.split('/').pop()
131
-
132
- // 文件名不能为空
133
- if (!filename || filename.trim() === '') {
134
- return false
135
- }
136
-
137
- return true
138
- },
139
-
140
- fileName() {
141
- // 从fullPath中提取文件名
142
- if (!this.fullPath) return ''
143
- const path = this.fullPath.replace(/\\/g, '/')
144
- const filename = path.split('/').pop()
145
- return filename || ''
146
- },
147
-
148
- fileExt() {
149
- // 从fullPath中提取文件扩展名
150
- const filename = this.fileName
151
- const dotIndex = filename.lastIndexOf('.')
152
- return dotIndex > -1 ? filename.slice(dotIndex + 1).toLowerCase() : ''
153
- },
154
-
155
- isImage() {
156
- return this.imageExtensions.includes(this.fileExt)
157
- },
158
-
159
- downloadUrl() {
160
- console.log('this.fileInfo?.url ', this.fileInfo?.url)
161
- return this.fileInfo?.url || this.fullPath
162
- },
163
-
164
- imageStyle() {
165
- return {
166
- transform: `translate(${this.position.x}px, ${this.position.y}px) scale(${this.scale})`,
167
- cursor: this.isDragging ? 'grabbing' : 'grab'
168
- }
169
- }
170
- },
171
-
172
- watch: {
173
- fullPath(val) {
174
- if (val && this.isImage && !this.isPrivate) {
175
- this.previewUrl = val
176
- }
177
- },
178
-
179
- previewVisible(val) {
180
- if (!val) {
181
- this.resetState()
182
- }
183
- }
184
- },
185
-
186
- mounted() {
187
- // 监听全局鼠标事件用于拖拽
188
- document.addEventListener('mousemove', this.handleDrag)
189
- document.addEventListener('mouseup', this.stopDrag)
190
- },
191
-
192
- beforeDestroy() {
193
- // 清理事件监听
194
- document.removeEventListener('mousemove', this.handleDrag)
195
- document.removeEventListener('mouseup', this.stopDrag)
196
-
197
- // 清理超时
198
- if (this.loadingTimeout) {
199
- clearTimeout(this.loadingTimeout)
200
- this.loadingTimeout = null
201
- }
202
- },
203
-
204
- methods: {
205
- async getFileInfo() {
206
- if (!this.fullPath) return null
207
-
208
- try {
209
- const result = await $api.admin.file.getByFullPath(this.fullPath)
210
- this.fileInfo = result
211
-
212
- console.log('result', result)
213
-
214
- return result
215
- } catch (error) {
216
- console.error('获取文件信息失败:', error)
217
- return null
218
- }
219
- },
220
-
221
- async showPreviewDialog() {
222
- if (!this.isImage) return
223
-
224
- this.resetState()
225
- this.imageLoading = true
226
- this.previewVisible = true
227
-
228
- try {
229
- const fileInfo = await this.getFileInfo()
230
- if (!fileInfo) {
231
- this.imageLoading = false
232
- this.imageError = true
233
- return
234
- }
235
-
236
- await this.setPreviewUrl(fileInfo)
237
-
238
- // 设置一个立即检查,防止缓存图片不触发load事件
239
- this.$nextTick(() => {
240
- setTimeout(() => {
241
- if (this.imageLoading && this.$refs.previewImage && this.$refs.previewImage.complete) {
242
- this.handleImageLoad()
243
- }
244
- }, 300) // 300ms后检查
245
- })
246
-
247
- // 设置超时,防止图片加载事件未触发
248
- this.loadingTimeout = setTimeout(() => {
249
- if (this.imageLoading) {
250
- console.warn('图片加载超时,强制结束加载状态')
251
- this.imageLoading = false
252
- // 检查图片是否已经加载完成
253
- if (this.$refs.previewImage && this.$refs.previewImage.complete) {
254
- this.handleImageLoad()
255
- }
256
- }
257
- }, 2000) // 2秒超时
258
- } catch (error) {
259
- console.error('打开预览对话框失败:', error)
260
- this.imageLoading = false
261
- this.imageError = true
262
- }
263
- },
264
-
265
- async setPreviewUrl(fileInfo) {
266
- let newUrl
267
- if (this.isPrivate && fileInfo.url) {
268
- try {
269
- newUrl = await $api.admin.file.preview(fileInfo.url)
270
- } catch {
271
- newUrl = fileInfo.url
272
- }
273
- } else {
274
- newUrl = fileInfo.url || this.fullPath
275
- }
276
-
277
- // 先清空URL,强制重新加载(即使URL相同)
278
- if (this.previewUrl) {
279
- this.previewUrl = ''
280
- // 等待一个tick确保DOM更新
281
- await this.$nextTick()
282
- }
283
-
284
- // 设置新的URL
285
- this.previewUrl = newUrl
286
-
287
- // 等待DOM更新后检查图片是否已经加载完成
288
- this.$nextTick(() => {
289
- // 如果图片元素存在且已经加载完成,直接触发加载完成事件
290
- if (this.$refs.previewImage && this.$refs.previewImage.complete) {
291
- // 小延迟确保图片完全渲染
292
- setTimeout(() => {
293
- if (this.imageLoading) {
294
- this.handleImageLoad()
295
- }
296
- }, 100)
297
- }
298
- })
299
- },
300
-
301
- async onDownload() {
302
- const fileInfo = await this.getFileInfo()
303
- const url = fileInfo?.url || this.fullPath
304
- this.$emit('download', url, this.fileName)
305
- },
306
-
307
- handleImageLoad() {
308
- // 清理超时
309
- if (this.loadingTimeout) {
310
- clearTimeout(this.loadingTimeout)
311
- this.loadingTimeout = null
312
- }
313
- this.imageLoading = false
314
- // 图片加载完成后自动居中
315
- this.resetImage()
316
- },
317
-
318
- handleImageError() {
319
- // 清理超时
320
- if (this.loadingTimeout) {
321
- clearTimeout(this.loadingTimeout)
322
- this.loadingTimeout = null
323
- }
324
- this.imageLoading = false
325
- this.imageError = true
326
- },
327
-
328
- // 鼠标滚轮缩放 - 以鼠标为中心点缩放
329
- handleWheel(event) {
330
- event.preventDefault()
331
-
332
- const delta = event.deltaY < 0 ? 0.1 : -0.1
333
- const newScale = Math.max(this.minScale, Math.min(this.maxScale, this.scale + delta))
334
-
335
- // 计算缩放中心(相对于图片)
336
- if (this.$refs.previewContainer) {
337
- const containerRect = this.$refs.previewContainer.getBoundingClientRect()
338
- const mouseX = event.clientX - containerRect.left
339
- const mouseY = event.clientY - containerRect.top
340
-
341
- // 计算鼠标相对于图片原始坐标系的位置
342
- // 注意:position.x 和 position.y 是图片相对于容器的平移
343
- const relativeX = (mouseX - this.position.x) / this.scale
344
- const relativeY = (mouseY - this.position.y) / this.scale
345
-
346
- // 更新位置以保持鼠标点不变
347
- this.position.x = mouseX - relativeX * newScale
348
- this.position.y = mouseY - relativeY * newScale
349
- this.scale = newScale
350
- } else {
351
- this.scale = newScale
352
- }
353
- },
354
-
355
- // 开始拖拽
356
- startDrag(event) {
357
- if (event.button !== 0) return // 只响应左键
358
- this.isDragging = true
359
- this.startPosition = {
360
- x: event.clientX - this.position.x,
361
- y: event.clientY - this.position.y
362
- }
363
- event.preventDefault()
364
- },
365
-
366
- // 处理拖拽
367
- handleDrag(event) {
368
- if (!this.isDragging) return
369
-
370
- this.position.x = event.clientX - this.startPosition.x
371
- this.position.y = event.clientY - this.startPosition.y
372
- },
373
-
374
- // 停止拖拽
375
- stopDrag() {
376
- this.isDragging = false
377
- },
378
-
379
- // 放大
380
- zoomIn() {
381
- const newScale = Math.min(this.maxScale, this.scale + 0.2)
382
- if (newScale !== this.scale) {
383
- this.centerZoom(newScale)
384
- }
385
- },
386
-
387
- // 缩小
388
- zoomOut() {
389
- const newScale = Math.max(this.minScale, this.scale - 0.2)
390
- if (newScale !== this.scale) {
391
- this.centerZoom(newScale)
392
- }
393
- },
394
-
395
- // 以当前视图中心点缩放(用于工具栏按钮)
396
- centerZoom(newScale) {
397
- if (this.$refs.previewContainer) {
398
- const containerRect = this.$refs.previewContainer.getBoundingClientRect()
399
- // 使用容器中心作为缩放中心点
400
- const centerX = containerRect.width / 2
401
- const centerY = containerRect.height / 2
402
-
403
- // 计算中心点相对于图片原始坐标系的位置
404
- const relativeX = (centerX - this.position.x) / this.scale
405
- const relativeY = (centerY - this.position.y) / this.scale
406
-
407
- // 更新位置以保持中心点不变
408
- this.position.x = centerX - relativeX * newScale
409
- this.position.y = centerY - relativeY * newScale
410
- }
411
- this.scale = newScale
412
- },
413
-
414
- // 重置图片位置和大小
415
- resetImage() {
416
- this.position = { x: 0, y: 0 }
417
- this.scale = 1
418
- },
419
-
420
- // 重置所有状态
421
- resetState() {
422
- // 清理超时
423
- if (this.loadingTimeout) {
424
- clearTimeout(this.loadingTimeout)
425
- this.loadingTimeout = null
426
- }
427
- this.position = { x: 0, y: 0 }
428
- this.scale = 1
429
- this.imageLoading = false
430
- this.imageError = false
431
- this.isDragging = false
432
- }
433
- }
434
- }
435
- </script>
436
-
437
- <style lang="scss" scoped>
438
- .file-preview {
439
- display: inline-block;
440
-
441
- .preview-link {
442
- color: #409eff;
443
- cursor: pointer;
444
- text-decoration: none;
445
- transition: color 0.2s;
446
-
447
- &:hover {
448
- color: #66b1ff;
449
- text-decoration: underline;
450
- }
451
- }
452
- }
453
-
454
- .preview-wrapper {
455
- width: 100%;
456
- height: 750px;
457
- background: #000;
458
- position: relative;
459
- overflow: hidden;
460
- display: flex;
461
- align-items: center;
462
- justify-content: center;
463
- }
464
-
465
- .preview-container {
466
- width: 100%;
467
- height: 100%;
468
- display: flex;
469
- align-items: center;
470
- justify-content: center;
471
- position: relative;
472
- overflow: hidden;
473
- touch-action: none;
474
- /* 防止移动端默认行为 */
475
- }
476
-
477
- .preview-image {
478
- max-width: 100%;
479
- max-height: 100%;
480
- object-fit: contain;
481
- /* 关键:保持比例并适应容器 */
482
- transform-origin: 0 0;
483
- /* 设置为左上角以匹配我们的数学计算 */
484
- transition: transform 0.2s ease;
485
- user-select: none;
486
- -webkit-user-drag: none;
487
-
488
- /* 平滑的拖拽和缩放效果 */
489
- will-change: transform;
490
- }
491
-
492
- /* 操作工具栏 */
493
- .toolbar {
494
- position: absolute;
495
- bottom: 20px;
496
- left: 50%;
497
- transform: translateX(-50%);
498
- display: flex;
499
- gap: 10px;
500
- background: rgba(0, 0, 0, 0.7);
501
- padding: 10px;
502
- border-radius: 4px;
503
- z-index: 10;
504
- }
505
-
506
- .toolbar-btn {
507
- display: flex;
508
- align-items: center;
509
- justify-content: center;
510
- gap: 5px;
511
- background: rgba(255, 255, 255, 0.1);
512
- border: 1px solid rgba(255, 255, 255, 0.2);
513
- color: white;
514
- padding: 8px 12px;
515
- border-radius: 4px;
516
- cursor: pointer;
517
- font-size: 12px;
518
- transition: all 0.2s;
519
-
520
- &:hover {
521
- background: rgba(255, 255, 255, 0.2);
522
- border-color: rgba(255, 255, 255, 0.3);
523
- }
524
-
525
- &:active {
526
- transform: scale(0.95);
527
- }
528
-
529
- .icon {
530
- font-size: 14px;
531
- font-weight: bold;
532
- }
533
-
534
- .text {
535
- white-space: nowrap;
536
- }
537
- }
538
- </style>
539
-
540
- <style lang="scss">
541
- /* 对话框全局样式 */
542
- .image-preview-dialog {
543
- .el-dialog {
544
- background: #000;
545
- border: 1px solid #333;
546
- }
547
-
548
- .el-dialog__header {
549
- background: #000;
550
- border-bottom: 1px solid #333;
551
- padding: 10px 20px;
552
-
553
- .el-dialog__title {
554
- color: #fff;
555
- font-size: 14px;
556
- }
557
-
558
- .el-dialog__close {
559
- color: #fff;
560
-
561
- &:hover {
562
- color: #409eff;
563
- }
564
- }
565
- }
566
-
567
- .el-dialog__body {
568
- padding: 0 !important;
569
- background: #000 !important;
570
- overflow: hidden !important;
571
- }
572
- }
573
- </style>