| | |
| | | </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" |
| | |
| | | </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"> |
| | |
| | | </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, |
| | |
| | | } 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']) |
| | |
| | | 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: "", |
| | |
| | | checkResult: "", |
| | | inspectType: '', |
| | | defectivePhenomena: '', |
| | | defectivePhotos: '', |
| | | tempFileIds: [], |
| | | dealResult: '', |
| | | dealName: '', |
| | | dealTime: '', |
| | |
| | | } |
| | | dialogFormVisible.value = true; |
| | | if (operationType.value === 'add') { |
| | | defectivePhotoFileList.value = []; |
| | | form.value = { |
| | | checkName: userStore.nickName || '', |
| | | dealName: '', |
| | | dealTime: '', |
| | | dealResult: '', |
| | | defectivePhenomena: '', |
| | | defectivePhotos: '', |
| | | tempFileIds: [], |
| | | inspectType: '', |
| | | checkTime: '', |
| | | productId: '', |
| | |
| | | lossMaterial: 0, |
| | | }; |
| | | } else { |
| | | defectivePhotoFileList.value = []; |
| | | form.value = {}; |
| | | } |
| | | getProductOptions(); |
| | |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 上传前校检(参考协同审批附件上传) |
| | | 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') |