| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="单位:" prop="unit"> |
| | | <el-input v-model="form.unit" disabled/> |
| | | <el-input v-model="form.unit" placeholder="自动带出" readonly class="readonly-display"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="厚度:" prop="thickness"> |
| | | <el-input v-model="form.thickness" placeholder="自动带出" readonly class="readonly-display"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="数量:" prop="quantity"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.quantity" placeholder="请输入" |
| | | clearable :precision="2" :disabled="supplierQuantityDisabled"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="检测单位:" prop="checkCompany"> |
| | | <el-input v-model="form.checkCompany" placeholder="请输入" clearable/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="检测结果:" prop="checkResult"> |
| | | <el-select v-model="form.checkResult"> |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="检验员:" prop="checkName"> |
| | | <el-select v-model="form.checkName" placeholder="请选择" clearable style="width: 100%"> |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="检测日期:" prop="checkTime"> |
| | | <el-date-picker |
| | |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item> |
| | | <template #label> |
| | | <div style="display: flex; align-items: center; justify-content: space-between; width: 100%;"> |
| | | <span>审批人选择:</span> |
| | | <el-button type="primary" |
| | | size="small" |
| | | @click="addApproverNode" |
| | | icon="Plus">新增节点</el-button> |
| | | </div> |
| | | </template> |
| | | <div class="approver-nodes-container"> |
| | | <div v-for="(node, index) in approverNodes" |
| | | :key="node.id" |
| | | class="approver-node-item"> |
| | | <div class="approver-node-header"> |
| | | <span class="approver-node-label">审批节点 {{ index + 1 }}</span> |
| | | <el-button v-if="approverNodes.length > 1" |
| | | type="danger" |
| | | size="small" |
| | | text |
| | | @click="removeApproverNode(index)" |
| | | icon="Delete">删除</el-button> |
| | | </div> |
| | | <el-select v-model="node.userId" |
| | | placeholder="请选择审批人" |
| | | filterable |
| | | style="width: 100%"> |
| | | <el-option |
| | | v-for="item in approverList" |
| | | :key="item.userId" |
| | | :label="item.userName" |
| | | :value="item.userId" |
| | | /> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | import {qualityInspectParamDel, qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js"; |
| | | import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js"; |
| | | import {userListNoPage} from "@/api/system/user.js"; |
| | | import { approveUserList } from "@/api/collaborativeApproval/approvalProcess.js"; |
| | | |
| | | const {proxy} = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | |
| | | model: "", |
| | | testStandardId: "", |
| | | unit: "", |
| | | thickness: "", |
| | | quantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | reviewName: "", |
| | | }, |
| | | rules: { |
| | | checkTime: [{required: true, message: "请输入", trigger: "blur"},], |
| | |
| | | productModelId: [{required: true, message: "请选择产品型号", trigger: "change"}], |
| | | testStandardId: [{required: false, message: "请选择指标", trigger: "change"}], |
| | | unit: [{required: false, message: "请输入", trigger: "blur"}], |
| | | thickness: [{required: false, message: "请输入", trigger: "blur"}], |
| | | quantity: [{required: true, message: "请输入", trigger: "blur"}], |
| | | checkCompany: [{required: false, message: "请输入", trigger: "blur"}], |
| | | checkResult: [{required: true, message: "请选择检测结果", trigger: "change"}], |
| | |
| | | const testStandardOptions = ref([]); // 指标选择下拉框数据 |
| | | const modelOptions = ref([]); |
| | | const userList = ref([]); // 检验员下拉列表 |
| | | const approverList = ref([]); // 审批人下拉列表 |
| | | const approverNodes = ref([{ id: 1, userId: null }]); |
| | | let nextApproverId = 2; |
| | | const addApproverNode = () => { |
| | | approverNodes.value.push({ id: nextApproverId++, userId: null }); |
| | | }; |
| | | const removeApproverNode = index => { |
| | | approverNodes.value.splice(index, 1); |
| | | }; |
| | | |
| | | // 编辑时:productMainId 或 purchaseLedgerId 任一有值则供应商、数量置灰 |
| | | const supplierQuantityDisabled = computed(() => { |
| | |
| | | try { |
| | | const userRes = await userListNoPage(); |
| | | userList.value = userRes.data || []; |
| | | const approverRes = await approveUserList({ approveType: 9 }); |
| | | approverList.value = approverRes.data || []; |
| | | } catch (e) { |
| | | console.error("加载检验员列表失败", e); |
| | | console.error("加载人员列表失败", e); |
| | | userList.value = []; |
| | | approverList.value = []; |
| | | } |
| | | // 先重置表单数据(保持字段完整,避免弹窗首次渲染时触发必填红框“闪一下”) |
| | | form.value = { |
| | |
| | | model: "", |
| | | testStandardId: "", |
| | | unit: "", |
| | | thickness: "", |
| | | quantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | reviewName: "", |
| | | } |
| | | approverNodes.value = [{ id: 1, userId: null }]; |
| | | nextApproverId = 2; |
| | | testStandardOptions.value = []; |
| | | tableData.value = []; |
| | | // 先确保产品树已加载,否则编辑时产品/规格型号无法反显 |
| | |
| | | // 先保存 testStandardId,避免被清空 |
| | | const savedTestStandardId = row.testStandardId; |
| | | form.value = {...row} |
| | | if (form.value.approveUserIds) { |
| | | const ids = String(form.value.approveUserIds) |
| | | .split(",") |
| | | .map(id => id.trim()) |
| | | .filter(Boolean); |
| | | if (ids.length > 0) { |
| | | approverNodes.value = ids.map((id, index) => ({ |
| | | id: index + 1, |
| | | userId: Number(id), |
| | | })); |
| | | nextApproverId = ids.length + 1; |
| | | } |
| | | } else if (form.value.reviewName) { |
| | | const matchedReviewer = approverList.value.find(item => item.userName === form.value.reviewName); |
| | | if (matchedReviewer?.userId) { |
| | | approverNodes.value = [{ id: 1, userId: matchedReviewer.userId }]; |
| | | nextApproverId = 2; |
| | | } |
| | | } |
| | | currentProductId.value = row.productId || 0 |
| | | // 关键:编辑时加载规格型号下拉选项,才能反显 productModelId |
| | | if (currentProductId.value) { |
| | |
| | | const getModels = (value) => { |
| | | form.value.productModelId = undefined; |
| | | form.value.unit = undefined; |
| | | form.value.thickness = undefined; |
| | | modelOptions.value = []; |
| | | currentProductId.value = value |
| | | form.value.productName = findNodeById(productOptions.value, value); |
| | |
| | | }; |
| | | |
| | | const handleChangeModel = (value) => { |
| | | form.value.model = modelOptions.value.find(item => item.id == value)?.model || ''; |
| | | form.value.unit = modelOptions.value.find(item => item.id == value)?.unit || ''; |
| | | const selectedModel = modelOptions.value.find(item => item.id == value); |
| | | form.value.model = selectedModel?.model || ''; |
| | | form.value.unit = selectedModel?.unit || ''; |
| | | form.value.thickness = selectedModel?.thickness ?? ''; |
| | | } |
| | | |
| | | const findNodeById = (nodes, productId) => { |
| | |
| | | const submitForm = () => { |
| | | proxy.$refs.formRef.validate(valid => { |
| | | if (valid) { |
| | | const hasEmptyApprover = approverNodes.value.some(node => !node.userId); |
| | | if (hasEmptyApprover) { |
| | | proxy.$modal.msgError("请为所有审批节点选择审批人!"); |
| | | return; |
| | | } |
| | | const approveUserIds = approverNodes.value.map(node => node.userId).join(","); |
| | | const firstApproverName = |
| | | approverList.value.find(item => String(item.userId) === String(approverNodes.value[0]?.userId)) |
| | | ?.userName || ""; |
| | | form.value.inspectType = 0 |
| | | if (operationType.value === "add") { |
| | | tableData.value.forEach((item) => { |
| | | delete item.id |
| | | }) |
| | | } |
| | | const data = {...form.value, qualityInspectParams: tableData.value} |
| | | const data = { |
| | | ...form.value, |
| | | reviewName: firstApproverName, |
| | | approveUserIds, |
| | | // 兼容后端不同字段命名 |
| | | auditName: firstApproverName, |
| | | qualityInspectParams: tableData.value, |
| | | } |
| | | if (operationType.value === "add") { |
| | | qualityInspectAdd(data).then(res => { |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | |
| | | // 关闭弹框 |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | approverNodes.value = [{ id: 1, userId: null }]; |
| | | nextApproverId = 2; |
| | | tableData.value = []; |
| | | testStandardOptions.value = []; |
| | | form.value.testStandardId = ''; |
| | |
| | | |
| | | <style scoped> |
| | | |
| | | :deep(.readonly-display .el-input__wrapper) { |
| | | background-color: var(--el-disabled-bg-color); |
| | | box-shadow: 0 0 0 1px var(--el-disabled-border-color) inset; |
| | | } |
| | | |
| | | :deep(.readonly-display .el-input__inner) { |
| | | color: var(--el-disabled-text-color); |
| | | -webkit-text-fill-color: var(--el-disabled-text-color); |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | .approver-nodes-container { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 16px; |
| | | padding: 16px; |
| | | background-color: #f8f9fa; |
| | | border-radius: 4px; |
| | | border: 1px solid #e4e7ed; |
| | | } |
| | | |
| | | .approver-node-item { |
| | | flex: 0 0 calc(33.333% - 12px); |
| | | min-width: 200px; |
| | | padding: 12px; |
| | | background-color: #fff; |
| | | border-radius: 4px; |
| | | border: 1px solid #dcdfe6; |
| | | transition: all 0.3s; |
| | | } |
| | | |
| | | .approver-node-item:hover { |
| | | border-color: #409eff; |
| | | box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1); |
| | | } |
| | | |
| | | .approver-node-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .approver-node-label { |
| | | font-size: 13px; |
| | | font-weight: 500; |
| | | color: #606266; |
| | | } |
| | | |
| | | @media (max-width: 1200px) { |
| | | .approver-node-item { |
| | | flex: 0 0 calc(50% - 8px); |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .approver-node-item { |
| | | flex: 0 0 100%; |
| | | } |
| | | } |
| | | |
| | | </style> |