gaoluyang
4 天以前 f42a646e394dbf4b68cb1beba0015ca8de03a61c
君歌
1.不合格管理修改
已修改3个文件
881 ■■■■ 文件已修改
src/api/qualityManagement/nonconformingManagement.js 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/nonconformingManagement/components/formDia.vue 539 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/nonconformingManagement/index.vue 293 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/qualityManagement/nonconformingManagement.js
@@ -1,50 +1,45 @@
import request from "@/utils/request";
// 查询不合格管理列表
// 查询不合格品处理单列表
export function qualityUnqualifiedListPage(query) {
  return request({
    url: "/quality/qualityUnqualified/listPage",
    url: "/qualityUnqualifiedOrder/listPage",
    method: "get",
    params: query,
  });
}
// 新增不合格管理列表
export function qualityUnqualifiedAdd(query) {
// 新增不合格品处理单
export function qualityUnqualifiedAdd(data) {
  return request({
    url: "/quality/qualityUnqualified/add",
    url: "/qualityUnqualifiedOrder/save",
    method: "post",
    data: query,
    data: data,
  });
}
// 修改不合格管理列表
export function qualityUnqualifiedUpdate(query) {
// 修改不合格品处理单
export function qualityUnqualifiedUpdate(data) {
  return request({
    url: "/quality/qualityUnqualified/update",
    method: "post",
    data: query,
    url: "/qualityUnqualifiedOrder/update",
    method: "put",
    data: data,
  });
}
// 不合格处理
export function qualityUnqualifiedDeal(query) {
// 删除不合格品处理单
export function qualityUnqualifiedDel(ids) {
  return request({
    url: "/quality/qualityUnqualified/deal",
    method: "post",
    data: query,
  });
}
// 删除不合格管理列表
export function qualityUnqualifiedDel(query) {
  return request({
    url: "/quality/qualityUnqualified/del",
    url: "/qualityUnqualifiedOrder/delete",
    method: "delete",
    data: query,
    data: ids,
  });
}
// 查询不合格管理信息
export function getQualityUnqualifiedInfo(query) {
// 查询不合格品处理单详情
export function getQualityUnqualifiedInfo(id) {
  return request({
    url: "/quality/qualityUnqualified/" + query,
    url: "/qualityUnqualifiedOrder/listPage?current=1&size=1&id=" + id,
    method: "get",
    data: query,
  });
}
src/views/qualityManagement/nonconformingManagement/components/formDia.vue
@@ -2,70 +2,108 @@
  <div>
    <el-dialog
        v-model="dialogFormVisible"
        :title="operationType === 'add' ? '新增不合格管理' : '编辑不合格管理'"
        width="70%"
        :title="operationType === 'add' ? '新增不合格品处理单' : '编辑不合格品处理单'"
        width="80%"
        @close="closeDia"
    >
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <!-- 第一行:项目名称、项目编号 -->
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="类别:" prop="inspectType">
              <el-select v-model="form.inspectType">
                <el-option label="原材料检验" :value="0" />
                <el-option label="过程检验" :value="1" />
                <el-option label="出厂检验" :value="2" />
              </el-select>
            <el-form-item label="项目名称:" prop="projectName">
              <el-input v-model="form.projectName" placeholder="请输入项目名称" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="项目编号:" prop="projectNo">
              <el-input v-model="form.projectNo" placeholder="请输入项目编号" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第二行:设备名称、设备图号 -->
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="产品名称:" prop="productId">
              <el-tree-select
                  v-model="form.productId"
                  placeholder="请选择"
                  clearable
                  check-strictly
                  @change="getModels"
                  :data="productOptions"
                  :render-after-expand="false"
                  style="width: 100%"
              />
            <el-form-item label="设备名称:" prop="equipmentName">
              <el-input v-model="form.equipmentName" placeholder="请输入设备名称" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="model">
              <el-select v-model="form.model" placeholder="请选择" clearable :disabled="operationType === 'edit'"
                          filterable readonly @change="handleChangeModel">
              <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
            </el-select>
            <el-form-item label="设备图号:" prop="equipmentDrawingNo">
              <el-input v-model="form.equipmentDrawingNo" placeholder="请输入设备图号" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第三行:物料/部件名称、物料图号 -->
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="单位:" prop="unit">
              <el-input v-model="form.unit" placeholder="请输入" clearable/>
            <el-form-item label="物料/部件名称:" prop="materialName">
              <el-input v-model="form.materialName" placeholder="请输入物料/部件名称" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="物料图号:" prop="materialDrawingNo">
              <el-input v-model="form.materialDrawingNo" placeholder="请输入物料图号" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第四行:型号规格、材质、数量、不合格数 -->
        <el-row :gutter="30">
          <el-col :span="6">
            <el-form-item label="型号规格:" prop="specificationModel">
              <el-input v-model="form.specificationModel" placeholder="请输入型号规格" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="材质:" prop="materialQuality">
              <el-input v-model="form.materialQuality" placeholder="请输入材质" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <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"/>
              <el-input-number :step="1" :min="0" style="width: 100%" v-model="form.quantity" placeholder="请输入数量" :precision="0"/>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="不合格数:" prop="unqualifiedQuantity">
              <el-input-number :step="1" :min="0" style="width: 100%" v-model="form.unqualifiedQuantity" placeholder="请输入不合格数" :precision="0"/>
            </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-form-item label="不合格工序:" prop="unqualifiedProcess">
              <el-radio-group v-model="form.unqualifiedProcess">
                <el-radio :label="1">来料</el-radio>
                <el-radio :label="2">制程</el-radio>
                <el-radio :label="3">成品</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="供货商名称:" prop="supplierName">
              <el-input v-model="form.supplierName" placeholder="请输入供货商名称" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第六行:检验员、检验日期、责任人、责任部门 -->
        <el-row :gutter="30">
          <el-col :span="6">
            <el-form-item label="检验员:" prop="inspectorName">
              <el-select v-model="form.inspectorName" placeholder="请选择" clearable style="width: 100%">
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="检测日期:" prop="checkTime">
          <el-col :span="6">
            <el-form-item label="检验日期:" prop="inspectDate">
              <el-date-picker
                  v-model="form.checkTime"
                  v-model="form.inspectDate"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
@@ -75,93 +113,142 @@
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="不合格现象:" prop="defectivePhenomena">
              <el-input v-model="form.defectivePhenomena" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="处理结果:" prop="dealResult">
              <el-select v-model="form.dealResult" placeholder="请选择" clearable>
                <el-option :label="item.label" :value="item.value" v-for="item in rejection_handling" :key="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="处理人:" prop="dealName">
              <el-select v-model="form.dealName" placeholder="请选择" clearable style="width: 100%">
          <el-col :span="6">
            <el-form-item label="责任人:" prop="responsiblePerson">
              <el-select v-model="form.responsiblePerson" placeholder="请选择" clearable style="width: 100%">
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="处理日期:" prop="dealTime">
              <el-date-picker
                  v-model="form.dealTime"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
          <el-col :span="6">
            <el-form-item label="责任部门:" prop="responsibleDept">
              <el-input v-model="form.responsibleDept" placeholder="请输入责任部门" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第七行:问题描述 -->
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="问题描述:" prop="problemDescription">
              <el-input
                  v-model="form.problemDescription"
                  type="textarea"
                  :rows="3"
                  placeholder="请输入问题描述"
                  clearable
                  style="width: 100%"
              />
            </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"
                  :min="0"
                  :step="0.01"
                  :precision="2"
                  style="width: 100%"
                  placeholder="请输入"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="材料费损失:" prop="lossMaterial">
              <el-input-number
                  v-model="form.lossMaterial"
                  :min="0"
                  :step="0.01"
                  :precision="2"
                  style="width: 100%"
                  placeholder="请输入"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="原因分析:" prop="reasonAnalysis">
          <el-col :span="24">
            <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="请输入"
                  placeholder="请输入原因分析及建议"
                  clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第九行:纠正措施 -->
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="纠正措施:" prop="correctionAction">
              <el-input
                  v-model="form.correctionAction"
                  type="textarea"
                  :rows="3"
                  placeholder="请输入纠正措施"
                  clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第十行:处置方式 -->
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="处置方式:" prop="disposalMethod">
              <el-radio-group v-model="form.disposalMethod">
                <el-radio :label="1">让步接收</el-radio>
                <el-radio :label="2">厂内维修</el-radio>
                <el-radio :label="3">返厂维修</el-radio>
                <el-radio :label="4">换货</el-radio>
                <el-radio :label="5">退货</el-radio>
                <el-radio :label="6">报废</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第十一行:厂内/返厂维修评估 -->
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="厂内/返厂维修评估:" prop="repairEvaluation">
              <el-input
                  v-model="form.repairEvaluation"
                  type="textarea"
                  :rows="3"
                  placeholder="请输入厂内/返厂维修评估"
                  clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第十二行:预防措施 -->
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="预防措施:" prop="preventiveAction">
              <el-input
                  v-model="form.preventiveAction"
                  type="textarea"
                  :rows="3"
                  placeholder="请输入预防措施"
                  clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第十三行:状态 -->
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="状态:" prop="status">
              <el-radio-group v-model="form.status">
                <el-radio :label="0">草稿</el-radio>
                <el-radio :label="1">待审核</el-radio>
                <el-radio :label="2">审批中</el-radio>
                <el-radio :label="3">已完成</el-radio>
                <el-radio :label="4">已驳回</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第十四行:备注 -->
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="备注:" prop="remark">
              <el-input
                  v-model="form.remark"
                  type="textarea"
                  :rows="3"
                  placeholder="请输入备注"
                  clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 第十五行:不良品照片 -->
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="不良品照片:" prop="defectivePhotos">
@@ -181,7 +268,7 @@
                <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
                    文件格式支持 jpg,jpeg,png,gif,bmp
                  </div>
                </template>
              </el-upload>
@@ -200,8 +287,7 @@
</template>
<script setup>
import { ref, reactive, toRefs, getCurrentInstance, watch } from "vue";
import {modelList, productTreeList} from "@/api/basicData/product.js";
import { ref, reactive, toRefs, getCurrentInstance } from "vue";
import {
  getQualityUnqualifiedInfo,
  qualityUnqualifiedAdd,
@@ -216,54 +302,62 @@
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: "",
    process: "",
    checkName: "",
    productName: "",
    productId: "",
    model: "",
    unit: "",
    quantity: "",
    checkCompany: "",
    checkResult: "",
    inspectType: '',
    defectivePhenomena: '',
    // 基本信息
    projectName: '',
    projectNo: '',
    equipmentName: '',
    equipmentDrawingNo: '',
    materialName: '',
    materialDrawingNo: '',
    specificationModel: '',
    materialQuality: '',
    quantity: 0,
    unqualifiedQuantity: 0,
    unqualifiedProcess: undefined,
    supplierName: '',
    inspectorName: '',
    inspectDate: '',
    responsiblePerson: '',
    responsibleDept: '',
    // 问题描述和处理
    problemDescription: '',
    reasonAnalysis: '',
    correctionAction: '',
    disposalMethod: undefined,
    repairEvaluation: '',
    preventiveAction: '',
    // 状态
    status: 0,
    remark: '',
    // 附件
    defectivePhotos: '',
    tempFileIds: [],
    dealResult: '',
    dealName: '',
    dealTime: '',
    reasonAnalysis: '',
    preventiveCorrective: '',
    lossWorking: 0,
    lossMaterial: 0,
  },
  rules: {
    checkTime: [{ required: false, message: "请输入", trigger: "blur" },],
    process: [{ required: true, message: "请输入", trigger: "blur" }],
    checkName: [{ required: true, message: "请选择检验员", trigger: "change" }],
    productId: [{ required: true, message: "请输入", trigger: "blur" }],
    model: [{ required: true, message: "请输入", trigger: "blur" }],
    unit: [{ required: false, message: "请输入", trigger: "blur" }],
    quantity: [{ required: true, message: "请输入", trigger: "blur" }],
    checkCompany: [{ required: false, message: "请输入", trigger: "blur" }],
    checkResult: [{ required: false, message: "请输入", trigger: "blur" }],
    dealName: [{ required: true, message: "请选择处理人", trigger: "change" }],
    projectName: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
    materialName: [{ required: true, message: "请输入物料/部件名称", trigger: "blur" }],
    quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
    unqualifiedQuantity: [{ required: true, message: "请输入不合格数", trigger: "blur" }],
    inspectorName: [{ required: true, message: "请选择检验员", trigger: "change" }],
    inspectDate: [{ required: true, message: "请选择检验日期", trigger: "change" }],
    problemDescription: [{ required: true, message: "请输入问题描述", trigger: "blur" }],
  },
});
const { form, rules } = toRefs(data);
const productOptions = ref([]);
const modelOptions = ref([]);
const userList = ref([]); // 检验员/处理人下拉列表
const userList = ref([]); // 检验员/责任人下拉列表
// 打开弹框
const openDialog = async (type, row) => {
@@ -279,95 +373,57 @@
  if (operationType.value === 'add') {
    defectivePhotoFileList.value = [];
    form.value = {
      checkName: userStore.nickName || '',
      dealName: '',
      dealTime: '',
      dealResult: '',
      defectivePhenomena: '',
      projectName: '',
      projectNo: '',
      equipmentName: '',
      equipmentDrawingNo: '',
      materialName: '',
      materialDrawingNo: '',
      specificationModel: '',
      materialQuality: '',
      quantity: 0,
      unqualifiedQuantity: 0,
      unqualifiedProcess: undefined,
      supplierName: '',
      inspectorName: userStore.nickName || '',
      inspectDate: '',
      responsiblePerson: '',
      responsibleDept: '',
      problemDescription: '',
      reasonAnalysis: '',
      correctionAction: '',
      disposalMethod: undefined,
      repairEvaluation: '',
      preventiveAction: '',
      status: 0,
      remark: '',
      defectivePhotos: '',
      tempFileIds: [],
      inspectType: '',
      checkTime: '',
      productId: '',
      model: '',
      unit: '',
      quantity: '',
      productName: '',
      reasonAnalysis: '',
      preventiveCorrective: '',
      lossWorking: 0,
      lossMaterial: 0,
    };
  } else {
    defectivePhotoFileList.value = [];
    form.value = {};
  }
  getProductOptions();
  if (operationType.value === 'edit') {
    getQualityUnqualifiedInfo(row.id).then(res => {
      const { inspectState, ...rest } = (res.data || {})
      form.value = {
        reasonAnalysis: '',
        preventiveCorrective: '',
        lossWorking: 0,
        lossMaterial: 0,
        ...rest
      }
      const data = res.data?.records?.[0] || res.data || {}
      form.value = { ...data }
    })
  }
}
const getProductOptions = () => {
  productTreeList().then((res) => {
    productOptions.value = convertIdToValue(res);
  });
};
const getModels = (value) => {
  form.value.productName = findNodeById(productOptions.value, value);
  modelList({ id: value }).then((res) => {
    modelOptions.value = res;
  })
};
const findNodeById = (nodes, productId) => {
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].value === productId) {
      return nodes[i].label; // 找到节点,返回该节点
    }
    if (nodes[i].children && nodes[i].children.length > 0) {
      const foundNode = findNodeById(nodes[i].children, productId);
      if (foundNode) {
        return foundNode; // 在子节点中找到,返回该节点
      }
    }
  }
  return null; // 没有找到节点,返回null
};
function convertIdToValue(data) {
  return data.map((item) => {
    const { id, children, ...rest } = item;
    const newItem = {
      ...rest,
      value: id, // 将 id 改为 value
    };
    if (children && children.length > 0) {
      newItem.children = convertIdToValue(children);
    }
    return newItem;
  });
}
// 提交产品表单
const submitForm = () => {
  proxy.$refs.formRef.validate(valid => {
    if (valid) {
      // 状态字段不在表单填写,也不传给后端
      const { inspectState, ...payload } = (form.value || {})
      if (operationType.value === "add") {
        qualityUnqualifiedAdd(payload).then(res => {
        qualityUnqualifiedAdd(form.value).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      } else {
        qualityUnqualifiedUpdate(payload).then(res => {
        qualityUnqualifiedUpdate(form.value).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
@@ -376,16 +432,18 @@
  })
}
// 上传前校检(参考协同审批附件上传)
// 上传前校检
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) {
@@ -396,76 +454,29 @@
    if (!form.value.tempFileIds) form.value.tempFileIds = [];
    if (tempId) form.value.tempFileIds.push(tempId);
    // el-upload 列表回显需要 url/name
    file.id = tempId || file.id;
    file.url = tempPath;
    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);
// 不良品照片移除
function handleDefectivePhotoRemove(file, fileList) {
  const tempId = file?.response?.data?.tempId;
  if (tempId && form.value.tempFileIds) {
    const idx = form.value.tempFileIds.indexOf(tempId);
    if (idx > -1) form.value.tempFileIds.splice(idx, 1);
  }
  syncDefectivePhotosFromFileList();
  defectivePhotoFileList.value = fileList;
}
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')
};
}
defineExpose({
  openDialog,
});
})
</script>
<style scoped>
</style>
src/views/qualityManagement/nonconformingManagement/index.vue
@@ -1,38 +1,40 @@
// 不合格管理
// 不合格品处理单
<template>
  <div class="app-container">
    <div class="search_form">
      <div style="display: flex;flex-direction: row;align-items: center;">
        <div>
          <span class="search_title">类型:</span>
          <el-select v-model="searchForm.inspectType" clearable style="width: 200px" @change="handleQuery">
            <el-option label="原材料检验" :value="0" />
            <el-option label="过程检验" :value="1" />
            <el-option label="出厂检验" :value="2" />
          </el-select>
        </div>
        <div style="margin-left: 10px">
          <span class="search_title">状态:</span>
          <el-select v-model="searchForm.inspectState" clearable style="width: 200px" @change="handleQuery">
            <el-option label="待处理" :value="0" />
            <el-option label="已处理" :value="1" />
          <el-select v-model="searchForm.status" clearable style="width: 200px" @change="handleQuery">
            <el-option label="草稿" :value="0" />
            <el-option label="待审核" :value="1" />
            <el-option label="审批中" :value="2" />
            <el-option label="已完成" :value="3" />
            <el-option label="已驳回" :value="4" />
          </el-select>
        </div>
        <div style="margin-left: 10px">
          <span class="search_title">产品名称:</span>
          <span class="search_title">项目名称:</span>
          <el-input
              v-model="searchForm.productName"
              v-model="searchForm.projectName"
              style="width: 200px"
              placeholder="请输入产品名称搜索"
              placeholder="请输入项目名称搜索"
              @change="handleQuery"
              clearable
              :prefix-icon="Search"
          />
        </div>
        <span  style="margin-left: 10px" class="search_title">检测日期:</span>
        <el-date-picker  v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                                                 style="width: 300px"
                         placeholder="请选择" clearable @change="changeDaterange" />
        <div style="margin-left: 10px">
          <span class="search_title">处理单号:</span>
          <el-input
              v-model="searchForm.orderNo"
              style="width: 200px"
              placeholder="请输入处理单号搜索"
              @change="handleQuery"
              clearable
              :prefix-icon="Search"
          />
        </div>
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button>
      </div>
      <div>
@@ -55,9 +57,7 @@
      >
      </PIMTable>
    </div>
    <DetailDia ref="detailDiaRef" />
    <FormDia ref="formDia" @close="handleQuery"></FormDia>
    <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia>
  </div>
</template>
@@ -67,136 +67,130 @@
import FormDia from "@/views/qualityManagement/nonconformingManagement/components/formDia.vue";
import {ElMessageBox} from "element-plus";
import {qualityUnqualifiedDel, qualityUnqualifiedListPage} from "@/api/qualityManagement/nonconformingManagement.js";
import InspectionFormDia from "@/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue";
import DetailDia from "@/views/qualityManagement/nonconformingManagement/components/detailDia.vue";
import dayjs from "dayjs";
const data = reactive({
  searchForm: {
    inspectType: "",
    inspectState: "",
    productName: "",
    entryDate: undefined, // 录入日期
    entryDateStart: undefined,
    entryDateEnd: undefined,
    status: "",
    projectName: "",
    orderNo: "",
  },
});
const { searchForm } = toRefs(data);
const tableColumn = ref([
  {
    label: "状态",
    prop: "inspectState",
    prop: "status",
    dataType: "tag",
    width: 100,
    formatData: (params) => {
      if (params == 0) {
        return "待处理";
      } else if (params == 1) {
        return "已处理";
      } else {
        return null;
      }
      const statusMap = {
        0: "草稿",
        1: "待审核",
        2: "审批中",
        3: "已完成",
        4: "已驳回"
      };
      return statusMap[params] || "-";
    },
    formatType: (params) => {
      if (params == '不合格') {
        return "danger";
      } else if (params == '合格') {
        return "success";
      } else {
        return null;
      }
      const typeMap = {
        0: "info",
        1: "warning",
        2: "primary",
        3: "success",
        4: "danger"
      };
      return typeMap[params] || "info";
    },
  },
  {
    label: "检测日期",
    prop: "checkTime",
    label: "处理单号",
    prop: "orderNo",
    width: 160
  },
  {
    label: "项目名称",
    prop: "projectName",
    width: 140
  },
  {
    label: "项目编号",
    prop: "projectNo",
    width: 140
  },
  {
    label: "设备名称",
    prop: "equipmentName",
    width: 140
  },
  {
    label: "物料/部件名称",
    prop: "materialName",
    width: 160
  },
  {
    label: "型号规格",
    prop: "specificationModel",
    width: 120
  },
  {
    label: "类别",
    prop: "inspectType",
    dataType: "tag",
    width: 120,
    formatData: (params) => {
      if (params == 0) {
        return "原材料检验";
      } else if (params == 1) {
        return "过程检验";
      } else {
        return '出厂检验';
      }
    },
    formatType: (params) => {
      if (params == '不合格') {
        return "info";
      } else if (params == '合格') {
        return "success";
      } else {
        return 'primary';
      }
    },
  },
  {
    label: "检验员",
    prop: "checkName",
  },
  {
    label: "产品名称",
    prop: "productName",
  },
  {
    label: "规格型号",
    prop: "model",
  },
  {
    label: "单位",
    prop: "unit",
  },
  {
    label: "数量",
    prop: "quantity",
    width: 80
  },
  {
    label: "不合格数",
    prop: "unqualifiedQuantity",
    width: 90
  },
  {
    label: "不合格工序",
    prop: "unqualifiedProcess",
    width: 100,
    formatData: (params) => {
      const processMap = {
        1: "来料",
        2: "制程",
        3: "成品"
      };
      return processMap[params] || "-";
    },
  },
  {
    label: "检验员",
    prop: "inspectorName",
    width: 100
  },
  {
    label: "不合格现象",
    prop: "defectivePhenomena",
    label: "检验日期",
    prop: "inspectDate",
    width: 120
  },
  {
    label: "处理结果",
    prop: "dealResult",
    label: "责任人",
    prop: "responsiblePerson",
    width: 100
  },
  {
    label: "责任部门",
    prop: "responsibleDept",
    width: 120
  },
  {
    label: "处理人",
    prop: "dealName",
    width: 120
  },
  {
    label: "处理日期",
    prop: "dealTime",
    width: 120
  },
  {
    label: "原因分析",
    prop: "reasonAnalysis",
    slot: "reasonAnalysis",
    width: 120
  },
  {
    label: "预防与纠正措施",
    prop: "preventiveCorrective",
    slot: "preventiveCorrective",
    width: 120
  },
  {
    label: "工时损失",
    prop: "lossWorking",
    width: 140
  },
  {
    label: "材料费损失",
    prop: "lossMaterial",
    width: 140
    label: "处置方式",
    prop: "disposalMethod",
    width: 100,
    formatData: (params) => {
      const disposalMap = {
        1: "让步接收",
        2: "厂内维修",
        3: "返厂维修",
        4: "换货",
        5: "退货",
        6: "报废"
      };
      return disposalMap[params] || "-";
    },
  },
  {
    dataType: "action",
@@ -206,19 +200,18 @@
    width: 140,
    operation: [
      {
        name: "详情",
        name: "编辑",
        type: "text",
        clickFun: (row) => {
          openDetailDialog(row);
          openForm("edit", row);
        },
      },
      {
        name: "处理",
        name: "删除",
        type: "text",
        clickFun: (row) => {
          openInspectionForm("edit", row);
          handleDeleteRow(row);
        },
        disabled: (row) => row.inspectState === 1,
      },
    ],
  },
@@ -232,19 +225,8 @@
  total: 0
});
const formDia = ref()
const inspectionFormDia = ref()
const detailDiaRef = ref()
const { proxy } = getCurrentInstance()
const changeDaterange = (value) => {
  searchForm.value.entryDateStart = undefined;
  searchForm.value.entryDateEnd = undefined;
  if (value) {
    searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
    searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
  }
  getList();
};
// 查询列表
/** 搜索按钮操作 */
const handleQuery = () => {
@@ -259,7 +241,6 @@
const getList = () => {
  tableLoading.value = true;
  const params = { ...searchForm.value, ...page };
  params.entryDate = undefined
  qualityUnqualifiedListPage(params).then(res => {
    tableLoading.value = false;
    tableData.value = res.data.records
@@ -275,27 +256,27 @@
// 打开弹框
const openForm = (type, row) => {
  if (type !== 'add' && row?.inspectState === 1) {
    proxy.$modal.msgWarning("已处理的数据不能再编辑");
    return;
  }
  nextTick(() => {
    formDia.value?.openDialog(type, row)
  })
};
// 打开处理弹框
const openInspectionForm = (type, row) => {
  if (row?.inspectState === 1) {
    proxy.$modal.msgWarning("已处理的数据不能再处理");
    return;
  }
  nextTick(() => {
    inspectionFormDia.value?.openDialog(type, row)
// 删除单行
const handleDeleteRow = (row) => {
  ElMessageBox.confirm("确认删除该不合格品处理单?", "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
};
// 打开详情弹框
const openDetailDialog = (row) => {
  detailDiaRef.value?.openDialog(row);
      .then(() => {
        qualityUnqualifiedDel([row.id]).then((res) => {
          proxy.$modal.msgSuccess("删除成功");
          getList();
        });
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
// 删除
@@ -307,7 +288,7 @@
    proxy.$modal.msgWarning("请选择数据");
    return;
  }
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
@@ -330,7 +311,7 @@
    type: "warning",
  })
      .then(() => {
        proxy.download("/quality/qualityUnqualified/export", {}, "不合格管理.xlsx");
        proxy.download("/qualityUnqualifiedOrder/export", {}, "不合格品处理单.xlsx");
      })
      .catch(() => {
        proxy.$modal.msg("已取消");