You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 4 година
пре 4 година
пре 4 година
пре 4 година
пре 2 година
пре 4 година
пре 4 година
пре 4 година
пре 2 година
пре 4 година
пре 2 година
пре 4 година
пре 4 година
пре 4 година
пре 4 година
пре 4 година
пре 4 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <template>
  2. <view>
  3. <view class="cu-form-group" style="border-bottom: none; padding-bottom: 0;">
  4. <view class="title">
  5. <text v-if="required" class="lr-required">*</text>
  6. {{ title || '' }}
  7. </view>
  8. </view>
  9. <view class="cu-form-group" style="border-top: none;">
  10. <view class="grid col-4 grid-square flex-sub">
  11. <view v-for="(file, index) in value" :key="index" class="bg-img" style="position: relative;">
  12. <view v-if="file.noUpdated" class="mask"></view>
  13. <image
  14. v-if="isImgFile(file.type)"
  15. @click="fileClick(index)"
  16. :src="file.path?file.path:file"
  17. :webp="file.type === 'webp'"
  18. mode="aspectFill"
  19. ></image>
  20. <view v-else-if="isDocFile(file.type)" @click="fileClick(index)" class="file-icon solids">
  21. <l-icon type="text" />
  22. </view>
  23. <view v-else class="file-icon solids" @click="fileClick(index)"><l-icon type="text" /></view>
  24. <view v-if="!readonly" @click.stop="delFile(index,file.uid)" class="cu-tag bg-red" style="height: 24px; width: 24px;">
  25. <l-icon type="close" color="white" style="width: 18px; height: 24px; font-size: 24px;" />
  26. </view>
  27. <view class="fileName">
  28. <text>{{file.name}}</text>
  29. </view>
  30. </view>
  31. <view v-if="!readonly && value.length < Number(number)" @click="chooseFile" class="solids">
  32. <l-icon type="file" />
  33. </view>
  34. </view>
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. export default {
  40. name: 'l-upload-file',
  41. props: {
  42. number: { default: 1 },
  43. readonly: {},
  44. value: { default: () => [] },
  45. title: {},
  46. required: {}
  47. },
  48. methods: {
  49. getFileExt(path) {
  50. return /\.(\w{2,5})$/.exec(path)[1] || null
  51. },
  52. isImgFile(type) {
  53. const typeString = (type || '').toLowerCase()
  54. return ['jpg','image/jpg','jpeg','image/jpeg', 'png', 'image/png','gif', 'image/gif','bmp', 'image/bmp','webp', 'image/webp','image'].includes(typeString)
  55. },
  56. isDocFile(type) {
  57. const typeString = (type || '').toLowerCase()
  58. return ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf'].includes(typeString)
  59. },
  60. async delFile(index,fileId) {
  61. if (!(await this.CONFIRM('删除文件', '确定要删除该文件吗?', true))) {
  62. return
  63. }
  64. const newList = JSON.parse(JSON.stringify(this.value))
  65. newList.splice(index, 1)
  66. this.$emit('input', newList)
  67. this.$emit('change')
  68. this.$emit('del')
  69. //物理删除
  70. this.DELETE_FILE(fileId);
  71. },
  72. chooseFile() {
  73. // #ifdef MP-DINGTALK
  74. // dd.chooseImage({
  75. // count: Number(this.number),
  76. // success: ({ filePaths }) => {
  77. // if (filePaths) {
  78. // const newList = JSON.parse(JSON.stringify(this.value || [])).concat(
  79. // filePaths.map(t => ({ path: t, type: this.getFileExt(t) }))
  80. // )
  81. // this.$emit('input', newList)
  82. // this.$emit('change', newList)
  83. // this.$emit('add')
  84. // }
  85. // }
  86. // })
  87. // #endif
  88. // #ifndef MP-DINGTALK
  89. // uni.chooseFile({
  90. // count: Number(this.number),
  91. // sizeType: ['original', 'compressed'],
  92. // sourceType: ['album', 'camera'],
  93. // success: ({ tempFilePaths }) => {
  94. // const newList = JSON.parse(JSON.stringify(this.value || [])).concat(
  95. // tempFilePaths//.map(t => ({ path: t, type: this.getFileExt(t) }))
  96. // )
  97. // this.$emit('input', newList)
  98. // this.$emit('change', newList)
  99. // this.$emit('add')
  100. // }
  101. // })
  102. uni.chooseFile({
  103. count: Number(this.number),
  104. sizeType: ['original', 'compressed'],
  105. sourceType: ['album', 'camera'],
  106. success: ({ tempFilePaths,tempFiles }) => {
  107. const newList = JSON.parse(JSON.stringify(this.value || [])).concat(
  108. // tempFilePaths//.map(t => ({ path: t, type: this.getFileExt(t) }))
  109. tempFilePaths.map((t,i) => ({ path: t, type: tempFiles[i].type, size:tempFiles[i].size, name:tempFiles[i].name, noUpdated:true} ))
  110. )
  111. this.$emit('input', newList)
  112. this.$emit('change', newList)
  113. this.$emit('add')
  114. }
  115. })
  116. // #endif
  117. },
  118. async fileClick(index) {
  119. // if(typeof this.value[index] == "string"){
  120. // uni.previewImage({ urls: this.value.filter(item=>typeof this.value[index] == "string"), current: this.value[index] })
  121. // return
  122. // }
  123. const { path, type, uid, size = 0 } = this.value[index]
  124. if (this.isImgFile(type)) {
  125. uni.previewImage({ urls: [path], current: path })
  126. }else{
  127. uni.openDocument({ filePath: path, fileType: type })
  128. }
  129. // if (this.isImgFile(type)) {
  130. // uni.previewImage({ urls: [path], current: path })
  131. // } else if (this.isDocFile(type)) {
  132. // // #ifndef H5 || MP-DINGTALK
  133. // if (size >= 50 * 1024 * 1024) {
  134. // this.TOAST('小程序端无法下载超过50MB的文件,此文件大小为${size}KB,超过限制')
  135. // return
  136. // }
  137. // // #endif
  138. // // #ifndef MP-DINGTALK
  139. // const tempFilePath = await this.HTTP_DOWNLOAD(uid)
  140. // uni.openDocument({ filePath: tempFilePath, fileType: type })
  141. // // #endif
  142. // // #ifdef MP-DINGTALK
  143. // this.TOAST('钉钉小程序只支持查看图片文件')
  144. // // #endif
  145. // } else {
  146. // // #ifndef MP-DINGTALK
  147. // this.TOAST('小程序端只支持打开图片和文档(word、pdf等)文件')
  148. // // #endif
  149. // // #ifdef MP-DINGTALK
  150. // this.TOAST('钉钉小程序只支持查看图片文件')
  151. // // #endif
  152. // // #ifdef APP-VUE
  153. // const tempFilePath = await this.HTTP_DOWNLOAD(uid)
  154. // uni.openDocument({ filePath: tempFilePath, fileType: type })
  155. // // #endif
  156. // // #ifdef H5
  157. // await this.HTTP_DOWNLOAD(uid)
  158. // // #endif
  159. // }
  160. }
  161. }
  162. }
  163. </script>
  164. <style lang="less" scoped>
  165. .file-icon {
  166. line-height: 100%;
  167. position: static;
  168. }
  169. .fileName{
  170. padding: 2px 2px;
  171. margin-bottom: 2px;
  172. text-align: center;
  173. position: absolute;
  174. bottom: 0px;
  175. width: 100%;
  176. background: rgba(0,0,0,0.2);
  177. color: #fff;
  178. font-size: 12px;
  179. text-overflow: ellipsis;
  180. overflow: hidden;
  181. white-space: nowrap;
  182. }
  183. .mask{
  184. position: absolute;
  185. top: 0;left: 0;
  186. width: 100%;
  187. height: 100%;
  188. // background: rgba(255,252,153,0.2);
  189. background: rgba(0,0,0,0.7);
  190. z-index: 100;
  191. pointer-events: none;
  192. }
  193. </style>