您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

224 行
6.6 KiB

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