mali-applet-ui 0.2.77 → 0.2.79

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.
@@ -64,6 +64,7 @@ export default {
64
64
  .ml-dict-type {
65
65
  display: inline-block;
66
66
  padding: 0 4rpx;
67
+ vertical-align: middle;
67
68
  &+.ml-dict-type {
68
69
  margin-left: 20rpx;
69
70
  }
@@ -257,6 +257,9 @@ export default {
257
257
  width: 100%;
258
258
  padding: 10rpx 0;
259
259
  }
260
+ .ml-form-item-default-content {
261
+ vertical-align: middle;
262
+ }
260
263
  .ml-form-item-content-error {
261
264
  position: absolute;
262
265
  left: 0;
@@ -66,6 +66,7 @@ export default {
66
66
  .ml-text {
67
67
  display: inline-block;
68
68
  padding: 0 4rpx;
69
+ vertical-align: middle;
69
70
  &.is-underline {
70
71
  text-decoration: underline;
71
72
  // #ifdef H5
@@ -95,6 +95,9 @@ export default {
95
95
  },
96
96
  computed: {
97
97
  isFromReadonly () {
98
+ if (this.readonly) {
99
+ return true
100
+ }
98
101
  return this.form ? this.form.readonly : false
99
102
  }
100
103
  },
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <view class="ml-upload" :class="[className || '']">
2
+ <view class="ml-upload" :class="[className || '', {'is-loading': loading}]">
3
3
  <!-- 上传图片 -->
4
4
  <view v-if="mediatype === 'image'" class="ml-upload-image-list">
5
5
  <view class="ml-upload-image-item" v-for="(item, index) in fileList" :key="index">
@@ -8,22 +8,26 @@
8
8
  <ml-icon name="close" />
9
9
  </view>
10
10
  </view>
11
- <view v-if="!isFromReadonly" class="ml-upload-image-add">
11
+ <view v-if="!isFromReadonly && fileList.length < limit" class="ml-upload-image-add">
12
12
  <view class="ml-upload-image-add-btn" @tap="chooseEvent">
13
13
  <view class="ml-upload-image-add-icon">
14
- <ml-icon name="add" />
14
+ <ml-icon v-if="loading" name="loading" roll />
15
+ <ml-icon v-else name="add" />
16
+ <view v-if="loading" class="ml-upload-image-add-loading-text">上传中...</view>
15
17
  </view>
16
18
  </view>
17
19
  </view>
18
20
  </view>
19
21
  <!-- 上传文件 -->
20
22
  <view v-else class="ml-upload-file-list">
21
- <view v-if="!isFromReadonly" class="ml-upload-file-add">
23
+ <view v-if="!isFromReadonly && fileList.length < limit" class="ml-upload-file-add">
22
24
  <view class="ml-upload-file-add-btn" @tap="chooseEvent">
23
25
  <text class="ml-upload-file-add-icon">
24
- <ml-icon name="add" />
26
+ <ml-icon v-if="loading" name="loading" roll />
27
+ <ml-icon v-else name="add" />
25
28
  </text>
26
- <text>添加文件</text>
29
+ <text v-if="loading">上传中...</text>
30
+ <text v-else>添加文件</text>
27
31
  </view>
28
32
  </view>
29
33
  <view class="ml-upload-file-item" v-for="(item, index) in fileList" :key="index">
@@ -39,9 +43,9 @@
39
43
  <ml-button status="primary" type="text" @click="downloadEvent(item)">下载</ml-button>
40
44
  </view>
41
45
  </view>
42
- <view v-if="!isFromReadonly || fileList.length <= limit" class="ml-upload-file-right">
46
+ <view v-if="!isFromReadonly" class="ml-upload-file-right">
43
47
  <view class="ml-upload-file-del-btn" @click="removeEvent(item)">
44
- <ml-icon name="close" />
48
+ <ml-icon name="close" />
45
49
  </view>
46
50
  </view>
47
51
  </view>
@@ -106,6 +110,7 @@ export default {
106
110
  },
107
111
  data () {
108
112
  return {
113
+ loading: false,
109
114
  fileList: [],
110
115
  docsTypes: ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx'],
111
116
  imgTypes: ['png', 'jpg']
@@ -173,7 +178,7 @@ export default {
173
178
  },
174
179
  loadList () {
175
180
  if (this.simpleValue) {
176
- this.fileList = this.urlList.map(url => {
181
+ this.fileList = (this.urlList || []).map(url => {
177
182
  const name = this.getUrlName(url)
178
183
  const obj = {
179
184
  id: null,
@@ -192,7 +197,7 @@ export default {
192
197
  this.isUpdate = true
193
198
  this.$emit('input', this.fileList)
194
199
  } else {
195
- this.fileList = this.value.map(item => {
200
+ this.fileList = (this.value || []).map(item => {
196
201
  item.tempPath = this.getUrl(item)
197
202
  return item
198
203
  })
@@ -351,6 +356,9 @@ export default {
351
356
  })
352
357
  },
353
358
  chooseEvent () {
359
+ if (this.loading) {
360
+ return
361
+ }
354
362
  let chooseMethod = uploadAllFiles
355
363
  if (this.mediatype === 'image') {
356
364
  chooseMethod = uploadImageFiles
@@ -360,6 +368,7 @@ export default {
360
368
  count: this.limit - this.fileList.length
361
369
  }).then(res => {
362
370
  const { tempFiles } = res
371
+ this.loading = true
363
372
  Promise.all(
364
373
  tempFiles.map(file => {
365
374
  const fileSuffix = this.getSuffix(file.name)
@@ -389,9 +398,13 @@ export default {
389
398
  this.fileList.push(...list)
390
399
  this.isUpdate = true
391
400
  this.updateModel()
401
+ this.loading = false
392
402
  }).catch((e) => {
393
403
  console.log(e)
404
+ this.loading = false
394
405
  })
406
+ }).catch(e => {
407
+ console.log(e)
395
408
  })
396
409
  }
397
410
  }
@@ -433,12 +446,23 @@ export default {
433
446
  .ml-upload-image-add-btn {
434
447
  width: 120rpx;
435
448
  height: 120rpx;
436
- line-height: 120rpx;
437
449
  font-size: 60rpx;
438
450
  color: #c8c8c9;
439
451
  border: 1px dashed #c8c8c9;
440
452
  border-radius: $ml-border-radius;
441
453
  }
454
+ .ml-upload-image-add-icon {
455
+ width: 100%;
456
+ height: 100%;
457
+ display: flex;
458
+ flex-direction: column;
459
+ align-items: center;
460
+ justify-content: center;
461
+ text-align: center;
462
+ }
463
+ .ml-upload-image-add-loading-text {
464
+ font-size: 24rpx;
465
+ }
442
466
  .ml-upload-image-img {
443
467
  width: 120rpx;
444
468
  height: 120rpx;
@@ -475,6 +499,9 @@ export default {
475
499
  border: 1px dashed #c8c8c9;
476
500
  border-radius: $ml-border-radius;
477
501
  }
502
+ .ml-upload-file-add-icon {
503
+ margin-right: 10rpx;
504
+ }
478
505
  .ml-upload-file-del-btn {
479
506
  width: 40rpx;
480
507
  height: 40rpx;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mali-applet-ui",
3
- "version": "0.2.77",
3
+ "version": "0.2.79",
4
4
  "description": "码里云小程序组件库",
5
5
  "scripts": {
6
6
  "release": "node script/release.js && npm publish"
@@ -1,410 +0,0 @@
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>