AttachList.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. <template>
  2. <view class="d-attach-list">
  3. <view class="d-attach-upload" @click="$emit('upload')">
  4. <view class="up-icon"><van-icon name="plus" /></view>
  5. <view class="up-text">
  6. <view class="up-title">添加附件</view>
  7. <view class="up-sub">支持 PDF / 图片 / Office,可多选上传</view>
  8. </view>
  9. <van-icon name="arrow" color="#22c55e" />
  10. </view>
  11. <view
  12. v-for="a in files"
  13. :key="a.name"
  14. class="d-attach-card"
  15. :class="fileTypeClass(a.name)"
  16. >
  17. <view class="file-icon">
  18. <van-icon :name="fileTypeIcon(a.name)" />
  19. <text class="ext">{{ fileExt(a.name) }}</text>
  20. </view>
  21. <view class="file-body">
  22. <view class="file-name">{{ a.name }}</view>
  23. <view class="file-meta">
  24. <text>{{ a.size || '—' }}</text>
  25. <text>{{ a.time || '—' }}</text>
  26. </view>
  27. </view>
  28. <view class="file-ops">
  29. <view class="op-btn btn-preview" @click="$emit('preview', a)">
  30. <van-icon name="eye-o" />
  31. </view>
  32. <view class="op-btn btn-download" @click="$emit('download', a)">
  33. <view class="icon-download">
  34. <view style="width:28rpx;height:28rpx;position:relative">
  35. <van-icon name="down" size="14px" />
  36. </view>
  37. </view>
  38. </view>
  39. </view>
  40. </view>
  41. </view>
  42. </template>
  43. <script>
  44. export default {
  45. name: 'AttachList',
  46. props: {
  47. files: { type: Array, default: () => [] }
  48. },
  49. emits: ['upload', 'preview', 'download'],
  50. methods: {
  51. fileExt(name) {
  52. const i = (name || '').lastIndexOf('.')
  53. return i >= 0 ? name.slice(i + 1).slice(0, 4) : 'FILE'
  54. },
  55. fileTypeClass(name) {
  56. const ext = this.fileExt(name).toLowerCase()
  57. if (ext === 'pdf') return 'ft-pdf'
  58. if (['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(ext)) return 'ft-img'
  59. if (['xls', 'xlsx', 'csv'].includes(ext)) return 'ft-xls'
  60. if (['doc', 'docx'].includes(ext)) return 'ft-doc'
  61. return 'ft-other'
  62. },
  63. fileTypeIcon(name) {
  64. const cls = this.fileTypeClass(name)
  65. if (cls === 'ft-pdf') return 'description'
  66. if (cls === 'ft-img') return 'photo-o'
  67. if (cls === 'ft-xls') return 'bar-chart-o'
  68. if (cls === 'ft-doc') return 'records'
  69. return 'bag-o'
  70. }
  71. }
  72. }
  73. </script>