@ddwl/ddwl-ui 1.1.5 → 1.1.6

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.
@@ -1,352 +1,352 @@
1
- <!-- 上传组件 -->
2
- <template>
3
- <div>
4
- <div
5
- v-show="imgOrVideoList.length || !readonly"
6
- ref="imgList"
7
- class="img-list el-upload-list el-upload-list--picture-card"
8
- >
9
- <div
10
- v-for="(file, index) in imgOrVideoList"
11
- v-show="imgOrVideoList.length"
12
- :key="file.uid"
13
- class="img-part el-upload-list__item is-success"
14
- >
15
- <el-image
16
- v-if="_hasFileType(imgExts, file)"
17
- class="el-upload-list__item-thumbnail"
18
- :src="file.fileUrl"
19
- />
20
- <el-image
21
- v-if="_hasFileType(videoExts, file)"
22
- class="el-upload-list__item-thumbnail"
23
- :src="videoBg"
24
- />
25
- <span class="el-upload-list__item-actions">
26
- <span
27
- v-if="_hasFileType(imgExts, file)"
28
- class="el-upload-list__item-preview"
29
- @click="picturePreview(index)"
30
- >
31
- <i class="el-icon-zoom-in" />
32
- </span>
33
- <span
34
- v-if="_hasFileType(videoExts, file)"
35
- class="el-upload-list__item-preview"
36
- @click="picturePreview(index)"
37
- >
38
- <i class="el-icon-video-play" />
39
- </span>
40
- <span
41
- v-show="!readonly"
42
- class="el-upload-list__item-delete"
43
- @click="uploadRemove(file)"
44
- >
45
- <i class="el-icon-delete" />
46
- </span>
47
- </span>
48
- </div>
49
- <div
50
- v-show="!readonly && value.length < limit"
51
- class="img-part el-upload-list__item is-success"
52
- style="border: none"
53
- >
54
- <el-upload
55
- ref="fileUpload"
56
- class="custom-upload-files"
57
- :class="
58
- showFileList && list.length >= limit && 'custom-upload-files-limit'
59
- "
60
- v-bind="$attrs"
61
- :show-file-list="false"
62
- action="#"
63
- :file-list="list"
64
- list-type="picture-card"
65
- :http-request="uploadRequest"
66
- :before-upload="beforeUpload"
67
- :on-success="uploadSuccess"
68
- :on-error="uploadError"
69
- v-on="$listeners"
70
- >
71
- <div
72
- slot="default"
73
- class="custom-upload-files-content"
74
- >
75
- <i class="el-icon-plus" />
76
- </div>
77
- </el-upload>
78
- </div>
79
- </div>
80
- <div class="file-list">
81
- <div
82
- v-for="file in restFileList"
83
- :key="file.uid"
84
- class="el-upload-list__item is-success"
85
- style="width: 100%; height: auto"
86
- >
87
- <a
88
- class="el-upload-list__item-name"
89
- :href="file.fileUrl"
90
- :download="file.name || file.fileName"
91
- >
92
- <i class="el-icon-document" />
93
- {{ file.name || file.fileName }}
94
- </a>
95
- <label class="el-upload-list__item-status-label">
96
- <i
97
- v-show="!readonly"
98
- class="el-icon-upload-success el-icon-circle-check"
99
- />
100
- </label>
101
- <i
102
- v-show="!readonly"
103
- class="el-icon-close"
104
- @click="uploadRemove(file)"
105
- />
106
- </div>
107
- </div>
108
- <div
109
- v-show="!readonly"
110
- slot="tip"
111
- class="el-upload__tip"
112
- >
113
- 文件大小不超过 {{ limitSizeText }} , 支持扩展名: {{ (_calcLimitType(limitType) || []).join(' ') }}
114
- </div>
115
- <file-preview
116
- v-if="previewVisible"
117
- :default-index="preveiwIndex"
118
- :list="imgOrVideoList.map(i=> i.fileUrl)"
119
- @close="previewVisible = false"
120
- />
121
- </div>
122
- </template>
123
-
124
- <script>
125
- import { get } from 'lodash'
126
- import videoBg from '../../assets/video-play.jpeg'
127
- import { convertBytesToSize } from '@/utils'
128
- import FilePreview from '../file-preview/index.vue'
129
- import {imgExts, videoExts, fileExts} from '../../utils/constant'
130
- export default {
131
- name: 'DUpload',
132
- components: { FilePreview },
133
- model: {
134
- prop: 'modelValue',
135
- event: 'change'
136
- },
137
- props: {
138
- readonly: {
139
- default: false,
140
- type: Boolean
141
- },
142
- limit: {
143
- default: 5,
144
- type: Number
145
- },
146
- limitSize: {
147
- default: 5,
148
- type: Number
149
- },
150
- imgExts: {
151
- type: Array,
152
- default: () => imgExts
153
- },
154
- fileExts: {
155
- type: Array,
156
- default: () => fileExts
157
- },
158
- videoExts: {
159
- type: Array,
160
- default: () => videoExts
161
- },
162
- limitType: {
163
- default: () => [...imgExts, ...fileExts, ...videoExts],
164
- type: [Array, String] // 兼容自定义表单配置
165
- },
166
- showFileList: {
167
- default: true,
168
- type: Boolean
169
- },
170
- modelValue: {
171
- default: () => [],
172
- type: Array
173
- },
174
- onSuccess: {
175
- default: () => [], // 外部传入上传成功处理函数,备用
176
- type: Function
177
- }
178
- },
179
- data () {
180
- return {
181
- list: [],
182
- dialogVisible: false,
183
- dialogImageUrl: '',
184
- videoBg,
185
- preveiwIndex: 0,
186
- previewVisible: false
187
- }
188
- },
189
- computed: {
190
- value: {
191
- get () {
192
- if (this.modelValue && this.modelValue.length && this.modelValue.some(v => typeof v === 'string')) {
193
- return this.modelValue.filter(url => url).map(url => this._urlToObj(url))
194
- } else {
195
- return this.modelValue || []
196
- }
197
- },
198
- set (value) {
199
- this.$emit('change', value)
200
- }
201
- },
202
- imgOrVideoList () {
203
- return this.value.filter(
204
- (item) => this._hasFileType(imgExts.concat(videoExts), item)
205
- )
206
- },
207
- restFileList () {
208
- return this.value.filter((item) => !this._hasFileType(imgExts.concat(videoExts), item))
209
- },
210
- limitSizeText () {
211
- return convertBytesToSize(Number(this.limitSize || 5) * 1024 * 1024)
212
- }
213
- },
214
- mounted () {
215
- },
216
- methods: {
217
- _hasFileType (files, item) {
218
- if (!item.fileExt) {
219
- return false
220
- }
221
- return files.includes(item.fileExt.toLowerCase())
222
- },
223
- _calcLimitType (limitType) {
224
- if (typeof limitType === 'string') return limitType.split(',').map(l => l.trim())
225
- return limitType
226
- },
227
- _urlToObj (url) {
228
- if (typeof url !== 'string') return url
229
- const name = url.substring(url.lastIndexOf('/') + 1, url.length) // 最后的文件名截取出来
230
- const fileExt = url.substring(url.lastIndexOf('.') + 1)
231
- return {
232
- name,
233
- fileExt,
234
- url,
235
- fileUrl: url
236
- }
237
- },
238
- async uploadRequest (data) {
239
- const formData = new FormData()
240
- formData.append('file', data.file)
241
- const res = await this.$DDWL.upload(formData)
242
- return res
243
- },
244
- beforeUpload (file) {
245
- const isLimit = file.size / 1024 / 1024 < this.limitSize
246
- const limitType = this._calcLimitType(this.limitType)
247
- const isType = limitType.includes(
248
- file.name.substr(file.name.lastIndexOf('.') + 1)
249
- )
250
-
251
- if (!isType) {
252
- this.$message.error(
253
- `请上传正确的文件格式(${limitType.join('、')})`
254
- )
255
- return false
256
- }
257
- if (!isLimit) {
258
- this.$message.error(`上传文件大小不能超过${this.limitSize}MB`)
259
- return false
260
- }
261
- },
262
- uploadSuccess (res, file) {
263
- if (res.code === 200) {
264
- this.value = this.value.concat({
265
- ...file,
266
- ...get(file, 'response.data'),
267
- fileUrl: get(file, 'response.data.filePath'),
268
- filePath: get(file, 'response.data.filePath')
269
- })
270
- this.$parent.$emit('el.form.change')
271
- } else {
272
- this.$message.error(res.message)
273
- }
274
- },
275
- uploadError (res) {
276
- console.log('upload error', res)
277
- },
278
- uploadRemove (file) {
279
- this.value = this.value.filter(item => item.fileUrl !== file.fileUrl)
280
- // const index = this.value.findIndex((item) => item.fileUrl === file.fileUrl)
281
- // index > -1 && this.value.splice(index, 1)
282
- this.$parent.$emit('el.form.change')
283
- },
284
- picturePreview (index) {
285
- this.preveiwIndex = index
286
- this.previewVisible = true
287
- }
288
- }
289
- }
290
- </script>
291
-
292
- <style lang='scss' scoped>
293
- .custom-upload-files-content {
294
- display: inline-block;
295
- width: 80px;
296
- height: 80px;
297
- text-align: center;
298
- & > span {
299
- line-height: 16px;
300
- margin-top: 4px;
301
- color: #999;
302
- font-size: 12px;
303
- }
304
- i {
305
- text-align: center;
306
- }
307
- }
308
- .custom-upload-files {
309
- display: inline-block;
310
- }
311
- .custom-upload-files-limit {
312
- :deep(.el-upload--picture-card) {
313
- display: none;
314
- }
315
- }
316
- .img-list {
317
- padding-left: 3px;
318
- display: block;
319
- line-height: 1;
320
- .img-part {
321
- width: 80px;
322
- height: 80px;
323
- }
324
- }
325
- .file-list {
326
- :deep(.el-upload-list__item:first-child) {
327
- margin-top: -5px;
328
- }
329
- }
330
- :deep(.upload-preview-dialog) {
331
- margin-top: 0vh !important;
332
- max-height: 90vh;
333
- max-width: 80%;
334
- min-width: 150px;
335
- min-height: 150px;
336
- width: inherit;
337
- display: flex;
338
- flex-direction: column;
339
- .el-dialog__body {
340
- flex: 1;
341
- overflow: auto;
342
- text-align: center;
343
- img{
344
- max-height: 65vh;
345
- }
346
- }
347
- }
348
- .el-upload__tip {
349
- line-height: 20px;
350
- margin-top: 0;
351
- }
352
- </style>
1
+ <!-- 上传组件 -->
2
+ <template>
3
+ <div>
4
+ <div
5
+ v-show="imgOrVideoList.length || !readonly"
6
+ ref="imgList"
7
+ class="img-list el-upload-list el-upload-list--picture-card"
8
+ >
9
+ <div
10
+ v-for="(file, index) in imgOrVideoList"
11
+ v-show="imgOrVideoList.length"
12
+ :key="file.uid"
13
+ class="img-part el-upload-list__item is-success"
14
+ >
15
+ <el-image
16
+ v-if="_hasFileType(imgExts, file)"
17
+ class="el-upload-list__item-thumbnail"
18
+ :src="file.fileUrl"
19
+ />
20
+ <el-image
21
+ v-if="_hasFileType(videoExts, file)"
22
+ class="el-upload-list__item-thumbnail"
23
+ :src="videoBg"
24
+ />
25
+ <span class="el-upload-list__item-actions">
26
+ <span
27
+ v-if="_hasFileType(imgExts, file)"
28
+ class="el-upload-list__item-preview"
29
+ @click="picturePreview(index)"
30
+ >
31
+ <i class="el-icon-zoom-in" />
32
+ </span>
33
+ <span
34
+ v-if="_hasFileType(videoExts, file)"
35
+ class="el-upload-list__item-preview"
36
+ @click="picturePreview(index)"
37
+ >
38
+ <i class="el-icon-video-play" />
39
+ </span>
40
+ <span
41
+ v-show="!readonly"
42
+ class="el-upload-list__item-delete"
43
+ @click="uploadRemove(file)"
44
+ >
45
+ <i class="el-icon-delete" />
46
+ </span>
47
+ </span>
48
+ </div>
49
+ <div
50
+ v-show="!readonly && value.length < limit"
51
+ class="img-part el-upload-list__item is-success"
52
+ style="border: none"
53
+ >
54
+ <el-upload
55
+ ref="fileUpload"
56
+ class="custom-upload-files"
57
+ :class="
58
+ showFileList && list.length >= limit && 'custom-upload-files-limit'
59
+ "
60
+ v-bind="$attrs"
61
+ :show-file-list="false"
62
+ action="#"
63
+ :file-list="list"
64
+ list-type="picture-card"
65
+ :http-request="uploadRequest"
66
+ :before-upload="beforeUpload"
67
+ :on-success="uploadSuccess"
68
+ :on-error="uploadError"
69
+ v-on="$listeners"
70
+ >
71
+ <div
72
+ slot="default"
73
+ class="custom-upload-files-content"
74
+ >
75
+ <i class="el-icon-plus" />
76
+ </div>
77
+ </el-upload>
78
+ </div>
79
+ </div>
80
+ <div class="file-list">
81
+ <div
82
+ v-for="file in restFileList"
83
+ :key="file.uid"
84
+ class="el-upload-list__item is-success"
85
+ style="width: 100%; height: auto"
86
+ >
87
+ <a
88
+ class="el-upload-list__item-name"
89
+ :href="file.fileUrl"
90
+ :download="file.name || file.fileName"
91
+ >
92
+ <i class="el-icon-document" />
93
+ {{ file.name || file.fileName }}
94
+ </a>
95
+ <label class="el-upload-list__item-status-label">
96
+ <i
97
+ v-show="!readonly"
98
+ class="el-icon-upload-success el-icon-circle-check"
99
+ />
100
+ </label>
101
+ <i
102
+ v-show="!readonly"
103
+ class="el-icon-close"
104
+ @click="uploadRemove(file)"
105
+ />
106
+ </div>
107
+ </div>
108
+ <div
109
+ v-show="!readonly"
110
+ slot="tip"
111
+ class="el-upload__tip"
112
+ >
113
+ 文件大小不超过 {{ limitSizeText }} , 支持扩展名: {{ (_calcLimitType(limitType) || []).join(' ') }}
114
+ </div>
115
+ <file-preview
116
+ v-if="previewVisible"
117
+ :default-index="preveiwIndex"
118
+ :list="imgOrVideoList.map(i=> i.fileUrl)"
119
+ @close="previewVisible = false"
120
+ />
121
+ </div>
122
+ </template>
123
+
124
+ <script>
125
+ import { get } from 'lodash'
126
+ import videoBg from '../../assets/video-play.jpeg'
127
+ import { convertBytesToSize } from '@/utils'
128
+ import FilePreview from '../file-preview/index.vue'
129
+ import {imgExts, videoExts, fileExts} from '../../utils/constant'
130
+ export default {
131
+ name: 'DUpload',
132
+ components: { FilePreview },
133
+ model: {
134
+ prop: 'modelValue',
135
+ event: 'change'
136
+ },
137
+ props: {
138
+ readonly: {
139
+ default: false,
140
+ type: Boolean
141
+ },
142
+ limit: {
143
+ default: 5,
144
+ type: Number
145
+ },
146
+ limitSize: {
147
+ default: 5,
148
+ type: Number
149
+ },
150
+ imgExts: {
151
+ type: Array,
152
+ default: () => imgExts
153
+ },
154
+ fileExts: {
155
+ type: Array,
156
+ default: () => fileExts
157
+ },
158
+ videoExts: {
159
+ type: Array,
160
+ default: () => videoExts
161
+ },
162
+ limitType: {
163
+ default: () => [...imgExts, ...fileExts, ...videoExts],
164
+ type: [Array, String] // 兼容自定义表单配置
165
+ },
166
+ showFileList: {
167
+ default: true,
168
+ type: Boolean
169
+ },
170
+ modelValue: {
171
+ default: () => [],
172
+ type: Array
173
+ },
174
+ onSuccess: {
175
+ default: () => [], // 外部传入上传成功处理函数,备用
176
+ type: Function
177
+ }
178
+ },
179
+ data () {
180
+ return {
181
+ list: [],
182
+ dialogVisible: false,
183
+ dialogImageUrl: '',
184
+ videoBg,
185
+ preveiwIndex: 0,
186
+ previewVisible: false
187
+ }
188
+ },
189
+ computed: {
190
+ value: {
191
+ get () {
192
+ if (this.modelValue && this.modelValue.length && this.modelValue.some(v => typeof v === 'string')) {
193
+ return this.modelValue.filter(url => url).map(url => this._urlToObj(url))
194
+ } else {
195
+ return this.modelValue || []
196
+ }
197
+ },
198
+ set (value) {
199
+ this.$emit('change', value)
200
+ }
201
+ },
202
+ imgOrVideoList () {
203
+ return this.value.filter(
204
+ (item) => this._hasFileType(imgExts.concat(videoExts), item)
205
+ )
206
+ },
207
+ restFileList () {
208
+ return this.value.filter((item) => !this._hasFileType(imgExts.concat(videoExts), item))
209
+ },
210
+ limitSizeText () {
211
+ return convertBytesToSize(Number(this.limitSize || 5) * 1024 * 1024)
212
+ }
213
+ },
214
+ mounted () {
215
+ },
216
+ methods: {
217
+ _hasFileType (files, item) {
218
+ if (!item.fileExt) {
219
+ return false
220
+ }
221
+ return files.includes(item.fileExt.toLowerCase())
222
+ },
223
+ _calcLimitType (limitType) {
224
+ if (typeof limitType === 'string') return limitType.split(',').map(l => l.trim())
225
+ return limitType
226
+ },
227
+ _urlToObj (url) {
228
+ if (typeof url !== 'string') return url
229
+ const name = url.substring(url.lastIndexOf('/') + 1, url.length) // 最后的文件名截取出来
230
+ const fileExt = url.substring(url.lastIndexOf('.') + 1)
231
+ return {
232
+ name,
233
+ fileExt,
234
+ url,
235
+ fileUrl: url
236
+ }
237
+ },
238
+ async uploadRequest (data) {
239
+ const formData = new FormData()
240
+ formData.append('file', data.file)
241
+ const res = await this.$DDWL.upload(formData)
242
+ return res
243
+ },
244
+ beforeUpload (file) {
245
+ const isLimit = file.size / 1024 / 1024 < this.limitSize
246
+ const limitType = this._calcLimitType(this.limitType)
247
+ const isType = limitType.includes(
248
+ file.name.substr(file.name.lastIndexOf('.') + 1)
249
+ )
250
+
251
+ if (!isType) {
252
+ this.$message.error(
253
+ `请上传正确的文件格式(${limitType.join('、')})`
254
+ )
255
+ return false
256
+ }
257
+ if (!isLimit) {
258
+ this.$message.error(`上传文件大小不能超过${this.limitSize}MB`)
259
+ return false
260
+ }
261
+ },
262
+ uploadSuccess (res, file) {
263
+ if (res.code === 200) {
264
+ this.value = this.value.concat({
265
+ ...file,
266
+ ...get(file, 'response.data'),
267
+ fileUrl: get(file, 'response.data.filePath'),
268
+ filePath: get(file, 'response.data.filePath')
269
+ })
270
+ this.$parent.$emit('el.form.change')
271
+ } else {
272
+ this.$message.error(res.message)
273
+ }
274
+ },
275
+ uploadError (res) {
276
+ console.log('upload error', res)
277
+ },
278
+ uploadRemove (file) {
279
+ this.value = this.value.filter(item => item.fileUrl !== file.fileUrl)
280
+ // const index = this.value.findIndex((item) => item.fileUrl === file.fileUrl)
281
+ // index > -1 && this.value.splice(index, 1)
282
+ this.$parent.$emit('el.form.change')
283
+ },
284
+ picturePreview (index) {
285
+ this.preveiwIndex = index
286
+ this.previewVisible = true
287
+ }
288
+ }
289
+ }
290
+ </script>
291
+
292
+ <style lang='scss' scoped>
293
+ .custom-upload-files-content {
294
+ display: inline-block;
295
+ width: 80px;
296
+ height: 80px;
297
+ text-align: center;
298
+ & > span {
299
+ line-height: 16px;
300
+ margin-top: 4px;
301
+ color: #999;
302
+ font-size: 12px;
303
+ }
304
+ i {
305
+ text-align: center;
306
+ }
307
+ }
308
+ .custom-upload-files {
309
+ display: inline-block;
310
+ }
311
+ .custom-upload-files-limit {
312
+ :deep(.el-upload--picture-card) {
313
+ display: none;
314
+ }
315
+ }
316
+ .img-list {
317
+ padding-left: 3px;
318
+ display: block;
319
+ line-height: 1;
320
+ .img-part {
321
+ width: 80px;
322
+ height: 80px;
323
+ }
324
+ }
325
+ .file-list {
326
+ :deep(.el-upload-list__item:first-child) {
327
+ margin-top: -5px;
328
+ }
329
+ }
330
+ :deep(.upload-preview-dialog) {
331
+ margin-top: 0vh !important;
332
+ max-height: 90vh;
333
+ max-width: 80%;
334
+ min-width: 150px;
335
+ min-height: 150px;
336
+ width: inherit;
337
+ display: flex;
338
+ flex-direction: column;
339
+ .el-dialog__body {
340
+ flex: 1;
341
+ overflow: auto;
342
+ text-align: center;
343
+ img{
344
+ max-height: 65vh;
345
+ }
346
+ }
347
+ }
348
+ .el-upload__tip {
349
+ line-height: 20px;
350
+ margin-top: 0;
351
+ }
352
+ </style>