@ddwl/ddwl-ui 1.1.4 → 1.1.5-beta.1

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,356 +1,356 @@
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
-
130
- const imgExts = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'svg']
131
- const fileExts = ['doc', 'docx', 'pdf']
132
- const videoExts = ['mp4']
133
-
134
- export default {
135
- name: 'DUpload',
136
- components: { FilePreview },
137
- model: {
138
- prop: 'modelValue',
139
- event: 'change'
140
- },
141
- props: {
142
- readonly: {
143
- default: false,
144
- type: Boolean
145
- },
146
- limit: {
147
- default: 5,
148
- type: Number
149
- },
150
- limitSize: {
151
- default: 5,
152
- type: Number
153
- },
154
- imgExts: {
155
- type: Array,
156
- default: () => imgExts
157
- },
158
- fileExts: {
159
- type: Array,
160
- default: () => fileExts
161
- },
162
- videoExts: {
163
- type: Array,
164
- default: () => videoExts
165
- },
166
- limitType: {
167
- default: () => [...imgExts, ...fileExts, ...videoExts],
168
- type: [Array, String] // 兼容自定义表单配置
169
- },
170
- showFileList: {
171
- default: true,
172
- type: Boolean
173
- },
174
- modelValue: {
175
- default: () => [],
176
- type: Array
177
- },
178
- onSuccess: {
179
- default: () => [], // 外部传入上传成功处理函数,备用
180
- type: Function
181
- }
182
- },
183
- data () {
184
- return {
185
- list: [],
186
- dialogVisible: false,
187
- dialogImageUrl: '',
188
- videoBg,
189
- preveiwIndex: 0,
190
- previewVisible: false
191
- }
192
- },
193
- computed: {
194
- value: {
195
- get () {
196
- if (this.modelValue && this.modelValue.length && this.modelValue.some(v => typeof v === 'string')) {
197
- return this.modelValue.filter(url => url).map(url => this._urlToObj(url))
198
- } else {
199
- return this.modelValue || []
200
- }
201
- },
202
- set (value) {
203
- this.$emit('change', value)
204
- }
205
- },
206
- imgOrVideoList () {
207
- return this.value.filter(
208
- (item) => this._hasFileType(imgExts.concat(videoExts), item)
209
- )
210
- },
211
- restFileList () {
212
- return this.value.filter((item) => !this._hasFileType(imgExts.concat(videoExts), item))
213
- },
214
- limitSizeText () {
215
- return convertBytesToSize(Number(this.limitSize || 5) * 1024 * 1024)
216
- }
217
- },
218
- mounted () {
219
- },
220
- methods: {
221
- _hasFileType (files, item) {
222
- if (!item.fileExt) {
223
- return false
224
- }
225
- return files.includes(item.fileExt.toLowerCase())
226
- },
227
- _calcLimitType (limitType) {
228
- if (typeof limitType === 'string') return limitType.split(',').map(l => l.trim())
229
- return limitType
230
- },
231
- _urlToObj (url) {
232
- if (typeof url !== 'string') return url
233
- const name = url.substring(url.lastIndexOf('/') + 1, url.length) // 最后的文件名截取出来
234
- const fileExt = url.substring(url.lastIndexOf('.') + 1)
235
- return {
236
- name,
237
- fileExt,
238
- url,
239
- fileUrl: url
240
- }
241
- },
242
- async uploadRequest (data) {
243
- const formData = new FormData()
244
- formData.append('file', data.file)
245
- const res = await this.$DDWL.upload(formData)
246
- return res
247
- },
248
- beforeUpload (file) {
249
- const isLimit = file.size / 1024 / 1024 < this.limitSize
250
- const limitType = this._calcLimitType(this.limitType)
251
- const isType = limitType.includes(
252
- file.name.substr(file.name.lastIndexOf('.') + 1)
253
- )
254
-
255
- if (!isType) {
256
- this.$message.error(
257
- `请上传正确的文件格式(${limitType.join('、')})`
258
- )
259
- return false
260
- }
261
- if (!isLimit) {
262
- this.$message.error(`上传文件大小不能超过${this.limitSize}MB`)
263
- return false
264
- }
265
- },
266
- uploadSuccess (res, file) {
267
- if (res.code === 200) {
268
- this.value = this.value.concat({
269
- ...file,
270
- ...get(file, 'response.data'),
271
- fileUrl: get(file, 'response.data.filePath'),
272
- filePath: get(file, 'response.data.filePath')
273
- })
274
- this.$parent.$emit('el.form.change')
275
- } else {
276
- this.$message.error(res.message)
277
- }
278
- },
279
- uploadError (res) {
280
- console.log('upload error', res)
281
- },
282
- uploadRemove (file) {
283
- this.value = this.value.filter(item => item.fileUrl !== file.fileUrl)
284
- // const index = this.value.findIndex((item) => item.fileUrl === file.fileUrl)
285
- // index > -1 && this.value.splice(index, 1)
286
- this.$parent.$emit('el.form.change')
287
- },
288
- picturePreview (index) {
289
- this.preveiwIndex = index
290
- this.previewVisible = true
291
- }
292
- }
293
- }
294
- </script>
295
-
296
- <style lang='scss' scoped>
297
- .custom-upload-files-content {
298
- display: inline-block;
299
- width: 80px;
300
- height: 80px;
301
- text-align: center;
302
- & > span {
303
- line-height: 16px;
304
- margin-top: 4px;
305
- color: #999;
306
- font-size: 12px;
307
- }
308
- i {
309
- text-align: center;
310
- }
311
- }
312
- .custom-upload-files {
313
- display: inline-block;
314
- }
315
- .custom-upload-files-limit {
316
- :deep(.el-upload--picture-card) {
317
- display: none;
318
- }
319
- }
320
- .img-list {
321
- padding-left: 3px;
322
- display: block;
323
- line-height: 1;
324
- .img-part {
325
- width: 80px;
326
- height: 80px;
327
- }
328
- }
329
- .file-list {
330
- :deep(.el-upload-list__item:first-child) {
331
- margin-top: -5px;
332
- }
333
- }
334
- :deep(.upload-preview-dialog) {
335
- margin-top: 0vh !important;
336
- max-height: 90vh;
337
- max-width: 80%;
338
- min-width: 150px;
339
- min-height: 150px;
340
- width: inherit;
341
- display: flex;
342
- flex-direction: column;
343
- .el-dialog__body {
344
- flex: 1;
345
- overflow: auto;
346
- text-align: center;
347
- img{
348
- max-height: 65vh;
349
- }
350
- }
351
- }
352
- .el-upload__tip {
353
- line-height: 20px;
354
- margin-top: 0;
355
- }
356
- </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
+
130
+ const imgExts = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'svg']
131
+ const fileExts = ['doc', 'docx', 'pdf']
132
+ const videoExts = ['mp4']
133
+
134
+ export default {
135
+ name: 'DUpload',
136
+ components: { FilePreview },
137
+ model: {
138
+ prop: 'modelValue',
139
+ event: 'change'
140
+ },
141
+ props: {
142
+ readonly: {
143
+ default: false,
144
+ type: Boolean
145
+ },
146
+ limit: {
147
+ default: 5,
148
+ type: Number
149
+ },
150
+ limitSize: {
151
+ default: 5,
152
+ type: Number
153
+ },
154
+ imgExts: {
155
+ type: Array,
156
+ default: () => imgExts
157
+ },
158
+ fileExts: {
159
+ type: Array,
160
+ default: () => fileExts
161
+ },
162
+ videoExts: {
163
+ type: Array,
164
+ default: () => videoExts
165
+ },
166
+ limitType: {
167
+ default: () => [...imgExts, ...fileExts, ...videoExts],
168
+ type: [Array, String] // 兼容自定义表单配置
169
+ },
170
+ showFileList: {
171
+ default: true,
172
+ type: Boolean
173
+ },
174
+ modelValue: {
175
+ default: () => [],
176
+ type: Array
177
+ },
178
+ onSuccess: {
179
+ default: () => [], // 外部传入上传成功处理函数,备用
180
+ type: Function
181
+ }
182
+ },
183
+ data () {
184
+ return {
185
+ list: [],
186
+ dialogVisible: false,
187
+ dialogImageUrl: '',
188
+ videoBg,
189
+ preveiwIndex: 0,
190
+ previewVisible: false
191
+ }
192
+ },
193
+ computed: {
194
+ value: {
195
+ get () {
196
+ if (this.modelValue && this.modelValue.length && this.modelValue.some(v => typeof v === 'string')) {
197
+ return this.modelValue.filter(url => url).map(url => this._urlToObj(url))
198
+ } else {
199
+ return this.modelValue || []
200
+ }
201
+ },
202
+ set (value) {
203
+ this.$emit('change', value)
204
+ }
205
+ },
206
+ imgOrVideoList () {
207
+ return this.value.filter(
208
+ (item) => this._hasFileType(imgExts.concat(videoExts), item)
209
+ )
210
+ },
211
+ restFileList () {
212
+ return this.value.filter((item) => !this._hasFileType(imgExts.concat(videoExts), item))
213
+ },
214
+ limitSizeText () {
215
+ return convertBytesToSize(Number(this.limitSize || 5) * 1024 * 1024)
216
+ }
217
+ },
218
+ mounted () {
219
+ },
220
+ methods: {
221
+ _hasFileType (files, item) {
222
+ if (!item.fileExt) {
223
+ return false
224
+ }
225
+ return files.includes(item.fileExt.toLowerCase())
226
+ },
227
+ _calcLimitType (limitType) {
228
+ if (typeof limitType === 'string') return limitType.split(',').map(l => l.trim())
229
+ return limitType
230
+ },
231
+ _urlToObj (url) {
232
+ if (typeof url !== 'string') return url
233
+ const name = url.substring(url.lastIndexOf('/') + 1, url.length) // 最后的文件名截取出来
234
+ const fileExt = url.substring(url.lastIndexOf('.') + 1)
235
+ return {
236
+ name,
237
+ fileExt,
238
+ url,
239
+ fileUrl: url
240
+ }
241
+ },
242
+ async uploadRequest (data) {
243
+ const formData = new FormData()
244
+ formData.append('file', data.file)
245
+ const res = await this.$DDWL.upload(formData)
246
+ return res
247
+ },
248
+ beforeUpload (file) {
249
+ const isLimit = file.size / 1024 / 1024 < this.limitSize
250
+ const limitType = this._calcLimitType(this.limitType)
251
+ const isType = limitType.includes(
252
+ file.name.substr(file.name.lastIndexOf('.') + 1)
253
+ )
254
+
255
+ if (!isType) {
256
+ this.$message.error(
257
+ `请上传正确的文件格式(${limitType.join('、')})`
258
+ )
259
+ return false
260
+ }
261
+ if (!isLimit) {
262
+ this.$message.error(`上传文件大小不能超过${this.limitSize}MB`)
263
+ return false
264
+ }
265
+ },
266
+ uploadSuccess (res, file) {
267
+ if (res.code === 200) {
268
+ this.value = this.value.concat({
269
+ ...file,
270
+ ...get(file, 'response.data'),
271
+ fileUrl: get(file, 'response.data.filePath'),
272
+ filePath: get(file, 'response.data.filePath')
273
+ })
274
+ this.$parent.$emit('el.form.change')
275
+ } else {
276
+ this.$message.error(res.message)
277
+ }
278
+ },
279
+ uploadError (res) {
280
+ console.log('upload error', res)
281
+ },
282
+ uploadRemove (file) {
283
+ this.value = this.value.filter(item => item.fileUrl !== file.fileUrl)
284
+ // const index = this.value.findIndex((item) => item.fileUrl === file.fileUrl)
285
+ // index > -1 && this.value.splice(index, 1)
286
+ this.$parent.$emit('el.form.change')
287
+ },
288
+ picturePreview (index) {
289
+ this.preveiwIndex = index
290
+ this.previewVisible = true
291
+ }
292
+ }
293
+ }
294
+ </script>
295
+
296
+ <style lang='scss' scoped>
297
+ .custom-upload-files-content {
298
+ display: inline-block;
299
+ width: 80px;
300
+ height: 80px;
301
+ text-align: center;
302
+ & > span {
303
+ line-height: 16px;
304
+ margin-top: 4px;
305
+ color: #999;
306
+ font-size: 12px;
307
+ }
308
+ i {
309
+ text-align: center;
310
+ }
311
+ }
312
+ .custom-upload-files {
313
+ display: inline-block;
314
+ }
315
+ .custom-upload-files-limit {
316
+ :deep(.el-upload--picture-card) {
317
+ display: none;
318
+ }
319
+ }
320
+ .img-list {
321
+ padding-left: 3px;
322
+ display: block;
323
+ line-height: 1;
324
+ .img-part {
325
+ width: 80px;
326
+ height: 80px;
327
+ }
328
+ }
329
+ .file-list {
330
+ :deep(.el-upload-list__item:first-child) {
331
+ margin-top: -5px;
332
+ }
333
+ }
334
+ :deep(.upload-preview-dialog) {
335
+ margin-top: 0vh !important;
336
+ max-height: 90vh;
337
+ max-width: 80%;
338
+ min-width: 150px;
339
+ min-height: 150px;
340
+ width: inherit;
341
+ display: flex;
342
+ flex-direction: column;
343
+ .el-dialog__body {
344
+ flex: 1;
345
+ overflow: auto;
346
+ text-align: center;
347
+ img{
348
+ max-height: 65vh;
349
+ }
350
+ }
351
+ }
352
+ .el-upload__tip {
353
+ line-height: 20px;
354
+ margin-top: 0;
355
+ }
356
+ </style>