Explorar o código

IQC表单更新

liuwb hai 2 meses
pai
achega
9487d7822e
Modificáronse 19 ficheiros con 1170 adicións e 185 borrados
  1. 79 0
      docs/qms/IQC来料质量检验.md
  2. 71 8
      yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcInspectBillDetailItemRespVO.java
  3. 39 11
      yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcInspectBillMainRespVO.java
  4. 111 16
      yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcInspectBillSaveReqVO.java
  5. 10 4
      yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcTaskDetailRespVO.java
  6. 2 2
      yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcTaskProcessInfoVO.java
  7. 4 4
      yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcTaskRespVO.java
  8. 2 0
      yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/dal/mysql/iqc/IqcApplyMapper.java
  9. 28 2
      yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/dal/mysql/iqc/IqcTaskMapper.java
  10. 5 2
      yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/service/iqc/IqcApplyServiceImpl.java
  11. 13 29
      yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/service/iqc/IqcTaskServiceImpl.java
  12. 10 7
      yudao-module-qms/src/main/resources/mapper/iqc/IqcApplyMapper.xml
  13. 95 16
      yudao-module-qms/src/main/resources/mapper/iqc/IqcTaskMapper.xml
  14. 85 20
      yudao-ui/yudao-ui-admin-vue3/src/api/qms/iqc/task/index.ts
  15. 5 5
      yudao-ui/yudao-ui-admin-vue3/src/config/qmsModules.ts
  16. 146 25
      yudao-ui/yudao-ui-admin-vue3/src/store/modules/qms/inspectBill.ts
  17. 12 3
      yudao-ui/yudao-ui-admin-vue3/src/views/qms/ApplicationForm.vue
  18. 426 27
      yudao-ui/yudao-ui-admin-vue3/src/views/qms/iqc/task/InspectBillEdit.vue
  19. 27 4
      yudao-ui/yudao-ui-admin-vue3/src/views/qms/iqc/task/ProcessDetailForm.vue

+ 79 - 0
docs/qms/IQC来料质量检验.md

@@ -1,5 +1,43 @@
 IQC来料品质检验
 
+## 昨日修改要点(2026-01-29)
+
+### 审批详情/任务详情(流程详情页)
+- **申请信息展示**:任务编号、单据编号、申请人、申请时间、批次、数量、单位、供应商编码、任务状态等信息统一从**任务详情接口**返回并中文展示。
+- **字段命名规范化**:流程/任务详情展示字段统一规范为**物料编码/物料名称**(由后端映射返回),不再使用“来源单号/来源类型”的含义混用。
+- **任务状态中文**:待检验/检验中/检验完成直接中文展示。
+
+### 来料检验单编辑页(流程中的编辑页面)
+- **右上角只读三行**:表单编号/表单版本/表单生效日期默认值固定显示(灰色三行),不再用输入框:
+  - 表单编号:`RS/IV-7.4-32`
+  - 表单版本:`1.2`
+  - 表单生效日期:`2022.04.01`
+- **主表字段默认&只读**:
+  - 检规编号默认:`QC-H644-1-05`(只读)
+  - 检规版本默认:`A.8`(只读)
+  - 检验员:取当前账号昵称(只读)
+  - 检验数量:来自任务列表数量(只读)
+- **数量字段逻辑**:
+  - 合格数量/不合格数量:互相自动计算(留样/破坏不参与)
+  - 处理方式:下拉(退货/挑选/让步接收)
+  - 留样数量、破坏数量:普通输入框
+  - 所有数量类输入框改为**普通输入框 + 整数校验**
+- **附件**:由输入框改为**上传控件**(不限格式),存储为链接到 `fj`
+- **主表判断**:增加“判断(合格/不合格)”
+
+### 检验明细(子表)
+- **只读字段**:检验项目、检验标准只读
+- **判断列**:下拉(合格/不合格)
+- **样本量列**:手填整数;**列数只增不减**(若变更更小不收缩,变大则新增样本列)
+- **样本列**:扩展到样本1~样本20
+- **操作列**:移到最左侧
+- **整数校验**:上限/下限/样本量/样本1~20均为整数校验
+
+### 申请信息字段规则
+- 申请人:前端显示用户名/昵称;数据库存用户 ID
+- 组织/部门:前端显示“部门名称”;数据库存部门 ID;与申请人一致设为只读
+
+
 - 来料检验申请
 
 业务流程
@@ -345,3 +383,44 @@ selectc.idassqid,a.*,f.scph,cd.sh_purchase_namefromqms_qcp_inspbilla/*检验单*
 | qms_qcp_inspbilllist | j149 | 样本149 |
 | qms_qcp_inspbilllist | j150 | 样本150 |
 | qms_qcp_inspbilllist | bzz | 备注 |
+
+数据表及字段补充1
+
+| qms_qcp_inspbill| bdbh | 表单编号 |
+| qms_qcp_inspbill | bb | 表单版本 |
+| qms_qcp_inspbill | sxrq | 生效日期 |
+| qms_qcp_inspbill | jgbh| 检规编号 |
+|qms_qcp_inspbill | jgbb | 检规版本 |
+| qms_qcp_inspbill | jyr | 检验员 |
+| qms_qcp_inspbill | jysl| 检验数量 |
+| qms_qcp_inspbill | bhgsl | 不合格数量 |
+|qms_qcp_inspbill| fj | 附件 |
+主表没有 bz 字段(备注),子表使用 bz 作为检验标准
+| qms_qcp_inspbilllist | jyxm | 检验项目 |
+| qms_qcp_inspbilllist | bz | 检验标准 |
+| qms_qcp_inspbilllist | sx | 上限 |
+| qms_qcp_inspbilllist | xx | 下限 |
+| qms_qcp_inspbilllist | pd | 判断 |
+| qms_qcp_inspbilllist | j1 | 样本1 |
+| qms_qcp_inspbilllist | j2 | 样本2 |
+| qms_qcp_inspbilllist | j3 | 样本3 |
+数据表及字段补充1
+
+| qms_qcp_inspbill| bdbh | 表单编号 |
+| qms_qcp_inspbill | bb | 表单版本 |
+| qms_qcp_inspbill | sxrq | 生效日期 |
+| qms_qcp_inspbill | jgbh| 检规编号 |
+|qms_qcp_inspbill | jgbb | 检规版本 |
+| qms_qcp_inspbill | jyr | 检验员 |
+| qms_qcp_inspbill | jysl| 检验数量 |
+| qms_qcp_inspbill | bhgsl | 不合格数量 |
+|qms_qcp_inspbill| fj | 附件 |
+主表没有 bz 字段(备注),子表使用 bz 作为检验标准
+| qms_qcp_inspbilllist | jyxm | 检验项目 |
+| qms_qcp_inspbilllist | bz | 检验标准 |
+| qms_qcp_inspbilllist | sx | 上限 |
+| qms_qcp_inspbilllist | xx | 下限 |
+| qms_qcp_inspbilllist | pd | 判断 |
+| qms_qcp_inspbilllist | j1 | 样本1 |
+| qms_qcp_inspbilllist | j2 | 样本2 |
+| qms_qcp_inspbilllist | j3 | 样本3 |

+ 71 - 8
yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcInspectBillDetailItemRespVO.java

@@ -13,15 +13,78 @@ public class IqcInspectBillDetailItemRespVO {
     @Schema(description = "检验单编号", example = "1001")
     private Long billId;
 
-    @Schema(description = "字段A")
-    private String a;
+    @Schema(description = "检验项目")
+    private String jyxm;
 
-    @Schema(description = "字段B")
-    private String b;
+    @Schema(description = "检验标准")
+    private String bz;
 
-    @Schema(description = "字段C")
-    private String c;
+    @Schema(description = "上限")
+    private String sx;
 
-    @Schema(description = "字段D")
-    private String d;
+    @Schema(description = "下限")
+    private String xx;
+
+    @Schema(description = "判断")
+    private Long pd;
+
+    @Schema(description = "样本1")
+    private String j1;
+
+    @Schema(description = "样本2")
+    private String j2;
+
+    @Schema(description = "样本3")
+    private String j3;
+
+    @Schema(description = "样本4")
+    private String j4;
+
+    @Schema(description = "样本5")
+    private String j5;
+
+    @Schema(description = "样本6")
+    private String j6;
+
+    @Schema(description = "样本7")
+    private String j7;
+
+    @Schema(description = "样本8")
+    private String j8;
+
+    @Schema(description = "样本9")
+    private String j9;
+
+    @Schema(description = "样本10")
+    private String j10;
+
+    @Schema(description = "样本11")
+    private String j11;
+
+    @Schema(description = "样本12")
+    private String j12;
+
+    @Schema(description = "样本13")
+    private String j13;
+
+    @Schema(description = "样本14")
+    private String j14;
+
+    @Schema(description = "样本15")
+    private String j15;
+
+    @Schema(description = "样本16")
+    private String j16;
+
+    @Schema(description = "样本17")
+    private String j17;
+
+    @Schema(description = "样本18")
+    private String j18;
+
+    @Schema(description = "样本19")
+    private String j19;
+
+    @Schema(description = "样本20")
+    private String j20;
 }

+ 39 - 11
yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcInspectBillMainRespVO.java

@@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.qms.controller.admin.iqc.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import java.math.BigDecimal;
 
 @Schema(description = "管理后台 - IQC 检验单主表信息 Response VO")
 @Data
@@ -11,18 +12,45 @@ public class IqcInspectBillMainRespVO {
     @Schema(description = "检验单编号", example = "1001")
     private Long billId;
 
-    @Schema(description = "字段A")
-    private String mainA;
+    @Schema(description = "表单编号")
+    private String bdbh;
+
+    @Schema(description = "表单版本")
+    private String bb;
+
+    @Schema(description = "生效日期")
+    private String sxrq;
+
+    @Schema(description = "检规编号")
+    private String jgbh;
+
+    @Schema(description = "检规版本")
+    private String jgbb;
+
+    @Schema(description = "检验员")
+    private String jyr;
+
+    @Schema(description = "检验数量")
+    private BigDecimal jysl;
+
+    @Schema(description = "不合格数量")
+    private BigDecimal bhgsl;
+
+    @Schema(description = "合格数量")
+    private BigDecimal jyhgsl;
+
+    @Schema(description = "处理方式")
+    private String clfs;
 
-    @Schema(description = "字段B")
-    private String mainB;
+    @Schema(description = "留样数量")
+    private BigDecimal lysl;
 
-    @Schema(description = "字段C")
-    private String mainC;
+    @Schema(description = "破坏数量")
+    private BigDecimal phsl;
 
-    @Schema(description = "字段D")
-    private String mainD;
+    @Schema(description = "主表判断")
+    private String jgpd;
 
-    @JsonIgnore
-    private String comment;
+    @Schema(description = "附件")
+    private String fj;
 }

+ 111 - 16
yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcInspectBillSaveReqVO.java

@@ -4,6 +4,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import jakarta.validation.constraints.NotNull;
+
+import java.math.BigDecimal;
 import java.util.List;
 
 @Schema(description = "管理后台 - IQC 检验单保存 Request VO")
@@ -14,17 +16,47 @@ public class IqcInspectBillSaveReqVO {
     @NotNull(message = "任务编号不能为空")
     private Long taskId;
 
-    @Schema(description = "主表字段A")
-    private String mainA;
+    @Schema(description = "表单编号")
+    private String bdbh;
+
+    @Schema(description = "表单版本")
+    private String bb;
+
+    @Schema(description = "生效日期")
+    private String sxrq;
+
+    @Schema(description = "检规编号")
+    private String jgbh;
+
+    @Schema(description = "检规版本")
+    private String jgbb;
+
+    @Schema(description = "检验员")
+    private String jyr;
+
+    @Schema(description = "检验数量")
+    private BigDecimal jysl;
+
+    @Schema(description = "不合格数量")
+    private BigDecimal bhgsl;
 
-    @Schema(description = "主表字段B")
-    private String mainB;
+    @Schema(description = "合格数量")
+    private BigDecimal jyhgsl;
 
-    @Schema(description = "主表字段C")
-    private String mainC;
+    @Schema(description = "处理方式")
+    private String clfs;
 
-    @Schema(description = "主表字段D")
-    private String mainD;
+    @Schema(description = "留样数量")
+    private BigDecimal lysl;
+
+    @Schema(description = "破坏数量")
+    private BigDecimal phsl;
+
+    @Schema(description = "主表判断")
+    private String jgpd;
+
+    @Schema(description = "附件")
+    private String fj;
 
     @Schema(description = "明细列表")
     private List<IqcInspectBillDetailSaveReqVO> details;
@@ -36,16 +68,79 @@ public class IqcInspectBillSaveReqVO {
         @Schema(description = "明细编号")
         private Long id;
 
-        @Schema(description = "字段A")
-        private String a;
+        @Schema(description = "检验项目")
+        private String jyxm;
+
+        @Schema(description = "检验标准")
+        private String bz;
+
+        @Schema(description = "上限")
+        private String sx;
+
+        @Schema(description = "下限")
+        private String xx;
+
+        @Schema(description = "判断")
+        private Long pd;
+
+        @Schema(description = "样本1")
+        private String j1;
+
+        @Schema(description = "样本2")
+        private String j2;
+
+        @Schema(description = "样本3")
+        private String j3;
+
+        @Schema(description = "样本4")
+        private String j4;
+
+        @Schema(description = "样本5")
+        private String j5;
+
+        @Schema(description = "样本6")
+        private String j6;
+
+        @Schema(description = "样本7")
+        private String j7;
+
+        @Schema(description = "样本8")
+        private String j8;
+
+        @Schema(description = "样本9")
+        private String j9;
+
+        @Schema(description = "样本10")
+        private String j10;
+
+        @Schema(description = "样本11")
+        private String j11;
+
+        @Schema(description = "样本12")
+        private String j12;
+
+        @Schema(description = "样本13")
+        private String j13;
+
+        @Schema(description = "样本14")
+        private String j14;
+
+        @Schema(description = "样本15")
+        private String j15;
+
+        @Schema(description = "样本16")
+        private String j16;
+
+        @Schema(description = "样本17")
+        private String j17;
 
-        @Schema(description = "字段B")
-        private String b;
+        @Schema(description = "样本18")
+        private String j18;
 
-        @Schema(description = "字段C")
-        private String c;
+        @Schema(description = "样本19")
+        private String j19;
 
-        @Schema(description = "字段D")
-        private String d;
+        @Schema(description = "样本20")
+        private String j20;
     }
 }

+ 10 - 4
yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcTaskDetailRespVO.java

@@ -34,11 +34,14 @@ public class IqcTaskDetailRespVO {
     @Schema(description = "检验状态")
     private String inspectStatus;
 
-    @Schema(description = "来源单号")
-    private String sourceOrderNum;
+    @Schema(description = "任务状态(pending/processing/completed)")
+    private String status;
 
-    @Schema(description = "来源单类型")
-    private String sourceOrderType;
+    @Schema(description = "物料编码")
+    private String materialCode;
+
+    @Schema(description = "物料名称")
+    private String materialName;
 
     @Schema(description = "批次")
     private String batch;
@@ -49,6 +52,9 @@ public class IqcTaskDetailRespVO {
     @Schema(description = "单位")
     private String unit;
 
+    @Schema(description = "供应商编码")
+    private String supplierCode;
+
     @Schema(description = "备注")
     private String remark;
 }

+ 2 - 2
yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcTaskProcessInfoVO.java

@@ -16,8 +16,8 @@ public class IqcTaskProcessInfoVO {
     @Schema(description = "申请人编号")
     private Long applicantId;
 
-    @Schema(description = "来源单号")
-    private String sourceOrderNum;
+    @Schema(description = "物料编码")
+    private String materialCode;
 
     @Schema(description = "批次")
     private String batch;

+ 4 - 4
yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/controller/admin/iqc/vo/IqcTaskRespVO.java

@@ -19,11 +19,11 @@ public class IqcTaskRespVO {
     @Schema(description = "任务状态", example = "pending")
     private String status;
 
-    @Schema(description = "来源单号")
-    private String sourceOrderNum;
+    @Schema(description = "物料编码")
+    private String materialCode;
 
-    @Schema(description = "来源单类型")
-    private String sourceOrderType;
+    @Schema(description = "物料名称")
+    private String materialName;
 
     @Schema(description = "批次")
     private String batch;

+ 2 - 0
yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/dal/mysql/iqc/IqcApplyMapper.java

@@ -47,6 +47,7 @@ public interface IqcApplyMapper {
                      @Param("billNo") String billNo,
                      @Param("status") String status,
                      @Param("applyUserId") Long applyUserId,
+                     @Param("deptId") Long deptId,
                      @Param("applyTime") LocalDateTime applyTime,
                      @Param("billType") String billType,
                      @Param("remark") String remark,
@@ -55,6 +56,7 @@ public interface IqcApplyMapper {
 
     @TenantIgnore
     int updateApplyByBillNo(@Param("billNo") String billNo,
+                            @Param("deptId") Long deptId,
                             @Param("applyTime") LocalDateTime applyTime,
                             @Param("billType") String billType,
                             @Param("remark") String remark,

+ 28 - 2
yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/dal/mysql/iqc/IqcTaskMapper.java

@@ -57,7 +57,20 @@ public interface IqcTaskMapper {
     @TenantIgnore
     void insertInspectBillMain(@Param("id") Long id,
                                @Param("taskId") Long taskId,
-                               @Param("comment") String comment,
+                               @Param("bdbh") String bdbh,
+                               @Param("bb") String bb,
+                               @Param("sxrq") String sxrq,
+                               @Param("jgbh") String jgbh,
+                               @Param("jgbb") String jgbb,
+                               @Param("jyr") String jyr,
+                               @Param("jysl") java.math.BigDecimal jysl,
+                               @Param("bhgsl") java.math.BigDecimal bhgsl,
+                               @Param("jyhgsl") java.math.BigDecimal jyhgsl,
+                               @Param("clfs") String clfs,
+                               @Param("lysl") java.math.BigDecimal lysl,
+                               @Param("phsl") java.math.BigDecimal phsl,
+                               @Param("jgpd") String jgpd,
+                               @Param("fj") String fj,
                                @Param("creatorId") Long creatorId);
 
     /**
@@ -65,7 +78,20 @@ public interface IqcTaskMapper {
      */
     @TenantIgnore
     void updateInspectBillMain(@Param("id") Long id,
-                               @Param("comment") String comment,
+                               @Param("bdbh") String bdbh,
+                               @Param("bb") String bb,
+                               @Param("sxrq") String sxrq,
+                               @Param("jgbh") String jgbh,
+                               @Param("jgbb") String jgbb,
+                               @Param("jyr") String jyr,
+                               @Param("jysl") java.math.BigDecimal jysl,
+                               @Param("bhgsl") java.math.BigDecimal bhgsl,
+                               @Param("jyhgsl") java.math.BigDecimal jyhgsl,
+                               @Param("clfs") String clfs,
+                               @Param("lysl") java.math.BigDecimal lysl,
+                               @Param("phsl") java.math.BigDecimal phsl,
+                               @Param("jgpd") String jgpd,
+                               @Param("fj") String fj,
                                @Param("modifierId") Long modifierId);
 
     /**

+ 5 - 2
yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/service/iqc/IqcApplyServiceImpl.java

@@ -19,6 +19,7 @@ import java.time.format.DateTimeFormatter;
 import java.util.Collections;
 import java.util.List;
 
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserDeptId;
 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 /**
@@ -44,8 +45,9 @@ public class IqcApplyServiceImpl implements IqcApplyService {
         Long applyId = IdUtil.getSnowflakeNextId();
         String billNo = generateBillNo();
         Long userId = getLoginUserId();
+        Long deptId = getLoginUserDeptId();
         LocalDateTime now = LocalDateTime.now();
-        iqcApplyMapper.insertApply(applyId, billNo, DEFAULT_STATUS, userId,
+        iqcApplyMapper.insertApply(applyId, billNo, DEFAULT_STATUS, userId, deptId,
                 createReqVO.getApplyTime(), createReqVO.getBusinessType(), createReqVO.getRemark(), userId, now);
         List<IqcApplyDetailSaveReqVO> details = normalizeDetails(createReqVO.getDetails());
         if (!details.isEmpty()) {
@@ -65,8 +67,9 @@ public class IqcApplyServiceImpl implements IqcApplyService {
             return;
         }
         Long userId = getLoginUserId();
+        Long deptId = getLoginUserDeptId();
         LocalDateTime now = LocalDateTime.now();
-        iqcApplyMapper.updateApplyByBillNo(updateReqVO.getId(), updateReqVO.getApplyTime(),
+        iqcApplyMapper.updateApplyByBillNo(updateReqVO.getId(), deptId, updateReqVO.getApplyTime(),
                 updateReqVO.getBusinessType(), updateReqVO.getRemark(), userId, now);
         iqcApplyMapper.deleteApplyDetailsByApplyId(applyId);
         List<IqcApplyDetailSaveReqVO> details = normalizeDetails(updateReqVO.getDetails());

+ 13 - 29
yudao-module-qms/src/main/java/cn/iocoder/yudao/module/qms/service/iqc/IqcTaskServiceImpl.java

@@ -1,13 +1,11 @@
 package cn.iocoder.yudao.module.qms.service.iqc;
 
-import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.module.qms.controller.admin.iqc.vo.IqcInspectBillDetailItemRespVO;
 import cn.iocoder.yudao.module.qms.controller.admin.iqc.vo.IqcInspectBillMainRespVO;
 import cn.iocoder.yudao.module.qms.controller.admin.iqc.vo.IqcInspectBillSaveReqVO;
@@ -74,23 +72,7 @@ public class IqcTaskServiceImpl implements IqcTaskService {
         if (taskId == null) {
             return null;
         }
-        IqcInspectBillMainRespVO main = iqcTaskMapper.selectInspectBillMain(taskId);
-        if (main == null || StrUtil.isBlank(main.getComment())) {
-            return main;
-        }
-        try {
-            java.util.Map<String, Object> data = JsonUtils.parseObject(main.getComment(), java.util.Map.class);
-            if (data != null) {
-                main.setMainA(data.get("A") == null ? null : String.valueOf(data.get("A")));
-                main.setMainB(data.get("B") == null ? null : String.valueOf(data.get("B")));
-                main.setMainC(data.get("C") == null ? null : String.valueOf(data.get("C")));
-                main.setMainD(data.get("D") == null ? null : String.valueOf(data.get("D")));
-            }
-        } catch (Exception ignore) {
-            // 不是 JSON 时,兼容把 comment 当作 A
-            main.setMainA(main.getComment());
-        }
-        return main;
+        return iqcTaskMapper.selectInspectBillMain(taskId);
     }
 
     @Override
@@ -100,19 +82,20 @@ public class IqcTaskServiceImpl implements IqcTaskService {
         Long userId = getLoginUserId();
         Long billId;
 
-        java.util.Map<String, Object> commentPayload = new java.util.HashMap<>();
-        commentPayload.put("A", reqVO.getMainA());
-        commentPayload.put("B", reqVO.getMainB());
-        commentPayload.put("C", reqVO.getMainC());
-        commentPayload.put("D", reqVO.getMainD());
-        String comment = JsonUtils.toJsonString(commentPayload);
-
         if (main == null || main.getBillId() == null) {
             billId = IdUtil.getSnowflakeNextId();
-            iqcTaskMapper.insertInspectBillMain(billId, reqVO.getTaskId(), comment, userId);
+            iqcTaskMapper.insertInspectBillMain(billId, reqVO.getTaskId(),
+                    reqVO.getBdbh(), reqVO.getBb(), reqVO.getSxrq(), reqVO.getJgbh(), reqVO.getJgbb(),
+                    reqVO.getJyr(), reqVO.getJysl(), reqVO.getBhgsl(), reqVO.getJyhgsl(),
+                    reqVO.getClfs(), reqVO.getLysl(), reqVO.getPhsl(), reqVO.getJgpd(),
+                    reqVO.getFj(), userId);
         } else {
             billId = main.getBillId();
-            iqcTaskMapper.updateInspectBillMain(billId, comment, userId);
+            iqcTaskMapper.updateInspectBillMain(billId,
+                    reqVO.getBdbh(), reqVO.getBb(), reqVO.getSxrq(), reqVO.getJgbh(), reqVO.getJgbb(),
+                    reqVO.getJyr(), reqVO.getJysl(), reqVO.getBhgsl(), reqVO.getJyhgsl(),
+                    reqVO.getClfs(), reqVO.getLysl(), reqVO.getPhsl(), reqVO.getJgpd(),
+                    reqVO.getFj(), userId);
         }
 
         // 先清空再插入,简化批量编辑
@@ -145,7 +128,8 @@ public class IqcTaskServiceImpl implements IqcTaskService {
         variables.put("taskId", taskInfo.getId());
         variables.put("applicationId", taskInfo.getApplicationId());
         variables.put("applicantId", taskInfo.getApplicantId());
-        variables.put("sourceOrderNum", taskInfo.getSourceOrderNum());
+        variables.put("materialCode", taskInfo.getMaterialCode());
+        variables.put("sourceOrderNum", taskInfo.getMaterialCode());
         variables.put("batch", taskInfo.getBatch());
 
         Long userId = getLoginUserId();

+ 10 - 7
yudao-module-qms/src/main/resources/mapper/iqc/IqcApplyMapper.xml

@@ -12,6 +12,7 @@
                 u.username AS applicantName,
                 a.FAPPLYTIME AS applyTime,
                 a.FBILLTYPE AS businessType,
+                a.FORGID AS department,
                 a.FCOMMENT AS remark,
                 COUNT(b.id) AS materialCount,
                 CASE
@@ -38,7 +39,7 @@
                     AND a.FAPPLYTIME BETWEEN #{req.applyTime[0]} AND #{req.applyTime[1]}
                 </if>
             </where>
-            GROUP BY a.id, a.FBILLNO, a.FAPPLYUSER, u.username, a.FAPPLYTIME, a.FBILLTYPE, a.FCOMMENT
+            GROUP BY a.id, a.FBILLNO, a.FAPPLYUSER, u.username, a.FAPPLYTIME, a.FBILLTYPE, a.FORGID, a.FCOMMENT
         ) t
         <where>
             <if test="req.statusList != null and req.statusList.size > 0">
@@ -59,6 +60,7 @@
             u.username AS applicantName,
             a.FAPPLYTIME AS applyTime,
             a.FBILLTYPE AS businessType,
+            a.FORGID AS department,
             a.FCOMMENT AS remark,
             COUNT(b.id) AS materialCount,
             CASE
@@ -71,7 +73,7 @@
         LEFT JOIN system_users u ON u.id = a.FAPPLYUSER
         LEFT JOIN qms_qcp_insappnentry b ON b.glid = a.id
         WHERE a.FBILLNO = #{billNo}
-        GROUP BY a.id, a.FBILLNO, a.FAPPLYUSER, u.username, a.FAPPLYTIME, a.FBILLTYPE, a.FCOMMENT
+        GROUP BY a.id, a.FBILLNO, a.FAPPLYUSER, u.username, a.FAPPLYTIME, a.FBILLTYPE, a.FORGID, a.FCOMMENT
     </select>
 
     <select id="selectApplyIdByBillNo" resultType="long">
@@ -84,7 +86,7 @@
         SELECT
             FSRCORDERNUM AS materialCode,
             FSRCORDERTYPE AS materialName,
-            NULL AS specification,
+            ggxh AS specification,
             FLOTNUMBER AS batch,
             COALESCE(FINSPECTSTATUS, '待检验') AS inspectStatus,
             FAPPLYQTY AS quantity,
@@ -98,16 +100,17 @@
     <insert id="insertApply">
         INSERT INTO qms_qcp_inspecapplyn
             (id, FBILLNO, FBILLSTATUS, FCREATORID, FCREATETIME, FMODIFIERID, FMODIFYTIME,
-             FAPPLYUSER, FAPPLYTIME, FBILLTYPE, FCOMMENT)
+             FAPPLYUSER, FORGID, FAPPLYTIME, FBILLTYPE, FCOMMENT)
         VALUES
             (#{id}, #{billNo}, #{status}, #{creatorId}, #{createTime}, #{creatorId}, #{createTime},
-             #{applyUserId}, #{applyTime}, #{billType}, #{remark})
+             #{applyUserId}, #{deptId}, #{applyTime}, #{billType}, #{remark})
     </insert>
 
     <update id="updateApplyByBillNo">
         UPDATE qms_qcp_inspecapplyn
         SET FAPPLYTIME = #{applyTime},
             FBILLTYPE = #{billType},
+            FORGID = #{deptId},
             FCOMMENT = #{remark},
             FMODIFIERID = #{modifierId},
             FMODIFYTIME = #{modifyTime}
@@ -126,11 +129,11 @@
 
     <insert id="insertApplyDetails">
         INSERT INTO qms_qcp_insappnentry
-            (id, glid, FSEQ, FMATERIELID, FSRCORDERNUM, FSRCORDERTYPE, FLOTNUMBER, FUNIT, FAPPLYQTY, FINSPECTSTATUS, FSUPPLIER)
+            (id, glid, FSEQ, FMATERIELID, FSRCORDERNUM, FSRCORDERTYPE, ggxh, FLOTNUMBER, FUNIT, FAPPLYQTY, FINSPECTSTATUS, FSUPPLIER)
         VALUES
         <foreach collection="details" item="detail" separator=",">
             (#{detail.id}, #{applyId}, #{detail.seq}, #{detail.materialId},
-             #{detail.materialCode}, #{detail.materialName}, #{detail.batch},
+             #{detail.materialCode}, #{detail.materialName}, #{detail.specification}, #{detail.batch},
              #{detail.unit}, #{detail.quantity}, #{detail.inspectStatus}, #{detail.supplierCode})
         </foreach>
     </insert>

+ 95 - 16
yudao-module-qms/src/main/resources/mapper/iqc/IqcTaskMapper.xml

@@ -11,8 +11,8 @@
             u.username AS applicantName,
             b.FSUPPLIER AS supplierCode,
             b.process_instance_id AS processInstanceId,
-            b.FSRCORDERNUM AS sourceOrderNum,
-            b.FSRCORDERTYPE AS sourceOrderType,
+            b.FSRCORDERNUM AS materialCode,
+            b.FSRCORDERTYPE AS materialName,
             b.FLOTNUMBER AS batch,
             b.FAPPLYQTY AS quantity,
             b.FUNIT AS unit,
@@ -42,7 +42,7 @@
             b.id AS id,
             a.FBILLNO AS applicationId,
             a.FAPPLYUSER AS applicantId,
-            b.FSRCORDERNUM AS sourceOrderNum,
+            b.FSRCORDERNUM AS materialCode,
             b.FLOTNUMBER AS batch,
             b.process_instance_id AS processInstanceId,
             b.flowstate AS flowState,
@@ -63,11 +63,17 @@
             b.process_instance_id AS processInstanceId,
             b.flowstate AS flowState,
             b.FINSPECTSTATUS AS inspectStatus,
-            b.FSRCORDERNUM AS sourceOrderNum,
-            b.FSRCORDERTYPE AS sourceOrderType,
+            b.FSUPPLIER AS supplierCode,
+            b.FSRCORDERNUM AS materialCode,
+            b.FSRCORDERTYPE AS materialName,
             b.FLOTNUMBER AS batch,
             b.FAPPLYQTY AS quantity,
-            b.FUNIT AS unit
+            b.FUNIT AS unit,
+            CASE
+                WHEN COALESCE(b.FINSPECTSTATUS, a.FBILLSTATUS) IN ('processing', '检验中') THEN 'processing'
+                WHEN COALESCE(b.FINSPECTSTATUS, a.FBILLSTATUS) IN ('completed', '检验完成') THEN 'completed'
+                ELSE 'pending'
+            END AS status
         FROM qms_qcp_insappnentry b
         LEFT JOIN qms_qcp_inspecapplyn a ON a.id = b.glid
         LEFT JOIN system_users u ON u.id = a.FAPPLYUSER
@@ -78,10 +84,31 @@
         SELECT
             l.id AS id,
             l.billid AS billId,
-            l.jyxm AS a,
-            l.bz AS b,
-            l.sx AS c,
-            l.xx AS d
+            l.jyxm AS jyxm,
+            l.bz AS bz,
+            l.sx AS sx,
+            l.xx AS xx,
+            l.pd AS pd,
+            l.j1 AS j1,
+            l.j2 AS j2,
+            l.j3 AS j3,
+            l.j4 AS j4,
+            l.j5 AS j5,
+            l.j6 AS j6,
+            l.j7 AS j7,
+            l.j8 AS j8,
+            l.j9 AS j9,
+            l.j10 AS j10,
+            l.j11 AS j11,
+            l.j12 AS j12,
+            l.j13 AS j13,
+            l.j14 AS j14,
+            l.j15 AS j15,
+            l.j16 AS j16,
+            l.j17 AS j17,
+            l.j18 AS j18,
+            l.j19 AS j19,
+            l.j20 AS j20
         FROM qms_qcp_inspbill b
         LEFT JOIN qms_qcp_inspbilllist l ON l.billid = b.id
         WHERE b.hid = #{taskId}
@@ -91,7 +118,20 @@
     <select id="selectInspectBillMain" resultType="cn.iocoder.yudao.module.qms.controller.admin.iqc.vo.IqcInspectBillMainRespVO">
         SELECT
             b.id AS billId,
-            b.FCOMMENT AS comment
+            b.bdbh AS bdbh,
+            b.bb AS bb,
+            b.sxrq AS sxrq,
+            b.jgbh AS jgbh,
+            b.jgbb AS jgbb,
+            b.jyr AS jyr,
+            b.jysl AS jysl,
+            b.bhgsl AS bhgsl,
+            b.jyhgsl AS jyhgsl,
+            b.clfs AS clfs,
+            b.lysl AS lysl,
+            b.phsl AS phsl,
+            b.jgpd AS jgpd,
+            b.fj AS fj
         FROM qms_qcp_inspbill b
         WHERE b.hid = #{taskId}
         ORDER BY b.id DESC
@@ -102,13 +142,39 @@
         INSERT INTO qms_qcp_inspbill (
             id,
             hid,
-            FCOMMENT,
+            bdbh,
+            bb,
+            sxrq,
+            jgbh,
+            jgbb,
+            jyr,
+            jysl,
+            bhgsl,
+            jyhgsl,
+            clfs,
+            lysl,
+            phsl,
+            jgpd,
+            fj,
             FCREATORID,
             FCREATETIME
         ) VALUES (
             #{id},
             #{taskId},
-            #{comment},
+            #{bdbh},
+            #{bb},
+            #{sxrq},
+            #{jgbh},
+            #{jgbb},
+            #{jyr},
+            #{jysl},
+            #{bhgsl},
+            #{jyhgsl},
+            #{clfs},
+            #{lysl},
+            #{phsl},
+            #{jgpd},
+            #{fj},
             #{creatorId},
             NOW()
         )
@@ -117,7 +183,20 @@
     <update id="updateInspectBillMain">
         UPDATE qms_qcp_inspbill
         SET
-            FCOMMENT = #{comment},
+            bdbh = #{bdbh},
+            bb = #{bb},
+            sxrq = #{sxrq},
+            jgbh = #{jgbh},
+            jgbb = #{jgbb},
+            jyr = #{jyr},
+            jysl = #{jysl},
+            bhgsl = #{bhgsl},
+            jyhgsl = #{jyhgsl},
+            clfs = #{clfs},
+            lysl = #{lysl},
+            phsl = #{phsl},
+            jgpd = #{jgpd},
+            fj = #{fj},
             FMODIFIERID = #{modifierId},
             FMODIFYTIME = NOW()
         WHERE id = #{id}
@@ -128,10 +207,10 @@
     </delete>
 
     <insert id="insertInspectBillDetailBatch">
-        INSERT INTO qms_qcp_inspbilllist (id, billid, jyxm, bz, sx, xx)
+        INSERT INTO qms_qcp_inspbilllist (id, billid, jyxm, bz, sx, xx, pd, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15, j16, j17, j18, j19, j20)
         VALUES
         <foreach collection="list" item="item" separator=",">
-            (#{item.id}, #{billId}, #{item.a}, #{item.b}, #{item.c}, #{item.d})
+            (#{item.id}, #{billId}, #{item.jyxm}, #{item.bz}, #{item.sx}, #{item.xx}, #{item.pd}, #{item.j1}, #{item.j2}, #{item.j3}, #{item.j4}, #{item.j5}, #{item.j6}, #{item.j7}, #{item.j8}, #{item.j9}, #{item.j10}, #{item.j11}, #{item.j12}, #{item.j13}, #{item.j14}, #{item.j15}, #{item.j16}, #{item.j17}, #{item.j18}, #{item.j19}, #{item.j20})
         </foreach>
     </insert>
 

+ 85 - 20
yudao-ui/yudao-ui-admin-vue3/src/api/qms/iqc/task/index.ts

@@ -8,8 +8,8 @@ export interface IqcTaskRespVO {
   id: number
   applicationId: string
   status: string
-  sourceOrderNum?: string
-  sourceOrderType?: string
+  materialCode?: string
+  materialName?: string
   batch?: string
   quantity?: number
   unit?: string
@@ -29,43 +29,108 @@ export interface IqcTaskDetailRespVO {
   processInstanceId?: string
   flowState?: string
   inspectStatus?: string
-  sourceOrderNum?: string
-  sourceOrderType?: string
+  status?: string
+  materialCode?: string
+  materialName?: string
   batch?: string
   quantity?: number
   unit?: string
+  supplierCode?: string
   remark?: string
 }
 
 export interface IqcInspectBillDetailItemRespVO {
   id?: number | string
   billId?: number | string
-  a?: string
-  b?: string
-  c?: string
-  d?: string
+  sampleCount?: number | string
+  jyxm?: string
+  bz?: string
+  sx?: string
+  xx?: string
+  pd?: number | string
+  j1?: string
+  j2?: string
+  j3?: string
+  j4?: string
+  j5?: string
+  j6?: string
+  j7?: string
+  j8?: string
+  j9?: string
+  j10?: string
+  j11?: string
+  j12?: string
+  j13?: string
+  j14?: string
+  j15?: string
+  j16?: string
+  j17?: string
+  j18?: string
+  j19?: string
+  j20?: string
 }
 
 export interface IqcInspectBillMainRespVO {
   billId?: number | string
-  mainA?: string
-  mainB?: string
-  mainC?: string
-  mainD?: string
+  bdbh?: string
+  bb?: string
+  sxrq?: string
+  jgbh?: string
+  jgbb?: string
+  jyr?: string
+  jysl?: number | string
+  bhgsl?: number | string
+  jyhgsl?: number | string
+  clfs?: string
+  lysl?: number | string
+  phsl?: number | string
+  jgpd?: string
+  fj?: string
 }
 
 export interface IqcInspectBillSaveReqVO {
   taskId: number | string
-  mainA?: string
-  mainB?: string
-  mainC?: string
-  mainD?: string
+  bdbh?: string
+  bb?: string
+  sxrq?: string
+  jgbh?: string
+  jgbb?: string
+  jyr?: string
+  jysl?: number | string
+  bhgsl?: number | string
+  jyhgsl?: number | string
+  clfs?: string
+  lysl?: number | string
+  phsl?: number | string
+  jgpd?: string
+  fj?: string
   details?: Array<{
     id?: number | string
-    a?: string
-    b?: string
-    c?: string
-    d?: string
+    jyxm?: string
+    bz?: string
+    sx?: string
+    xx?: string
+    pd?: number | string
+    j1?: string
+    j2?: string
+    j3?: string
+    j4?: string
+    j5?: string
+    j6?: string
+    j7?: string
+    j8?: string
+    j9?: string
+    j10?: string
+    j11?: string
+    j12?: string
+    j13?: string
+    j14?: string
+    j15?: string
+    j16?: string
+    j17?: string
+    j18?: string
+    j19?: string
+    j20?: string
   }>
 }
 

+ 5 - 5
yudao-ui/yudao-ui-admin-vue3/src/config/qmsModules.ts

@@ -29,7 +29,7 @@ export const QMS_MODULES: Record<string, any> = {
         { key: 'id', label: '单据编号', width: 200, type: 'applicationLink' },
         { key: 'applicantName', label: '申请人', width: 100 },
         { key: 'applyTime', label: '申请时间', width: 160, type: 'datetime' },
-        { key: 'materialCount', label: '物料', width: 100, type: 'number' },
+        { key: 'materialCount', label: '物料种类', width: 100, type: 'number' },
         { key: 'remark', label: '备注', minWidth: 200, type: 'tooltip' }
       ],
       advancedFilters: [
@@ -39,10 +39,10 @@ export const QMS_MODULES: Record<string, any> = {
     applicationForm: {
       title: '来料检验申请单',
       baseFields: [
-        { key: 'applicantName', label: '申请人', type: 'input', required: true, span: 8 },
+        { key: 'applicantName', label: '申请人', type: 'input', required: true, span: 8, readonly: true },
         { key: 'applyTime', label: '申请时间', type: 'datetime', required: true, span: 8 },
         { key: 'businessType', label: '业务类型', type: 'select', span: 8, options: ['常规', '精密', '特殊'] },
-        { key: 'department', label: '组织/部门', type: 'input', span: 8 }
+        { key: 'department', label: '组织/部门', type: 'input', span: 8, readonly: true }
       ],
       detail: {
         title: '物料明细',
@@ -78,13 +78,13 @@ export const QMS_MODULES: Record<string, any> = {
         { key: 'processing', label: '检验中' },
         { key: 'completed', label: '已完成' }
       ],
-      keywordFields: ['applicationId', 'sourceOrderNum', 'batch'],
+      keywordFields: ['applicationId', 'materialCode', 'batch'],
       columns: [
         { type: 'selection', width: 55 },
         { key: 'status', label: '状态', width: 90, type: 'status' },
         { key: 'id', label: '任务编号', width: 140 },
         { key: 'applicationId', label: '单据编号', width: 160, type: 'taskLink' },
-        { key: 'sourceOrderNum', label: '来源单号', width: 160 },
+        { key: 'materialCode', label: '物料编码', width: 160 },
         { key: 'batch', label: '批次', width: 130, type: 'batch' },
         { key: 'quantity', label: '数量', width: 100 },
         { key: 'unit', label: '单位', width: 80 },

+ 146 - 25
yudao-ui/yudao-ui-admin-vue3/src/store/modules/qms/inspectBill.ts

@@ -8,25 +8,75 @@ import {
 } from '@/api/qms/iqc/task'
 
 type InspectBillMain = {
-  mainA: string
-  mainB: string
-  mainC: string
-  mainD: string
+  bdbh: string
+  bb: string
+  sxrq: string
+  jgbh: string
+  jgbb: string
+  jyr: string
+  jysl: number | string
+  bhgsl: number | string
+  jyhgsl: number | string
+  clfs: string
+  lysl: number | string
+  phsl: number | string
+  jgpd: string
+  fj: string
   billId?: number | string
 }
 
+const DEFAULT_FORM_INFO = {
+  bdbh: 'RS/IV-7.4-32',
+  bb: '1.2',
+  sxrq: '2022-04-01',
+  jgbh: 'QC-H644-1-05',
+  jgbb: 'A.8'
+}
+
 const createEmptyMain = (): InspectBillMain => ({
-  mainA: '',
-  mainB: '',
-  mainC: '',
-  mainD: ''
+  bdbh: DEFAULT_FORM_INFO.bdbh,
+  bb: DEFAULT_FORM_INFO.bb,
+  sxrq: DEFAULT_FORM_INFO.sxrq,
+  jgbh: DEFAULT_FORM_INFO.jgbh,
+  jgbb: DEFAULT_FORM_INFO.jgbb,
+  jyr: '',
+  jysl: 0,
+  bhgsl: 0,
+  jyhgsl: '',
+  clfs: '',
+  lysl: '',
+  phsl: '',
+  jgpd: '',
+  fj: ''
 })
 
 const createEmptyRow = (): IqcInspectBillDetailItemRespVO => ({
-  a: '',
-  b: '',
-  c: '',
-  d: ''
+  sampleCount: '',
+  jyxm: '',
+  bz: '',
+  sx: '',
+  xx: '',
+  pd: undefined,
+  j1: '',
+  j2: '',
+  j3: '',
+  j4: '',
+  j5: '',
+  j6: '',
+  j7: '',
+  j8: '',
+  j9: '',
+  j10: '',
+  j11: '',
+  j12: '',
+  j13: '',
+  j14: '',
+  j15: '',
+  j16: '',
+  j17: '',
+  j18: '',
+  j19: '',
+  j20: ''
 })
 
 export const useIqcInspectBillStore = defineStore('iqcInspectBill', {
@@ -71,29 +121,100 @@ export const useIqcInspectBillStore = defineStore('iqcInspectBill', {
       const main = (mainResult as any)?.data ?? mainResult
       const details = (detailResult as any)?.data ?? detailResult
       draft.main = {
-        mainA: main?.mainA || '',
-        mainB: main?.mainB || '',
-        mainC: main?.mainC || '',
-        mainD: main?.mainD || '',
+        bdbh: main?.bdbh || DEFAULT_FORM_INFO.bdbh,
+        bb: main?.bb || DEFAULT_FORM_INFO.bb,
+        sxrq: main?.sxrq || DEFAULT_FORM_INFO.sxrq,
+        jgbh: main?.jgbh || DEFAULT_FORM_INFO.jgbh,
+        jgbb: main?.jgbb || DEFAULT_FORM_INFO.jgbb,
+        jyr: main?.jyr || '',
+        jysl: main?.jysl ?? 0,
+        bhgsl: main?.bhgsl ?? 0,
+        jyhgsl: main?.jyhgsl ?? '',
+        clfs: main?.clfs || '',
+        lysl: main?.lysl ?? '',
+        phsl: main?.phsl ?? '',
+        jgpd: main?.jgpd || '',
+        fj: main?.fj || '',
         billId: main?.billId
       }
-      draft.details = Array.isArray(details) && details.length ? details : [createEmptyRow()]
+      draft.details = Array.isArray(details) && details.length
+        ? details.map((item: any) => ({
+          id: item.id,
+          billId: item.billId,
+          jyxm: item.jyxm || '',
+          bz: item.bz || '',
+          sx: item.sx || '',
+          xx: item.xx || '',
+          pd: item.pd ?? undefined,
+          j1: item.j1 || '',
+          j2: item.j2 || '',
+          j3: item.j3 || '',
+          j4: item.j4 || '',
+          j5: item.j5 || '',
+          j6: item.j6 || '',
+          j7: item.j7 || '',
+          j8: item.j8 || '',
+          j9: item.j9 || '',
+          j10: item.j10 || '',
+          j11: item.j11 || '',
+          j12: item.j12 || '',
+          j13: item.j13 || '',
+          j14: item.j14 || '',
+          j15: item.j15 || '',
+          j16: item.j16 || '',
+          j17: item.j17 || '',
+          j18: item.j18 || '',
+          j19: item.j19 || '',
+          j20: item.j20 || ''
+        }))
+        : [createEmptyRow()]
       return draft
     },
     async save(taskId: string) {
       const draft = this.ensureDraft(taskId)
       const payload: IqcInspectBillSaveReqVO = {
         taskId,
-        mainA: draft.main.mainA,
-        mainB: draft.main.mainB,
-        mainC: draft.main.mainC,
-        mainD: draft.main.mainD,
+        bdbh: draft.main.bdbh,
+        bb: draft.main.bb,
+        sxrq: draft.main.sxrq,
+        jgbh: draft.main.jgbh,
+        jgbb: draft.main.jgbb,
+        jyr: draft.main.jyr,
+        jysl: draft.main.jysl,
+        bhgsl: draft.main.bhgsl,
+        jyhgsl: draft.main.jyhgsl,
+        clfs: draft.main.clfs,
+        lysl: draft.main.lysl,
+        phsl: draft.main.phsl,
+        jgpd: draft.main.jgpd,
+        fj: draft.main.fj,
         details: draft.details.map((item) => ({
           id: item.id,
-          a: item.a,
-          b: item.b,
-          c: item.c,
-          d: item.d
+          jyxm: item.jyxm,
+          bz: item.bz,
+          sx: item.sx,
+          xx: item.xx,
+          pd: item.pd,
+          j1: item.j1,
+          j2: item.j2,
+          j3: item.j3,
+          j4: item.j4,
+          j5: item.j5,
+          j6: item.j6,
+          j7: item.j7,
+          j8: item.j8,
+          j9: item.j9,
+          j10: item.j10,
+          j11: item.j11,
+          j12: item.j12,
+          j13: item.j13,
+          j14: item.j14,
+          j15: item.j15,
+          j16: item.j16,
+          j17: item.j17,
+          j18: item.j18,
+          j19: item.j19,
+          j20: item.j20
         }))
       }
       const result = await saveIqcInspectBill(payload)

+ 12 - 3
yudao-ui/yudao-ui-admin-vue3/src/views/qms/ApplicationForm.vue

@@ -70,9 +70,11 @@ import { reactive, ref, computed, onMounted } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
 import { getQmsModuleConfig, DEFAULT_QMS_MODULE } from '@/config/qmsModules'
 import { createIqcApply, getIqcApply, updateIqcApply } from '@/api/qms/iqc/apply'
+import { useUserStore } from '@/store/modules/user'
 
 const route = useRoute()
 const router = useRouter()
+const userStore = useUserStore()
 const moduleCode = computed(() => (route.meta.module as string) || DEFAULT_QMS_MODULE)
 const moduleConfig = computed(() => getQmsModuleConfig(moduleCode.value))
 const isIqcModule = computed(() => moduleCode.value === 'iqc')
@@ -120,9 +122,14 @@ const getFieldComponent = (field: any) => {
 }
 
 const getFieldProps = (field: any) => {
-  if (field.type === 'datetime') return { type: 'datetime', placeholder: '请选择时间', format: 'YYYY-MM-DD HH:mm:ss', 'value-format': 'x', style: 'width: 100%' }
-  if (field.type === 'textarea') return { type: 'textarea', rows: field.rows || 3, placeholder: `请输入${field.label}` }
-  return { placeholder: `请输入${field.label}`, style: 'width: 100%' }
+  const readonly = !!field.readonly
+  if (field.type === 'datetime') {
+    return { type: 'datetime', placeholder: '请选择时间', format: 'YYYY-MM-DD HH:mm:ss', 'value-format': 'x', style: 'width: 100%', readonly }
+  }
+  if (field.type === 'textarea') {
+    return { type: 'textarea', rows: field.rows || 3, placeholder: `请输入${field.label}`, readonly }
+  }
+  return { placeholder: `请输入${field.label}`, style: 'width: 100%', readonly }
 }
 
 const getDetailComponent = (column: any) => {
@@ -215,6 +222,8 @@ const applyResponseToForm = (data: any) => {
 const fetchApplication = async () => {
   if (isCreate.value) {
     initFormData()
+    formData.applicantName = userStore.getUser.nickname || ''
+    formData.department = userStore.getUser.deptId ? String(userStore.getUser.deptId) : ''
     formData.details = [createDetailRow()]
     return
   }

+ 426 - 27
yudao-ui/yudao-ui-admin-vue3/src/views/qms/iqc/task/InspectBillEdit.vue

@@ -13,28 +13,93 @@
 
     <el-card class="section-card" shadow="never">
       <template #header>
-        <div class="section-title">主表信息(A/B/C/D 占位)</div>
+        <div class="section-header">
+          <div class="section-title">主表信息</div>
+          <div class="default-form-info header-default-info">
+            <div>表单编号:{{ mainForm.bdbh || '-' }}</div>
+            <div>表单版本:{{ mainForm.bb || '-' }}</div>
+            <div>表单生效日期:{{ formatFormDate(mainForm.sxrq) }}</div>
+          </div>
+        </div>
       </template>
       <el-form label-width="100px">
         <el-row :gutter="16">
-          <el-col :span="6">
-            <el-form-item label="A">
-              <el-input v-model="mainForm.mainA" placeholder="请输入 A" />
+          <el-col :span="8">
+            <el-form-item label="检规编号">
+              <el-input v-model="mainForm.jgbh" placeholder="请输入检规编号" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="检规版本">
+              <el-input v-model="mainForm.jgbb" placeholder="请输入检规版本" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="检验员">
+              <el-input v-model="mainForm.jyr" placeholder="请输入检验员" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="检验数量">
+              <el-input v-model="mainForm.jysl" placeholder="请输入检验数量" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="合格数量">
+              <el-input
+                :model-value="mainForm.jyhgsl"
+                placeholder="请输入合格数量"
+                @update:model-value="(val) => (mainForm.jyhgsl = sanitizeInt(val))"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="不合格数量">
+              <el-input
+                :model-value="mainForm.bhgsl"
+                placeholder="请输入不合格数量"
+                @update:model-value="(val) => (mainForm.bhgsl = sanitizeInt(val))"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="处理方式">
+              <el-select v-model="mainForm.clfs" placeholder="请选择处理方式" style="width: 100%">
+                <el-option label="退货" value="退货" />
+                <el-option label="挑选" value="挑选" />
+                <el-option label="让步接收" value="让步接收" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="留样数量">
+              <el-input
+                :model-value="mainForm.lysl"
+                placeholder="请输入留样数量"
+                @update:model-value="(val) => (mainForm.lysl = sanitizeInt(val))"
+              />
             </el-form-item>
           </el-col>
-          <el-col :span="6">
-            <el-form-item label="B">
-              <el-input v-model="mainForm.mainB" placeholder="请输入 B" />
+          <el-col :span="8">
+            <el-form-item label="破坏数量">
+              <el-input
+                :model-value="mainForm.phsl"
+                placeholder="请输入破坏数量"
+                @update:model-value="(val) => (mainForm.phsl = sanitizeInt(val))"
+              />
             </el-form-item>
           </el-col>
-          <el-col :span="6">
-            <el-form-item label="C">
-              <el-input v-model="mainForm.mainC" placeholder="请输入 C" />
+          <el-col :span="8">
+            <el-form-item label="附件">
+              <UploadFile v-model="mainForm.fj" :limit="1" :file-type="[]" :is-show-tip="false" />
             </el-form-item>
           </el-col>
-          <el-col :span="6">
-            <el-form-item label="D">
-              <el-input v-model="mainForm.mainD" placeholder="请输入 D" />
+          <el-col :span="8">
+            <el-form-item label="判断">
+              <el-select v-model="mainForm.jgpd" placeholder="请选择判断" style="width: 100%">
+                <el-option label="合格" value="合格" />
+                <el-option label="不合格" value="不合格" />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -44,36 +109,241 @@
     <el-card class="section-card" shadow="never">
       <template #header>
         <div class="section-title">
-          检验明细(A/B/C/D 占位)
+          检验明细
           <div class="section-actions">
             <el-button type="primary" size="small" @click="handleAddRow">新增行</el-button>
           </div>
         </div>
       </template>
       <el-table :data="detailRows" border>
-        <el-table-column label="A" width="220">
+        <el-table-column label="操作" width="100">
+          <template #default="{ $index }">
+            <el-button link type="danger" size="small" @click="handleDeleteRow($index)">删除</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column label="检验项目" min-width="200">
           <template #default="{ row }">
-            <el-input v-model="row.a" placeholder="请输入 A" />
+            <el-input v-model="row.jyxm" placeholder="请输入检验项目" disabled />
           </template>
         </el-table-column>
-        <el-table-column label="B" width="220">
+        <el-table-column label="检验标准" min-width="200">
           <template #default="{ row }">
-            <el-input v-model="row.b" placeholder="请输入 B" />
+            <el-input v-model="row.bz" placeholder="请输入检验标准" disabled />
           </template>
         </el-table-column>
-        <el-table-column label="C" width="180">
+        <el-table-column label="上限" width="140">
           <template #default="{ row }">
-            <el-input v-model="row.c" placeholder="请输入 C" />
+            <el-input
+              :model-value="row.sx"
+              placeholder="请输入上限"
+              @update:model-value="(val) => updateRowInt(row, 'sx', val)"
+            />
           </template>
         </el-table-column>
-        <el-table-column label="D" width="180">
+        <el-table-column label="下限" width="140">
           <template #default="{ row }">
-            <el-input v-model="row.d" placeholder="请输入 D" />
+            <el-input
+              :model-value="row.xx"
+              placeholder="请输入下限"
+              @update:model-value="(val) => updateRowInt(row, 'xx', val)"
+            />
           </template>
         </el-table-column>
-        <el-table-column label="操作" width="100">
-          <template #default="{ $index }">
-            <el-button link type="danger" size="small" @click="handleDeleteRow($index)">删除</el-button>
+        <el-table-column label="判断" width="140">
+          <template #default="{ row }">
+            <el-select v-model="row.pd" placeholder="请选择判断" style="width: 100%">
+              <el-option label="合格" :value="1" />
+              <el-option label="不合格" :value="0" />
+            </el-select>
+          </template>
+        </el-table-column>
+        <el-table-column label="样本量" width="100">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.sampleCount"
+              placeholder="数量"
+              @update:model-value="(val) => updateRowInt(row, 'sampleCount', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 1" label="样本1" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j1"
+              placeholder="请输入样本1"
+              @update:model-value="(val) => updateRowInt(row, 'j1', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 2" label="样本2" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j2"
+              placeholder="请输入样本2"
+              @update:model-value="(val) => updateRowInt(row, 'j2', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 3" label="样本3" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j3"
+              placeholder="请输入样本3"
+              @update:model-value="(val) => updateRowInt(row, 'j3', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 4" label="样本4" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j4"
+              placeholder="请输入样本4"
+              @update:model-value="(val) => updateRowInt(row, 'j4', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 5" label="样本5" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j5"
+              placeholder="请输入样本5"
+              @update:model-value="(val) => updateRowInt(row, 'j5', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 6" label="样本6" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j6"
+              placeholder="请输入样本6"
+              @update:model-value="(val) => updateRowInt(row, 'j6', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 7" label="样本7" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j7"
+              placeholder="请输入样本7"
+              @update:model-value="(val) => updateRowInt(row, 'j7', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 8" label="样本8" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j8"
+              placeholder="请输入样本8"
+              @update:model-value="(val) => updateRowInt(row, 'j8', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 9" label="样本9" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j9"
+              placeholder="请输入样本9"
+              @update:model-value="(val) => updateRowInt(row, 'j9', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 10" label="样本10" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j10"
+              placeholder="请输入样本10"
+              @update:model-value="(val) => updateRowInt(row, 'j10', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 11" label="样本11" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j11"
+              placeholder="请输入样本11"
+              @update:model-value="(val) => updateRowInt(row, 'j11', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 12" label="样本12" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j12"
+              placeholder="请输入样本12"
+              @update:model-value="(val) => updateRowInt(row, 'j12', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 13" label="样本13" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j13"
+              placeholder="请输入样本13"
+              @update:model-value="(val) => updateRowInt(row, 'j13', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 14" label="样本14" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j14"
+              placeholder="请输入样本14"
+              @update:model-value="(val) => updateRowInt(row, 'j14', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 15" label="样本15" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j15"
+              placeholder="请输入样本15"
+              @update:model-value="(val) => updateRowInt(row, 'j15', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 16" label="样本16" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j16"
+              placeholder="请输入样本16"
+              @update:model-value="(val) => updateRowInt(row, 'j16', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 17" label="样本17" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j17"
+              placeholder="请输入样本17"
+              @update:model-value="(val) => updateRowInt(row, 'j17', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 18" label="样本18" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j18"
+              placeholder="请输入样本18"
+              @update:model-value="(val) => updateRowInt(row, 'j18', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 19" label="样本19" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j19"
+              placeholder="请输入样本19"
+              @update:model-value="(val) => updateRowInt(row, 'j19', val)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column v-if="maxSampleCount >= 20" label="样本20" width="120">
+          <template #default="{ row }">
+            <el-input
+              :model-value="row.j20"
+              placeholder="请输入样本20"
+              @update:model-value="(val) => updateRowInt(row, 'j20', val)"
+            />
           </template>
         </el-table-column>
       </el-table>
@@ -87,13 +357,18 @@ defineOptions({ name: 'IqcInspectBillEdit' })
 import { computed, ref, watch } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
 import { useIqcInspectBillStore } from '@/store/modules/qms/inspectBill'
+import { getIqcTaskDetail } from '@/api/qms/iqc/task'
+import { useUserStore } from '@/store/modules/user'
+import { UploadFile } from '@/components/UploadFile'
 
 const route = useRoute()
 const router = useRouter()
 const inspectBillStore = useIqcInspectBillStore()
+const userStore = useUserStore()
 
 const loading = ref(false)
 const saving = ref(false)
+const isSyncing = ref(false)
 
 const taskId = computed(() => String(route.params.taskId || ''))
 
@@ -107,16 +382,105 @@ const detailRows = computed(() => {
   return inspectBillStore.ensureDraft(taskId.value).details
 })
 
+const maxSampleCount = ref(0)
+
+const toSampleCount = (value: any) => {
+  if (value === null || value === undefined || value === '') return 0
+  const num = Number(value)
+  if (Number.isNaN(num)) return 0
+  return Math.max(0, Math.min(20, Math.floor(num)))
+}
+
+const sanitizeInt = (value: any) => {
+  if (value === null || value === undefined) return ''
+  const text = String(value).replace(/[^\d]/g, '')
+  if (text === '') return ''
+  return String(parseInt(text, 10))
+}
+
+const updateRowInt = (row: any, key: string, value: any) => {
+  row[key] = sanitizeInt(value)
+}
+
+const refreshMaxSampleCount = () => {
+  const currentMax = detailRows.value.reduce((max: number, row: any) => {
+    const count = toSampleCount(row?.sampleCount)
+    return count > max ? count : max
+  }, 0)
+  if (currentMax > maxSampleCount.value) {
+    maxSampleCount.value = currentMax
+  }
+}
+
+const toNumber = (value: any) => {
+  if (value === null || value === undefined || value === '') return undefined
+  const num = Number(value)
+  return Number.isNaN(num) ? undefined : num
+}
+
+const syncComplement = (changedKey: 'jyhgsl' | 'bhgsl') => {
+  if (isSyncing.value) return
+  const total = toNumber(mainForm.value.jysl)
+  if (total === undefined) return
+  const current = toNumber(mainForm.value[changedKey])
+  if (current === undefined) return
+  const otherKey = changedKey === 'jyhgsl' ? 'bhgsl' : 'jyhgsl'
+  const next = Math.max(0, total - current)
+  isSyncing.value = true
+  mainForm.value[otherKey] = Number.isNaN(next) ? '' : String(next)
+  isSyncing.value = false
+}
+
 const fetchData = async () => {
   if (!taskId.value) return
   loading.value = true
   try {
     await inspectBillStore.load(taskId.value)
+    if (!mainForm.value.jyr) {
+      mainForm.value.jyr = userStore.getUser.nickname || ''
+    }
+    const result = await getIqcTaskDetail(taskId.value)
+    const detail = (result as any)?.data ?? result
+    if ((mainForm.value.jysl === 0 || mainForm.value.jysl === '' || mainForm.value.jysl === null || mainForm.value.jysl === undefined)
+      && detail?.quantity !== undefined && detail?.quantity !== null) {
+      mainForm.value.jysl = detail.quantity
+    }
+    if (mainForm.value.jyhgsl) {
+      syncComplement('jyhgsl')
+    } else if (mainForm.value.bhgsl) {
+      syncComplement('bhgsl')
+    }
+    refreshMaxSampleCount()
   } finally {
     loading.value = false
   }
 }
 
+const resolveProcessInstanceId = async () => {
+  const fromQuery = String(route.query.processInstanceId || '')
+  if (fromQuery) return fromQuery
+  if (!taskId.value) return ''
+  try {
+    const result = await getIqcTaskDetail(taskId.value)
+    const detail = (result as any)?.data ?? result
+    return String(detail?.processInstanceId || '')
+  } catch {
+    return ''
+  }
+}
+
+const goToProcessDetail = async () => {
+  const processInstanceId = await resolveProcessInstanceId()
+  if (processInstanceId) {
+    await router.replace({
+      path: '/bpm/process-instance/detail',
+      query: { id: processInstanceId }
+    })
+    return
+  }
+  router.back()
+}
+
 const handleAddRow = () => {
   if (!taskId.value) return
   inspectBillStore.addDetailRow(taskId.value)
@@ -127,12 +491,28 @@ const handleDeleteRow = (index: number) => {
   inspectBillStore.deleteDetailRow(taskId.value, index)
 }
 
+const formatFormDate = (value: any) => {
+  if (!value) return '-'
+  const text = String(value)
+  if (/^\d{4}-\d{2}-\d{2}$/.test(text)) return text.replaceAll('-', '.')
+  return text
+}
+
+const getSampleCount = (row: any) => {
+  const keys = ['j1','j2','j3','j4','j5','j6','j7','j8','j9','j10','j11','j12','j13','j14','j15','j16','j17','j18','j19','j20']
+  return keys.reduce((count, key) => {
+    const val = row?.[key]
+    return val !== null && val !== undefined && String(val).trim() !== '' ? count + 1 : count
+  }, 0)
+}
+
 const handleSave = async () => {
   if (!taskId.value) return
   saving.value = true
   try {
     await inspectBillStore.save(taskId.value)
     ElMessage.success('保存成功')
+    await goToProcessDetail()
   } catch {
     ElMessage.error('保存失败')
   } finally {
@@ -140,11 +520,15 @@ const handleSave = async () => {
   }
 }
 
-const handleBack = () => {
-  router.back()
+const handleBack = async () => {
+  await goToProcessDetail()
 }
 
 watch(taskId, () => { fetchData() }, { immediate: true })
+
+watch(() => mainForm.value.jyhgsl, () => { syncComplement('jyhgsl') })
+watch(() => mainForm.value.bhgsl, () => { syncComplement('bhgsl') })
+watch(detailRows, () => { refreshMaxSampleCount() }, { deep: true })
 </script>
 
 <style scoped lang="scss">
@@ -178,4 +562,19 @@ watch(taskId, () => { fetchData() }, { immediate: true })
     margin-left: auto;
   }
 }
+.section-header {
+  display: flex;
+  align-items: flex-start;
+  justify-content: space-between;
+  gap: 12px;
+}
+.default-form-info {
+  color: var(--el-text-color-secondary);
+  font-size: 13px;
+  line-height: 20px;
+}
+.header-default-info {
+  text-align: right;
+  min-width: 220px;
+}
 </style>

+ 27 - 4
yudao-ui/yudao-ui-admin-vue3/src/views/qms/iqc/task/ProcessDetailForm.vue

@@ -33,11 +33,26 @@
           <el-descriptions-item label="申请人">
             {{ detail.applicantName || '-' }}
           </el-descriptions-item>
-          <el-descriptions-item label="来源单号">
-            {{ detail.sourceOrderNum || '-' }}
+          <el-descriptions-item label="物料编码">
+            {{ detail.materialCode || '-' }}
           </el-descriptions-item>
-          <el-descriptions-item label="来源类型">
-            {{ detail.sourceOrderType || '-' }}
+          <el-descriptions-item label="物料名称">
+            {{ detail.materialName || '-' }}
+          </el-descriptions-item>
+          <el-descriptions-item label="批次">
+            {{ detail.batch || '-' }}
+          </el-descriptions-item>
+          <el-descriptions-item label="数量">
+            {{ detail.quantity ?? '-' }}
+          </el-descriptions-item>
+          <el-descriptions-item label="单位">
+            {{ detail.unit || '-' }}
+          </el-descriptions-item>
+          <el-descriptions-item label="供应商编码">
+            {{ detail.supplierCode || '-' }}
+          </el-descriptions-item>
+          <el-descriptions-item label="任务状态">
+            {{ formatTaskStatus(detail.status) }}
           </el-descriptions-item>
         </el-descriptions>
         <div class="section-actions-inline">
@@ -77,6 +92,14 @@ const detail = ref<IqcTaskDetailRespVO | null>(null)
 
 const remarkValue = computed(() => detail.value?.remark || '')
 
+const formatTaskStatus = (value?: string) => {
+  if (!value) return '-'
+  if (value === 'pending') return '待检验'
+  if (value === 'processing') return '检验中'
+  if (value === 'completed') return '检验完成'
+  return value
+}
+
 const handleOpenEditor = () => {
   if (!props.id) return
   const currentPath = router.currentRoute.value.path || ''