From 2fda34643bc22e25f6c569415da5f955c81536bf Mon Sep 17 00:00:00 2001 From: Houjie <714924425@qq.com> Date: 星期二, 03 六月 2025 09:37:08 +0800 Subject: [PATCH] 设备详情通过ID过滤/设备详情增加上传附件 --- uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue | 751 ++++++++++++++++++++++++++++++-------------------------- 1 files changed, 401 insertions(+), 350 deletions(-) diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue b/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue index 785c7eb..7b45a83 100644 --- a/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue +++ b/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue @@ -16,7 +16,7 @@ </upload-image> <upload-file v-if="fileMediatype !== 'image' || showType !== 'grid'" :readonly="readonly" :list-styles="listStyles" :files-list="filesList" :showType="showType" :delIcon="delIcon" - @uploadFiles="uploadFiles" @choose="choose" @delFile="delFile"> + @uploadFiles="uploadFiles" @choose="choose" @delFile="delFile" @downloadFile="downloadFile"> <slot><button type="primary" size="mini">閫夋嫨鏂囦欢</button></slot> </upload-file> </view> @@ -87,7 +87,7 @@ options: { virtualHost: true }, - emits: ['select', 'success', 'fail', 'progress', 'delete', 'update:modelValue', 'input'], + emits: ['select', 'success', 'fail', 'progress', 'delete', 'update:modelValue', 'input', 'downloadFile'], props: { modelValue: { type: [Array, Object], @@ -183,7 +183,7 @@ sourceType: { type: Array, default () { - return ['album', 'camera'] + return ['album', 'camera'] } }, provider: { @@ -254,366 +254,417 @@ } }, methods: { - /** - * 鍏紑鐢ㄦ埛浣跨敤锛屾竻绌烘枃浠� - * @param {Object} index - */ - clearFiles(index) { - if (index !== 0 && !index) { - this.files = [] - this.$nextTick(() => { - this.setEmit() - }) - } else { - this.files.splice(index, 1) - } - this.$nextTick(() => { - this.setEmit() - }) - }, - /** - * 鍏紑鐢ㄦ埛浣跨敤锛岀户缁笂浼� - */ - upload() { - let files = [] - this.files.forEach((v, index) => { - if (v.status === 'ready' || v.status === 'error') { - files.push(Object.assign({}, v)) - } - }) - return this.uploadFiles(files) - }, - async setValue(newVal, oldVal) { - const newData = async (v) => { - const reg = /cloud:\/\/([\w.]+\/?)\S*/ - let url = '' - if(v.fileID){ - url = v.fileID - }else{ - url = v.url - } - if (reg.test(url)) { - v.fileID = url - v.url = await this.getTempFileURL(url) - } - if(v.url) v.path = v.url - return v - } - if (this.returnType === 'object') { - if (newVal) { - await newData(newVal) - } else { - newVal = {} - } - } else { - if (!newVal) newVal = [] - for(let i =0 ;i < newVal.length ;i++){ - let v = newVal[i] - await newData(v) - } - } - this.localValue = newVal - if (this.form && this.formItem &&!this.is_reset) { - this.is_reset = false - this.formItem.setValue(this.localValue) - } - let filesData = Object.keys(newVal).length > 0 ? newVal : []; - this.files = [].concat(filesData) - }, - /** - * 閫夋嫨鏂囦欢 - */ - choose() { - if (this.disabled) return - if (this.files.length >= Number(this.limitLength) && this.showType !== 'grid' && this.returnType === - 'array') { + downloadFile(item) { + console.log('鍑嗗涓嬭浇:', item); + + if (!item.url) { uni.showToast({ - title: `鎮ㄦ渶澶氶�夋嫨 ${this.limitLength} 涓枃浠禶, + title: '鏂囦欢涓嶅彲涓嬭浇', icon: 'none' - }) - return + }); + return; } - this.chooseFiles() - }, - /** - * 閫夋嫨鏂囦欢骞朵笂浼� - */ - chooseFiles() { - const _extname = get_extname(this.fileExtname) - // 鑾峰彇鍚庣紑 - uniCloud - .chooseAndUploadFile({ - type: this.fileMediatype, - compressed: false, - sizeType: this.sizeType, - sourceType: this.sourceType, - // TODO 濡傛灉涓虹┖锛寁ideo 鏈夐棶棰� - extension: _extname.length > 0 ? _extname : undefined, - count: this.limitLength - this.files.length, //榛樿9 - onChooseFile: this.chooseFileCallback, - onUploadProgress: progressEvent => { - this.setProgress(progressEvent, progressEvent.index) + // #ifdef H5 + const a = document.createElement('a'); + a.href = item.url; + a.download = item.name || 'file'; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + // #endif + + // #ifndef H5 + uni.downloadFile({ + url: item.url, + success: (res) => { + if (res.statusCode === 200) { + uni.openDocument({ + filePath: res.tempFilePath, + success: () => { + console.log('鎵撳紑鏂囨。鎴愬姛'); + }, + fail: () => { + uni.showToast({ + title: '鏃犳硶鎵撳紑姝ゆ枃妗g被鍨�', + icon: 'none' + }); + } + }); } - }) - .then(result => { - this.setSuccessAndError(result.tempFiles) - }) - .catch(err => { - console.log('閫夋嫨澶辫触', err) - }) - }, - - /** - * 閫夋嫨鏂囦欢鍥炶皟 - * @param {Object} res - */ - async chooseFileCallback(res) { - const _extname = get_extname(this.fileExtname) - const is_one = (Number(this.limitLength) === 1 && - this.disablePreview && - !this.disabled) || - this.returnType === 'object' - // 濡傛灉杩欐湁涓�涓枃浠� 锛岄渶瑕佹竻绌烘湰鍦扮紦瀛樻暟鎹� - if (is_one) { - this.files = [] - } - - let { - filePaths, - files - } = get_files_and_is_max(res, _extname) - if (!(_extname && _extname.length > 0)) { - filePaths = res.tempFilePaths - files = res.tempFiles - } - - let currentData = [] - for (let i = 0; i < files.length; i++) { - if (this.limitLength - this.files.length <= 0) break - files[i].uuid = Date.now() - let filedata = await get_file_data(files[i], this.fileMediatype) - filedata.progress = 0 - filedata.status = 'ready' - this.files.push(filedata) - currentData.push({ - ...filedata, - file: files[i] - }) - } - this.$emit('select', { - tempFiles: currentData, - tempFilePaths: filePaths - }) - res.tempFiles = files - // 鍋滄鑷姩涓婁紶 - if (!this.autoUpload || this.noSpace) { - res.tempFiles = [] - } - res.tempFiles.forEach((fileItem, index) => { - this.provider && (fileItem.provider = this.provider); - const fileNameSplit = fileItem.name.split('.') - const ext = fileNameSplit.pop() - const fileName = fileNameSplit.join('.').replace(/[\s\/\?<>\\:\*\|":]/g, '_') - fileItem.cloudPath = fileName + '_' + Date.now() + '_' + index + '.' + ext - }) - }, - - /** - * 鎵逛紶 - * @param {Object} e - */ - uploadFiles(files) { - files = [].concat(files) - return uploadCloudFiles.call(this, files, 5, res => { - this.setProgress(res, res.index, true) - }) - .then(result => { - this.setSuccessAndError(result) - return result; - }) - .catch(err => { - console.log(err) - }) - }, - - /** - * 鎴愬姛鎴栧け璐� - */ - async setSuccessAndError(res, fn) { - let successData = [] - let errorData = [] - let tempFilePath = [] - let errorTempFilePath = [] - for (let i = 0; i < res.length; i++) { - const item = res[i] - const index = item.uuid ? this.files.findIndex(p => p.uuid === item.uuid) : item.index - - if (index === -1 || !this.files) break - if (item.errMsg === 'request:fail') { - this.files[index].url = item.path - this.files[index].status = 'error' - this.files[index].errMsg = item.errMsg - // this.files[index].progress = -1 - errorData.push(this.files[index]) - errorTempFilePath.push(this.files[index].url) - } else { - this.files[index].errMsg = '' - this.files[index].fileID = item.url - const reg = /cloud:\/\/([\w.]+\/?)\S*/ - if (reg.test(item.url)) { - this.files[index].url = await this.getTempFileURL(item.url) - }else{ - this.files[index].url = item.url - } - - this.files[index].status = 'success' - this.files[index].progress += 1 - successData.push(this.files[index]) - tempFilePath.push(this.files[index].fileID) + }, + fail: () => { + uni.showToast({ + title: '涓嬭浇澶辫触', + icon: 'none' + }); } - } - - if (successData.length > 0) { - this.setEmit() - // 鐘舵�佹敼鍙樿繑鍥� - this.$emit('success', { - tempFiles: this.backObject(successData), - tempFilePaths: tempFilePath - }) - } - - if (errorData.length > 0) { - this.$emit('fail', { - tempFiles: this.backObject(errorData), - tempFilePaths: errorTempFilePath - }) - } + }); + // #endif }, + - /** - * 鑾峰彇杩涘害 - * @param {Object} progressEvent - * @param {Object} index - * @param {Object} type - */ - setProgress(progressEvent, index, type) { - const fileLenth = this.files.length - const percentNum = (index / fileLenth) * 100 - const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total) - let idx = index - if (!type) { - idx = this.files.findIndex(p => p.uuid === progressEvent.tempFile.uuid) - } - if (idx === -1 || !this.files[idx]) return - // fix by mehaotian 100 灏变細娑堝け锛�-1 鏄负浜嗚杩涘害鏉℃秷澶� - this.files[idx].progress = percentCompleted - 1 - // 涓婁紶涓� - this.$emit('progress', { - index: idx, - progress: parseInt(percentCompleted), - tempFile: this.files[idx] - }) - }, - - /** - * 鍒犻櫎鏂囦欢 - * @param {Object} index - */ - delFile(index) { - this.$emit('delete', { - index, - tempFile: this.files[index], - tempFilePath: this.files[index].url - }) - this.files.splice(index, 1) + /** + * 鍏紑鐢ㄦ埛浣跨敤锛屾竻绌烘枃浠� + * @param {Object} index + */ + clearFiles(index) { + if (index !== 0 && !index) { + this.files = [] this.$nextTick(() => { this.setEmit() }) - }, - - /** - * 鑾峰彇鏂囦欢鍚嶅拰鍚庣紑 - * @param {Object} name - */ - getFileExt(name) { - const last_len = name.lastIndexOf('.') - const len = name.length - return { - name: name.substring(0, last_len), - ext: name.substring(last_len + 1, len) - } - }, - - /** - * 澶勭悊杩斿洖浜嬩欢 - */ - setEmit() { - let data = [] - if (this.returnType === 'object') { - data = this.backObject(this.files)[0] - this.localValue = data?data:null - } else { - data = this.backObject(this.files) - if (!this.localValue) { - this.localValue = [] - } - this.localValue = [...data] - } - // #ifdef VUE3 - this.$emit('update:modelValue', this.localValue) - // #endif - // #ifndef VUE3 - this.$emit('input', this.localValue) - // #endif - }, - - /** - * 澶勭悊杩斿洖鍙傛暟 - * @param {Object} files - */ - backObject(files) { - let newFilesData = [] - files.forEach(v => { - newFilesData.push({ - extname: v.extname, - fileType: v.fileType, - image: v.image, - name: v.name, - path: v.path, - size: v.size, - fileID:v.fileID, - url: v.url, - // 淇敼鍒犻櫎涓�涓枃浠跺悗涓嶈兘鍐嶄笂浼犵殑bug, #694 - uuid: v.uuid, - status: v.status, - cloudPath: v.cloudPath - }) - }) - return newFilesData - }, - async getTempFileURL(fileList) { - fileList = { - fileList: [].concat(fileList) - } - const urls = await uniCloud.getTempFileURL(fileList) - return urls.fileList[0].tempFileURL || '' - }, - /** - * 鑾峰彇鐖跺厓绱犲疄渚� - */ - getForm(name = 'uniForms') { - let parent = this.$parent; - let parentName = parent.$options.name; - while (parentName !== name) { - parent = parent.$parent; - if (!parent) return false; - parentName = parent.$options.name; - } - return parent; + } else { + this.files.splice(index, 1) } + this.$nextTick(() => { + this.setEmit() + }) + }, + /** + * 鍏紑鐢ㄦ埛浣跨敤锛岀户缁笂浼� + */ + upload() { + let files = [] + this.files.forEach((v, index) => { + if (v.status === 'ready' || v.status === 'error') { + files.push(Object.assign({}, v)) + } + }) + return this.uploadFiles(files) + }, + async setValue(newVal, oldVal) { + const newData = async (v) => { + const reg = /cloud:\/\/([\w.]+\/?)\S*/ + let url = '' + if (v.fileID) { + url = v.fileID + } else { + url = v.url + } + if (reg.test(url)) { + v.fileID = url + v.url = await this.getTempFileURL(url) + } + if (v.url) v.path = v.url + return v + } + if (this.returnType === 'object') { + if (newVal) { + await newData(newVal) + } else { + newVal = {} + } + } else { + if (!newVal) newVal = [] + for (let i = 0; i < newVal.length; i++) { + let v = newVal[i] + await newData(v) + } + } + this.localValue = newVal + if (this.form && this.formItem && !this.is_reset) { + this.is_reset = false + this.formItem.setValue(this.localValue) + } + let filesData = Object.keys(newVal).length > 0 ? newVal : []; + this.files = [].concat(filesData) + }, + + /** + * 閫夋嫨鏂囦欢 + */ + choose() { + if (this.disabled) return + if (this.files.length >= Number(this.limitLength) && this.showType !== 'grid' && this.returnType === + 'array') { + uni.showToast({ + title: `鎮ㄦ渶澶氶�夋嫨 ${this.limitLength} 涓枃浠禶, + icon: 'none' + }) + return + } + this.chooseFiles() + }, + + /** + * 閫夋嫨鏂囦欢骞朵笂浼� + */ + chooseFiles() { + const _extname = get_extname(this.fileExtname) + // 鑾峰彇鍚庣紑 + uniCloud + .chooseAndUploadFile({ + type: this.fileMediatype, + compressed: false, + sizeType: this.sizeType, + sourceType: this.sourceType, + // TODO 濡傛灉涓虹┖锛寁ideo 鏈夐棶棰� + extension: _extname.length > 0 ? _extname : undefined, + count: this.limitLength - this.files.length, //榛樿9 + onChooseFile: this.chooseFileCallback, + onUploadProgress: progressEvent => { + this.setProgress(progressEvent, progressEvent.index) + } + }) + .then(result => { + this.setSuccessAndError(result.tempFiles) + }) + .catch(err => { + console.log('閫夋嫨澶辫触', err) + }) + }, + + /** + * 閫夋嫨鏂囦欢鍥炶皟 + * @param {Object} res + */ + async chooseFileCallback(res) { + const _extname = get_extname(this.fileExtname) + const is_one = (Number(this.limitLength) === 1 && + this.disablePreview && + !this.disabled) || + this.returnType === 'object' + // 濡傛灉杩欐湁涓�涓枃浠� 锛岄渶瑕佹竻绌烘湰鍦扮紦瀛樻暟鎹� + if (is_one) { + this.files = [] + } + + let { + filePaths, + files + } = get_files_and_is_max(res, _extname) + if (!(_extname && _extname.length > 0)) { + filePaths = res.tempFilePaths + files = res.tempFiles + } + + let currentData = [] + for (let i = 0; i < files.length; i++) { + if (this.limitLength - this.files.length <= 0) break + files[i].uuid = Date.now() + let filedata = await get_file_data(files[i], this.fileMediatype) + filedata.progress = 0 + filedata.status = 'ready' + this.files.push(filedata) + currentData.push({ + ...filedata, + file: files[i] + }) + } + this.$emit('select', { + tempFiles: currentData, + tempFilePaths: filePaths + }) + res.tempFiles = files + // 鍋滄鑷姩涓婁紶 + if (!this.autoUpload || this.noSpace) { + res.tempFiles = [] + } + res.tempFiles.forEach((fileItem, index) => { + this.provider && (fileItem.provider = this.provider); + const fileNameSplit = fileItem.name.split('.') + const ext = fileNameSplit.pop() + const fileName = fileNameSplit.join('.').replace(/[\s\/\?<>\\:\*\|":]/g, '_') + fileItem.cloudPath = fileName + '_' + Date.now() + '_' + index + '.' + ext + }) + }, + + /** + * 鎵逛紶 + * @param {Object} e + */ + uploadFiles(files) { + files = [].concat(files) + return uploadCloudFiles.call(this, files, 5, res => { + this.setProgress(res, res.index, true) + }) + .then(result => { + this.setSuccessAndError(result) + return result; + }) + .catch(err => { + console.log(err) + }) + }, + + /** + * 鎴愬姛鎴栧け璐� + */ + async setSuccessAndError(res, fn) { + let successData = [] + let errorData = [] + let tempFilePath = [] + let errorTempFilePath = [] + for (let i = 0; i < res.length; i++) { + const item = res[i] + const index = item.uuid ? this.files.findIndex(p => p.uuid === item.uuid) : item.index + + if (index === -1 || !this.files) break + if (item.errMsg === 'request:fail') { + this.files[index].url = item.path + this.files[index].status = 'error' + this.files[index].errMsg = item.errMsg + // this.files[index].progress = -1 + errorData.push(this.files[index]) + errorTempFilePath.push(this.files[index].url) + } else { + this.files[index].errMsg = '' + this.files[index].fileID = item.url + const reg = /cloud:\/\/([\w.]+\/?)\S*/ + if (reg.test(item.url)) { + this.files[index].url = await this.getTempFileURL(item.url) + } else { + this.files[index].url = item.url + } + + this.files[index].status = 'success' + this.files[index].progress += 1 + successData.push(this.files[index]) + tempFilePath.push(this.files[index].fileID) + } + } + + if (successData.length > 0) { + this.setEmit() + // 鐘舵�佹敼鍙樿繑鍥� + this.$emit('success', { + tempFiles: this.backObject(successData), + tempFilePaths: tempFilePath + }) + } + + if (errorData.length > 0) { + this.$emit('fail', { + tempFiles: this.backObject(errorData), + tempFilePaths: errorTempFilePath + }) + } + }, + + /** + * 鑾峰彇杩涘害 + * @param {Object} progressEvent + * @param {Object} index + * @param {Object} type + */ + setProgress(progressEvent, index, type) { + const fileLenth = this.files.length + const percentNum = (index / fileLenth) * 100 + const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total) + let idx = index + if (!type) { + idx = this.files.findIndex(p => p.uuid === progressEvent.tempFile.uuid) + } + if (idx === -1 || !this.files[idx]) return + // fix by mehaotian 100 灏变細娑堝け锛�-1 鏄负浜嗚杩涘害鏉℃秷澶� + this.files[idx].progress = percentCompleted - 1 + // 涓婁紶涓� + this.$emit('progress', { + index: idx, + progress: parseInt(percentCompleted), + tempFile: this.files[idx] + }) + }, + + /** + * 鍒犻櫎鏂囦欢 + * @param {Object} index + */ + delFile(index) { + this.$emit('delete', { + index, + tempFile: this.files[index], + tempFilePath: this.files[index].url + }) + this.files.splice(index, 1) + this.$nextTick(() => { + this.setEmit() + }) + }, + + /** + * 鑾峰彇鏂囦欢鍚嶅拰鍚庣紑 + * @param {Object} name + */ + getFileExt(name) { + const last_len = name.lastIndexOf('.') + const len = name.length + return { + name: name.substring(0, last_len), + ext: name.substring(last_len + 1, len) + } + }, + + /** + * 澶勭悊杩斿洖浜嬩欢 + */ + setEmit() { + let data = [] + if (this.returnType === 'object') { + data = this.backObject(this.files)[0] + this.localValue = data ? data : null + } else { + data = this.backObject(this.files) + if (!this.localValue) { + this.localValue = [] + } + this.localValue = [...data] + } + // #ifdef VUE3 + this.$emit('update:modelValue', this.localValue) + // #endif + // #ifndef VUE3 + this.$emit('input', this.localValue) + // #endif + }, + + /** + * 澶勭悊杩斿洖鍙傛暟 + * @param {Object} files + */ + backObject(files) { + let newFilesData = [] + files.forEach(v => { + newFilesData.push({ + extname: v.extname, + fileType: v.fileType, + image: v.image, + name: v.name, + path: v.path, + size: v.size, + fileID: v.fileID, + url: v.url, + // 淇敼鍒犻櫎涓�涓枃浠跺悗涓嶈兘鍐嶄笂浼犵殑bug, #694 + uuid: v.uuid, + status: v.status, + cloudPath: v.cloudPath + }) + }) + return newFilesData + }, + async getTempFileURL(fileList) { + fileList = { + fileList: [].concat(fileList) + } + const urls = await uniCloud.getTempFileURL(fileList) + return urls.fileList[0].tempFileURL || '' + }, + /** + * 鑾峰彇鐖跺厓绱犲疄渚� + */ + getForm(name = 'uniForms') { + let parent = this.$parent; + let parentName = parent.$options.name; + while (parentName !== name) { + parent = parent.$parent; + if (!parent) return false; + parentName = parent.$options.name; + } + return parent; } + } } </script> @@ -665,4 +716,4 @@ position: absolute; transform: rotate(90deg); } -</style> +</style> \ No newline at end of file -- Gitblit v1.9.3