/** * 图片上传和下载工具类 */ export default { /** * 获取文件列表 * @param {String} type - 类型 * @param {String} orderFileType - 订单文件类型 (1:聊天记录, 2:实物图, 3:细节图) * @param {String} receiptId - 收单ID * @param {String} itemBrand - 物品品牌 * @param {String} clueId - 线索ID */ async getFileList(type, orderFileType, receiptId, itemBrand, clueId) { try { const params = { clueId, sourceId: receiptId, type, orderFileType, isDuplicate: '1', pageNum: 1, pageSize: 1000 } const response = await uni.$u.api.selectClueFileByDto(params) const rows = response.rows || [] // 如果品牌包含逗号,说明是多个品牌,需要过滤 // if (itemBrand && itemBrand.indexOf(',') !== -1) { return rows.filter(item => item.sourceId === receiptId) // } // return rows } catch (error) { console.error('获取文件列表失败:', error) uni.$u.toast('获取文件列表失败') return [] } }, /** * 选择图片 * @param {Number} count - 最多选择数量 * @returns {Promise} 图片路径数组 */ chooseImage(count = 9) { return new Promise((resolve, reject) => { uni.chooseImage({ count, sizeType: ['compressed'], sourceType: ['album', 'camera'], success: (res) => { resolve(res.tempFilePaths) }, fail: (err) => { console.error('选择图片失败:', err) reject(err) } }) }) }, /** * 上传文件 * @param {String} filePath - 文件路径 * @returns {Promise} 上传结果 */ async uploadFile(filePath) { try { uni.showLoading({ title: '上传中...', mask: true }) const { data } = await uni.$u.api.uploadFile(filePath) return { fileSize: data.fileSize, fileSuffix: data.fileSuffix, fileName: data.name, fileUrl: data.url } } catch (error) { console.error('文件上传失败:', error) uni.$u.toast('上传失败,请重试') throw error } finally { uni.hideLoading() } }, /** * 批量上传文件 * @param {Array} filePaths - 文件路径数组 * @returns {Promise} 上传结果数组 */ async uploadFiles(filePaths) { try { const uploadPromises = filePaths.map(filePath => this.uploadFile(filePath)) return await Promise.all(uploadPromises) } catch (error) { console.error('批量上传失败:', error) throw error } }, /** * 绑定订单文件 * @param {String} clueId - 线索ID * @param {String} receiptId - 收单ID * @param {String} orderFileType - 订单文件类型 * @param {Array} fileList - 文件列表 */ async bindOrderFile(clueId, receiptId, orderFileType, fileList) { try { const list = fileList.map(file => ({ fileSize: file.fileSize, fileSuffix: file.fileSuffix, fileName: file.fileName, fileUrl: file.fileUrl, orderFileType })) await uni.$u.api.saveClueFile({ clueId, list, sourceId: receiptId, type: '2', orderFileType }) uni.$u.toast('上传成功') } catch (error) { console.error('绑定订单文件失败:', error) uni.$u.toast('上传失败') throw error } }, /** * 删除文件 * @param {String|Array} fileIds - 文件ID或ID数组 */ async deleteFile(fileIds) { try { const ids = Array.isArray(fileIds) ? fileIds : [fileIds] await uni.$u.api.deleteClueFile(ids) uni.showToast({ title: '删除成功', icon: 'success', duration: 2000 }) } catch (error) { console.error('删除文件失败:', error) uni.showToast({ title: '删除失败', icon: 'error', duration: 2000 }) throw error } }, /** * 保存图片到本地相册 * @param {String} url - 图片URL * @returns {Promise} */ saveImageToLocal(url) { return new Promise((resolve, reject) => { this._doSaveImage(url, resolve, reject) }) }, /** * 执行保存图片操作 * @private */ _doSaveImage(url, resolve, reject) { uni.downloadFile({ url, success: (res) => { if (res.statusCode === 200 && res.tempFilePath) { uni.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: () => { resolve() }, fail: (err) => { console.error('保存到相册失败:', err) // 错误代码 12 通常表示权限问题 const isPermissionError = err.code === 12 || err.errCode === 12 || err.errMsg.includes('auth denied') || err.errMsg.includes('permission') || err.errMsg.includes('UNKOWN ERROR') if (isPermissionError) { uni.showModal({ title: '权限不足', content: '需要访问相册权限来保存图片,是否前往设置开启权限?', confirmText: '去设置', cancelText: '取消', success: (modalRes) => { if (modalRes.confirm) { uni.openSetting({ success: (settingRes) => { // 检查是否开启了相册权限 const hasPermission = settingRes.authSetting && settingRes.authSetting['scope.writePhotosAlbum'] if (hasPermission) { uni.showToast({ title: '权限已开启,请重试保存', icon: 'none', duration: 2000 }) } else { uni.showToast({ title: '请在设置中开启相册权限', icon: 'none', duration: 2000 }) } }, fail: () => { uni.showToast({ title: '无法打开设置', icon: 'none' }) } }) } } }) } else { uni.showToast({ title: '保存失败,请稍后重试', icon: 'none' }) } reject(err) } }) } else { const errorMsg = `下载失败,状态码: ${res.statusCode}` console.error(errorMsg) uni.showToast({ title: '下载图片失败', icon: 'none' }) reject(new Error(errorMsg)) } }, fail: (err) => { console.error('下载图片失败:', err) uni.showToast({ title: '下载图片失败,请检查网络', icon: 'none' }) reject(err) } }) }, /** * 批量保存图片到本地 * @param {Array} urls - 图片URL数组 */ async saveImagesToLocal(urls) { try { uni.showLoading({ title: '正在保存图片...', mask: true }) const savedImages = [] const failedImages = [] for (let i = 0; i < urls.length; i++) { const url = urls[i] try { await this.saveImageToLocal(url) savedImages.push(url) } catch (error) { console.error(`保存图片失败: ${url}`, error) failedImages.push(url) } uni.showLoading({ title: `正在保存图片... (${i + 1}/${urls.length})`, mask: true }) } uni.hideLoading() let message = `成功保存 ${savedImages.length} 张图片` if (failedImages.length > 0) { message += `,${failedImages.length} 张保存失败` } uni.showToast({ title: message, icon: 'none', duration: 3000 }) } catch (error) { uni.hideLoading() console.error('保存图片过程中发生错误:', error) uni.showToast({ title: '保存图片失败', icon: 'error' }) } }, /** * 复制图片链接 * @param {Array} urls - 图片URL数组 */ copyImageUrls(urls) { uni.setClipboardData({ data: JSON.stringify(urls), success: () => { uni.showToast({ title: '图片链接已复制', icon: 'none' }) } }) } }