mali-applet-ui 0.2.71 → 0.2.72

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,33 +1,58 @@
1
1
  <template>
2
2
  <view class="ml-upload" :class="[className || '']">
3
- <view v-if="isFromReadonly">
4
- <view v-if="mediatype === 'image'" class="ml-upload-image-list">
5
- <view class="ml-upload-file-item" v-for="(item, index) in value" :key="index">
6
- <image class="ml-upload-file-img" mode="aspectFill" :src="getUrl(item)" @click="previewEvent(item, index)"></image>
3
+ <!-- 上传图片 -->
4
+ <view v-if="mediatype === 'image'" class="ml-upload-image-list">
5
+ <view class="ml-upload-image-item" v-for="(item, index) in fileList" :key="index">
6
+ <image class="ml-upload-image-img" mode="aspectFit" :src="getUrl(item)" @click="previewImageEvent(item, index)"></image>
7
+ <view class="ml-upload-image-del-btn" @click="removeEvent(item)">
8
+ <ml-icon name="close" />
7
9
  </view>
8
10
  </view>
9
- <view v-else class="ml-upload-file-list">
10
- <view class="ml-upload-file-item" v-for="(item, index) in value" :key="index">
11
- <view class="ml-upload-file-name" @click="downloadEvent(item)">{{ item[nameField] }}</view>
11
+ <view v-if="!isFromReadonly" class="ml-upload-image-add">
12
+ <view class="ml-upload-image-add-btn" @tap="chooseEvent">
13
+ <view class="ml-upload-image-add-icon">
14
+ <ml-icon name="add" />
15
+ </view>
16
+ </view>
17
+ </view>
18
+ </view>
19
+ <!-- 上传文件 -->
20
+ <view v-else class="ml-upload-file-list">
21
+ <view v-if="!isFromReadonly" class="ml-upload-file-add">
22
+ <view class="ml-upload-file-add-btn" @tap="chooseEvent">
23
+ <text class="ml-upload-file-add-icon">
24
+ <ml-icon name="add" />
25
+ </text>
26
+ <text>添加文件</text>
27
+ </view>
28
+ </view>
29
+ <view class="ml-upload-file-item" v-for="(item, index) in fileList" :key="index">
30
+ <view class="ml-upload-file-left">
31
+ <view class="ml-upload-file-icon">
32
+ <ml-icon :name="getFileIcon(item)" />
33
+ </view>
34
+ </view>
35
+ <view class="ml-upload-file-info">
36
+ <view class="ml-upload-file-name">{{ item[nameField] }}</view>
37
+ <view class="ml-upload-file-desc">
38
+ <ml-button v-if="docsTypes.includes(item[typeField])" status="primary" type="text" @click="previewDocs(item)">预览</ml-button>
39
+ <ml-button status="primary" type="text" @click="downloadEvent(item)">下载</ml-button>
40
+ </view>
41
+ </view>
42
+ <view class="ml-upload-file-right">
43
+ <view class="ml-upload-file-del-btn" @click="removeEvent(item)">
44
+ <ml-icon name="close" />
45
+ </view>
12
46
  </view>
13
47
  </view>
14
48
  </view>
15
- <uni-file-picker
16
- v-else
17
- v-model="selectUniFileList"
18
- :limit="limit"
19
- file-mediatype="image"
20
- :image-styles="imageStyles"
21
- :auto-upload="false"
22
- @select="selectFile"
23
- @delete="removeEvent">
24
- </uni-file-picker>
25
49
  </view>
26
50
  </template>
27
51
 
28
52
  <script>
29
53
  import XEUtils from 'xe-utils'
30
54
  import globalStore from '../../config/store'
55
+ import { uploadAllFiles, uploadImageFiles } from './file-handle'
31
56
 
32
57
  export default {
33
58
  name: 'MlUpload',
@@ -82,16 +107,7 @@ export default {
82
107
  data () {
83
108
  return {
84
109
  fileList: [],
85
- selectUniFileList: [],
86
- imageStyles: {
87
- // "height": 60, // 边框高度
88
- // "width": 60, // 边框宽度
89
- // "border":{ // 如果为 Boolean 值,可以控制边框显示与否
90
- // "color":"transparent", // 边框颜色
91
- // "width":"1px", // 边框宽度
92
- // "style":"solid", // 边框样式
93
- // }
94
- },
110
+ docsTypes: ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx'],
95
111
  imgTypes: ['png', 'jpg']
96
112
  }
97
113
  },
@@ -119,7 +135,7 @@ export default {
119
135
  }
120
136
  },
121
137
  watch: {
122
- value (val) {
138
+ value () {
123
139
  if (!this.isUpdate) {
124
140
  this.isUpdate = true
125
141
  this.loadList()
@@ -133,6 +149,25 @@ export default {
133
149
  this.loadList()
134
150
  },
135
151
  methods: {
152
+ getFileIcon (item) {
153
+ switch (item[[this.typeField]]) {
154
+ case 'png':
155
+ case 'jpg':
156
+ return 'file-image'
157
+ case 'doc':
158
+ case 'docx':
159
+ return 'file-word'
160
+ case 'xls':
161
+ case 'xlsx':
162
+ return 'file-excel'
163
+ case 'ppt':
164
+ case 'pptx':
165
+ return 'file-ppt'
166
+ case 'pdf':
167
+ return 'file-pdf'
168
+ }
169
+ return 'file-txt'
170
+ },
136
171
  loadList () {
137
172
  if (this.simpleValue) {
138
173
  this.fileList = this.urlList.map(url => {
@@ -151,21 +186,6 @@ export default {
151
186
  tempPath: this.getUrl(obj)
152
187
  }
153
188
  })
154
- this.selectUniFileList = this.urlList.map(url => {
155
- const name = this.getUrlName(url)
156
- const extname = this.getSuffix(name)
157
- const obj = {
158
- [this.nameField]: name,
159
- [this.typeField]: extname,
160
- [this.urlField]: url
161
- }
162
- return {
163
- ...obj,
164
- name: name,
165
- extname: extname,
166
- url: this.getUrl(obj)
167
- }
168
- })
169
189
  this.isUpdate = true
170
190
  this.$emit('input', this.fileList)
171
191
  } else {
@@ -173,14 +193,6 @@ export default {
173
193
  item.tempPath = this.getUrl(item)
174
194
  return item
175
195
  })
176
- this.selectUniFileList = this.value.map(item => {
177
- return {
178
- ...item,
179
- name: item[this.nameField],
180
- extname: item[this.typeField],
181
- url: this.getUrl(item)
182
- }
183
- })
184
196
  }
185
197
  },
186
198
  updateModel () {
@@ -189,61 +201,8 @@ export default {
189
201
  this.$emit('input', this.fileList)
190
202
  this.$emit('change', { value: this.simpleValue ? urlList : this.fileList })
191
203
  },
192
- async selectFile (e) {
193
- const { tempFiles } = e
194
- if (this.$loading) {
195
- this.$loading.show('上传中')
196
- }
197
- const uploadMethod = this.uploadFile ? this.uploadFile : (globalStore.upload ? globalStore.upload.uploadFile : null)
198
- Promise.all(
199
- tempFiles.map(file => {
200
- const fileSuffix = this.getSuffix(file.name)
201
- if (uploadMethod) {
202
- return Promise.resolve(
203
- uploadMethod.call(this.currVM, {
204
- file,
205
- params: this.params
206
- })
207
- ).then(res => {
208
- const item = {
209
- ...res,
210
- [this.nameField]: res[this.nameField] || file.name,
211
- [this.typeField]: res[this.typeField] || fileSuffix,
212
- tempPath: file.path
213
- }
214
- this.selectUniFileList.push(file)
215
- this.fileList.push(item)
216
- this.isUpdate = true
217
- this.updateModel()
218
- })
219
- } else {
220
- const item = {
221
- [this.nameField]: file.name,
222
- [this.typeField]: file.extname,
223
- [this.urlField]: file.path,
224
- tempPath: file.path
225
- }
226
- this.selectUniFileList.push(file)
227
- this.fileList.push(item)
228
- this.isUpdate = true
229
- this.updateModel()
230
- }
231
- })
232
- ).then(res => {
233
- if (this.$loading) {
234
- this.$loading.hide()
235
- }
236
- }).catch((e) => {
237
- if (this.$loading) {
238
- this.$loading.hide()
239
- }
240
- })
241
- },
242
- removeEvent (e) {
243
- const { tempFilePath } = e
244
- const item = this.fileList.find(item => item.tempPath === tempFilePath)
245
- this.selectUniFileList = this.selectUniFileList.filter(item => item.url !== tempFilePath)
246
- this.fileList = this.fileList.filter(item => item.tempPath !== tempFilePath)
204
+ removeEvent (item) {
205
+ this.fileList = this.fileList.filter(obj => obj.tempPath !== item.tempPath)
247
206
  const removeMethod = this.removeFile ? this.removeFile : (globalStore.upload ? globalStore.upload.removeFile : null)
248
207
  if (!item) {
249
208
  console.error('删除出错!!!')
@@ -281,7 +240,7 @@ export default {
281
240
  }
282
241
  return suffix
283
242
  },
284
- previewEvent (item, index) {
243
+ previewImageEvent (item, index) {
285
244
  if (this.previewStatus) {
286
245
  return
287
246
  }
@@ -327,40 +286,54 @@ export default {
327
286
  }
328
287
  })
329
288
  },
289
+ previewDocs (item) {
290
+ // 仅支持文档和图片
291
+ const supportDocs = this.docsTypes.includes(item[this.typeField])
292
+ const supportImg = this.imgTypes.includes(item[this.typeField])
293
+ if (supportDocs || supportImg) {
294
+ uni.downloadFile({
295
+ url: this.getUrl(item),
296
+ success: (downRes) => {
297
+ if (supportDocs) {
298
+ uni.openDocument({
299
+ filePath: downRes.tempFilePath,
300
+ showMenu: true,
301
+ success () {},
302
+ fail () {
303
+ uni.showModal({
304
+ content: '打开失败',
305
+ showCancel: false
306
+ })
307
+ }
308
+ })
309
+ } else if (supportImg) {
310
+ this.previewImg(item)
311
+ }
312
+ },
313
+ fail () {
314
+ uni.showModal({
315
+ content: '下载失败',
316
+ showCancel: false
317
+ })
318
+ }
319
+ })
320
+ }
321
+ },
330
322
  downloadEvent (item) {
331
323
  uni.downloadFile({
332
324
  url: this.getUrl(item),
333
325
  success: (downRes) => {
334
- // 仅支持类型
335
- if (['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx'].includes(item[this.typeField])) {
336
- uni.openDocument({
337
- filePath: downRes.tempFilePath,
338
- showMenu: true,
339
- success (saveRes) {
340
- },
341
- fail () {
342
- uni.showModal({
343
- content: '打开失败',
344
- showCancel: false
345
- });
346
- }
347
- })
348
- } else if (['png', 'jpg'].includes(item[this.typeField])) {
349
- this.previewImg(item)
350
- } else {
351
- uni.saveFile({
352
- tempFilePath: downRes.tempFilePath,
353
- success: function(res) {
354
- uni.showToast({
355
- icon: 'none',
356
- mask: true,
357
- title: '文件已保存:' + res.savedFilePath, //保存路径
358
- duration: 3000,
359
- })
360
- }
361
- })
362
-
363
- }
326
+ uni.saveFile({
327
+ tempFilePath: downRes.tempFilePath,
328
+ success: function(res) {
329
+ uni.showToast({
330
+ icon: 'none',
331
+ mask: true,
332
+ title: '文件已保存:' + res.savedFilePath, //保存路径
333
+ duration: 3000,
334
+ })
335
+ }
336
+ })
364
337
  },
365
338
  fail () {
366
339
  uni.showModal({
@@ -369,6 +342,50 @@ export default {
369
342
  });
370
343
  }
371
344
  })
345
+ },
346
+ chooseEvent () {
347
+ let chooseMethod = uploadAllFiles
348
+ if (this.mediatype === 'image') {
349
+ chooseMethod = uploadImageFiles
350
+ }
351
+ const uploadMethod = this.uploadFile ? this.uploadFile : (globalStore.upload ? globalStore.upload.uploadFile : null)
352
+ chooseMethod({
353
+ count: this.limit
354
+ }).then(res => {
355
+ const { tempFiles } = res
356
+ Promise.all(
357
+ tempFiles.map(file => {
358
+ const fileSuffix = this.getSuffix(file.name)
359
+ if (uploadMethod) {
360
+ return Promise.resolve(
361
+ uploadMethod.call(this.currVM, {
362
+ file,
363
+ params: this.params
364
+ })
365
+ ).then(res => {
366
+ return {
367
+ ...res,
368
+ [this.nameField]: res[this.nameField] || file.name,
369
+ [this.typeField]: res[this.typeField] || fileSuffix,
370
+ tempPath: file.path
371
+ }
372
+ })
373
+ }
374
+ return {
375
+ [this.nameField]: file.name,
376
+ [this.typeField]: file.extname,
377
+ [this.urlField]: file.path,
378
+ tempPath: file.path
379
+ }
380
+ })
381
+ ).then(list => {
382
+ this.fileList.push(...list)
383
+ this.isUpdate = true
384
+ this.updateModel()
385
+ }).catch((e) => {
386
+ console.log(e)
387
+ })
388
+ })
372
389
  }
373
390
  }
374
391
  }
@@ -380,31 +397,105 @@ export default {
380
397
  background: #fff;
381
398
  }
382
399
  .ml-upload-image-list {
383
- .ml-upload-file-item {
384
- display: inline-block;
400
+ display: flex;
401
+ flex-direction: row;
402
+ flex-wrap: wrap;
403
+ .ml-upload-image-item,
404
+ .ml-upload-image-add {
405
+ display: flex;
406
+ justify-content: center;
407
+ align-items: center;
408
+ position: relative;
385
409
  width: 140rpx;
386
410
  height: 140rpx;
387
- padding: 0 10rpx;
411
+ text-align: center;
388
412
  }
389
- .ml-upload-file-img {
390
- width: 100%;
391
- height: 100%;
413
+ .ml-upload-image-del-btn {
414
+ position: absolute;
415
+ right: 0;
416
+ top: 0;
417
+ width: 40rpx;
418
+ height: 40rpx;
419
+ line-height: 40rpx;
420
+ font-size: 28rpx;
421
+ text-align: center;
422
+ border-radius: 50%;
423
+ color: #ffffff;
424
+ background: #c8c8c9;
425
+ }
426
+ .ml-upload-image-add-btn {
427
+ width: 120rpx;
428
+ height: 120rpx;
429
+ line-height: 120rpx;
430
+ font-size: 60rpx;
431
+ color: #c8c8c9;
432
+ border: 1px dashed #c8c8c9;
433
+ border-radius: $ml-border-radius;
434
+ }
435
+ .ml-upload-image-img {
436
+ width: 120rpx;
437
+ height: 120rpx;
438
+ line-height: 120rpx;
439
+ border-radius: $ml-border-radius;
392
440
  }
393
441
  }
394
442
  .ml-upload-file-list {
395
- display: block;
443
+ .ml-upload-file-add,
396
444
  .ml-upload-file-item {
397
- border: 1rpx solid rgba(39, 42, 48, 0.0200);
398
- background-color: rgba(39, 42, 48, 0.0200);
399
- margin: 10rpx 0;
445
+ margin: 20rpx 0;
446
+ }
447
+ .ml-upload-file-item {
448
+ display: flex;
449
+ flex-direction: row;
450
+ }
451
+ .ml-upload-file-item {
452
+ padding-bottom: 10rpx;
453
+ border-bottom: 1px solid #f1f1f1;
454
+ }
455
+ .ml-upload-file-left,
456
+ .ml-upload-file-right {
457
+ display: flex;
458
+ flex-direction: row;
459
+ align-items: center;
460
+ justify-content: center;
461
+ flex-shrink: 0;
462
+ }
463
+ .ml-upload-file-add-btn {
464
+ height: 70rpx;
465
+ line-height: 70rpx;
466
+ text-align: center;
467
+ color: #8a8686;
468
+ border: 1px dashed #c8c8c9;
400
469
  border-radius: $ml-border-radius;
401
- padding: 20rpx;
402
470
  }
403
- .ml-upload-file-name {
404
- width: 600rpx;
471
+ .ml-upload-file-del-btn {
472
+ width: 40rpx;
473
+ height: 40rpx;
474
+ line-height: 40rpx;
475
+ text-align: center;
476
+ font-size: 28rpx;
477
+ color: #ffffff;
478
+ background: #c8c8c9;
479
+ border-radius: 50%;
480
+ }
481
+ .ml-upload-file-left {
482
+ width: 80rpx;
483
+ }
484
+ .ml-upload-file-icon {
485
+ font-size: 60rpx;
486
+ color: #666666;
487
+ }
488
+ .ml-upload-file-info {
489
+ flex-grow: 1;
405
490
  overflow: hidden;
406
- text-overflow: ellipsis;
407
- white-space: nowrap;
491
+ .ml-upload-file-name {
492
+ overflow: hidden;
493
+ text-overflow: ellipsis;
494
+ white-space: nowrap;
495
+ }
496
+ }
497
+ .ml-upload-file-right {
498
+ width: 60rpx;
408
499
  }
409
500
  }
410
501
  </style>
@@ -0,0 +1,410 @@
1
+ <template>
2
+ <view class="ml-upload" :class="[className || '']">
3
+ <view v-if="isFromReadonly">
4
+ <view v-if="mediatype === 'image'" class="ml-upload-image-list">
5
+ <view class="ml-upload-file-item" v-for="(item, index) in value" :key="index">
6
+ <image class="ml-upload-file-img" mode="aspectFill" :src="getUrl(item)" @click="previewEvent(item, index)"></image>
7
+ </view>
8
+ </view>
9
+ <view v-else class="ml-upload-file-list">
10
+ <view class="ml-upload-file-item" v-for="(item, index) in value" :key="index">
11
+ <view class="ml-upload-file-name" @click="downloadEvent(item)">{{ item[nameField] }}</view>
12
+ </view>
13
+ </view>
14
+ </view>
15
+ <uni-file-picker
16
+ v-else
17
+ v-model="selectUniFileList"
18
+ :limit="limit"
19
+ file-mediatype="image"
20
+ :image-styles="imageStyles"
21
+ :auto-upload="false"
22
+ @select="selectFile"
23
+ @delete="removeEvent">
24
+ </uni-file-picker>
25
+ </view>
26
+ </template>
27
+
28
+ <script>
29
+ import XEUtils from 'xe-utils'
30
+ import globalStore from '../../config/store'
31
+
32
+ export default {
33
+ name: 'MlUpload',
34
+ props: {
35
+ value: {
36
+ type: Array,
37
+ default: () => ([])
38
+ },
39
+ urlList: {
40
+ type: Array,
41
+ default: () => ([])
42
+ },
43
+ simpleValue: {
44
+ type: Boolean,
45
+ default: false
46
+ },
47
+ readonly: {
48
+ type: Boolean,
49
+ default: false
50
+ },
51
+ limit: {
52
+ type: Number,
53
+ default: 9
54
+ },
55
+ className: String,
56
+ mediatype: {
57
+ type: String,
58
+ default: 'all'
59
+ },
60
+ params: {
61
+ type: Object,
62
+ default: () => ({})
63
+ },
64
+ fileProps: {
65
+ type: Object,
66
+ default: () => ({})
67
+ },
68
+ getFileUrl: Function,
69
+ uploadFile: Function,
70
+ removeFile: Function
71
+ },
72
+ inject: {
73
+ currVM: {
74
+ from: '$pageVM',
75
+ default: null
76
+ },
77
+ form: {
78
+ from: 'mlForm',
79
+ default: null
80
+ }
81
+ },
82
+ data () {
83
+ return {
84
+ fileList: [],
85
+ selectUniFileList: [],
86
+ imageStyles: {
87
+ // "height": 60, // 边框高度
88
+ // "width": 60, // 边框宽度
89
+ // "border":{ // 如果为 Boolean 值,可以控制边框显示与否
90
+ // "color":"transparent", // 边框颜色
91
+ // "width":"1px", // 边框宽度
92
+ // "style":"solid", // 边框样式
93
+ // }
94
+ },
95
+ imgTypes: ['png', 'jpg']
96
+ }
97
+ },
98
+ computed: {
99
+ isFromReadonly () {
100
+ if (this.readonly) {
101
+ return true
102
+ }
103
+ return this.form ? this.form.readonly : false
104
+ },
105
+ imageList () {
106
+ return this.value ? this.value.filter(item => this.imgTypes.includes(item[this.typeField])) : []
107
+ },
108
+ fieldMaps () {
109
+ return { ...globalStore.upload.fileProps, ...this.fileProps }
110
+ },
111
+ urlField () {
112
+ return this.fieldMaps.fileUrl || 'fileUrl'
113
+ },
114
+ typeField () {
115
+ return this.fieldMaps.fileType || 'fileType'
116
+ },
117
+ nameField () {
118
+ return this.fieldMaps.fileName || 'fileName'
119
+ }
120
+ },
121
+ watch: {
122
+ value (val) {
123
+ if (!this.isUpdate) {
124
+ this.isUpdate = true
125
+ this.loadList()
126
+ }
127
+ },
128
+ urlList () {
129
+ this.loadList()
130
+ }
131
+ },
132
+ created () {
133
+ this.loadList()
134
+ },
135
+ methods: {
136
+ loadList () {
137
+ if (this.simpleValue) {
138
+ this.fileList = this.urlList.map(url => {
139
+ const name = this.getUrlName(url)
140
+ const obj = {
141
+ id: null,
142
+ [this.nameField]: name,
143
+ [this.typeField]: this.getSuffix(name),
144
+ [this.urlField]: url
145
+ }
146
+ return {
147
+ id: null,
148
+ [this.nameField]: name,
149
+ [this.typeField]: this.getSuffix(name),
150
+ [this.urlField]: url,
151
+ tempPath: this.getUrl(obj)
152
+ }
153
+ })
154
+ this.selectUniFileList = this.urlList.map(url => {
155
+ const name = this.getUrlName(url)
156
+ const extname = this.getSuffix(name)
157
+ const obj = {
158
+ [this.nameField]: name,
159
+ [this.typeField]: extname,
160
+ [this.urlField]: url
161
+ }
162
+ return {
163
+ ...obj,
164
+ name: name,
165
+ extname: extname,
166
+ url: this.getUrl(obj)
167
+ }
168
+ })
169
+ this.isUpdate = true
170
+ this.$emit('input', this.fileList)
171
+ } else {
172
+ this.fileList = this.value.map(item => {
173
+ item.tempPath = this.getUrl(item)
174
+ return item
175
+ })
176
+ this.selectUniFileList = this.value.map(item => {
177
+ return {
178
+ ...item,
179
+ name: item[this.nameField],
180
+ extname: item[this.typeField],
181
+ url: this.getUrl(item)
182
+ }
183
+ })
184
+ }
185
+ },
186
+ updateModel () {
187
+ const urlList = this.fileList.map(item => item[this.urlField])
188
+ this.$emit('update:urlList', urlList)
189
+ this.$emit('input', this.fileList)
190
+ this.$emit('change', { value: this.simpleValue ? urlList : this.fileList })
191
+ },
192
+ async selectFile (e) {
193
+ const { tempFiles } = e
194
+ if (this.$loading) {
195
+ this.$loading.show('上传中')
196
+ }
197
+ const uploadMethod = this.uploadFile ? this.uploadFile : (globalStore.upload ? globalStore.upload.uploadFile : null)
198
+ Promise.all(
199
+ tempFiles.map(file => {
200
+ const fileSuffix = this.getSuffix(file.name)
201
+ if (uploadMethod) {
202
+ return Promise.resolve(
203
+ uploadMethod.call(this.currVM, {
204
+ file,
205
+ params: this.params
206
+ })
207
+ ).then(res => {
208
+ const item = {
209
+ ...res,
210
+ [this.nameField]: res[this.nameField] || file.name,
211
+ [this.typeField]: res[this.typeField] || fileSuffix,
212
+ tempPath: file.path
213
+ }
214
+ this.selectUniFileList.push(file)
215
+ this.fileList.push(item)
216
+ this.isUpdate = true
217
+ this.updateModel()
218
+ })
219
+ } else {
220
+ const item = {
221
+ [this.nameField]: file.name,
222
+ [this.typeField]: file.extname,
223
+ [this.urlField]: file.path,
224
+ tempPath: file.path
225
+ }
226
+ this.selectUniFileList.push(file)
227
+ this.fileList.push(item)
228
+ this.isUpdate = true
229
+ this.updateModel()
230
+ }
231
+ })
232
+ ).then(res => {
233
+ if (this.$loading) {
234
+ this.$loading.hide()
235
+ }
236
+ }).catch((e) => {
237
+ if (this.$loading) {
238
+ this.$loading.hide()
239
+ }
240
+ })
241
+ },
242
+ removeEvent (e) {
243
+ const { tempFilePath } = e
244
+ const item = this.fileList.find(item => item.tempPath === tempFilePath)
245
+ this.selectUniFileList = this.selectUniFileList.filter(item => item.url !== tempFilePath)
246
+ this.fileList = this.fileList.filter(item => item.tempPath !== tempFilePath)
247
+ const removeMethod = this.removeFile ? this.removeFile : (globalStore.upload ? globalStore.upload.removeFile : null)
248
+ if (!item) {
249
+ console.error('删除出错!!!')
250
+ }
251
+ if (item && !item.id) {
252
+ if (removeMethod) {
253
+ removeMethod.call(this.currVM, {
254
+ item,
255
+ params: this.params
256
+ })
257
+ }
258
+ }
259
+ this.isUpdate = true
260
+ this.updateModel()
261
+ },
262
+ getUrl (item) {
263
+ const getFileMethod = this.getFileUrl ? this.getFileUrl : (globalStore.upload ? globalStore.upload.getFileUrl : null)
264
+ if (getFileMethod) {
265
+ return getFileMethod.call(this.currVM, {
266
+ item,
267
+ params: this.params
268
+ })
269
+ }
270
+ return item[this.urlField]
271
+ },
272
+ getUrlName (url) {
273
+ const urlRest = XEUtils.parseUrl(url)
274
+ return urlRest.pathname.split('/').slice(-1)[0] || ''
275
+ },
276
+ getSuffix (filename) {
277
+ const pos = filename.lastIndexOf('.')
278
+ let suffix = ''
279
+ if (pos !== -1) {
280
+ suffix = filename.substring(pos + 1)
281
+ }
282
+ return suffix
283
+ },
284
+ previewEvent (item, index) {
285
+ if (this.previewStatus) {
286
+ return
287
+ }
288
+ this.previewStatus = true
289
+ Promise.all(
290
+ this.value.map(item => {
291
+ return new Promise((resolve) => {
292
+ uni.downloadFile({
293
+ url: this.getUrl(item),
294
+ success: (downRes) => {
295
+ resolve({
296
+ url: downRes.tempFilePath
297
+ })
298
+ },
299
+ fail () {
300
+ resolve({
301
+ url: ''
302
+ })
303
+ }
304
+ })
305
+ })
306
+ })
307
+ ).then(res => {
308
+ uni.previewImage({
309
+ current: index,
310
+ urls: res.map(item => item.url)
311
+ })
312
+ this.previewStatus = false
313
+ })
314
+ },
315
+ previewImg (item) {
316
+ uni.downloadFile({
317
+ url: this.getUrl(item),
318
+ success: (downRes) => {
319
+ uni.previewImage({
320
+ urls: [
321
+ downRes.tempFilePath
322
+ ],
323
+ longPressActions: {
324
+ itemList: ['保存图片']
325
+ }
326
+ })
327
+ }
328
+ })
329
+ },
330
+ downloadEvent (item) {
331
+ uni.downloadFile({
332
+ url: this.getUrl(item),
333
+ success: (downRes) => {
334
+ // 仅支持类型
335
+ if (['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx'].includes(item[this.typeField])) {
336
+ uni.openDocument({
337
+ filePath: downRes.tempFilePath,
338
+ showMenu: true,
339
+ success (saveRes) {
340
+ },
341
+ fail () {
342
+ uni.showModal({
343
+ content: '打开失败',
344
+ showCancel: false
345
+ });
346
+ }
347
+ })
348
+ } else if (['png', 'jpg'].includes(item[this.typeField])) {
349
+ this.previewImg(item)
350
+ } else {
351
+ uni.saveFile({
352
+ tempFilePath: downRes.tempFilePath,
353
+ success: function(res) {
354
+ uni.showToast({
355
+ icon: 'none',
356
+ mask: true,
357
+ title: '文件已保存:' + res.savedFilePath, //保存路径
358
+ duration: 3000,
359
+ })
360
+ }
361
+ })
362
+
363
+ }
364
+ },
365
+ fail () {
366
+ uni.showModal({
367
+ content: '下载失败',
368
+ showCancel: false
369
+ });
370
+ }
371
+ })
372
+ }
373
+ }
374
+ }
375
+ </script>
376
+
377
+ <style lang="scss">
378
+ .ml-upload{
379
+ margin: 20rpx 0;
380
+ background: #fff;
381
+ }
382
+ .ml-upload-image-list {
383
+ .ml-upload-file-item {
384
+ display: inline-block;
385
+ width: 140rpx;
386
+ height: 140rpx;
387
+ padding: 0 10rpx;
388
+ }
389
+ .ml-upload-file-img {
390
+ width: 100%;
391
+ height: 100%;
392
+ }
393
+ }
394
+ .ml-upload-file-list {
395
+ display: block;
396
+ .ml-upload-file-item {
397
+ border: 1rpx solid rgba(39, 42, 48, 0.0200);
398
+ background-color: rgba(39, 42, 48, 0.0200);
399
+ margin: 10rpx 0;
400
+ border-radius: $ml-border-radius;
401
+ padding: 20rpx;
402
+ }
403
+ .ml-upload-file-name {
404
+ width: 600rpx;
405
+ overflow: hidden;
406
+ text-overflow: ellipsis;
407
+ white-space: nowrap;
408
+ }
409
+ }
410
+ </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mali-applet-ui",
3
- "version": "0.2.71",
3
+ "version": "0.2.72",
4
4
  "description": "码里云小程序组件库",
5
5
  "scripts": {
6
6
  "release": "node script/release.js && npm publish"
package/utils/date.js CHANGED
@@ -7,7 +7,7 @@ import XEUtils from 'xe-utils'
7
7
  * @returns
8
8
  */
9
9
  export function toDateString (date, format = 'yyyy-MM-dd HH:mm:ss') {
10
- return XEUtils.toDateString(date, format.replace('YYYY', 'yyyy').replace('DD', 'dd'))
10
+ return XEUtils.toDateString(date, format.replace('YYYY', 'yyyy').replace('DD', 'dd').replace('D', 'd'))
11
11
  }
12
12
 
13
13
  /**
@@ -1,480 +0,0 @@
1
- <template>
2
- <view class="ml-upload" :class="[className || '']">
3
- <!-- 上传图片 -->
4
- <view v-if="mediatype === 'image'" class="ml-upload-image-list">
5
- <view class="ml-upload-image-item" v-for="(item, index) in fileList" :key="index">
6
- <image class="ml-upload-image-img" mode="aspectFit" :src="getUrl(item)" @click="previewImageEvent(item, index)"></image>
7
- <view class="ml-upload-image-del-btn" @click="removeEvent(item)">
8
- <ml-icon name="close" />
9
- </view>
10
- </view>
11
- <view class="ml-upload-image-add">
12
- <view class="ml-upload-image-add-btn" @tap="chooseEvent">
13
- <view class="ml-upload-image-add-icon">
14
- <ml-icon name="add" />
15
- </view>
16
- </view>
17
- </view>
18
- </view>
19
- <!-- 上传文件 -->
20
- <view v-else class="ml-upload-file-list">
21
- <view class="ml-upload-file-add">
22
- <view class="ml-upload-file-add-btn" @tap="chooseEvent">
23
- <text class="ml-upload-file-add-icon">
24
- <ml-icon name="add" />
25
- </text>
26
- <text>添加文件</text>
27
- </view>
28
- </view>
29
- <view class="ml-upload-file-item" v-for="(item, index) in fileList" :key="index">
30
- <view class="ml-upload-file-left">
31
- <view class="ml-upload-file-icon">
32
- <ml-icon name="file-txt" />
33
- </view>
34
- </view>
35
- <view class="ml-upload-file-info">
36
- <view class="ml-upload-file-name">{{ item[nameField] }}</view>
37
- <view class="ml-upload-file-desc">
38
- <ml-button status="primary" type="text" @click="previewDocs(item)">预览</ml-button>
39
- <ml-button status="primary" type="text" @click="downloadEvent(item)">下载</ml-button>
40
- </view>
41
- </view>
42
- <view class="ml-upload-file-right">
43
- <view class="ml-upload-file-del-btn" @click="removeEvent(item)">
44
- <ml-icon name="close" />
45
- </view>
46
- </view>
47
- </view>
48
- </view>
49
- </view>
50
- </template>
51
-
52
- <script>
53
- import XEUtils from 'xe-utils'
54
- import globalStore from '../../config/store'
55
- import mlButton from '../ml-button/ml-button.vue'
56
- import { uploadAllFiles, uploadImageFiles } from './file-handle'
57
-
58
- export default {
59
- components: { mlButton },
60
- name: 'MlUpload',
61
- props: {
62
- value: {
63
- type: Array,
64
- default: () => ([])
65
- },
66
- urlList: {
67
- type: Array,
68
- default: () => ([])
69
- },
70
- simpleValue: {
71
- type: Boolean,
72
- default: false
73
- },
74
- readonly: {
75
- type: Boolean,
76
- default: false
77
- },
78
- limit: {
79
- type: Number,
80
- default: 9
81
- },
82
- className: String,
83
- mediatype: {
84
- type: String,
85
- default: 'all'
86
- },
87
- params: {
88
- type: Object,
89
- default: () => ({})
90
- },
91
- fileProps: {
92
- type: Object,
93
- default: () => ({})
94
- },
95
- getFileUrl: Function,
96
- uploadFile: Function,
97
- removeFile: Function
98
- },
99
- inject: {
100
- currVM: {
101
- from: '$pageVM',
102
- default: null
103
- },
104
- form: {
105
- from: 'mlForm',
106
- default: null
107
- }
108
- },
109
- data () {
110
- return {
111
- fileList: [],
112
- docsTypes: ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx'],
113
- imgTypes: ['png', 'jpg']
114
- }
115
- },
116
- computed: {
117
- isFromReadonly () {
118
- if (this.readonly) {
119
- return true
120
- }
121
- return this.form ? this.form.readonly : false
122
- },
123
- imageList () {
124
- return this.value ? this.value.filter(item => this.imgTypes.includes(item[this.typeField])) : []
125
- },
126
- fieldMaps () {
127
- return { ...globalStore.upload.fileProps, ...this.fileProps }
128
- },
129
- urlField () {
130
- return this.fieldMaps.fileUrl || 'fileUrl'
131
- },
132
- typeField () {
133
- return this.fieldMaps.fileType || 'fileType'
134
- },
135
- nameField () {
136
- return this.fieldMaps.fileName || 'fileName'
137
- }
138
- },
139
- watch: {
140
- value () {
141
- if (!this.isUpdate) {
142
- this.isUpdate = true
143
- this.loadList()
144
- }
145
- },
146
- urlList () {
147
- this.loadList()
148
- }
149
- },
150
- created () {
151
- this.loadList()
152
- },
153
- methods: {
154
- loadList () {
155
- if (this.simpleValue) {
156
- this.fileList = this.urlList.map(url => {
157
- const name = this.getUrlName(url)
158
- const obj = {
159
- id: null,
160
- [this.nameField]: name,
161
- [this.typeField]: this.getSuffix(name),
162
- [this.urlField]: url
163
- }
164
- return {
165
- id: null,
166
- [this.nameField]: name,
167
- [this.typeField]: this.getSuffix(name),
168
- [this.urlField]: url,
169
- tempPath: this.getUrl(obj)
170
- }
171
- })
172
- this.isUpdate = true
173
- this.$emit('input', this.fileList)
174
- } else {
175
- this.fileList = this.value.map(item => {
176
- item.tempPath = this.getUrl(item)
177
- return item
178
- })
179
- }
180
- },
181
- updateModel () {
182
- const urlList = this.fileList.map(item => item[this.urlField])
183
- this.$emit('update:urlList', urlList)
184
- this.$emit('input', this.fileList)
185
- this.$emit('change', { value: this.simpleValue ? urlList : this.fileList })
186
- },
187
- removeEvent (item) {
188
- this.fileList = this.fileList.filter(obj => obj.tempPath !== item.tempPath)
189
- const removeMethod = this.removeFile ? this.removeFile : (globalStore.upload ? globalStore.upload.removeFile : null)
190
- if (!item) {
191
- console.error('删除出错!!!')
192
- }
193
- if (item && !item.id) {
194
- if (removeMethod) {
195
- removeMethod.call(this.currVM, {
196
- item,
197
- params: this.params
198
- })
199
- }
200
- }
201
- this.isUpdate = true
202
- this.updateModel()
203
- },
204
- getUrl (item) {
205
- const getFileMethod = this.getFileUrl ? this.getFileUrl : (globalStore.upload ? globalStore.upload.getFileUrl : null)
206
- if (getFileMethod) {
207
- return getFileMethod.call(this.currVM, {
208
- item,
209
- params: this.params
210
- })
211
- }
212
- return item[this.urlField]
213
- },
214
- getUrlName (url) {
215
- const urlRest = XEUtils.parseUrl(url)
216
- return urlRest.pathname.split('/').slice(-1)[0] || ''
217
- },
218
- getSuffix (filename) {
219
- const pos = filename.lastIndexOf('.')
220
- let suffix = ''
221
- if (pos !== -1) {
222
- suffix = filename.substring(pos + 1)
223
- }
224
- return suffix
225
- },
226
- previewImageEvent (item, index) {
227
- if (this.previewStatus) {
228
- return
229
- }
230
- this.previewStatus = true
231
- Promise.all(
232
- this.value.map(item => {
233
- return new Promise((resolve) => {
234
- uni.downloadFile({
235
- url: this.getUrl(item),
236
- success: (downRes) => {
237
- resolve({
238
- url: downRes.tempFilePath
239
- })
240
- },
241
- fail () {
242
- resolve({
243
- url: ''
244
- })
245
- }
246
- })
247
- })
248
- })
249
- ).then(res => {
250
- uni.previewImage({
251
- current: index,
252
- urls: res.map(item => item.url)
253
- })
254
- this.previewStatus = false
255
- })
256
- },
257
- previewImg (item) {
258
- uni.downloadFile({
259
- url: this.getUrl(item),
260
- success: (downRes) => {
261
- uni.previewImage({
262
- urls: [
263
- downRes.tempFilePath
264
- ],
265
- longPressActions: {
266
- itemList: ['保存图片']
267
- }
268
- })
269
- }
270
- })
271
- },
272
- previewDocs (item) {
273
- // 仅支持文档和图片
274
- const supportDocs = this.docsTypes.includes(item[this.typeField])
275
- const supportImg = this.imgTypes.includes(item[this.typeField])
276
- if (supportDocs || supportImg) {
277
- uni.downloadFile({
278
- url: this.getUrl(item),
279
- success: (downRes) => {
280
- if (supportDocs) {
281
- uni.openDocument({
282
- filePath: downRes.tempFilePath,
283
- showMenu: true,
284
- success () {},
285
- fail () {
286
- uni.showModal({
287
- content: '打开失败',
288
- showCancel: false
289
- })
290
- }
291
- })
292
- } else if (supportImg) {
293
- this.previewImg(item)
294
- }
295
- },
296
- fail () {
297
- uni.showModal({
298
- content: '下载失败',
299
- showCancel: false
300
- })
301
- }
302
- })
303
- }
304
- },
305
- downloadEvent (item) {
306
- uni.downloadFile({
307
- url: this.getUrl(item),
308
- success: (downRes) => {
309
- uni.saveFile({
310
- tempFilePath: downRes.tempFilePath,
311
- success: function(res) {
312
- uni.showToast({
313
- icon: 'none',
314
- mask: true,
315
- title: '文件已保存:' + res.savedFilePath, //保存路径
316
- duration: 3000,
317
- })
318
- }
319
- })
320
- },
321
- fail () {
322
- uni.showModal({
323
- content: '下载失败',
324
- showCancel: false
325
- });
326
- }
327
- })
328
- },
329
- chooseEvent () {
330
- let chooseMethod = uploadAllFiles
331
- if (this.mediatype === 'image') {
332
- chooseMethod = uploadImageFiles
333
- }
334
- const uploadMethod = this.uploadFile ? this.uploadFile : (globalStore.upload ? globalStore.upload.uploadFile : null)
335
- chooseMethod({}).then(res => {
336
- const { tempFiles } = res
337
- Promise.all(
338
- tempFiles.map(file => {
339
- const fileSuffix = this.getSuffix(file.name)
340
- if (uploadMethod) {
341
- return Promise.resolve(
342
- uploadMethod.call(this.currVM, {
343
- file,
344
- params: this.params
345
- })
346
- ).then(res => {
347
- return {
348
- ...res,
349
- [this.nameField]: res[this.nameField] || file.name,
350
- [this.typeField]: res[this.typeField] || fileSuffix,
351
- tempPath: file.path
352
- }
353
- })
354
- }
355
- return {
356
- [this.nameField]: file.name,
357
- [this.typeField]: file.extname,
358
- [this.urlField]: file.path,
359
- tempPath: file.path
360
- }
361
- })
362
- ).then(list => {
363
- this.fileList.push(...list)
364
- this.isUpdate = true
365
- this.updateModel()
366
- }).catch((e) => {
367
- console.log(e)
368
- })
369
- })
370
- }
371
- }
372
- }
373
- </script>
374
-
375
- <style lang="scss">
376
- .ml-upload{
377
- margin: 20rpx 0;
378
- background: #fff;
379
- }
380
- .ml-upload-image-list {
381
- display: flex;
382
- flex-direction: row;
383
- flex-wrap: wrap;
384
- .ml-upload-image-item,
385
- .ml-upload-image-add {
386
- display: flex;
387
- justify-content: center;
388
- align-items: center;
389
- position: relative;
390
- width: 140rpx;
391
- height: 140rpx;
392
- text-align: center;
393
- }
394
- .ml-upload-image-del-btn {
395
- position: absolute;
396
- right: 0;
397
- top: 0;
398
- width: 40rpx;
399
- height: 40rpx;
400
- line-height: 40rpx;
401
- font-size: 28rpx;
402
- text-align: center;
403
- border-radius: 50%;
404
- color: #ffffff;
405
- background: #c8c8c9;
406
- }
407
- .ml-upload-image-add-btn {
408
- width: 100rpx;
409
- height: 100rpx;
410
- line-height: 100rpx;
411
- font-size: 60rpx;
412
- color: #c8c8c9;
413
- border: 1px solid #c8c8c9;
414
- border-radius: 50%;
415
- }
416
- .ml-upload-image-img {
417
- width: 120rpx;
418
- height: 120rpx;
419
- line-height: 120rpx;
420
- border-radius: $ml-border-radius;
421
- }
422
- }
423
- .ml-upload-file-list {
424
- .ml-upload-file-add,
425
- .ml-upload-file-item {
426
- margin: 20rpx 0;
427
- }
428
- .ml-upload-file-item {
429
- display: flex;
430
- flex-direction: row;
431
- }
432
- .ml-upload-file-item {
433
- padding-bottom: 10rpx;
434
- border-bottom: 1px solid #f1f1f1;
435
- }
436
- .ml-upload-file-left,
437
- .ml-upload-file-right {
438
- display: flex;
439
- flex-direction: row;
440
- align-items: center;
441
- justify-content: center;
442
- flex-shrink: 0;
443
- }
444
- .ml-upload-file-add-btn {
445
- height: 70rpx;
446
- line-height: 70rpx;
447
- text-align: center;
448
- color: #8a8686;
449
- border: 1px solid #c8c8c9;
450
- border-radius: $ml-border-radius;
451
- }
452
- .ml-upload-file-del-btn {
453
- width: 40rpx;
454
- height: 40rpx;
455
- line-height: 40rpx;
456
- text-align: center;
457
- font-size: 28rpx;
458
- color: #ffffff;
459
- background: #c8c8c9;
460
- border-radius: 50%;
461
- }
462
- .ml-upload-file-left {
463
- width: 80rpx;
464
- }
465
- .ml-upload-file-icon {
466
- font-size: 60rpx;
467
- }
468
- .ml-upload-file-info {
469
- flex-grow: 1;
470
- .ml-upload-file-name {
471
- overflow: hidden;
472
- text-overflow: ellipsis;
473
- white-space: nowrap;
474
- }
475
- }
476
- .ml-upload-file-right {
477
- width: 60rpx;
478
- }
479
- }
480
- </style>