From c7df828a939478c246d15dd8583e078840820353 Mon Sep 17 00:00:00 2001 From: liugongyu <290219706@qq.com> Date: Wed, 17 Dec 2025 22:01:39 +0800 Subject: [PATCH] 快速工单 样式优化 --- App.vue | 5 +++++ common/utils/useUploadImgs.js | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/utils/useUploadImgs.ts | 154 ---------------------------------------------------------------------------------------------------------------------------------------------------------- pages-sub/daily/maintain-manage/finish-plan-detail.vue | 2 +- pages-sub/daily/patrol-manage/finish-plan-detail.vue | 2 +- pages-sub/daily/quick-order/add-order.vue | 21 +++++++++++---------- pages-sub/daily/quick-order/order-detail.vue | 6 +++--- pages-sub/problem/work-order-manage/add-order.vue | 673 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 8 files changed, 469 insertions(+), 553 deletions(-) create mode 100644 common/utils/useUploadImgs.js delete mode 100644 common/utils/useUploadImgs.ts diff --git a/App.vue b/App.vue index cf53a6a..b1bbf76 100644 --- a/App.vue +++ b/App.vue @@ -123,4 +123,9 @@ page { padding-left: 15px; padding-right: 15px; } + +.common-text-color{ + font-size: 14px; + color: #606266 +} \ No newline at end of file diff --git a/common/utils/useUploadImgs.js b/common/utils/useUploadImgs.js new file mode 100644 index 0000000..9e470f6 --- /dev/null +++ b/common/utils/useUploadImgs.js @@ -0,0 +1,159 @@ +import { ref } from 'vue' +import { uploadImages } from '@/common/utils/upload' + +/** + * 图片上传组合式函数(兼容非TS环境,纯数组格式) + * @param config 上传配置 + * @returns 上传相关方法和状态 + */ +export function useUploadImgs(config) { + // 默认配置 + const defaultConfig = { + maxCount: 3, + uploadText: '选择图片', + sizeType: ['compressed'], + ...config + } + + // 核心修复:初始化为纯数组,且格式适配u-upload + const imgList = ref([]) + + /** + * 删除图片 + */ + const deleteImg = (event) => { + // 确保index是有效数字 + const index = Number(event.index) + if (isNaN(index) || index < 0 || index >= imgList.value.length) return + + imgList.value.splice(index, 1) + // 删除后重新校验 + defaultConfig.formRef.value?.validateField(defaultConfig.fieldName) + uni.showToast({ title: '图片删除成功', icon: 'success' }) + } + + /** + * 上传图片(适配u-upload的file格式) + */ + const uploadImgs = async (event) => { + // 核心修复:标准化file数据格式 + const rawFile = event.file || {} + const fileList = Array.isArray(rawFile) ? rawFile : [rawFile] + + // 过滤无效文件 + const validFiles = fileList.filter(file => file && file.url) + if (validFiles.length === 0) { + uni.showToast({ title: '请选择有效图片', icon: 'none' }) + return + } + + const targetImgList = imgList.value + + // 校验最大数量 + if (targetImgList.length + validFiles.length > defaultConfig.maxCount) { + uni.showToast({ title: `最多只能上传${defaultConfig.maxCount}张图片`, icon: 'none' }) + return + } + + // 核心修复:转换为u-upload兼容的格式 + const filePaths = validFiles.map(item => item.url) + const tempItems = validFiles.map(item => ({ + url: item.url, + status: 'uploading', + message: '上传中', + name: item.name || '', + size: item.size || 0 + })) + const startIndex = targetImgList.length + targetImgList.push(...tempItems) + + try { + const uploadResultUrls = await uploadImages({ + filePaths: filePaths, + ignoreError: true + }) + + // 更新上传成功的图片 + uploadResultUrls.forEach((url, index) => { + if (targetImgList[startIndex + index]) { + targetImgList.splice(startIndex + index, 1, { + url: url, + status: 'success', + message: '', + name: validFiles[index].name || '', + size: validFiles[index].size || 0 + }) + } + }) + + // 处理上传失败的图片 + if (uploadResultUrls.length < validFiles.length) { + const failCount = validFiles.length - uploadResultUrls.length + for (let i = uploadResultUrls.length; i < validFiles.length; i++) { + if (targetImgList[startIndex + i]) { + targetImgList.splice(startIndex + i, 1, { + url: validFiles[i].url, + status: 'failed', + message: '上传失败', + name: validFiles[i].name || '', + size: validFiles[i].size || 0 + }) + } + } + uni.showToast({ title: `成功上传${uploadResultUrls.length}张,失败${failCount}张`, icon: 'none' }) + } else { + uni.showToast({ title: `成功上传${validFiles.length}张图片`, icon: 'success' }) + } + + // 上传完成后校验 + defaultConfig.formRef.value?.validateField(defaultConfig.fieldName) + } catch (err) { + console.error(`【${defaultConfig.fieldName}】图片上传失败:`, err) + // 标记所有上传失败 + for (let i = 0; i < validFiles.length; i++) { + if (targetImgList[startIndex + i]) { + targetImgList.splice(startIndex + i, 1, { + url: validFiles[i].url, + status: 'failed', + message: '上传失败', + name: validFiles[i].name || '', + size: validFiles[i].size || 0 + }) + } + } + uni.showToast({ title: '图片上传失败,请重试', icon: 'none' }) + // 上传失败后校验 + defaultConfig.formRef.value?.validateField(defaultConfig.fieldName) + } + } + + /** + * 获取成功上传的图片URL列表 + */ + const getSuccessImgUrls = () => { + return imgList.value.filter(item => item.status === 'success').map(item => item.url) + } + + /** + * 图片校验规则(供表单使用) + */ + const imgValidateRule = { + required: true, + message: `请上传${defaultConfig.uploadText.replace('选择', '')}`, + trigger: 'change', + validator: (rule, value, callback) => { + const hasSuccessImg = imgList.value.some(item => item.status === 'success') + hasSuccessImg ? callback() : callback(new Error(`请上传至少1张${defaultConfig.uploadText.replace('选择', '')}`)) + } + } + + return { + imgList: imgList.value, // 核心修复:返回纯数组(解除响应式代理) + rawImgList: imgList, // 保留响应式引用(内部使用) + uploadImgs, + deleteImg, + getSuccessImgUrls, + imgValidateRule, + uploadConfig: defaultConfig + } +} \ No newline at end of file diff --git a/common/utils/useUploadImgs.ts b/common/utils/useUploadImgs.ts deleted file mode 100644 index 6f17211..0000000 --- a/common/utils/useUploadImgs.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { ref, type Ref } from 'vue' -import { uploadImages } from '@/common/utils/upload' -import type { UniFormRef } from '@/uni_modules/uview-plus/types' - -// 定义上传配置类型 -export interface UploadImgConfig { - maxCount?: number // 最大上传数量,默认3 - uploadText?: string // 上传按钮文案 - sizeType?: UniApp.UploadFileOption['sizeType'] // 图片压缩类型 - formRef: Ref // 表单ref,用于校验 - fieldName: string // 表单校验字段名(如problemImgs) -} - -// 定义图片项类型 -export interface UploadImgItem { - url: string - status: 'uploading' | 'success' | 'failed' - message: string - [key: string]: any // 兼容其他字段 -} - -/** - * 图片上传组合式函数(支持多实例复用) - * @param config 上传配置 - * @returns 上传相关方法和状态 - */ -export function useUploadImgs(config: UploadImgConfig) { - // 默认配置 - const defaultConfig = { - maxCount: 3, - uploadText: '选择图片', - sizeType: ['compressed'] as UniApp.UploadFileOption['sizeType'], - ...config - } - - // 图片列表 - const imgList = ref([]) - - /** - * 删除图片 - */ - const deleteImg = (event: { index: number }) => { - imgList.value.splice(event.index, 1) - // 删除后重新校验 - defaultConfig.formRef.value?.validateField(defaultConfig.fieldName) - uni.showToast({ title: '图片删除成功', icon: 'success' }) - } - - /** - * 上传图片 - */ - const uploadImgs = async (event: { file: UniApp.ChooseImageSuccessCallbackResult | UniApp.ChooseImageSuccessCallbackResult[] }) => { - const fileList = Array.isArray(event.file) ? event.file : [event.file] - const targetImgList = imgList.value - - // 过滤超出最大数量的图片 - if (targetImgList.length + fileList.length > defaultConfig.maxCount) { - uni.showToast({ title: `最多只能上传${defaultConfig.maxCount}张图片`, icon: 'none' }) - return - } - - const filePaths = fileList.map(item => item.url) - const tempItems = fileList.map(item => ({ - ...item, - status: 'uploading' as const, - message: '上传中' - })) - const startIndex = targetImgList.length - targetImgList.push(...tempItems) - - try { - const uploadResultUrls = await uploadImages({ - filePaths: filePaths, - ignoreError: true - }) - - // 更新上传成功的图片 - uploadResultUrls.forEach((url, index) => { - if (targetImgList[startIndex + index]) { - targetImgList.splice(startIndex + index, 1, { - ...fileList[index], - status: 'success' as const, - message: '', - url: url - }) - } - }) - - // 处理上传失败的图片 - if (uploadResultUrls.length < fileList.length) { - const failCount = fileList.length - uploadResultUrls.length - for (let i = uploadResultUrls.length; i < fileList.length; i++) { - if (targetImgList[startIndex + i]) { - targetImgList.splice(startIndex + i, 1, { - ...fileList[i], - status: 'failed' as const, - message: '上传失败' - }) - } - } - uni.showToast({ title: `成功上传${uploadResultUrls.length}张,失败${failCount}张`, icon: 'none' }) - } else { - uni.showToast({ title: `成功上传${fileList.length}张图片`, icon: 'success' }) - } - - // 上传完成后校验 - defaultConfig.formRef.value?.validateField(defaultConfig.fieldName) - } catch (err) { - console.error(`【${defaultConfig.fieldName}】图片上传失败:`, err) - // 标记所有上传失败 - for (let i = 0; i < fileList.length; i++) { - if (targetImgList[startIndex + i]) { - targetImgList.splice(startIndex + i, 1, { - ...fileList[i], - status: 'failed' as const, - message: '上传失败' - }) - } - } - uni.showToast({ title: '图片上传失败,请重试', icon: 'none' }) - // 上传失败后校验 - defaultConfig.formRef.value?.validateField(defaultConfig.fieldName) - } - } - - /** - * 获取成功上传的图片URL列表 - */ - const getSuccessImgUrls = () => { - return imgList.value.filter(item => item.status === 'success').map(item => item.url) - } - - /** - * 图片校验规则(供表单使用) - */ - const imgValidateRule = { - required: true, - message: `请上传${defaultConfig.uploadText.replace('选择', '')}`, - trigger: 'change', - validator: (rule: any, value: any, callback: (error?: Error) => void) => { - const hasSuccessImg = imgList.value.some(item => item.status === 'success') - hasSuccessImg ? callback() : callback(new Error(`请上传至少1张${defaultConfig.uploadText.replace('选择', '')}`)) - } - } - - return { - imgList, - uploadImgs, - deleteImg, - getSuccessImgUrls, - imgValidateRule, - uploadConfig: defaultConfig - } -} \ No newline at end of file diff --git a/pages-sub/daily/maintain-manage/finish-plan-detail.vue b/pages-sub/daily/maintain-manage/finish-plan-detail.vue index ab86727..f72c6ee 100644 --- a/pages-sub/daily/maintain-manage/finish-plan-detail.vue +++ b/pages-sub/daily/maintain-manage/finish-plan-detail.vue @@ -71,7 +71,7 @@ 巡查描述 diff --git a/pages-sub/daily/patrol-manage/finish-plan-detail.vue b/pages-sub/daily/patrol-manage/finish-plan-detail.vue index 972ca3e..3b62805 100644 --- a/pages-sub/daily/patrol-manage/finish-plan-detail.vue +++ b/pages-sub/daily/patrol-manage/finish-plan-detail.vue @@ -72,7 +72,7 @@ 巡查描述 diff --git a/pages-sub/daily/quick-order/add-order.vue b/pages-sub/daily/quick-order/add-order.vue index 82ba3cc..8a27550 100644 --- a/pages-sub/daily/quick-order/add-order.vue +++ b/pages-sub/daily/quick-order/add-order.vue @@ -1,5 +1,5 @@ @@ -54,7 +54,7 @@ 情况描述 @@ -101,7 +101,7 @@ 处理结果 diff --git a/pages-sub/problem/work-order-manage/add-order.vue b/pages-sub/problem/work-order-manage/add-order.vue index 4f7b89e..d709bd6 100644 --- a/pages-sub/problem/work-order-manage/add-order.vue +++ b/pages-sub/problem/work-order-manage/add-order.vue @@ -1,6 +1,5 @@ - +