Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

342 wiersze
8.5 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. <!-- #ifdef APP-PLUS -->
  9. <view v-if="formData.folderId&&!readonly && value.length < Number(number)" style="display: inline-block;padding-left: 20px;">
  10. <lsjupload ref="lsjUpload" height="32px" width="80px" :option="{
  11. url:API+'/learun/adms/annexes/wxupload',formData
  12. }" :instantly="true" :count="1" :size="200" @change="chooseChange" @uploadEnd="uploadEnd">
  13. </lsjupload>
  14. </view>
  15. <!-- #endif -->
  16. </view>
  17. <view class="cu-form-group" style="border-top: none;">
  18. <view class="grid col-4 grid-square flex-sub">
  19. <view v-for="(file, index) in value" :key="index" class="bg-img" style="position: relative;">
  20. <view v-if="file.noUpdated" class="mask"></view>
  21. <image v-if="isImgFile(file.type)" @click="fileClick(index)" :src="file.path?file.path:file"
  22. :webp="file.type === 'webp'" mode="aspectFill"></image>
  23. <view v-else-if="isDocFile(file.type)" @click="fileClick(index)" class="file-icon solids">
  24. <l-icon type="text" />
  25. </view>
  26. <view v-else class="file-icon solids" @click="fileClick(index)">
  27. <l-icon type="text" />
  28. </view>
  29. <view v-if="!readonly" @click.stop="delFile(index,file.uid)" class="cu-tag bg-red"
  30. style="height: 24px; width: 24px;">
  31. <l-icon type="close" color="white" style="width: 18px; height: 24px; font-size: 24px;" />
  32. </view>
  33. <view class="fileName">
  34. <text>{{file.name}}</text>
  35. </view>
  36. </view>
  37. <!-- #ifndef APP-PLUS -->
  38. <view v-if="!readonly && value.length < Number(number)" @click="chooseFile" class="solids">
  39. <l-icon type="file" />
  40. </view>
  41. <!-- #endif -->
  42. </view>
  43. </view>
  44. </view>
  45. </template>
  46. <script>
  47. import lsjupload from '@/components/lsj-upload/lsj-upload.vue'
  48. export default {
  49. name: 'l-upload-file',
  50. components: {
  51. lsjupload,
  52. },
  53. props: {
  54. number: {
  55. default: 1
  56. },
  57. labelId: {
  58. default: ''
  59. },
  60. tableName: {
  61. default: ''
  62. },
  63. fieldName: {
  64. default: ''
  65. },
  66. readonly: {},
  67. value: {
  68. default: () => []
  69. },
  70. title: {},
  71. required: {}
  72. },
  73. data() {
  74. return {
  75. formData: {},
  76. }
  77. },
  78. created() {
  79. // #ifdef APP-PLUS
  80. if(this.labelId){
  81. var guid = undefined
  82. // 先生成一个guid
  83. guid = this.newguid();
  84. // 取出当前列对应的labelId
  85. var labeId = this.labelId
  86. // 从缓存取出当前审批流程所有的guid
  87. var guids = JSON.parse(uni.getStorageSync('guids'))
  88. if (guids && JSON.stringify(guids) !== '{}' && guids[labeId]) {
  89. guid = guids[labeId]
  90. }
  91. this.formData.loginMark=this.getLoginMark(),
  92. this.formData.token=this.GET_GLOBAL('token')
  93. this.formData['folderId'] = guid
  94. }else{
  95. if(!this.tableName||!this.fieldName)return
  96. var uploadUid = '',
  97. tableName=this.tableName,
  98. fieldName=this.fieldName
  99. let folderIds = uni.getStorageSync('folderIds');
  100. if(folderIds){
  101. folderIds = JSON.parse(folderIds)
  102. if(folderIds[tableName]&&folderIds[tableName][fieldName]){
  103. uploadUid = folderIds[tableName][fieldName]
  104. }
  105. }
  106. if(!uploadUid){
  107. uploadUid = this.newguid()
  108. }
  109. this.formData.loginMark=this.getLoginMark(),
  110. this.formData.token=this.GET_GLOBAL('token')
  111. this.formData['folderId'] = uploadUid
  112. }
  113. // #endif
  114. },
  115. methods: {
  116. async chooseChange(files) {
  117. this.LOADING('正在提交...')
  118. },
  119. async uploadEnd(){
  120. this.$refs.lsjUpload.clear()
  121. this.HIDE_LOADING()
  122. this.folderIdToList(this.formData['folderId'])
  123. },
  124. async chooseChangeOld(files) {
  125. this.LOADING('正在提交...')
  126. await this.$refs.lsjUpload.upload()
  127. this.HIDE_LOADING()
  128. let array = Array.from(files);
  129. if (array.length) {
  130. await this.$refs.lsjUpload.clear()
  131. }
  132. let tempFilePaths = [],
  133. tempFiles = [];
  134. array.forEach(item => {
  135. tempFilePaths.push(item[1].path)
  136. tempFiles.push({
  137. name: item[1].name,
  138. size: item[1].size,
  139. folderId: this.formData.folderId
  140. })
  141. })
  142. if (!tempFilePaths.length) {
  143. return
  144. }
  145. // let fileName = tempFiles[tempFiles.length]
  146. // let uploadRes = await this.$refs.lsjUpload.upload(tempFiles[i].name)
  147. // if(!uploadRes){
  148. // this.TOAST('上传失败!')
  149. // return
  150. // }
  151. const newList = JSON.parse(JSON.stringify(this.value || [])).concat(
  152. tempFilePaths.map((t, i) => ({
  153. path: t,
  154. type: tempFiles[i].type,
  155. size: tempFiles[i].size,
  156. name: tempFiles[i].name,
  157. folderId:tempFiles[i].folderId,
  158. noUpdated: false
  159. }))
  160. )
  161. this.$emit('input', newList)
  162. this.$emit('change', newList)
  163. this.$emit('add')
  164. },
  165. // 文件夹id转化为文件列表
  166. async folderIdToList(folderId){
  167. const uidList = folderId;
  168. const fileList = []
  169. const wxlist = await this.FETCH_FILEList(uidList);
  170. for (const wxfile of wxlist) {
  171. const fileInfo = await this.FETCH_FILEINFO(wxfile.F_Id)
  172. if (!fileInfo) {
  173. continue
  174. }
  175. const fileType = fileInfo.F_FileType
  176. const fileSize = fileInfo.F_FileSize
  177. const fileName = fileInfo.F_FileName
  178. const path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(wxfile.F_Id, true)
  179. fileList.push({
  180. path,
  181. type: fileType,
  182. uid:wxfile.F_Id,
  183. folderId:wxfile.F_FolderId,
  184. size: fileSize,
  185. name:fileName
  186. })
  187. }
  188. this.$emit('input', fileList)
  189. this.$emit('change', fileList)
  190. this.$emit('add')
  191. },
  192. getFileExt(path) {
  193. return /\.(\w{2,5})$/.exec(path)[1] || null
  194. },
  195. isImgFile(type) {
  196. const typeString = (type || '').toLowerCase()
  197. return ['jpg', 'image/jpg', 'jpeg', 'image/jpeg', 'png', 'image/png', 'gif', 'image/gif', 'bmp',
  198. 'image/bmp', 'webp', 'image/webp', 'image'
  199. ].includes(typeString)
  200. },
  201. isDocFile(type) {
  202. const typeString = (type || '').toLowerCase()
  203. return ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf'].includes(typeString)
  204. },
  205. async delFile(index, fileId) {
  206. if (!(await this.CONFIRM('删除文件', '确定要删除该文件吗?', true))) {
  207. return
  208. }
  209. const newList = JSON.parse(JSON.stringify(this.value))
  210. newList.splice(index, 1)
  211. this.$emit('input', newList)
  212. this.$emit('change')
  213. this.$emit('del')
  214. //物理删除
  215. this.DELETE_FILE(fileId);
  216. },
  217. chooseFile() {
  218. // #ifdef APP-PLUS
  219. return
  220. // #endif
  221. uni.chooseFile({
  222. count: Number(this.number),
  223. sizeType: ['original', 'compressed'],
  224. sourceType: ['album', 'camera'],
  225. success: ({
  226. tempFilePaths,
  227. tempFiles
  228. }) => {
  229. const newList = JSON.parse(JSON.stringify(this.value || [])).concat(
  230. tempFilePaths.map((t, i) => ({
  231. path: t,
  232. type: tempFiles[i].type,
  233. size: tempFiles[i].size,
  234. name: tempFiles[i].name,
  235. noUpdated: false
  236. }))
  237. )
  238. this.$emit('input', newList)
  239. this.$emit('change', newList)
  240. this.$emit('add')
  241. }
  242. })
  243. },
  244. async fileClick(index) {
  245. const {
  246. path,
  247. type,
  248. uid,
  249. size = 0
  250. } = this.value[index]
  251. if (this.isImgFile(type)) {
  252. uni.previewImage({
  253. urls: [path],
  254. current: path
  255. })
  256. } else {
  257. // #ifdef APP-PLUS
  258. uni.downloadFile({
  259. url: path, //仅为示例,并非真实的资源
  260. success: (res) => {
  261. if (res.statusCode === 200) {
  262. uni.openDocument({
  263. filePath: res.tempFilePath,
  264. fileType: type
  265. })
  266. }else{
  267. this.TOAST('下载失败!')
  268. }
  269. }
  270. });
  271. return
  272. // #endif
  273. uni.openDocument({
  274. filePath: path,
  275. fileType: type
  276. })
  277. }
  278. },
  279. newguid() {
  280. return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  281. var r = Math.random() * 16 | 0,
  282. v = c == 'x' ? r : (r & 0x3 | 0x8);
  283. return v.toString(16);
  284. });
  285. },
  286. }
  287. }
  288. </script>
  289. <style lang="less" scoped>
  290. .file-icon {
  291. line-height: 100%;
  292. position: static;
  293. }
  294. .fileName {
  295. padding: 2px 2px;
  296. margin-bottom: 2px;
  297. text-align: center;
  298. position: absolute;
  299. bottom: 0px;
  300. width: 100%;
  301. background: rgba(0, 0, 0, 0.2);
  302. color: #fff;
  303. font-size: 12px;
  304. text-overflow: ellipsis;
  305. overflow: hidden;
  306. white-space: nowrap;
  307. }
  308. .mask {
  309. position: absolute;
  310. top: 0;
  311. left: 0;
  312. width: 100%;
  313. height: 100%;
  314. // background: rgba(255,252,153,0.2);
  315. background: rgba(0, 0, 0, 0.7);
  316. z-index: 100;
  317. pointer-events: none;
  318. }
  319. </style>