src/views/qualityManagement/nonconformingManagement/components/formDia.vue
@@ -114,30 +114,6 @@ </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="原因分析:" prop="reasonAnalysis"> <el-input v-model="form.reasonAnalysis" type="textarea" :rows="4" placeholder="请输入" clearable /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="预防与纠正措施:" prop="preventiveCorrective"> <el-input v-model="form.preventiveCorrective" type="textarea" :rows="4" placeholder="请输入" clearable /> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="工时损失:" prop="lossWorking"> <el-input-number v-model="form.lossWorking" @@ -162,6 +138,56 @@ </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="原因分析:" prop="reasonAnalysis"> <el-input v-model="form.reasonAnalysis" type="textarea" :rows="4" placeholder="请输入" clearable /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="预防与纠正措施:" prop="preventiveCorrective"> <el-input v-model="form.preventiveCorrective" type="textarea" :rows="4" placeholder="请输入" clearable /> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="24"> <el-form-item label="不良品照片:" prop="defectivePhotos"> <el-upload v-model:file-list="defectivePhotoFileList" :action="upload.url" multiple ref="defectivePhotoUploadRef" auto-upload accept="image/*" :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError" :on-success="handleDefectivePhotoUploadSuccess" :on-remove="handleDefectivePhotoRemove" > <el-button type="primary" v-if="operationType !== 'view'">上传</el-button> <template #tip v-if="operationType !== 'view'"> <div class="el-upload__tip"> 文件格式支持 doc,docx,xls,xlsx,ppt,pptx,pdf,txt,xml,jpg,jpeg,png,gif,bmp,rar,zip,7z </div> </template> </el-upload> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <div class="dialog-footer"> @@ -174,7 +200,7 @@ </template> <script setup> import {ref, reactive, toRefs, getCurrentInstance} from "vue"; import { ref, reactive, toRefs, getCurrentInstance, watch } from "vue"; import {modelList, productTreeList} from "@/api/basicData/product.js"; import { getQualityUnqualifiedInfo, @@ -183,6 +209,7 @@ } from "@/api/qualityManagement/nonconformingManagement.js"; import {userListNoPage} from "@/api/system/user.js"; import useUserStore from "@/store/modules/user"; import { getToken } from "@/utils/auth"; const { proxy } = getCurrentInstance() const userStore = useUserStore() const emit = defineEmits(['close']) @@ -190,6 +217,12 @@ const dialogFormVisible = ref(false); const operationType = ref('') const { rejection_handling } = proxy.useDict("rejection_handling") const defectivePhotoFileList = ref([]); const defectivePhotoUploadRef = ref(null); const upload = reactive({ url: import.meta.env.VITE_APP_BASE_API + "/file/upload", headers: { Authorization: "Bearer " + getToken() }, }); const data = reactive({ form: { checkTime: "", @@ -204,6 +237,8 @@ checkResult: "", inspectType: '', defectivePhenomena: '', defectivePhotos: '', tempFileIds: [], dealResult: '', dealName: '', dealTime: '', @@ -242,12 +277,15 @@ } dialogFormVisible.value = true; if (operationType.value === 'add') { defectivePhotoFileList.value = []; form.value = { checkName: userStore.nickName || '', dealName: '', dealTime: '', dealResult: '', defectivePhenomena: '', defectivePhotos: '', tempFileIds: [], inspectType: '', checkTime: '', productId: '', @@ -261,6 +299,7 @@ lossMaterial: 0, }; } else { defectivePhotoFileList.value = []; form.value = {}; } getProductOptions(); @@ -336,8 +375,88 @@ } }) } // 上传前校检(参考协同审批附件上传) function handleBeforeUpload() { proxy.$modal.loading("正在上传文件,请稍候..."); return true; } function handleUploadError() { proxy.$modal.msgError("上传文件失败"); proxy.$modal.closeLoading(); } // 不良品照片上传成功:保存 tempId 与 tempPath,并回写到表单 function handleDefectivePhotoUploadSuccess(res, file) { proxy.$modal.closeLoading(); if (res?.code === 200) { const tempId = res?.data?.tempId; const tempPath = res?.data?.tempPath || res?.data?.url || ""; const originalName = res?.data?.originalName || file?.name || "图片"; if (!form.value.tempFileIds) form.value.tempFileIds = []; if (tempId) form.value.tempFileIds.push(tempId); // el-upload 列表回显需要 url/name file.id = tempId || file.id; file.name = originalName; file.url = tempPath ? (import.meta.env.VITE_APP_BASE_API + tempPath) : file.url; // 以“路径字符串”形式传给新增/编辑接口(后端若只认 tempFileIds 也不冲突) syncDefectivePhotosFromFileList(); proxy.$modal.msgSuccess("上传成功"); } else { proxy.$modal.msgError(res?.msg || "上传失败"); defectivePhotoUploadRef.value?.handleRemove(file); } } function handleDefectivePhotoRemove(file) { // 同步移除 tempFileIds const tempId = file?.id || file?.response?.data?.tempId; if (tempId && Array.isArray(form.value.tempFileIds)) { form.value.tempFileIds = form.value.tempFileIds.filter(id => id !== tempId); } syncDefectivePhotosFromFileList(); } function syncDefectivePhotosFromFileList() { const base = import.meta.env.VITE_APP_BASE_API; const paths = (defectivePhotoFileList.value || []) .map(f => f?.url || f?.response?.data?.tempPath || f?.response?.data?.url) .filter(Boolean) .map(url => (typeof url === "string" ? url.replace(base, "") : "")) .filter(Boolean); form.value.defectivePhotos = paths.join(","); } // 编辑/详情时,把后端返回的 defectivePhotos 路径串转成 el-upload 可回显的 fileList watch( () => form.value?.defectivePhotos, val => { if (!val) { defectivePhotoFileList.value = []; return; } const base = import.meta.env.VITE_APP_BASE_API; const list = String(val) .split(",") .map((p, idx) => { const path = p?.trim(); if (!path) return null; return { name: `图片${idx + 1}`, url: path.startsWith("http") ? path : base + path, id: undefined, }; }) .filter(Boolean); defectivePhotoFileList.value = list; }, { immediate: true } ); // 关闭弹框 const closeDia = () => { defectivePhotoFileList.value = [] proxy.resetForm("formRef"); dialogFormVisible.value = false; emit('close') src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue
@@ -111,30 +111,6 @@ </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="原因分析:" prop="reasonAnalysis"> <el-input v-model="form.reasonAnalysis" type="textarea" :rows="4" placeholder="请输入" clearable /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="预防与纠正措施:" prop="preventiveCorrective"> <el-input v-model="form.preventiveCorrective" type="textarea" :rows="4" placeholder="请输入" clearable /> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="工时损失:" prop="lossWorking"> <el-input-number v-model="form.lossWorking" @@ -159,6 +135,56 @@ </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="原因分析:" prop="reasonAnalysis"> <el-input v-model="form.reasonAnalysis" type="textarea" :rows="4" placeholder="请输入" clearable /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="预防与纠正措施:" prop="preventiveCorrective"> <el-input v-model="form.preventiveCorrective" type="textarea" :rows="4" placeholder="请输入" clearable /> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="24"> <el-form-item label="不良品照片:" prop="defectivePhotos"> <el-upload v-model:file-list="defectivePhotoFileList" :action="upload.url" multiple ref="defectivePhotoUploadRef" auto-upload accept="image/*" :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError" :on-success="handleDefectivePhotoUploadSuccess" :on-remove="handleDefectivePhotoRemove" > <el-button type="primary" v-if="operationType !== 'view'">上传</el-button> <template #tip v-if="operationType !== 'view'"> <div class="el-upload__tip"> 文件格式支持 jpg,jpeg,png,gif,bmp </div> </template> </el-upload> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <div class="dialog-footer"> @@ -171,20 +197,26 @@ </template> <script setup> import {ref, reactive, toRefs, computed} from "vue"; import { ref, reactive, toRefs, computed, watch, getCurrentInstance } from "vue"; import {productTreeList} from "@/api/basicData/product.js"; import { getQualityUnqualifiedInfo, qualityUnqualifiedDeal } from "@/api/qualityManagement/nonconformingManagement.js"; import {userListNoPage} from "@/api/system/user.js"; import { getCurrentInstance } from "vue"; import { getToken } from "@/utils/auth"; const { proxy } = getCurrentInstance() const emit = defineEmits(['close']) const { rejection_handling } = proxy.useDict("rejection_handling") const dialogFormVisible = ref(false); const operationType = ref('') const defectivePhotoFileList = ref([]); const defectivePhotoUploadRef = ref(null); const upload = reactive({ url: import.meta.env.VITE_APP_BASE_API + "/file/upload", headers: { Authorization: "Bearer " + getToken() }, }); const data = reactive({ form: { checkTime: "", @@ -199,6 +231,9 @@ checkResult: "", inspectType: '', defectivePhenomena: '', defectivePhotos: '', tempFileIds: [], commonFileList: [], dealResult: '', dealName: '', dealTime: '', @@ -249,11 +284,15 @@ userList.value = []; } dialogFormVisible.value = true; defectivePhotoFileList.value = []; form.value = { reasonAnalysis: '', preventiveCorrective: '', lossWorking: 0, lossMaterial: 0, defectivePhotos: '', tempFileIds: [], commonFileList: [], }; getProductOptions(); if (operationType.value === 'edit') { @@ -265,6 +304,9 @@ preventiveCorrective: '', lossWorking: 0, lossMaterial: 0, defectivePhotos: '', tempFileIds: [], commonFileList: [], ...rest } }) @@ -319,8 +361,101 @@ } }) } // 上传前校检(与新增页一致) function handleBeforeUpload() { proxy.$modal.loading("正在上传文件,请稍候..."); return true; } function handleUploadError() { proxy.$modal.msgError("上传文件失败"); proxy.$modal.closeLoading(); } // 不良品照片上传成功:保存 tempId 与 tempPath,并回写到表单 function handleDefectivePhotoUploadSuccess(res, file) { proxy.$modal.closeLoading(); if (res?.code === 200) { const tempId = res?.data?.tempId; const tempPath = res?.data?.tempPath || res?.data?.url || ""; const originalName = res?.data?.originalName || file?.name || "图片"; if (!form.value.tempFileIds) form.value.tempFileIds = []; if (tempId) form.value.tempFileIds.push(tempId); file.id = tempId || file.id; file.name = originalName; file.url = tempPath ? (import.meta.env.VITE_APP_BASE_API + tempPath) : file.url; syncDefectivePhotosFromFileList(); proxy.$modal.msgSuccess("上传成功"); } else { proxy.$modal.msgError(res?.msg || "上传失败"); defectivePhotoUploadRef.value?.handleRemove(file); } } function handleDefectivePhotoRemove(file) { const tempId = file?.id || file?.response?.data?.tempId; if (tempId && Array.isArray(form.value.tempFileIds)) { form.value.tempFileIds = form.value.tempFileIds.filter(id => id !== tempId); } if (Array.isArray(form.value.commonFileList)) { form.value.commonFileList = form.value.commonFileList.filter(item => { return item?.id !== tempId && item?.url !== file?.url && item?.name !== file?.name; }); } syncDefectivePhotosFromFileList(); } function syncDefectivePhotosFromFileList() { const base = import.meta.env.VITE_APP_BASE_API; const paths = (defectivePhotoFileList.value || []) .map(f => f?.url || f?.response?.data?.tempPath || f?.response?.data?.url) .filter(Boolean) .map(url => (typeof url === "string" ? url.replace(base, "") : "")) .filter(Boolean); form.value.defectivePhotos = paths.join(","); } function buildDefectivePhotoFileList() { const commonFiles = Array.isArray(form.value?.commonFileList) ? form.value.commonFileList : []; if (commonFiles.length > 0) { defectivePhotoFileList.value = commonFiles .map((item, idx) => ({ name: item?.name || `图片${idx + 1}`, url: item?.url || "", id: item?.id, })) .filter(item => item.url); return; } const photos = form.value?.defectivePhotos; if (!photos) { defectivePhotoFileList.value = []; return; } const base = import.meta.env.VITE_APP_BASE_API; defectivePhotoFileList.value = String(photos) .split(",") .map((p, idx) => { const path = p?.trim(); if (!path) return null; return { name: `图片${idx + 1}`, url: path.startsWith("http") ? path : base + path, id: undefined, }; }) .filter(Boolean); } watch( () => [form.value?.defectivePhotos, form.value?.commonFileList], () => { buildDefectivePhotoFileList(); }, { immediate: true, deep: true } ); // 关闭弹框 const closeDia = () => { defectivePhotoFileList.value = [] proxy.resetForm("formRef"); dialogFormVisible.value = false; emit('close')