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

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