xydata-tools 1.0.43 → 1.0.44

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.
Files changed (48) hide show
  1. package/README.md +1 -2
  2. package/dist/assets/file-icon/document.png +0 -0
  3. package/dist/assets/file-icon/image.png +0 -0
  4. package/dist/assets/file-icon/ms-excel.png +0 -0
  5. package/dist/assets/file-icon/ms-powerpoint.png +0 -0
  6. package/dist/assets/file-icon/ms-word.png +0 -0
  7. package/dist/assets/file-icon/pdf.png +0 -0
  8. package/dist/assets/file-icon/video.png +0 -0
  9. package/dist/components/uni-app/{FilePicker.vue → file-picker/file-picker.vue} +172 -252
  10. package/dist/components/uni-app/file-picker/styles.scss +201 -0
  11. package/dist/components/uni-app/media-picker/media-picker.vue +1127 -0
  12. package/dist/components/uni-app/media-picker/shmily-drag-media.vue +777 -0
  13. package/dist/components/uni-app/media-picker/styles.scss +520 -0
  14. package/dist/types/components/aaa/auth/index.d.ts +1 -1
  15. package/dist/types/components/aaa/setting/permission/components/UpdateForm.d.ts +1 -1
  16. package/dist/types/components/aaa/setting/permission/components/UriModal.d.ts +1 -1
  17. package/dist/types/components/aaa/setting/permission/index.d.ts +1 -1
  18. package/dist/types/components/aaa/setting/requesturl/components/UpdateForm.d.ts +1 -1
  19. package/dist/types/components/aaa/setting/requesturl/index.d.ts +1 -1
  20. package/dist/types/components/aaa/setting/role/components/UpdateForm.d.ts +1 -1
  21. package/dist/types/components/aaa/setting/role/index.d.ts +1 -1
  22. package/dist/types/components/aaa/setting/user/components/UpdateForm.d.ts +1 -1
  23. package/dist/types/components/aaa/setting/user/index.d.ts +1 -1
  24. package/dist/types/components/both/security-layout/index.d.ts +1 -1
  25. package/dist/types/components/dictionary/components/UpdateForm.d.ts +1 -1
  26. package/dist/types/components/dictionary/index.d.ts +1 -1
  27. package/dist/types/components/downloadFile/index.d.ts +1 -1
  28. package/dist/types/components/materialCard/index.d.ts +1 -1
  29. package/dist/types/components/organization/components/CreatePeopleForm.d.ts +1 -1
  30. package/dist/types/components/organization/components/CreateSubStoreForm.d.ts +1 -1
  31. package/dist/types/components/organization/components/OrgTree.d.ts +1 -1
  32. package/dist/types/components/organization/index.d.ts +1 -1
  33. package/dist/types/components/sso/security-layout/index.d.ts +1 -1
  34. package/dist/types/components/sso/setting/permRole/index.d.ts +1 -1
  35. package/dist/types/components/sso/setting/permission/components/UpdateForm.d.ts +1 -1
  36. package/dist/types/components/sso/setting/permission/index.d.ts +1 -1
  37. package/dist/types/components/sso/setting/role/components/UpdateForm.d.ts +1 -1
  38. package/dist/types/components/sso/setting/role/index.d.ts +1 -1
  39. package/dist/types/components/sso/setting/user/components/RoleUpdateForm.d.ts +1 -1
  40. package/dist/types/components/sso/setting/user/index.d.ts +1 -1
  41. package/dist/types/components/tools/version.d.ts +1 -1
  42. package/dist/types/components/uploadFile/index.d.ts +1 -1
  43. package/dist/uniapp.d.ts +452 -0
  44. package/dist/uniapp.js +2 -7
  45. package/package.json +28 -5
  46. package/dist/components/uni-app/PicPicker.vue +0 -498
  47. package/dist/components/uni-app/VideoPicker.vue +0 -508
  48. package/dist/types/uniapp.d.ts +0 -1
package/README.md CHANGED
@@ -30,8 +30,7 @@
30
30
 
31
31
  #### uni-app 组件
32
32
 
33
- - [PicPicker - 图片选择器](./docs/uniapp/PicPicker.md)
34
- - [VideoPicker - 视频选择器](./docs/uniapp/VideoPicker.md)
33
+ - [MediaPicker - 媒体选择器](./docs/uniapp/MediaPicker.md)
35
34
  - [FilePicker - 文件选择器](./docs/uniapp/FilePicker.md)
36
35
 
37
36
  ### 模版使用文档
Binary file
Binary file
Binary file
@@ -6,7 +6,7 @@
6
6
  <view class="file-item uploading-item" v-if="uploading">
7
7
  <view class="file-info">
8
8
  <view class="file-icon">
9
- <image class="loading-icon" src="../../assets/loading.png" />
9
+ <image class="loading-icon" src="../../../assets/loading.png" />
10
10
  </view>
11
11
  <view class="file-content">
12
12
  <text class="file-name">上传中 {{ uploadProgress }}%</text>
@@ -22,7 +22,7 @@
22
22
  <!-- 默认上传按钮 -->
23
23
  <button class="upload-btn" v-if="fileList.length < limit && !uploading"
24
24
  @click="selectAndUploadFile">
25
- 上传文档
25
+ {{ buttonTitle }}
26
26
  </button>
27
27
  </slot>
28
28
 
@@ -57,7 +57,7 @@
57
57
  </view>
58
58
  </view>
59
59
  </view>
60
- </view>
60
+ </view>
61
61
  </view>
62
62
  </template>
63
63
 
@@ -94,6 +94,11 @@ export default {
94
94
  maxSize: {
95
95
  type: Number,
96
96
  default: 20
97
+ },
98
+ /** 上传按钮文字 */
99
+ buttonTitle: {
100
+ type: String,
101
+ default: '上传附件'
97
102
  }
98
103
  },
99
104
  data() {
@@ -101,17 +106,6 @@ export default {
101
106
  fileList: [],
102
107
  uploading: false,
103
108
  uploadProgress: 0,
104
- // 文件图标映射
105
- fileIcons: {
106
- doc: 'https://img.icons8.com/color/96/000000/ms-word.png',
107
- docx: 'https://img.icons8.com/color/96/000000/ms-word.png',
108
- xls: 'https://img.icons8.com/color/96/000000/ms-excel.png',
109
- xlsx: 'https://img.icons8.com/color/96/000000/ms-excel.png',
110
- ppt: 'https://img.icons8.com/color/96/000000/ms-powerpoint.png',
111
- pptx: 'https://img.icons8.com/color/96/000000/ms-powerpoint.png',
112
- pdf: 'https://img.icons8.com/color/96/000000/pdf.png',
113
- default: 'https://img.icons8.com/color/96/000000/document.png'
114
- },
115
109
  actualUploadUrl: '' // 实际使用的上传地址
116
110
  }
117
111
  },
@@ -143,6 +137,17 @@ export default {
143
137
  }
144
138
  },
145
139
  methods: {
140
+ // ==================== 事件监听辅助方法 ====================
141
+ /**
142
+ * 检查事件是否被监听
143
+ * @param {String} eventName - 事件名称
144
+ * @returns {Boolean} - 是否被监听
145
+ */
146
+ hasEventListener(eventName) {
147
+ return !!(this.$listeners && this.$listeners[eventName])
148
+ },
149
+
150
+ // ==================== 文件处理方法 ====================
146
151
  /**
147
152
  * 获取文件扩展名
148
153
  */
@@ -157,7 +162,39 @@ export default {
157
162
  */
158
163
  getFileIcon(fileName) {
159
164
  const ext = this.getFileExtension(fileName)
160
- return this.fileIcons[ext] || this.fileIcons.default
165
+ switch (ext) {
166
+ case 'doc':
167
+ case 'docx':
168
+ return require('../../../assets/file-icon/ms-word.png')
169
+ case 'xls':
170
+ case 'xlsx':
171
+ return require('../../../assets/file-icon/ms-excel.png')
172
+ case 'ppt':
173
+ case 'pptx':
174
+ return require('../../../assets/file-icon/ms-powerpoint.png')
175
+ case 'pdf':
176
+ return require('../../../assets/file-icon/pdf.png')
177
+ case 'png':
178
+ case 'jpeg':
179
+ case 'jpg':
180
+ case 'gif':
181
+ case 'webp':
182
+ case 'svg':
183
+ return require('../../../assets/file-icon/image.png')
184
+ case 'mp4':
185
+ case 'mov':
186
+ case 'avi':
187
+ case 'wmv':
188
+ case 'flv':
189
+ case 'mkv':
190
+ case 'webm':
191
+ case 'mpg':
192
+ case 'mpeg':
193
+ case 'm4v':
194
+ return require('../../../assets/file-icon/video.png')
195
+ default:
196
+ return require('../../../assets/file-icon/document.png')
197
+ }
161
198
  },
162
199
 
163
200
  /**
@@ -184,10 +221,19 @@ export default {
184
221
 
185
222
  if (this.fileList.length >= this.limit || this.uploading) {
186
223
  if (this.fileList.length >= this.limit) {
187
- uni.showToast({
188
- title: `最多上传${this.limit}个文件`,
189
- icon: 'none'
224
+ // 触发文件数量限制事件
225
+ this.$emit('fileLimitReached', {
226
+ current: this.fileList.length,
227
+ limit: this.limit
190
228
  })
229
+
230
+ // 如果用户未监听事件,显示默认提示
231
+ if (!this.hasEventListener('fileLimitReached')) {
232
+ uni.showToast({
233
+ title: `最多上传${this.limit}个文件`,
234
+ icon: 'none'
235
+ })
236
+ }
191
237
  }
192
238
  return
193
239
  }
@@ -232,20 +278,44 @@ export default {
232
278
  const ext = this.getFileExtension(fileName)
233
279
 
234
280
  if (!this.accept.includes(ext)) {
235
- uni.showToast({
236
- title: `只支持${this.accept.join(', ')}格式`,
237
- icon: 'none'
281
+ // 触发文件类型不支持事件
282
+ this.$emit('fileTypeInvalid', {
283
+ fileName: fileName,
284
+ fileType: ext,
285
+ acceptTypes: this.accept,
286
+ file: file,
287
+ message: `只支持${this.accept.join(', ')}格式`
238
288
  })
289
+
290
+ // 如果用户未监听事件,显示默认提示
291
+ if (!this.hasEventListener('fileTypeInvalid')) {
292
+ uni.showToast({
293
+ title: `只支持${this.accept.join(', ')}格式`,
294
+ icon: 'none'
295
+ })
296
+ }
239
297
  return
240
298
  }
241
299
 
242
300
  // 验证文件大小
243
301
  const maxBytes = this.maxSize * 1024 * 1024
244
302
  if (file.size > maxBytes) {
245
- uni.showToast({
246
- title: `文件大小不能超过${this.maxSize}MB`,
247
- icon: 'none'
303
+ // 触发文件大小超限事件
304
+ this.$emit('fileSizeExceed', {
305
+ size: file.size,
306
+ maxSize: maxBytes,
307
+ fileName: fileName,
308
+ file: file,
309
+ message: `文件大小不能超过${this.maxSize}MB(当前:${this.formatFileSize(file.size)})`
248
310
  })
311
+
312
+ // 如果用户未监听事件,显示默认提示
313
+ if (!this.hasEventListener('fileSizeExceed')) {
314
+ uni.showToast({
315
+ title: `文件大小不能超过${this.maxSize}MB`,
316
+ icon: 'none'
317
+ })
318
+ }
249
319
  return
250
320
  }
251
321
 
@@ -259,9 +329,10 @@ export default {
259
329
  uploadFile(file) {
260
330
  this.uploading = true
261
331
  this.uploadProgress = 0
332
+ let uploadTask = {}
262
333
 
263
334
  // #ifdef H5
264
- const uploadTask = uni.uploadFile({
335
+ uploadTask = uni.uploadFile({
265
336
  url: this.finalUploadUrl,
266
337
  file: file,
267
338
  name: 'file',
@@ -275,7 +346,7 @@ export default {
275
346
  // #endif
276
347
 
277
348
  // #ifndef H5
278
- const uploadTask = uni.uploadFile({
349
+ uploadTask = uni.uploadFile({
279
350
  url: this.finalUploadUrl,
280
351
  filePath: file.path,
281
352
  name: 'file',
@@ -317,10 +388,19 @@ export default {
317
388
  this.uploading = false
318
389
  this.emitChange()
319
390
 
320
- uni.showToast({
321
- title: '上传成功',
322
- icon: 'success'
391
+ // 触发上传成功事件
392
+ this.$emit('uploadSuccess', {
393
+ file: fileInfo,
394
+ response: result
323
395
  })
396
+
397
+ // 如果用户未监听事件,显示默认提示
398
+ if (!this.hasEventListener('uploadSuccess')) {
399
+ uni.showToast({
400
+ title: '上传成功',
401
+ icon: 'success'
402
+ })
403
+ }
324
404
  } catch (e) {
325
405
  this.handleUploadError(e)
326
406
  }
@@ -331,10 +411,21 @@ export default {
331
411
  */
332
412
  handleUploadError(err) {
333
413
  console.error('文件上传失败:', err)
334
- uni.showToast({
335
- icon: 'none',
336
- title: '文件上传失败'
414
+
415
+ // 触发上传失败事件
416
+ this.$emit('uploadFail', {
417
+ error: err,
418
+ message: '文件上传失败'
337
419
  })
420
+
421
+ // 如果用户未监听事件,显示默认提示
422
+ if (!this.hasEventListener('uploadFail')) {
423
+ uni.showToast({
424
+ icon: 'none',
425
+ title: '文件上传失败'
426
+ })
427
+ }
428
+
338
429
  this.uploading = false
339
430
  this.uploadProgress = 0
340
431
  },
@@ -420,44 +511,71 @@ export default {
420
511
  * 打开文档(小程序等)
421
512
  */
422
513
  openDocument(file) {
514
+ // 判断文件类型是否为可打开的文档类型
515
+ const ext = this.getFileExtension(file.name)
516
+ const supportedTypes = ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx']
517
+ const isDocument = supportedTypes.includes(ext)
518
+
519
+ // 显示加载提示
423
520
  uni.showLoading({
424
- title: '正在打开...'
521
+ title: isDocument ? '正在打开...' : '正在下载...'
425
522
  })
426
523
 
427
- // 先下载文件到本地
524
+ // 下载文件
428
525
  uni.downloadFile({
429
526
  url: file.url,
430
527
  success: (res) => {
431
528
  if (res.statusCode === 200) {
432
- // 打开文档
433
- uni.openDocument({
434
- filePath: res.tempFilePath,
435
- fileType: this.getFileExtension(file.name),
436
- success: () => {
437
- uni.hideLoading()
438
- },
439
- fail: (err) => {
440
- console.error('打开文档失败:', err)
441
- uni.hideLoading()
442
- uni.showToast({
443
- title: '打开文档失败',
444
- icon: 'none'
445
- })
446
- }
447
- })
529
+ if (isDocument) {
530
+ // 打开文档
531
+ uni.openDocument({
532
+ filePath: res.tempFilePath,
533
+ fileType: ext,
534
+ success: () => {
535
+ uni.hideLoading()
536
+ },
537
+ fail: (err) => {
538
+ console.error('打开文档失败:', err)
539
+ uni.hideLoading()
540
+ uni.showToast({
541
+ title: '打开文档失败',
542
+ icon: 'none'
543
+ })
544
+ }
545
+ })
546
+ } else {
547
+ // 保存文件到本地
548
+ uni.saveFile({
549
+ tempFilePath: res.tempFilePath,
550
+ success: (saveRes) => {
551
+ uni.hideLoading()
552
+ uni.showToast({
553
+ title: '已保存到本地',
554
+ icon: 'success'
555
+ })
556
+ },
557
+ fail: () => {
558
+ uni.hideLoading()
559
+ uni.showToast({
560
+ title: '保存失败',
561
+ icon: 'none'
562
+ })
563
+ }
564
+ })
565
+ }
448
566
  } else {
449
567
  uni.hideLoading()
450
568
  uni.showToast({
451
- title: '下载文件失败',
569
+ title: '下载失败',
452
570
  icon: 'none'
453
571
  })
454
572
  }
455
573
  },
456
574
  fail: (err) => {
457
- console.error('下载文件失败:', err)
575
+ console.error('下载失败:', err)
458
576
  uni.hideLoading()
459
577
  uni.showToast({
460
- title: '下载文件失败',
578
+ title: '下载失败',
461
579
  icon: 'none'
462
580
  })
463
581
  }
@@ -495,203 +613,5 @@ export default {
495
613
  </script>
496
614
 
497
615
  <style lang="scss">
498
- .file-picker-wrapper {
499
- width: 100%;
500
- }
501
-
502
- @keyframes rotate {
503
- 0% {
504
- transform: rotate(0deg);
505
- }
506
-
507
- 100% {
508
- transform: rotate(360deg);
509
- }
510
- }
511
-
512
- .file-picker-box {
513
- .upload-view {
514
- padding: 8rpx 0;
515
-
516
- .file-item {
517
- display: flex;
518
- align-items: center;
519
- justify-content: space-between;
520
- padding: 16rpx 20rpx;
521
- margin-top: 12rpx;
522
- background-color: #fff;
523
- border-radius: 8rpx;
524
- border: 2rpx solid #E5E5E5;
525
- transition: all 0.3s;
526
-
527
- &:active {
528
- background-color: #f5f5f5;
529
- }
530
-
531
- .file-info {
532
- flex: 1;
533
- display: flex;
534
- align-items: center;
535
- min-width: 0;
536
-
537
- .file-icon {
538
- width: 56rpx;
539
- height: 56rpx;
540
- margin-right: 16rpx;
541
- flex-shrink: 0;
542
-
543
- .icon-image {
544
- width: 100%;
545
- height: 100%;
546
- }
547
-
548
- .loading-icon {
549
- width: 100%;
550
- height: 100%;
551
- animation: rotate 2s linear infinite;
552
- }
553
- }
554
-
555
- .file-content {
556
- flex: 1;
557
- min-width: 0;
558
-
559
- .file-name {
560
- font-size: 28rpx;
561
- color: #333;
562
- overflow: hidden;
563
- text-overflow: ellipsis;
564
- white-space: nowrap;
565
- }
566
- }
567
- }
568
-
569
- .file-actions {
570
- margin-left: 16rpx;
571
- display: flex;
572
- align-items: center;
573
-
574
- .action-btn {
575
- width: 44rpx;
576
- height: 44rpx;
577
- border-radius: 50%;
578
- display: flex;
579
- align-items: center;
580
- justify-content: center;
581
- background-color: rgba(0, 0, 0, 0.6);
582
-
583
- &:active {
584
- opacity: 0.8;
585
- }
586
- }
587
-
588
- .delete-btn {
589
- .delete-icon {
590
- color: #fff;
591
- font-size: 32rpx;
592
- line-height: 0.1;
593
- font-weight: 300;
594
- }
595
- }
596
- }
597
-
598
- .progress-bar {
599
- position: absolute;
600
- bottom: 0;
601
- left: 0;
602
- right: 0;
603
- height: 8rpx;
604
- background-color: #e6f7ff;
605
- border-radius: 0 0 12rpx 12rpx;
606
- overflow: hidden;
607
-
608
- .progress-bar-inner {
609
- height: 100%;
610
- background-color: #1890ff;
611
- transition: width 0.3s;
612
- }
613
- }
614
-
615
- &.uploading-item {
616
- border-color: #1890ff;
617
- background-color: rgba(24, 144, 255, 0.05);
618
- position: relative;
619
- padding-bottom: 24rpx;
620
-
621
- .file-name {
622
- color: #1890ff;
623
- }
624
- }
625
- }
626
-
627
- .upload-btn {
628
- width: 100%;
629
- height: 80rpx;
630
- background-color: #fff;
631
- color: #1890ff;
632
- border: 2rpx solid #1890ff;
633
- border-radius: 12rpx;
634
- font-size: 28rpx;
635
- transition: all 0.3s;
636
-
637
- &:active {
638
- opacity: 0.8;
639
- background-color: #ecf5ff;
640
- }
641
-
642
- &::after {
643
- border: none;
644
- }
645
- }
646
- }
647
- }
648
-
649
- .file-readonly {
650
- .file-item {
651
- display: flex;
652
- align-items: center;
653
- padding: 16rpx 20rpx;
654
- margin-bottom: 12rpx;
655
- background-color: #fff;
656
- border-radius: 8rpx;
657
- border: 2rpx solid #E5E5E5;
658
- transition: all 0.3s;
659
-
660
- &:active {
661
- background-color: #f5f5f5;
662
- }
663
-
664
- .file-info {
665
- flex: 1;
666
- display: flex;
667
- align-items: center;
668
- min-width: 0;
669
-
670
- .file-icon {
671
- width: 56rpx;
672
- height: 56rpx;
673
- margin-right: 16rpx;
674
- flex-shrink: 0;
675
-
676
- .icon-image {
677
- width: 100%;
678
- height: 100%;
679
- }
680
- }
681
-
682
- .file-content {
683
- flex: 1;
684
- min-width: 0;
685
-
686
- .file-name {
687
- font-size: 28rpx;
688
- color: #333;
689
- overflow: hidden;
690
- text-overflow: ellipsis;
691
- white-space: nowrap;
692
- }
693
- }
694
- }
695
- }
696
- }
616
+ @import './styles.scss';
697
617
  </style>