From d1791f762791428af91467b8855de83d54f015f9 Mon Sep 17 00:00:00 2001
From: zhuguifei <312353457@qq.com>
Date: 星期五, 17 四月 2026 15:23:21 +0800
Subject: [PATCH] feat: 1.新增物料、物料类型、材料检验统计等表维护功能  2.完善判定依据-判断依据明细  3.新增判断依据、物料管理等字典翻译类  4.成品物料批次-原始数据维护页面

---
 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/QmJudgeDetails.java                                                         |    8 
 ruoyi-plus-soybean/src/router/elegant/routes.ts                                                                                                          |   27 +
 ruoyi-plus-soybean/src/typings/api/qm.judge-details.api.d.ts                                                                                             |   40 +
 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/bo/QmJudgeDetailsBo.java                                                    |    8 
 ruoyi-plus-soybean/src/views/qm/batch/modules/batch-operate-drawer.vue                                                                                   |  280 +++--------
 ruoyi-plus-soybean/src/service/api/qm/judge-details.ts                                                                                                   |   10 
 ruoyi-plus-soybean/src/views/qm/judge/index.vue                                                                                                          |  103 ++-
 ruoyi-plus-soybean/src/typings/api/qm.batch.api.d.ts                                                                                                     |    4 
 RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java                            |   11 
 RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports |    2 
 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeServiceImpl.java                                               |   61 ++
 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmBatchVo.java                                                           |   15 
 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeVo.java                                                           |    1 
 ruoyi-plus-soybean/src/views/qm/batch/index.vue                                                                                                          |  231 +++++++--
 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/controller/QmJudgeDetailsController.java                                           |   10 
 ruoyi-plus-soybean/src/views/qm/judge/modules/judge-operate-drawer.vue                                                                                   |   59 ++
 ruoyi-plus-soybean/src/views/qm/judge-details/modules/judge-details-operate-drawer.vue                                                                   |   70 +--
 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeDetailsVo.java                                                    |   54 ++
 RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/MatService.java                                              |   13 
 ruoyi-plus-soybean/src/views/qm/judge/modules/judge-search.vue                                                                                           |   54 ++
 RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/JudgeNameTranslationImpl.java                |   26 +
 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/IQmJudgeDetailsService.java                                                |    8 
 RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/JudgeService.java                                            |   13 
 ruoyi-plus-soybean/src/router/elegant/imports.ts                                                                                                         |    3 
 ruoyi-plus-soybean/src/typings/elegant-router.d.ts                                                                                                       |    6 
 ruoyi-plus-soybean/src/views/qm/batch/modules/batch-search.vue                                                                                           |  166 +++---
 RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeDetailsServiceImpl.java                                        |   45 +
 ruoyi-plus-soybean/src/router/elegant/transform.ts                                                                                                       |    3 
 28 files changed, 868 insertions(+), 463 deletions(-)

diff --git a/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/JudgeService.java b/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/JudgeService.java
new file mode 100644
index 0000000..36c1903
--- /dev/null
+++ b/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/JudgeService.java
@@ -0,0 +1,13 @@
+package org.dromara.common.core.service;
+
+/**
+ * 鍒ゅ畾渚濇嵁
+ */
+public interface JudgeService {
+    /**
+     * 鍒ゅ畾渚濇嵁code杞琻ame
+     * @param judgeCode
+     * @return
+     */
+    String selectJudgeNameByCode(String judgeCode);
+}
diff --git a/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/MatService.java b/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/MatService.java
new file mode 100644
index 0000000..283acda
--- /dev/null
+++ b/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/MatService.java
@@ -0,0 +1,13 @@
+package org.dromara.common.core.service;
+
+/**
+ * 鐗╂枡
+ */
+public interface MatService {
+    /**
+     * 鐗╂枡code杞琻ame
+     * @param matCode
+     * @return
+     */
+    String selectMatNameByCode(String matCode);
+}
diff --git a/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java b/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java
index c084ea1..254b13c 100755
--- a/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java
+++ b/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java
@@ -32,4 +32,15 @@
      */
     String OSS_ID_TO_URL = "oss_id_to_url";
 
+
+    /**
+     * 鐗╂枡code杞琻ame
+     */
+    String MAT_CODE_TO_NAME = "mat_code_to_name";
+
+    /**
+     * 鍒ゅ畾渚濇嵁code杞琻ame
+     */
+    String JUDGE_CODE_TO_NAME = "judge_code_to_name";
+
 }
diff --git a/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/JudgeNameTranslationImpl.java b/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/JudgeNameTranslationImpl.java
new file mode 100755
index 0000000..9234fd2
--- /dev/null
+++ b/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/JudgeNameTranslationImpl.java
@@ -0,0 +1,26 @@
+package org.dromara.common.translation.core.impl;
+
+import lombok.AllArgsConstructor;
+import org.dromara.common.core.service.JudgeService;
+import org.dromara.common.core.service.MatService;
+import org.dromara.common.translation.annotation.TranslationType;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.common.translation.core.TranslationInterface;
+
+/**
+ * judgeName缈昏瘧瀹炵幇
+ *
+ * @author zhuguifei
+ */
+@AllArgsConstructor
+@TranslationType(type = TransConstant.JUDGE_CODE_TO_NAME)
+public class JudgeNameTranslationImpl implements TranslationInterface<String> {
+
+    private final JudgeService judgeService;
+
+    @Override
+    public String translation(Object key, String other) {
+        if(key == null) return  "";
+        return judgeService.selectJudgeNameByCode(key.toString());
+    }
+}
diff --git a/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index ad40205..88a1ea3 100755
--- a/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -4,3 +4,5 @@
 org.dromara.common.translation.core.impl.OssUrlTranslationImpl
 org.dromara.common.translation.core.impl.UserNameTranslationImpl
 org.dromara.common.translation.core.impl.NicknameTranslationImpl
+org.dromara.common.translation.core.impl.MatNameTranslationImpl
+org.dromara.common.translation.core.impl.JudgeNameTranslationImpl
diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/controller/QmJudgeDetailsController.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/controller/QmJudgeDetailsController.java
index c58d4d6..20b4367 100644
--- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/controller/QmJudgeDetailsController.java
+++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/controller/QmJudgeDetailsController.java
@@ -46,6 +46,16 @@
     }
 
     /**
+     * 鏌ヨ鍒ゅ畾妯℃澘鏄庣粏鏍戝舰缁撴瀯鍒楄〃
+     */
+    @SaCheckPermission("qm:judgeDetails:list")
+    @GetMapping("/tree")
+    public TableDataInfo<QmJudgeDetailsVo> tree(@RequestParam @NotBlank(message = "judgeId涓嶈兘涓虹┖") String judgeId) {
+        List<QmJudgeDetailsVo> list = qmJudgeDetailsService.queryTreeListByJudgeId(judgeId);
+        return TableDataInfo.build(list);
+    }
+
+    /**
      * 瀵煎嚭鍒ゅ畾妯℃澘鏄庣粏鍒楄〃
      */
     @SaCheckPermission("qm:judgeDetails:export")
diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/QmJudgeDetails.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/QmJudgeDetails.java
index 1b07cdf..a7b227e 100644
--- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/QmJudgeDetails.java
+++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/QmJudgeDetails.java
@@ -44,17 +44,17 @@
     /**
      * 鏍囧噯鍊�
      */
-    private Long value3;
+    private Double value3;
 
     /**
      * 鍒ゅ畾鍊�1
      */
-    private Long value1;
+    private Double value1;
 
     /**
      * 鍒ゅ畾鍊�2
      */
-    private Long value2;
+    private Double value2;
 
     /**
      * 缂洪櫡浣嶇疆
@@ -69,7 +69,7 @@
     /**
      * 鍒嗗�兼爣鍑� (鎵e垎鏍囧噯锛屽緱鍒嗘爣鍑�),姣斿涓嶅悎鏍间竴娆℃墸澶氬皯鍒�
      */
-    private Long stdscore;
+    private Double stdscore;
 
     /**
      * 鏍囪姝ら」鏄惁涓哄悎鎴愰」鐩紝姣斿澶栬锛屽疄闄呬笂鍏宠仈浜嗗緢澶氬瓙椤圭洰
diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/bo/QmJudgeDetailsBo.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/bo/QmJudgeDetailsBo.java
index 9fd1f63..e5aa98d 100644
--- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/bo/QmJudgeDetailsBo.java
+++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/bo/QmJudgeDetailsBo.java
@@ -43,17 +43,17 @@
     /**
      * 鏍囧噯鍊�
      */
-    private Long value3;
+    private Double value3;
 
     /**
      * 鍒ゅ畾鍊�1
      */
-    private Long value1;
+    private Double value1;
 
     /**
      * 鍒ゅ畾鍊�2
      */
-    private Long value2;
+    private Double value2;
 
     /**
      * 缂洪櫡浣嶇疆
@@ -68,7 +68,7 @@
     /**
      * 鍒嗗�兼爣鍑� (鎵e垎鏍囧噯锛屽緱鍒嗘爣鍑�),姣斿涓嶅悎鏍间竴娆℃墸澶氬皯鍒�
      */
-    private Long stdscore;
+    private Double stdscore;
 
     /**
      * 鏍囪姝ら」鏄惁涓哄悎鎴愰」鐩紝姣斿澶栬锛屽疄闄呬笂鍏宠仈浜嗗緢澶氬瓙椤圭洰
diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmBatchVo.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmBatchVo.java
index 4d3132f..ce8136f 100644
--- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmBatchVo.java
+++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmBatchVo.java
@@ -2,6 +2,8 @@
 
 import java.util.Date;
 
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
 import org.dromara.qa.qm.domain.QmBatch;
 import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
 import cn.idev.excel.annotation.ExcelProperty;
@@ -59,8 +61,15 @@
     /**
      * 鐗屽彿
      */
-    @ExcelProperty(value = "鐗屽彿")
+    @ExcelProperty(value = "鐗屽彿code")
     private String matCode;
+
+    /**
+     * 鐗屽彿
+     */
+    @ExcelProperty(value = "鐗屽彿")
+    @Translation(type = TransConstant.MAT_CODE_TO_NAME, mapper = "matCode")
+    private String matName;
 
     /**
      * 鍒ゅ畾渚濇嵁浠g爜
@@ -68,6 +77,10 @@
     @ExcelProperty(value = "鍒ゅ畾渚濇嵁浠g爜")
     private String judgeCode;
 
+    @ExcelProperty(value = "鍒ゅ畾渚濇嵁")
+    @Translation(type = TransConstant.JUDGE_CODE_TO_NAME, mapper = "judgeCode")
+    private String judgeName;
+
     /**
      * 鎵规鐢熸垚鏃ユ湡
      */
diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeDetailsVo.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeDetailsVo.java
index f005ed1..9829c65 100644
--- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeDetailsVo.java
+++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeDetailsVo.java
@@ -11,7 +11,7 @@
 import java.io.Serial;
 import java.io.Serializable;
 import java.util.Date;
-
+import java.util.List;
 
 
 /**
@@ -27,6 +27,8 @@
 
     @Serial
     private static final long serialVersionUID = 1L;
+
+    private String id;
 
     /**
      * 鍒ゅ畾涓绘爣璇�
@@ -50,19 +52,19 @@
      * 鏍囧噯鍊�
      */
     @ExcelProperty(value = "鏍囧噯鍊�")
-    private Long value3;
+    private Double value3;
 
     /**
      * 鍒ゅ畾鍊�1
      */
     @ExcelProperty(value = "鍒ゅ畾鍊�1")
-    private Long value1;
+    private Double value1;
 
     /**
      * 鍒ゅ畾鍊�2
      */
     @ExcelProperty(value = "鍒ゅ畾鍊�2")
-    private Long value2;
+    private Double value2;
 
     /**
      * 缂洪櫡浣嶇疆
@@ -80,7 +82,7 @@
      * 鍒嗗�兼爣鍑� (鎵e垎鏍囧噯锛屽緱鍒嗘爣鍑�),姣斿涓嶅悎鏍间竴娆℃墸澶氬皯鍒�
      */
     @ExcelProperty(value = "鍒嗗�兼爣鍑� (鎵e垎鏍囧噯锛屽緱鍒嗘爣鍑�),姣斿涓嶅悎鏍间竴娆℃墸澶氬皯鍒�")
-    private Long stdscore;
+    private Double stdscore;
 
     /**
      * 鏍囪姝ら」鏄惁涓哄悎鎴愰」鐩紝姣斿澶栬锛屽疄闄呬笂鍏宠仈浜嗗緢澶氬瓙椤圭洰
@@ -113,4 +115,46 @@
     private String updateUser;
 
 
+    /**
+     * 瀛愭壒娆$爜
+     */
+    @ExcelProperty(value = "瀛愭壒娆$爜")
+    private String subBatchCode;
+
+    /**
+     * 涓嶈壇鍊�
+     */
+    @ExcelProperty(value = "涓嶈壇鍊�")
+    private Long badVal;
+
+    /**
+     * 鎵规鐮�
+     */
+    @ExcelProperty(value = "鎵规鐮�")
+    private String batchCode;
+
+    /**
+     * 鐗╂枡鐮�
+     */
+    @ExcelProperty(value = "鐗╂枡鐮�")
+    private String matCode;
+
+    /**
+     * 璁惧
+     */
+    @ExcelProperty(value = "璁惧")
+    private String eqp;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @ExcelProperty(value = "鏇存柊鏃堕棿")
+    private Date updateTime;
+
+    /**
+     * 瀛愰」鍒楄〃锛堢敤浜庢爲褰㈢粨鏋勶級
+     */
+    private List<QmJudgeDetailsVo> children;
+
+
 }
diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeVo.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeVo.java
index e0fd2d8..66fd9a8 100644
--- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeVo.java
+++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeVo.java
@@ -48,6 +48,7 @@
      * 鐗╂枡鐗屽彿
      */
     @ExcelProperty(value = "鐗╂枡鐗屽彿")
+    @Translation(type = TransConstant.MAT_CODE_TO_NAME, mapper = "matCode")
     private String matName;
 
     /**
diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/IQmJudgeDetailsService.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/IQmJudgeDetailsService.java
index d6506ed..ad2a804 100644
--- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/IQmJudgeDetailsService.java
+++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/IQmJudgeDetailsService.java
@@ -42,6 +42,14 @@
     List<QmJudgeDetailsVo> queryList(QmJudgeDetailsBo bo);
 
     /**
+     * 鏌ヨ鏍戝舰缁撴瀯鏁版嵁
+     *
+     * @param judgeId 鍒ゅ畾涓绘爣璇�
+     * @return 鏍戝舰缁撴瀯鍒楄〃
+     */
+    List<QmJudgeDetailsVo> queryTreeListByJudgeId(String judgeId);
+
+    /**
      * 鏂板鍒ゅ畾妯℃澘鏄庣粏
      *
      * @param bo 鍒ゅ畾妯℃澘鏄庣粏
diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeDetailsServiceImpl.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeDetailsServiceImpl.java
index ccfb91d..c76b09c 100644
--- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeDetailsServiceImpl.java
+++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeDetailsServiceImpl.java
@@ -70,6 +70,51 @@
         return baseMapper.selectVoList(lqw);
     }
 
+    /**
+     * 鏌ヨ鏍戝舰缁撴瀯鏁版嵁
+     *
+     * @param judgeId 鍒ゅ畾涓绘爣璇�
+     * @return 鏍戝舰缁撴瀯鍒楄〃
+     */
+    @Override
+    public List<QmJudgeDetailsVo> queryTreeListByJudgeId(String judgeId) {
+        if (StringUtils.isBlank(judgeId)) {
+            return new java.util.ArrayList<>();
+        }
+        // 1. 鏌ヨ鏍硅妭鐐� (rid is null)
+        List<QmJudgeDetailsVo> roots = selectTreeNodes(judgeId, null);
+        for (QmJudgeDetailsVo root : roots) {
+            // 2. 鏌ヨ绗竴绾у瓙鑺傜偣 (rid = root.itemCod)
+            List<QmJudgeDetailsVo> children = selectTreeNodes(judgeId, root.getItemCod());
+            for (QmJudgeDetailsVo child : children) {
+                // 3. 鏌ヨ绗簩绾у瓙鑺傜偣 (rid = child.itemCod)
+                List<QmJudgeDetailsVo> grandchildren = selectTreeNodes(judgeId, child.getItemCod());
+                child.setChildren(grandchildren);
+            }
+            root.setChildren(children);
+        }
+        return roots;
+    }
+
+    /**
+     * 鏌ヨ鏍戣妭鐐�
+     *
+     * @param judgeId 鍒ゅ畾涓绘爣璇�
+     * @param rid     鍏宠仈椤笽D
+     * @return 鑺傜偣鍒楄〃
+     */
+    private List<QmJudgeDetailsVo> selectTreeNodes(String judgeId, String rid) {
+        LambdaQueryWrapper<QmJudgeDetails> lqw = Wrappers.lambdaQuery();
+        lqw.eq(QmJudgeDetails::getJudgeId, judgeId);
+        if (rid == null) {
+            lqw.isNull(QmJudgeDetails::getRid);
+        } else {
+            lqw.eq(QmJudgeDetails::getRid, rid);
+        }
+        lqw.orderByAsc(QmJudgeDetails::getId);
+        return baseMapper.selectVoList(lqw);
+    }
+
     private LambdaQueryWrapper<QmJudgeDetails> buildQueryWrapper(QmJudgeDetailsBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<QmJudgeDetails> lqw = Wrappers.lambdaQuery();
diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeServiceImpl.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeServiceImpl.java
index 55b949c..e6edd0e 100644
--- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeServiceImpl.java
+++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeServiceImpl.java
@@ -1,5 +1,6 @@
 package org.dromara.qa.qm.service.impl;
 
+import org.dromara.common.core.service.JudgeService;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -19,6 +20,13 @@
 import org.dromara.qa.qm.service.IQmStdService;
 import org.dromara.qa.qm.mapper.QmStdMapper;
 
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import org.dromara.qa.qm.domain.QmCheckitem;
+import org.dromara.qa.qm.domain.QmJudgeDetails;
+import org.dromara.qa.qm.mapper.QmCheckitemMapper;
+import org.dromara.qa.qm.mapper.QmJudgeDetailsMapper;
+import org.springframework.transaction.annotation.Transactional;
+
 import java.util.List;
 import java.util.Map;
 import java.util.Collection;
@@ -35,10 +43,12 @@
 @Slf4j
 @RequiredArgsConstructor
 @Service
-public class QmJudgeServiceImpl implements IQmJudgeService {
+public class QmJudgeServiceImpl implements IQmJudgeService, JudgeService {
 
     private final QmJudgeMapper baseMapper;
     private final QmStdMapper qmStdMapper;
+    private final QmCheckitemMapper qmCheckitemMapper;
+    private final QmJudgeDetailsMapper qmJudgeDetailsMapper;
 
     /**
      * 鏌ヨ鍒ゅ畾渚濇嵁
@@ -127,12 +137,52 @@
      * @return 鏄惁鏂板鎴愬姛
      */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Boolean insertByBo(QmJudgeBo bo) {
         QmJudge add = MapstructUtils.convert(bo, QmJudge.class);
+        if (add.getCdate() == null) {
+            add.setCdate(new java.util.Date());
+        }
         validEntityBeforeSave(add);
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
             bo.setId(add.getId());
+
+            // 1. 鏍规嵁 stdCod 鏌ヨ鍚敤鐨勮绋嬫楠岄」鐩�
+            LambdaQueryWrapper<QmCheckitem> itemLqw = Wrappers.lambdaQuery();
+            itemLqw.eq(QmCheckitem::getStdCode, bo.getStdCod());
+            itemLqw.eq(QmCheckitem::getEnable, 1L);
+            itemLqw.ne(QmCheckitem::getDel, 1L);
+            List<QmCheckitem> checkitems = qmCheckitemMapper.selectList(itemLqw);
+
+            if (!checkitems.isEmpty()) {
+                List<QmJudgeDetails> detailsList = checkitems.stream().map(item -> {
+                    QmJudgeDetails detail = new QmJudgeDetails();
+                    detail.setJudgeId(add.getId());
+                    detail.setItemCod(item.getId());
+                    detail.setItemName(item.getItemName());
+                    detail.setValue3(0.0);
+                    detail.setValue1(0.0);
+                    detail.setValue2(0.0);
+                    detail.setLocation(item.getLocation());
+                    detail.setCls(item.getCheckLevel());
+                    detail.setStdscore(item.getScore() != null ? item.getScore() : 0.0);
+                    detail.setIsmix(item.getIsmix() != null ? item.getIsmix() : 0L);
+                    detail.setRid(item.getRid());
+                    detail.setCategory(item.getCategory());
+                    detail.setDecisionDes(item.getItemDes());
+                    return detail;
+                }).collect(Collectors.toList());
+                qmJudgeDetailsMapper.insertBatch(detailsList);
+            }
+
+            // 2. 灏嗗師鏉ュ瓨鍦ㄧ殑鐩稿悓鐗╂枡鐗屽彿鍜岀被鍨嬬殑渚濇嵁璁剧疆涓虹鐢�
+            LambdaUpdateWrapper<QmJudge> updateWrapper = Wrappers.lambdaUpdate();
+            updateWrapper.set(QmJudge::getStatus, 0L)
+                .eq(QmJudge::getMatCode, bo.getMatCode())
+                .eq(QmJudge::getCategory, bo.getCategory())
+                .ne(QmJudge::getId, add.getId());
+            baseMapper.update(null, updateWrapper);
         }
         return flag;
     }
@@ -171,4 +221,13 @@
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+
+    @Override
+    public String selectJudgeNameByCode(String judgeCode) {
+        QmJudgeVo qmJudgeVo = baseMapper.selectVoById(judgeCode);
+        if(qmJudgeVo!=null){
+            return qmJudgeVo.getJudgeName();
+        }
+        return null;
+    }
 }
diff --git a/ruoyi-plus-soybean/src/router/elegant/imports.ts b/ruoyi-plus-soybean/src/router/elegant/imports.ts
index 56a0110..b3e47ec 100755
--- a/ruoyi-plus-soybean/src/router/elegant/imports.ts
+++ b/ruoyi-plus-soybean/src/router/elegant/imports.ts
@@ -33,6 +33,8 @@
   demo_tree: () => import("@/views/demo/tree/index.vue"),
   home: () => import("@/views/home/index.vue"),
   md_instrument: () => import("@/views/md/instrument/index.vue"),
+  "md_mat-type": () => import("@/views/md/mat-type/index.vue"),
+  md_mat: () => import("@/views/md/mat/index.vue"),
   md_shift: () => import("@/views/md/shift/index.vue"),
   monitor_cache: () => import("@/views/monitor/cache/index.vue"),
   monitor_logininfor: () => import("@/views/monitor/logininfor/index.vue"),
@@ -41,6 +43,7 @@
   qm_batch: () => import("@/views/qm/batch/index.vue"),
   "qm_judge-details": () => import("@/views/qm/judge-details/index.vue"),
   qm_judge: () => import("@/views/qm/judge/index.vue"),
+  qm_matcheck: () => import("@/views/qm/matcheck/index.vue"),
   qm_std: () => import("@/views/qm/std/index.vue"),
   report_demo: () => import("@/views/report/demo/index.vue"),
   "report_silk-storage-output": () => import("@/views/report/silk-storage-output/index.vue"),
diff --git a/ruoyi-plus-soybean/src/router/elegant/routes.ts b/ruoyi-plus-soybean/src/router/elegant/routes.ts
index 1a339b1..3c1e430 100755
--- a/ruoyi-plus-soybean/src/router/elegant/routes.ts
+++ b/ruoyi-plus-soybean/src/router/elegant/routes.ts
@@ -199,6 +199,24 @@
         }
       },
       {
+        name: 'md_mat',
+        path: '/md/mat',
+        component: 'view.md_mat',
+        meta: {
+          title: 'md_mat',
+          i18nKey: 'route.md_mat'
+        }
+      },
+      {
+        name: 'md_mat-type',
+        path: '/md/mat-type',
+        component: 'view.md_mat-type',
+        meta: {
+          title: 'md_mat-type',
+          i18nKey: 'route.md_mat-type'
+        }
+      },
+      {
         name: 'md_shift',
         path: '/md/shift',
         component: 'view.md_shift',
@@ -293,6 +311,15 @@
         }
       },
       {
+        name: 'qm_matcheck',
+        path: '/qm/matcheck',
+        component: 'view.qm_matcheck',
+        meta: {
+          title: 'qm_matcheck',
+          i18nKey: 'route.qm_matcheck'
+        }
+      },
+      {
         name: 'qm_std',
         path: '/qm/std',
         component: 'view.qm_std',
diff --git a/ruoyi-plus-soybean/src/router/elegant/transform.ts b/ruoyi-plus-soybean/src/router/elegant/transform.ts
index edd1a94..d6aed04 100755
--- a/ruoyi-plus-soybean/src/router/elegant/transform.ts
+++ b/ruoyi-plus-soybean/src/router/elegant/transform.ts
@@ -186,6 +186,8 @@
   "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?",
   "md": "/md",
   "md_instrument": "/md/instrument",
+  "md_mat": "/md/mat",
+  "md_mat-type": "/md/mat-type",
   "md_shift": "/md/shift",
   "monitor": "/monitor",
   "monitor_cache": "/monitor/cache",
@@ -196,6 +198,7 @@
   "qm_batch": "/qm/batch",
   "qm_judge": "/qm/judge",
   "qm_judge-details": "/qm/judge-details",
+  "qm_matcheck": "/qm/matcheck",
   "qm_std": "/qm/std",
   "report": "/report",
   "report_demo": "/report/demo",
diff --git a/ruoyi-plus-soybean/src/service/api/qm/judge-details.ts b/ruoyi-plus-soybean/src/service/api/qm/judge-details.ts
index 3f180f9..971f037 100644
--- a/ruoyi-plus-soybean/src/service/api/qm/judge-details.ts
+++ b/ruoyi-plus-soybean/src/service/api/qm/judge-details.ts
@@ -8,6 +8,16 @@
     params
   });
 }
+/** 鑾峰彇鍒ゅ畾妯℃澘鏄庣粏鏍戝舰鍒楄〃 */
+export function fetchGetJudgeDetailsTree(params?: Api.Qm.JudgeDetailsSearchParams) {
+  return request<Api.Qm.JudgeDetailsList>({
+    url: '/qm/judgeDetails/tree',
+    method: 'get',
+    params
+  });
+}
+
+
 /** 鏂板鍒ゅ畾妯℃澘鏄庣粏 */
 export function fetchCreateJudgeDetails(data: Api.Qm.JudgeDetailsOperateParams) {
   return request<boolean>({
diff --git a/ruoyi-plus-soybean/src/typings/api/qm.batch.api.d.ts b/ruoyi-plus-soybean/src/typings/api/qm.batch.api.d.ts
index bdb8333..97572b6 100755
--- a/ruoyi-plus-soybean/src/typings/api/qm.batch.api.d.ts
+++ b/ruoyi-plus-soybean/src/typings/api/qm.batch.api.d.ts
@@ -24,6 +24,8 @@
       eqpCode: string;
       /** 鐗屽彿 */
       matCode: string;
+      /** 鐗屽彿 */
+      matName: string;
       /** 鍒ゅ畾渚濇嵁浠g爜 */
       judgeCode: string;
       /** 鎵规鐢熸垚鏃ユ湡 */
@@ -113,6 +115,7 @@
       Pick<
         Api.Qm.Batch,
         | 'batchCode'
+        | 'isflag'
         | 'typ'
         | 'eqpCode'
         | 'matCode'
@@ -120,6 +123,7 @@
         | 'flag'
         | 'toMesDate'
         | 'fromMesDate'
+        | 'enabled'
         | 'deleted'
         | 'category'
         | 'state'
diff --git a/ruoyi-plus-soybean/src/typings/api/qm.judge-details.api.d.ts b/ruoyi-plus-soybean/src/typings/api/qm.judge-details.api.d.ts
index 681ce8f..f4e3cbc 100644
--- a/ruoyi-plus-soybean/src/typings/api/qm.judge-details.api.d.ts
+++ b/ruoyi-plus-soybean/src/typings/api/qm.judge-details.api.d.ts
@@ -16,32 +16,54 @@
       id: CommonType.IdType;
       /** 鍒ゅ畾涓绘爣璇� */
       judgeId: CommonType.IdType;
-      /** 鍒ゅ畾椤笽TEM */
+      /** 妫�楠岄」鐩唬鐮� */
+      itemCode: string;
+      /** 鍒ゅ畾椤笽TEM (鍏煎鏃у瓧娈�) */
       itemCod: string;
-      /** 鍒ゅ畾椤筃AME */
+      /** 妫�楠岄」鐩悕绉� */
       itemName: string;
+      /** 鍗曚綅 */
+      unit: string;
+      /** 鍚敤 */
+      enable: number;
+      /** 鍒犻櫎 */
+      del: number;
+      /** 妫�楠岄」鎻忚堪 */
+      itemDes: string;
+      /** 瑙勭▼浠g爜 */
+      stdCode: string;
+      /** 浠櫒鎻忚堪 */
+      instrumentDes: string;
       /** 鏍囧噯鍊� */
       value3: number;
       /** 鍒ゅ畾鍊�1 */
       value1: number;
       /** 鍒ゅ畾鍊�2 */
       value2: number;
-      /** 缂洪櫡浣嶇疆 */
+      /** 缂洪櫡浣嶇疆-澶栬鐢� */
       location: string;
-      /** 鍒ゅ畾绾у埆 (A,B,C,D) */
+      /** 鍒咥,B,C,D鍥涗釜绾у埆 */
+      checkLevel: string;
+      /** 鍒ゅ畾绾у埆 (A,B,C,D) (鍏煎鏃у瓧娈�) */
       cls: string;
-      /** 鍒嗗�兼爣鍑� (鎵e垎鏍囧噯锛屽緱鍒嗘爣鍑�),姣斿涓嶅悎鏍间竴娆℃墸澶氬皯鍒� */
+      /** 鍒嗗�� */
+      score: number;
+      /** 鍒嗗�兼爣鍑� (鎵e垎鏍囧噯锛屽緱鍒嗘爣鍑�) (鍏煎鏃у瓧娈�) */
       stdscore: number;
-      /** 鏍囪姝ら」鏄惁涓哄悎鎴愰」鐩紝姣斿澶栬锛屽疄闄呬笂鍏宠仈浜嗗緢澶氬瓙椤圭洰 */
+      /** 鏄惁鍚堟垚椤� */
       ismix: number;
-      /** 鑻ユ瀛楁鏈塙UID鍊硷紝琛ㄦ槑瀹冨彲鑳戒负鍏朵粬椤圭洰鐨勫瓙椤癸紝姣斿鈥滅┖澶粹��,瀹冧负鐑熸敮澶栬椤圭洰鐨勫瓙椤� */
+      /** 鍏宠仈椤笽D */
       rid: CommonType.IdType;
-      /** 鑼冨洿-澶囩敤 */
+      /** 绫诲埆 0:鎴愬搧 1杈呮枡 */
       category: number;
-      /** 澶囨敞 */
+      /** 浠櫒缂栫爜 */
+      instrumentCode: string;
+      /** 澶囨敞 (鍏煎鏃у瓧娈�) */
       decisionDes: string;
       /** 淇敼浜� */
       updateUser: string;
+      /** 瀛愯妭鐐� */
+      children?: Api.Qm.JudgeDetails[];
     }>;
 
     /** judge details search params */
diff --git a/ruoyi-plus-soybean/src/typings/elegant-router.d.ts b/ruoyi-plus-soybean/src/typings/elegant-router.d.ts
index f9e689d..c6f6d88 100755
--- a/ruoyi-plus-soybean/src/typings/elegant-router.d.ts
+++ b/ruoyi-plus-soybean/src/typings/elegant-router.d.ts
@@ -40,6 +40,8 @@
     "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?";
     "md": "/md";
     "md_instrument": "/md/instrument";
+    "md_mat": "/md/mat";
+    "md_mat-type": "/md/mat-type";
     "md_shift": "/md/shift";
     "monitor": "/monitor";
     "monitor_cache": "/monitor/cache";
@@ -50,6 +52,7 @@
     "qm_batch": "/qm/batch";
     "qm_judge": "/qm/judge";
     "qm_judge-details": "/qm/judge-details";
+    "qm_matcheck": "/qm/matcheck";
     "qm_std": "/qm/std";
     "report": "/report";
     "report_demo": "/report/demo";
@@ -160,6 +163,8 @@
     | "demo_tree"
     | "home"
     | "md_instrument"
+    | "md_mat-type"
+    | "md_mat"
     | "md_shift"
     | "monitor_cache"
     | "monitor_logininfor"
@@ -168,6 +173,7 @@
     | "qm_batch"
     | "qm_judge-details"
     | "qm_judge"
+    | "qm_matcheck"
     | "qm_std"
     | "report_demo"
     | "report_silk-storage-output"
diff --git a/ruoyi-plus-soybean/src/views/qm/batch/index.vue b/ruoyi-plus-soybean/src/views/qm/batch/index.vue
index 96d7c52..e25ab9c 100755
--- a/ruoyi-plus-soybean/src/views/qm/batch/index.vue
+++ b/ruoyi-plus-soybean/src/views/qm/batch/index.vue
@@ -1,12 +1,14 @@
 <script setup lang="tsx">
-import { ref } from 'vue';
-import { NDivider } from 'naive-ui';
-import { fetchBatchDeleteBatch, fetchGetBatchList } from '@/service/api/qm/batch';
-import { useAppStore } from '@/store/modules/app';
-import { useAuth } from '@/hooks/business/auth';
-import { useDownload } from '@/hooks/business/download';
-import { defaultTransform, useNaivePaginatedTable, useTableOperate } from '@/hooks/common/table';
-import { $t } from '@/locales';
+import {nextTick, ref} from 'vue';
+import {useRouter} from 'vue-router';
+import {NDivider, NDropdown} from 'naive-ui';
+import {fetchBatchDeleteBatch, fetchGetBatchList} from '@/service/api/qm/batch';
+import {useAppStore} from '@/store/modules/app';
+import {useAuth} from '@/hooks/business/auth';
+import {useDownload} from '@/hooks/business/download';
+import {useSvgIcon} from '@/hooks/common/icon';
+import {defaultTransform, useNaivePaginatedTable, useTableOperate} from '@/hooks/common/table';
+import {$t} from '@/locales';
 import ButtonIcon from '@/components/custom/button-icon.vue';
 import BatchOperateDrawer from './modules/batch-operate-drawer.vue';
 import BatchSearch from './modules/batch-search.vue';
@@ -16,18 +18,145 @@
 });
 
 const appStore = useAppStore();
-const { download } = useDownload();
-const { hasAuth } = useAuth();
+const router = useRouter();
+const {download} = useDownload();
+const {hasAuth} = useAuth();
+const {SvgIconVNode} = useSvgIcon();
+
+// 鍙抽敭鑿滃崟鐩稿叧
+const showDropdown = ref(false);
+const x = ref(0);
+const y = ref(0);
+const currentRow = ref<Api.Qm.Batch | null>(null);
+
+const dropdownOptions = [
+  {
+    label: '鍘熷鏁版嵁缁存姢',
+    key: 'raw-data-maintenance',
+    icon: SvgIconVNode({icon: 'mdi:database-edit-outline', fontSize: 18})
+  },
+  {
+    label: '缁煎悎娴嬭瘯鍙版暟鎹淮鎶�',
+    key: 'test-bench-maintenance',
+    icon: SvgIconVNode({icon: 'mdi:monitor-dashboard', fontSize: 18})
+  },
+  {
+    label: '鏂板缓澶嶆鎵规',
+    key: 'new-recheck-batch',
+    icon: SvgIconVNode({icon: 'mdi:plus-circle-outline', fontSize: 18})
+  },
+  {
+    type: 'divider',
+    key: 'd1'
+  },
+  {
+    label: '鍗峰寘鍗峰埗妫�楠岀粨鏋滄姤鍛�',
+    key: 'report-rolling',
+    icon: SvgIconVNode({icon: 'mdi:file-document-outline', fontSize: 18})
+  },
+  {
+    label: '鍖呰鏍囪瘑妫�楠屽師濮嬭褰�',
+    key: 'record-packaging',
+    icon: SvgIconVNode({icon: 'mdi:barcode-scan', fontSize: 18})
+  },
+  {
+    label: '鐔勭伀銆佸惈姘寸巼銆佸惈鏈巼鍘熷璁板綍',
+    key: 'record-quality',
+    icon: SvgIconVNode({icon: 'mdi:water-percent', fontSize: 18})
+  },
+  {
+    label: '绔儴钀戒笣鍘熷璁板綍',
+    key: 'record-silk',
+    icon: SvgIconVNode({icon: 'mdi:format-list-bulleted-type', fontSize: 18})
+  },
+  {
+    label: '缁煎悎娴嬭瘯鍙板師濮嬭褰�',
+    key: 'record-bench',
+    icon: SvgIconVNode({icon: 'mdi:chart-line', fontSize: 18})
+  },
+  {
+    label: '澶栬妫�楠屽師濮嬭褰�',
+    key: 'record-appearance',
+    icon: SvgIconVNode({icon: 'mdi:eye-outline', fontSize: 18})
+  },
+  {
+    type: 'divider',
+    key: 'd2'
+  },
+  {
+    label: $t('common.edit'),
+    key: 'edit',
+    icon: SvgIconVNode({icon: 'material-symbols:drive-file-rename-outline-outline', fontSize: 18}),
+    show: hasAuth('qm:batch:edit')
+  },
+  {
+    label: $t('common.delete'),
+    key: 'delete',
+    icon: SvgIconVNode({icon: 'material-symbols:delete-outline', fontSize: 18}),
+    show: hasAuth('qm:batch:remove')
+  }
+];
+
+function handleSelect(key: string) {
+  showDropdown.value = false;
+  if (!currentRow.value) return;
+
+  if (key === 'edit') {
+    edit(currentRow.value.id);
+  } else if (key === 'delete') {
+    window.$dialog?.error({
+      title: $t('common.confirmDelete'),
+      content: $t('common.confirmDelete'),
+      positiveText: $t('common.confirm'),
+      negativeText: $t('common.cancel'),
+      onPositiveClick: () => {
+        handleDelete(currentRow.value!.id);
+      }
+    });
+  } else if (key === 'raw-data-maintenance') {
+    // 璺宠浆鍒� matcheck 椤甸潰
+    if (!currentRow.value.judgeCode) {
+      window.$message?.warning('璇ユ壒娆℃病鏈夊垽瀹氫緷鎹�');
+      return;
+    }
+    router.push({
+      path: '/qm/matcheck',
+      query: {
+        judgeCode: currentRow.value.judgeCode,
+        batchCode: currentRow.value.batchCode,
+        matCode: currentRow.value.matCode
+      }
+    });
+  } else {
+    // 澶勭悊鍏朵粬涓氬姟鎿嶄綔
+    window.$message?.info(`鐐瑰嚮浜�: ${key}`);
+  }
+}
+
+function handleRowProps(row: Api.Qm.Batch) {
+  return {
+    onContextmenu: (e: MouseEvent) => {
+      e.preventDefault();
+      showDropdown.value = false;
+      nextTick().then(() => {
+        currentRow.value = row;
+        x.value = e.clientX;
+        y.value = e.clientY;
+        showDropdown.value = true;
+      });
+    }
+  };
+}
 
 // 绫诲瀷/鍙嶉MES/绫诲埆鐨� value->label 鏄犲皠锛堢敤浜庤〃鏍兼樉绀猴級
-const TYP_MAP: Record<string, string> = { A: '鍒朵笣', B: '鎴愬瀷', C: '鍗峰寘', D: '灏佺', E: '绯栭鏂�' };
-const FLAG_MAP: Record<string, string> = { '0': '鏈笂浼爉es', '1': '宸蹭笂浼�', '3': '浠嶮ES涓嬭浇' };
-const CATEGORY_MAP: Record<string, string> = { '0': '鎴愬搧', '1': '杈呮潗' };
+const FLAG_MAP: Record<string, string> = {'0': '鏈笂浼爉es', '1': '宸蹭笂浼�', '3': '浠嶮ES涓嬭浇'};
+const CATEGORY_MAP: Record<string, string> = {'0': '鎴愬搧', '1': '杈呮潗'};
 
 const searchParams = ref<Api.Qm.BatchSearchParams>({
   pageNum: 1,
   pageSize: 10,
   batchCode: null,
+  isflag: '1',
   typ: null,
   eqpCode: null,
   matCode: null,
@@ -35,13 +164,17 @@
   flag: null,
   toMesDate: null,
   fromMesDate: null,
-  deleted: null,
-  category: null,
+  enabled: '1',
+  deleted: 0,
+  category: '0',
   state: null,
-  params: {}
+  params: {
+    beginBatchDate: `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}-${String(new Date().getDate()).padStart(2, '0')} 00:00:00`,
+    endBatchDate: `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}-${String(new Date().getDate()).padStart(2, '0')} 23:59:59`
+  }
 });
 
-const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagination, scrollX } =
+const {columns, columnChecks, data, getData, getDataByPage, loading, mobilePagination, scrollX} =
   useNaivePaginatedTable({
     api: () => fetchGetBatchList(searchParams.value),
     transform: response => defaultTransform(response),
@@ -63,45 +196,20 @@
         render: (_, index) => index + 1
       },
       {
-        key: 'id',
-        title: '缂栫爜',
-        align: 'center',
-        minWidth: 120
-      },
-      {
         key: 'batchCode',
-        title: '鎵规浠g爜',
+        title: '鎵规鍙�',
         align: 'center',
         minWidth: 120
       },
       {
-        key: 'batchName',
-        title: '鎵规鍚嶇О',
-        align: 'center',
-        minWidth: 120
-      },
-      {
-        key: 'typ',
-        title: '绫诲瀷',
-        align: 'center',
-        minWidth: 120,
-        render: row => TYP_MAP[row.typ] ?? row.typ
-      },
-      {
-        key: 'eqpCode',
-        title: '鏈哄彴浠g爜',
-        align: 'center',
-        minWidth: 120
-      },
-      {
-        key: 'matCode',
+        key: 'matName',
         title: '鐗屽彿',
         align: 'center',
         minWidth: 120
       },
       {
-        key: 'judgeCode',
-        title: '鍒ゅ畾渚濇嵁浠g爜',
+        key: 'judgeName',
+        title: '鍒ゅ畾渚濇嵁',
         align: 'center',
         minWidth: 120
       },
@@ -115,13 +223,15 @@
         key: 'isflag',
         title: '浣跨敤鏍囧織',
         align: 'center',
-        minWidth: 120
+        minWidth: 120,
+        render: row => (row.isflag == '1' ? '鏄�' : '鍚�')
       },
       {
         key: 'enabled',
         title: '鍚敤鏍囧織',
         align: 'center',
-        minWidth: 120
+        minWidth: 120,
+        render: row => (row.enabled == '1' ? '鏄�' : '鍚�')
       },
       {
         key: 'totalNum',
@@ -200,7 +310,8 @@
         key: 'deleted',
         title: '鍒犻櫎鏍囧織',
         align: 'center',
-        minWidth: 120
+        minWidth: 120,
+        render: row => (row.deleted == 1 ? '鏄�' : '鍚�')
       },
       {
         key: 'batchDes',
@@ -350,6 +461,7 @@
       {
         key: 'operate',
         title: $t('common.operate'),
+        fixed: 'right',
         align: 'center',
         width: 130,
         render: row => {
@@ -357,7 +469,7 @@
             if (!hasAuth('qm:batch:edit') || !hasAuth('qm:batch:remove')) {
               return null;
             }
-            return <NDivider vertical />;
+            return <NDivider vertical/>;
           };
 
           const editBtn = () => {
@@ -403,19 +515,19 @@
     ]
   });
 
-const { drawerVisible, operateType, editingData, handleAdd, handleEdit, checkedRowKeys, onBatchDeleted, onDeleted } =
+const {drawerVisible, operateType, editingData, handleAdd, handleEdit, checkedRowKeys, onBatchDeleted, onDeleted} =
   useTableOperate(data, 'id', getData);
 
 async function handleBatchDelete() {
   // request
-  const { error } = await fetchBatchDeleteBatch(checkedRowKeys.value);
+  const {error} = await fetchBatchDeleteBatch(checkedRowKeys.value);
   if (error) return;
   onBatchDeleted();
 }
 
 async function handleDelete(id: CommonType.IdType) {
   // request
-  const { error } = await fetchBatchDeleteBatch([id]);
+  const {error} = await fetchBatchDeleteBatch([id]);
   if (error) return;
   onDeleted();
 }
@@ -431,7 +543,7 @@
 
 <template>
   <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
-    <BatchSearch v-model:model="searchParams" @search="getDataByPage" />
+    <BatchSearch v-model:model="searchParams" @search="getDataByPage"/>
     <NCard title="妫�楠屾壒娆″垪琛�" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
       <template #header-extra>
         <TableHeaderOperation
@@ -458,8 +570,19 @@
         remote
         :row-key="row => row.id"
         :pagination="mobilePagination"
+        :row-props="handleRowProps"
         class="sm:h-full"
       />
+      <NDropdown
+        placement="bottom-start"
+        trigger="manual"
+        :x="x"
+        :y="y"
+        :options="dropdownOptions"
+        :show="showDropdown"
+        :on-clickoutside="() => (showDropdown = false)"
+        @select="handleSelect"
+      />
       <BatchOperateDrawer
         v-model:visible="drawerVisible"
         :operate-type="operateType"
diff --git a/ruoyi-plus-soybean/src/views/qm/batch/modules/batch-operate-drawer.vue b/ruoyi-plus-soybean/src/views/qm/batch/modules/batch-operate-drawer.vue
index bccc726..2af78f4 100755
--- a/ruoyi-plus-soybean/src/views/qm/batch/modules/batch-operate-drawer.vue
+++ b/ruoyi-plus-soybean/src/views/qm/batch/modules/batch-operate-drawer.vue
@@ -1,7 +1,9 @@
 <script setup lang="ts">
-import { computed, ref, watch } from 'vue';
+import { computed, onMounted, ref, watch } from 'vue';
 import { jsonClone } from '@sa/utils';
 import { fetchCreateBatch, fetchUpdateBatch } from '@/service/api/qm/batch';
+import { fetchGetMatList } from '@/service/api/md/mat';
+import { fetchGetJudgeList } from '@/service/api/qm/judge';
 import { useFormRules, useNaiveForm } from '@/hooks/common/form';
 import { $t } from '@/locales';
 
@@ -31,27 +33,41 @@
 const { formRef, validate, restoreValidation } = useNaiveForm();
 const { createRequiredRule } = useFormRules();
 
-// 绫诲瀷閫夐」锛欰-鍒朵笣 B-鎴愬瀷 C-鍗峰寘 D-灏佺 E-绯栭鏂�
-const typOptions = [
-  { label: '鍒朵笣', value: 'A' },
-  { label: '鎴愬瀷', value: 'B' },
-  { label: '鍗峰寘', value: 'C' },
-  { label: '灏佺', value: 'D' },
-  { label: '绯栭鏂�', value: 'E' }
+const matOptions = ref<CommonType.Option[]>([]);
+const judgeOptions = ref<CommonType.Option[]>([]);
+const stateOptions = [
+  { label: '姝e父', value: '0' },
+  { label: '鍋滅敤', value: '1' }
 ];
 
-// 鍙嶉MES閫夐」锛�0-鏈笂浼爉es 1-宸蹭笂浼� 3-浠嶮ES涓嬭浇
-const flagOptions = [
-  { label: '鏈笂浼爉es', value: '0' },
-  { label: '宸蹭笂浼�', value: '1' },
-  { label: '浠嶮ES涓嬭浇', value: '3' }
-];
+async function getMatOptions() {
+  const { data, error } = await fetchGetMatList({ tid: '1' as any, pageSize: 1000 });
+  if (!error) {
+    matOptions.value = data.rows.map(item => ({
+      label: item.name,
+      value: item.code
+    }));
+  }
+}
 
-// 绫诲埆閫夐」锛�0-鎴愬搧 1-杈呮潗
-const categoryOptions = [
-  { label: '鎴愬搧', value: '0' },
-  { label: '杈呮潗', value: '1' }
-];
+async function getJudgeOptions(matCode?: string | null) {
+  if (!matCode) {
+    judgeOptions.value = [];
+    return;
+  }
+  const params: Api.Qm.JudgeSearchParams = { category: 0, pageSize: 1000, matCode };
+  const { data, error } = await fetchGetJudgeList(params);
+  if (!error) {
+    judgeOptions.value = data.rows.map(item => ({
+      label: item.judgeName,
+      value: String(item.id)
+    })) as CommonType.Option[];
+  }
+}
+
+onMounted(() => {
+  getMatOptions();
+});
 
 const title = computed(() => {
   const titles: Record<NaiveUI.TableOperateType, string> = {
@@ -70,13 +86,13 @@
     id: '',
     batchCode: '',
     batchName: '',
-    typ: '',
+    typ: '0',
     eqpCode: '',
-    matCode: '',
+    matCode: null,
     judgeCode: '',
     batchDate: null,
-    isflag: '',
-    enabled: '',
+    isflag: '0',
+    enabled: '1',
     totalNum: null,
     results: '',
     approver: '',
@@ -86,19 +102,19 @@
     verName: '',
     verCode: '',
     archDate: '',
-    flag: '',
+    flag: '0',
     toMesDate: null,
     fromMesDate: null,
-    deleted: null,
+    deleted: 0,
     batchDes: '',
-    category: '',
+    category: '0',
     makeno: '',
     shifteqpno: '',
     boxno: '',
     pid: '',
     reviewer: '',
     rvcount: null,
-    state: '',
+    state: '0',
     reviewTime: null,
     auditTime: null,
     spec: '',
@@ -117,10 +133,11 @@
   };
 }
 
-type RuleKey = Extract<keyof Model, 'id'>;
+type RuleKey = Extract<keyof Model, 'batchCode' | 'matCode'>;
 
 const rules: Record<RuleKey, App.Global.FormRule> = {
-  id: createRequiredRule('缂栫爜涓嶈兘涓虹┖')
+  batchCode: createRequiredRule('鎵规鍙蜂笉鑳戒负绌�'),
+  matCode: createRequiredRule('鐗屽彿涓嶈兘涓虹┖')
 };
 
 function handleUpdateModelWhenEdit() {
@@ -303,201 +320,54 @@
   if (visible.value) {
     handleUpdateModelWhenEdit();
     restoreValidation();
+    getJudgeOptions(model.value.matCode);
   }
 });
+
+watch(
+  () => model.value.matCode,
+  newVal => {
+    if (visible.value) {
+      model.value.judgeCode = '';
+      getJudgeOptions(newVal);
+    }
+  }
+);
 </script>
 
 <template>
   <NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
     <NDrawerContent :title="title" :native-scrollbar="false" closable>
-      <NForm ref="formRef" :model="model" :rules="rules">
-        <NFormItem label="鎵规浠g爜" path="batchCode">
-          <NInput v-model:value="model.batchCode" placeholder="璇疯緭鍏ユ壒娆′唬鐮�" />
-        </NFormItem>
-        <NFormItem label="鎵规鍚嶇О" path="batchName">
-          <NInput v-model:value="model.batchName" placeholder="璇疯緭鍏ユ壒娆″悕绉�" />
-        </NFormItem>
-        <NFormItem label="绫诲瀷" path="typ">
-          <NSelect v-model:value="model.typ" :options="typOptions" placeholder="璇烽�夋嫨绫诲瀷" clearable />
-        </NFormItem>
-        <NFormItem label="鏈哄彴浠g爜" path="eqpCode">
-          <NInput v-model:value="model.eqpCode" placeholder="璇疯緭鍏ユ満鍙颁唬鐮�" />
+      <NForm ref="formRef" :model="model" :rules="rules" label-placement="left" :label-width="100">
+        <NFormItem label="鎵规鍙�" path="batchCode">
+          <NInput v-model:value="model.batchCode" placeholder="璇疯緭鍏ユ壒娆″彿" />
         </NFormItem>
         <NFormItem label="鐗屽彿" path="matCode">
-          <NInput v-model:value="model.matCode" placeholder="璇疯緭鍏ョ墝鍙�" />
+          <NSelect v-model:value="model.matCode" :options="matOptions" placeholder="璇烽�夋嫨鐗屽彿" clearable filterable />
         </NFormItem>
-        <NFormItem label="鍒ゅ畾渚濇嵁浠g爜" path="judgeCode">
-          <NInput v-model:value="model.judgeCode" placeholder="璇疯緭鍏ュ垽瀹氫緷鎹唬鐮�" />
-        </NFormItem>
-        <NFormItem label="鎵规鐢熸垚鏃ユ湡" path="batchDate">
-          <NDatePicker
-            v-model:formatted-value="model.batchDate"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
+        <NFormItem label="鍒ゅ畾渚濇嵁" path="judgeCode">
+          <NSelect
+            v-model:value="model.judgeCode"
+            :options="judgeOptions"
+            placeholder="璇烽�夋嫨鍒ゅ畾渚濇嵁"
             clearable
-          />
-        </NFormItem>
-        <NFormItem label="浣跨敤鏍囧織" path="isflag">
-          <NInput v-model:value="model.isflag" placeholder="璇疯緭鍏ヤ娇鐢ㄦ爣蹇�" />
-        </NFormItem>
-        <NFormItem label="鍚敤鏍囧織" path="enabled">
-          <NInput v-model:value="model.enabled" placeholder="璇疯緭鍏ュ惎鐢ㄦ爣蹇�" />
-        </NFormItem>
-        <NFormItem label="鍒拌揣鎬婚噺" path="totalNum">
-          <NInputNumber v-model:value="model.totalNum" placeholder="璇疯緭鍏ュ埌璐ф�婚噺" class="w-full" />
-        </NFormItem>
-        <NFormItem label="缁煎悎鍒ゅ畾" path="results">
-          <NInput v-model:value="model.results" placeholder="璇疯緭鍏ョ患鍚堝垽瀹�" />
-        </NFormItem>
-        <NFormItem label="鎵瑰噯浜�" path="approver">
-          <NInput v-model:value="model.approver" placeholder="璇疯緭鍏ユ壒鍑嗕汉" />
-        </NFormItem>
-        <NFormItem label="瀹℃牳浜�" path="auditor">
-          <NInput v-model:value="model.auditor" placeholder="璇疯緭鍏ュ鏍镐汉" />
-        </NFormItem>
-        <NFormItem label="鍒涘缓浜�" path="creater">
-          <NInput v-model:value="model.creater" placeholder="璇疯緭鍏ュ垱寤轰汉" />
-        </NFormItem>
-        <NFormItem label="鍒惰〃鏃ユ湡" path="tabDate">
-          <NDatePicker
-            v-model:formatted-value="model.tabDate"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            clearable
-          />
-        </NFormItem>
-        <NFormItem label="鐗堟湰鍚嶇О" path="verName">
-          <NInput v-model:value="model.verName" placeholder="璇疯緭鍏ョ増鏈悕绉�" />
-        </NFormItem>
-        <NFormItem label="鐗堟湰缂栧彿" path="verCode">
-          <NInput v-model:value="model.verCode" placeholder="璇疯緭鍏ョ増鏈紪鍙�" />
-        </NFormItem>
-        <NFormItem label="淇濆瓨鏈�" path="archDate">
-          <NInput v-model:value="model.archDate" placeholder="璇疯緭鍏ヤ繚瀛樻湡" />
-        </NFormItem>
-        <NFormItem label="鍙嶉MES" path="flag">
-          <NSelect v-model:value="model.flag" :options="flagOptions" placeholder="璇烽�夋嫨鍙嶉MES" clearable />
-        </NFormItem>
-        <NFormItem label="涓婁紶MES鏃堕棿" path="toMesDate">
-          <NDatePicker
-            v-model:formatted-value="model.toMesDate"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            clearable
-          />
-        </NFormItem>
-        <NFormItem label="浠嶮ES鏃堕棿涓嬭浇" path="fromMesDate">
-          <NDatePicker
-            v-model:formatted-value="model.fromMesDate"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            clearable
-          />
-        </NFormItem>
-        <NFormItem label="鍒犻櫎鏍囧織" path="deleted">
-          <NInputNumber v-model:value="model.deleted" placeholder="璇疯緭鍏ュ垹闄ゆ爣蹇�" class="w-full" />
-        </NFormItem>
-        <NFormItem label="鎵规鎻忚堪" path="batchDes">
-          <NInput v-model:value="model.batchDes" placeholder="璇疯緭鍏ユ壒娆℃弿杩�" />
-        </NFormItem>
-        <NFormItem label="绫诲埆" path="category">
-          <NSelect v-model:value="model.category" :options="categoryOptions" placeholder="璇烽�夋嫨绫诲埆" clearable />
-        </NFormItem>
-        <NFormItem label="鍗峰埗宸ュ彿" path="makeno">
-          <NInput v-model:value="model.makeno" placeholder="璇疯緭鍏ュ嵎鍒跺伐鍙�" />
-        </NFormItem>
-        <NFormItem label="鐝鏈哄彿" path="shifteqpno">
-          <NInput v-model:value="model.shifteqpno" placeholder="璇疯緭鍏ョ彮娆℃満鍙�" />
-        </NFormItem>
-        <NFormItem label="瑁呯鍙�" path="boxno">
-          <NInput v-model:value="model.boxno" placeholder="璇疯緭鍏ヨ绠卞彿" />
-        </NFormItem>
-        <NFormItem label="鐖舵壒娆″彿" path="pid">
-          <NInput v-model:value="model.pid as any" placeholder="璇疯緭鍏ョ埗鎵规鍙�" />
-        </NFormItem>
-        <NFormItem label="澶嶆牳浜�" path="reviewer">
-          <NInput v-model:value="model.reviewer" placeholder="璇疯緭鍏ュ鏍镐汉" />
-        </NFormItem>
-        <NFormItem label="澶嶆娆℃暟" path="rvcount">
-          <NInputNumber v-model:value="model.rvcount" placeholder="璇疯緭鍏ュ妫�娆℃暟" class="w-full" />
-        </NFormItem>
-        <NFormItem label="鎵规鐘舵��" path="state">
-          <NInput v-model:value="model.state" placeholder="璇疯緭鍏ユ壒娆$姸鎬�" />
-        </NFormItem>
-        <NFormItem label="澶嶆牳鏃ユ湡" path="reviewTime">
-          <NDatePicker
-            v-model:formatted-value="model.reviewTime"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            clearable
-          />
-        </NFormItem>
-        <NFormItem label="瀹℃牳鏃ユ湡" path="auditTime">
-          <NDatePicker
-            v-model:formatted-value="model.auditTime"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            clearable
+            filterable
           />
         </NFormItem>
         <NFormItem label="瑙勬牸" path="spec">
           <NInput v-model:value="model.spec" placeholder="璇疯緭鍏ヨ鏍�" />
         </NFormItem>
-        <NFormItem label="鎵瑰噯鏃堕棿" path="approveTime">
-          <NDatePicker
-            v-model:formatted-value="model.approveTime"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            clearable
-          />
+        <NFormItem label="瑁呯鍙�" path="boxno">
+          <NInput v-model:value="model.boxno" placeholder="璇疯緭鍏ヨ绠卞彿" />
         </NFormItem>
-        <NFormItem label="鍒拌揣鍗曚綅" path="unit">
-          <NInput v-model:value="model.unit" placeholder="璇疯緭鍏ュ埌璐у崟浣�" />
+        <NFormItem label="鐝鏈哄彿" path="shifteqpno">
+          <NInput v-model:value="model.shifteqpno" placeholder="璇疯緭鍏ョ彮娆℃満鍙�" />
         </NFormItem>
-        <NFormItem label="鍒拌揣鏃ユ湡" path="arrivalTime">
-          <NDatePicker
-            v-model:formatted-value="model.arrivalTime"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            clearable
-          />
+        <NFormItem label="鎻忚堪" path="batchDes">
+          <NInput v-model:value="model.batchDes" placeholder="璇疯緭鍏ユ弿杩�" />
         </NFormItem>
-        <NFormItem label="瀛樻斁鍦扮偣" path="storagePlace">
-          <NInput v-model:value="model.storagePlace" placeholder="璇疯緭鍏ュ瓨鏀惧湴鐐�" />
-        </NFormItem>
-        <NFormItem label="妫�楠屽憳" path="checker">
-          <NInput v-model:value="model.checker" placeholder="璇疯緭鍏ユ楠屽憳" />
-        </NFormItem>
-        <NFormItem label="鎺ュ崟鏃ユ湡" path="receiveTime">
-          <NDatePicker
-            v-model:formatted-value="model.receiveTime"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            clearable
-          />
-        </NFormItem>
-        <NFormItem label="鎶ユ鏃ユ湡" path="inspTime">
-          <NDatePicker
-            v-model:formatted-value="model.inspTime"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            clearable
-          />
-        </NFormItem>
-        <NFormItem label="浠撳簱淇濈鍛�" path="storer">
-          <NInput v-model:value="model.storer" placeholder="璇疯緭鍏ヤ粨搴撲繚绠″憳" />
-        </NFormItem>
-        <NFormItem label="鏄惁楠岃瘉" path="isverify">
-          <NInput v-model:value="model.isverify" placeholder="璇疯緭鍏ユ槸鍚﹂獙璇�" />
-        </NFormItem>
-        <NFormItem label="鏄惁妫�楠�" path="ischk">
-          <NInput v-model:value="model.ischk" placeholder="璇疯緭鍏ユ槸鍚︽楠�" />
-        </NFormItem>
-        <NFormItem label="澶囩敤1" path="bak1">
-          <NInput v-model:value="model.bak1" placeholder="璇疯緭鍏ュ鐢�1" />
-        </NFormItem>
-        <NFormItem label="澶囩敤2" path="bak2">
-          <NInput v-model:value="model.bak2" placeholder="璇疯緭鍏ュ鐢�2" />
+        <NFormItem label="鐘舵��" path="state">
+          <NSelect v-model:value="model.state" :options="stateOptions" placeholder="璇烽�夋嫨鐘舵��" clearable />
         </NFormItem>
       </NForm>
       <template #footer>
diff --git a/ruoyi-plus-soybean/src/views/qm/batch/modules/batch-search.vue b/ruoyi-plus-soybean/src/views/qm/batch/modules/batch-search.vue
index 77400be..3397bf9 100755
--- a/ruoyi-plus-soybean/src/views/qm/batch/modules/batch-search.vue
+++ b/ruoyi-plus-soybean/src/views/qm/batch/modules/batch-search.vue
@@ -1,6 +1,7 @@
 <script setup lang="ts">
-import { ref, toRaw } from 'vue';
+import { onMounted, ref, toRaw, watch } from 'vue';
 import { jsonClone } from '@sa/utils';
+import { fetchGetMatList } from '@/service/api/md/mat';
 import { useNaiveForm } from '@/hooks/common/form';
 import { $t } from '@/locales';
 
@@ -16,38 +17,53 @@
 
 const { formRef, validate, restoreValidation } = useNaiveForm();
 
-const dateRangeToMesDate = ref<[string, string] | null>(null);
-const dateRangeFromMesDate = ref<[string, string] | null>(null);
 const model = defineModel<Api.Qm.BatchSearchParams>('model', { required: true });
+
+const dateRangeBatchDate = ref<[string, string] | null>(null);
+
+const matOptions = ref<CommonType.Option[]>([]);
+
+async function getMatOptions() {
+  const { data } = await fetchGetMatList({ tid: '1' as any, pageSize: 1000 });
+  if (data) {
+    matOptions.value = data.rows.map(item => ({
+      label: item.name,
+      value: item.code
+    }));
+  }
+}
+
+onMounted(() => {
+  getMatOptions();
+});
+
+// sync model params to dateRangeBatchDate
+watch(
+  () => model.value.params,
+  val => {
+    if (val?.beginBatchDate && val?.endBatchDate) {
+      dateRangeBatchDate.value = [val.beginBatchDate, val.endBatchDate];
+    } else {
+      dateRangeBatchDate.value = null;
+    }
+  },
+  { immediate: true, deep: true }
+);
 
 const defaultModel = jsonClone(toRaw(model.value));
 
-// 绫诲瀷閫夐」锛欰-鍒朵笣 B-鎴愬瀷 C-鍗峰寘 D-灏佺 E-绯栭鏂�
-const typOptions = [
-  { label: '鍒朵笣', value: 'A' },
-  { label: '鎴愬瀷', value: 'B' },
-  { label: '鍗峰寘', value: 'C' },
-  { label: '灏佺', value: 'D' },
-  { label: '绯栭鏂�', value: 'E' }
-];
-
-// 鍙嶉MES閫夐」锛�0-鏈笂浼爉es 1-宸蹭笂浼� 3-浠嶮ES涓嬭浇
-const flagOptions = [
-  { label: '鏈笂浼爉es', value: '0' },
-  { label: '宸蹭笂浼�', value: '1' },
-  { label: '浠嶮ES涓嬭浇', value: '3' }
-];
-
-// 绫诲埆閫夐」锛�0-鎴愬搧 1-杈呮潗
-const categoryOptions = [
-  { label: '鎴愬搧', value: '0' },
-  { label: '杈呮潗', value: '1' }
-];
+function onDateRangeBatchDateUpdate(value: [string, string] | null) {
+  if (value && value.length === 2) {
+    model.value.params!.beginBatchDate = value[0];
+    model.value.params!.endBatchDate = value[1];
+  } else {
+    model.value.params!.beginBatchDate = undefined;
+    model.value.params!.endBatchDate = undefined;
+  }
+}
 
 function resetModel() {
-  dateRangeToMesDate.value = null;
-  dateRangeFromMesDate.value = null;
-  Object.assign(model.value, defaultModel);
+  Object.assign(model.value, jsonClone(defaultModel));
 }
 
 async function reset() {
@@ -58,14 +74,6 @@
 
 async function search() {
   await validate();
-  if (dateRangeToMesDate.value?.length) {
-    model.value.params!.beginToMesDate = dateRangeToMesDate.value[0];
-    model.value.params!.endToMesDate = dateRangeToMesDate.value[1];
-  }
-  if (dateRangeFromMesDate.value?.length) {
-    model.value.params!.beginFromMesDate = dateRangeFromMesDate.value[0];
-    model.value.params!.endFromMesDate = dateRangeFromMesDate.value[1];
-  }
   emit('search');
 }
 </script>
@@ -74,70 +82,68 @@
   <NCard :bordered="false" size="small" class="card-wrapper">
     <NCollapse>
       <NCollapseItem :title="$t('common.search')" name="qm-batch-search">
-        <NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
+        <NForm ref="formRef" :model="model" label-placement="left" :label-width="110">
           <NGrid responsive="screen" item-responsive>
-            <NFormItemGi span="24 s:12 m:8" label="鎵规浠g爜" label-width="auto" path="batchCode" class="pr-24px">
-              <NInput v-model:value="model.batchCode" placeholder="璇疯緭鍏ユ壒娆′唬鐮�" />
-            </NFormItemGi>
-            <NFormItemGi span="24 s:12 m:8" label="绫诲瀷" label-width="auto" path="typ" class="pr-24px">
-              <NSelect v-model:value="model.typ" :options="typOptions" placeholder="璇烽�夋嫨绫诲瀷" clearable />
-            </NFormItemGi>
-            <NFormItemGi span="24 s:12 m:8" label="鏈哄彴浠g爜" label-width="auto" path="eqpCode" class="pr-24px">
-              <NInput v-model:value="model.eqpCode" placeholder="璇疯緭鍏ユ満鍙颁唬鐮�" />
-            </NFormItemGi>
-            <NFormItemGi span="24 s:12 m:8" label="鐗屽彿" label-width="auto" path="matCode" class="pr-24px">
-              <NInput v-model:value="model.matCode" placeholder="璇疯緭鍏ョ墝鍙�" />
-            </NFormItemGi>
             <NFormItemGi span="24 s:12 m:8" label="鎵规鐢熸垚鏃ユ湡" label-width="auto" path="batchDate" class="pr-24px">
               <NDatePicker
-                v-model:formatted-value="model.batchDate"
-                type="datetime"
-                value-format="yyyy-MM-dd HH:mm:ss"
-                clearable
-              />
-            </NFormItemGi>
-            <NFormItemGi span="24 s:12 m:8" label="鍙嶉MES" label-width="auto" path="flag" class="pr-24px">
-              <NSelect v-model:value="model.flag" :options="flagOptions" placeholder="璇烽�夋嫨鍙嶉MES" clearable />
-            </NFormItemGi>
-            <NFormItemGi span="24 s:12 m:8" label="涓婁紶MES鏃堕棿" label-width="auto" path="toMesDate" class="pr-24px">
-              <NDatePicker
-                v-model:formatted-value="dateRangeToMesDate"
+                v-model:formatted-value="dateRangeBatchDate"
                 type="datetimerange"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 clearable
+                :default-time="['00:00:00', '23:59:59']"
+                @update:formatted-value="onDateRangeBatchDateUpdate"
               />
             </NFormItemGi>
-            <NFormItemGi span="24 s:12 m:8" label="浠嶮ES鏃堕棿涓嬭浇" label-width="auto" path="fromMesDate" class="pr-24px">
-              <NDatePicker
-                v-model:formatted-value="dateRangeFromMesDate"
-                type="datetimerange"
-                value-format="yyyy-MM-dd HH:mm:ss"
+            <NFormItemGi span="24 s:12 m:8" label="鐗屽彿" label-width="auto" path="matCode" class="pr-24px">
+              <NSelect v-model:value="model.matCode" placeholder="璇烽�夋嫨鐗屽彿" :options="matOptions" clearable />
+            </NFormItemGi>
+            <NFormItemGi span="24 s:12 m:8" label="浣跨敤鏍囧織" label-width="auto" path="isflag" class="pr-24px">
+              <NSelect
+                v-model:value="model.isflag"
+                placeholder="璇烽�夋嫨浣跨敤鏍囧織"
+                :options="[
+                  { label: '鏄�', value: '1' },
+                  { label: '鍚�', value: '0' }
+                ]"
+                clearable
+              />
+            </NFormItemGi>
+            <NFormItemGi span="24 s:12 m:8" label="鍚敤鏍囧織" label-width="auto" path="enabled" class="pr-24px">
+              <NSelect
+                v-model:value="model.enabled"
+                placeholder="璇烽�夋嫨鍚敤鏍囧織"
+                :options="[
+                  { label: '鏄�', value: '1' },
+                  { label: '鍚�', value: '0' }
+                ]"
                 clearable
               />
             </NFormItemGi>
             <NFormItemGi span="24 s:12 m:8" label="鍒犻櫎鏍囧織" label-width="auto" path="deleted" class="pr-24px">
-              <NInputNumber v-model:value="model.deleted" placeholder="璇疯緭鍏ュ垹闄ゆ爣蹇�" class="w-full" />
+              <NSelect
+                v-model:value="model.deleted"
+                placeholder="璇烽�夋嫨鍒犻櫎鏍囧織"
+                :options="[
+                  { label: '鏄�', value: 1 },
+                  { label: '鍚�', value: 0 }
+                ]"
+                clearable
+              />
             </NFormItemGi>
-            <NFormItemGi span="24 s:12 m:8" label="绫诲埆" label-width="auto" path="category" class="pr-24px">
-              <NSelect v-model:value="model.category" :options="categoryOptions" placeholder="璇烽�夋嫨绫诲埆" clearable />
-            </NFormItemGi>
-            <NFormItemGi span="24 s:12 m:8" label="鎵规鐘舵��" label-width="auto" path="state" class="pr-24px">
-              <NInput v-model:value="model.state" placeholder="璇疯緭鍏ユ壒娆$姸鎬�" />
-            </NFormItemGi>
-            <NFormItemGi :show-feedback="false" span="24" class="pr-24px">
-              <NSpace class="w-full" justify="end">
-                <NButton @click="reset">
-                  <template #icon>
-                    <icon-ic-round-refresh class="text-icon" />
-                  </template>
-                  {{ $t('common.reset') }}
-                </NButton>
+            <NFormItemGi :show-feedback="false" span="24 s:12 m:8" class="pr-24px">
+              <NSpace class="w-full" justify="start">
                 <NButton type="primary" ghost @click="search">
                   <template #icon>
                     <icon-ic-round-search class="text-icon" />
                   </template>
                   {{ $t('common.search') }}
                 </NButton>
+                <NButton @click="reset">
+                  <template #icon>
+                    <icon-ic-round-refresh class="text-icon" />
+                  </template>
+                  {{ $t('common.reset') }}
+                </NButton>
               </NSpace>
             </NFormItemGi>
           </NGrid>
diff --git a/ruoyi-plus-soybean/src/views/qm/judge-details/modules/judge-details-operate-drawer.vue b/ruoyi-plus-soybean/src/views/qm/judge-details/modules/judge-details-operate-drawer.vue
index f573bb8..55fcf0d 100644
--- a/ruoyi-plus-soybean/src/views/qm/judge-details/modules/judge-details-operate-drawer.vue
+++ b/ruoyi-plus-soybean/src/views/qm/judge-details/modules/judge-details-operate-drawer.vue
@@ -39,6 +39,13 @@
   return titles[props.operateType];
 });
 
+const clsOptions = [
+  { label: 'A', value: 'A' },
+  { label: 'B', value: 'B' },
+  { label: 'C', value: 'C' },
+  { label: 'D', value: 'D' }
+];
+
 type Model = Api.Qm.JudgeDetailsOperateParams;
 
 const model = ref<Model>(createDefaultModel());
@@ -65,12 +72,14 @@
 
 type RuleKey = Extract<keyof Model, 'id'>;
 
-const rules: Record<RuleKey, App.Global.FormRule> = {};
+const rules: Record<RuleKey, App.Global.FormRule | App.Global.FormRule[]> = {
+  id: createRequiredRule('璇疯緭鍏ョ紪鐮�')
+};
 
 function handleUpdateModelWhenEdit() {
   model.value = createDefaultModel();
 
-  if (props.operateType === 'edit' && props.rowData) {
+  if (props.rowData) {
     Object.assign(model.value, jsonClone(props.rowData));
   }
 }
@@ -160,59 +169,26 @@
   <NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
     <NDrawerContent :title="title" :native-scrollbar="false" closable>
       <NForm ref="formRef" :model="model" :rules="rules">
-        <NFormItem label="缂栫爜" path="id">
-          <NInput v-model:value="model.id" placeholder="璇疯緭鍏ョ紪鐮�" />
-        </NFormItem>
-        <NFormItem label="鍒ゅ畾涓绘爣璇�" path="judgeId">
-          <NInput v-model:value="model.judgeId" placeholder="璇疯緭鍏ュ垽瀹氫富鏍囪瘑" />
-        </NFormItem>
-        <NFormItem label="鍒ゅ畾椤笽TEM" path="itemCod">
-          <NInput v-model:value="model.itemCod" placeholder="璇疯緭鍏ュ垽瀹氶」ITEM" />
-        </NFormItem>
-        <NFormItem label="鍒ゅ畾椤筃AME" path="itemName">
-          <NInput v-model:value="model.itemName" placeholder="璇疯緭鍏ュ垽瀹氶」NAME" />
+        <NFormItem label="鍒ゅ畾椤�" path="itemName">
+          <NInput v-model:value="(model.itemName as any)" placeholder="璇疯緭鍏ュ垽瀹氶」" :disabled="operateType === 'edit'" />
         </NFormItem>
         <NFormItem label="鏍囧噯鍊�" path="value3">
-          <NInput v-model:value="model.value3" placeholder="璇疯緭鍏ユ爣鍑嗗��" />
+          <NInputNumber v-model:value="(model.value3 as any)" placeholder="璇疯緭鍏ユ爣鍑嗗��" class="w-full" />
         </NFormItem>
-        <NFormItem label="鍒ゅ畾鍊�1" path="value1">
-          <NInput v-model:value="model.value1" placeholder="璇疯緭鍏ュ垽瀹氬��1" />
+        <NFormItem label="涓嬮檺鍊�" path="value1">
+          <NInputNumber v-model:value="(model.value1 as any)" placeholder="璇疯緭鍏ヤ笅闄愬��" class="w-full" />
         </NFormItem>
-        <NFormItem label="鍒ゅ畾鍊�2" path="value2">
-          <NInput v-model:value="model.value2" placeholder="璇疯緭鍏ュ垽瀹氬��2" />
+        <NFormItem label="涓婇檺鍊�" path="value2">
+          <NInputNumber v-model:value="(model.value2 as any)" placeholder="璇疯緭鍏ヤ笂闄愬��" class="w-full" />
         </NFormItem>
-        <NFormItem label="缂洪櫡浣嶇疆" path="location">
-          <NInput v-model:value="model.location" placeholder="璇疯緭鍏ョ己闄蜂綅缃�" />
+        <NFormItem label="鍒嗗��" path="stdscore">
+          <NInputNumber v-model:value="(model.stdscore as any)" placeholder="璇疯緭鍏ュ垎鍊�" class="w-full" />
         </NFormItem>
-        <NFormItem label="鍒ゅ畾绾у埆 (A,B,C,D)" path="cls">
-          <NInput v-model:value="model.cls" placeholder="璇疯緭鍏ュ垽瀹氱骇鍒� (A,B,C,D)" />
-        </NFormItem>
-        <NFormItem label="鍒嗗�兼爣鍑� (鎵e垎鏍囧噯锛屽緱鍒嗘爣鍑�),姣斿涓嶅悎鏍间竴娆℃墸澶氬皯鍒�" path="stdscore">
-          <NInput
-            v-model:value="model.stdscore"
-            placeholder="璇疯緭鍏ュ垎鍊兼爣鍑� (鎵e垎鏍囧噯锛屽緱鍒嗘爣鍑�),姣斿涓嶅悎鏍间竴娆℃墸澶氬皯鍒�"
-          />
-        </NFormItem>
-        <NFormItem label="鏍囪姝ら」鏄惁涓哄悎鎴愰」鐩紝姣斿澶栬锛屽疄闄呬笂鍏宠仈浜嗗緢澶氬瓙椤圭洰" path="ismix">
-          <NInput
-            v-model:value="model.ismix"
-            placeholder="璇疯緭鍏ユ爣璁版椤规槸鍚︿负鍚堟垚椤圭洰锛屾瘮濡傚瑙傦紝瀹為檯涓婂叧鑱斾簡寰堝瀛愰」鐩�"
-          />
-        </NFormItem>
-        <NFormItem label="鑻ユ瀛楁鏈塙UID鍊硷紝琛ㄦ槑瀹冨彲鑳戒负鍏朵粬椤圭洰鐨勫瓙椤癸紝姣斿鈥滅┖澶粹��,瀹冧负鐑熸敮澶栬椤圭洰鐨勫瓙椤�" path="rid">
-          <NInput
-            v-model:value="model.rid"
-            placeholder="璇疯緭鍏ヨ嫢姝ゅ瓧娈垫湁UUID鍊硷紝琛ㄦ槑瀹冨彲鑳戒负鍏朵粬椤圭洰鐨勫瓙椤癸紝姣斿鈥滅┖澶粹��,瀹冧负鐑熸敮澶栬椤圭洰鐨勫瓙椤�"
-          />
-        </NFormItem>
-        <NFormItem label="鑼冨洿-澶囩敤" path="category">
-          <NInput v-model:value="model.category" placeholder="璇疯緭鍏ヨ寖鍥�-澶囩敤" />
+        <NFormItem label="鍒ゅ畾绾у埆" path="cls">
+          <NSelect v-model:value="(model.cls as any)" :options="clsOptions" placeholder="璇烽�夋嫨鍒ゅ畾绾у埆" />
         </NFormItem>
         <NFormItem label="澶囨敞" path="decisionDes">
-          <NInput v-model:value="model.decisionDes" placeholder="璇疯緭鍏ュ娉�" />
-        </NFormItem>
-        <NFormItem label="淇敼浜�" path="updateUser">
-          <NInput v-model:value="model.updateUser" placeholder="璇疯緭鍏ヤ慨鏀逛汉" />
+          <NInput v-model:value="(model.decisionDes as any)" type="textarea" placeholder="璇疯緭鍏ュ娉�" />
         </NFormItem>
       </NForm>
       <template #footer>
diff --git a/ruoyi-plus-soybean/src/views/qm/judge/index.vue b/ruoyi-plus-soybean/src/views/qm/judge/index.vue
index 84b5e37..13fe5c0 100644
--- a/ruoyi-plus-soybean/src/views/qm/judge/index.vue
+++ b/ruoyi-plus-soybean/src/views/qm/judge/index.vue
@@ -10,6 +10,8 @@
 import ButtonIcon from '@/components/custom/button-icon.vue';
 import JudgeOperateDrawer from './modules/judge-operate-drawer.vue';
 import JudgeSearch from './modules/judge-search.vue';
+import JudgeDetailsSubTable from '../judge-details/modules/judge-details-sub-table.vue';
+import StdSubTable from "@/views/qm/std/modules/std-sub-table.vue";
 
 defineOptions({
   name: 'JudgeList'
@@ -19,6 +21,8 @@
 const { download } = useDownload();
 const { hasAuth } = useAuth();
 
+const selectedJudgeId = ref<CommonType.IdType | null>(null);
+
 const searchParams = ref<Api.Qm.JudgeSearchParams>({
   pageNum: 1,
   pageSize: 10,
@@ -26,7 +30,7 @@
   matName: null,
   judgeName: null,
   category: 0, // 榛樿閫夋嫨鎴愬搧
-  status: -1, // 榛樿閫夋嫨鍏ㄩ儴
+  status: 1, // 榛樿鏌ヨ鍚敤
   params: {}
 });
 
@@ -276,47 +280,74 @@
 function handleExport() {
   download('/qm/judge/export', searchParams.value, `鍒ゅ畾渚濇嵁_${new Date().getTime()}.xlsx`);
 }
+
+function handleRowClick(row: any) {
+  return {
+    onClick: (e: MouseEvent) => {
+      const target = e.target as HTMLElement | null;
+      if (target?.closest('.n-checkbox') || target?.closest('.n-button') || target?.closest('a')) return;
+      selectedJudgeId.value = row.id;
+    },
+    style: 'cursor: pointer;'
+  };
+}
 </script>
 
 <template>
   <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
     <JudgeSearch v-model:model="searchParams" @search="getDataByPage" />
-    <NCard title="鍒ゅ畾渚濇嵁鍒楄〃" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
-      <template #header-extra>
-        <TableHeaderOperation
-          v-model:columns="columnChecks"
-          :disabled-delete="checkedRowKeys.length === 0"
-          :loading="loading"
-          :show-add="hasAuth('qm:judge:add')"
-          :show-delete="hasAuth('qm:judge:remove')"
-          :show-export="hasAuth('qm:judge:export')"
-          @add="handleAdd"
-          @delete="handleBatchDelete"
-          @export="handleExport"
-          @refresh="getData"
-        />
-      </template>
-      <NDataTable
-        v-model:checked-row-keys="checkedRowKeys"
-        :columns="columns"
-        :data="data"
+    <div class="judge-content-area relative flex-col-stretch gap-16px sm:flex-1-hidden">
+      <NCard
+        title="鍒ゅ畾渚濇嵁鍒楄〃"
+        :bordered="false"
         size="small"
-        :flex-height="!appStore.isMobile"
-        :scroll-x="scrollX"
-        :loading="loading"
-        remote
-        :row-key="row => row.id"
-        :pagination="mobilePagination"
-        class="sm:h-full"
-      />
-      <JudgeOperateDrawer
-        v-model:visible="drawerVisible"
-        :operate-type="operateType"
-        :row-data="editingData"
-        @submitted="getDataByPage"
-      />
-    </NCard>
+        class="flex-col-stretch card-wrapper sm:flex-1-hidden"
+        :content-style="{ flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column' }"
+      >
+        <template #header-extra>
+          <TableHeaderOperation
+            v-model:columns="columnChecks"
+            :disabled-delete="checkedRowKeys.length === 0"
+            :loading="loading"
+            :show-add="hasAuth('qm:judge:add')"
+            :show-delete="hasAuth('qm:judge:remove')"
+            :show-export="hasAuth('qm:judge:export')"
+            @add="handleAdd"
+            @delete="handleBatchDelete"
+            @export="handleExport"
+            @refresh="getData"
+          />
+        </template>
+        <NDataTable
+          v-model:checked-row-keys="checkedRowKeys"
+          :columns="columns"
+          :data="data"
+          size="small"
+          :flex-height="!appStore.isMobile"
+          :scroll-x="scrollX"
+          :loading="loading"
+          remote
+          :row-key="row => row.id"
+          :pagination="mobilePagination"
+          :row-props="handleRowClick"
+          class="flex-1-hidden"
+        />
+        <JudgeOperateDrawer
+          v-model:visible="drawerVisible"
+          :operate-type="operateType"
+          :row-data="editingData"
+          @submitted="getDataByPage"
+        />
+      </NCard>
+      <JudgeDetailsSubTable :judge-id="selectedJudgeId" class="sm:flex-1-hidden"  />
+    </div>
   </div>
 </template>
 
-<style scoped></style>
+<style scoped>
+:deep(.n-data-table-th),
+:deep(.n-data-table-td) {
+  padding: 4px 6px;
+  overflow: hidden;
+}
+</style>
diff --git a/ruoyi-plus-soybean/src/views/qm/judge/modules/judge-operate-drawer.vue b/ruoyi-plus-soybean/src/views/qm/judge/modules/judge-operate-drawer.vue
index 82a891e..28bfabd 100644
--- a/ruoyi-plus-soybean/src/views/qm/judge/modules/judge-operate-drawer.vue
+++ b/ruoyi-plus-soybean/src/views/qm/judge/modules/judge-operate-drawer.vue
@@ -1,10 +1,11 @@
 <script setup lang="ts">
-import { computed, onMounted, ref, watch } from 'vue';
+import { computed, ref, watch } from 'vue';
 import type { SelectOption } from 'naive-ui';
 import { NSelect } from 'naive-ui';
 import { jsonClone } from '@sa/utils';
 import { fetchCreateJudge, fetchUpdateJudge } from '@/service/api/qm/judge';
 import { fetchGetStdList } from '@/service/api/qm/std';
+import { fetchGetMatList } from '@/service/api/md/mat';
 import { useFormRules, useNaiveForm } from '@/hooks/common/form';
 import { $t } from '@/locales';
 
@@ -53,6 +54,7 @@
 ];
 
 const stdOptions = ref<SelectOption[]>([]);
+const matOptions = ref<SelectOption[]>([]);
 
 type Model = Api.Qm.JudgeOperateParams;
 
@@ -102,6 +104,20 @@
   }
 }
 
+async function fetchMatOptions() {
+  if (model.value.category === 1) {
+    matOptions.value = [];
+    return;
+  }
+  const { data } = await fetchGetMatList({ tid: 1, pageSize: 1000 });
+  if (data) {
+    matOptions.value = data.rows.map(item => ({
+      label: item.name,
+      value: item.code
+    }));
+  }
+}
+
 async function handleSubmit() {
   await validate();
 
@@ -147,20 +163,39 @@
   emit('submitted');
 }
 
-watch(visible, () => {
+watch(visible, async () => {
   if (visible.value) {
     handleUpdateModelWhenEdit();
     restoreValidation();
 
-    // Fetch stdOptions when the drawer becomes visible
-    fetchStdOptions();
+    await fetchStdOptions();
+    await fetchMatOptions();
   }
 });
 
 watch(
   () => model.value.category,
-  () => {
+  async () => {
     fetchStdOptions();
+    model.value.matName = '';
+    model.value.matCode = '';
+    await fetchMatOptions();
+  }
+);
+
+watch(
+  () => model.value.matCode,
+  val => {
+    if (val) {
+      const selectedOption = matOptions.value.find(opt => opt.value === val);
+      if (selectedOption && typeof selectedOption.label === 'string') {
+        const name = selectedOption.label as string;
+        model.value.matName = name;
+        model.value.judgeName = name;
+      }
+    } else {
+      model.value.matName = '';
+    }
   }
 );
 </script>
@@ -172,15 +207,17 @@
         <NFormItem label="鍒ゅ畾鍚嶇О" path="judgeName">
           <NInput v-model:value="model.judgeName" placeholder="璇疯緭鍏ュ垽瀹氬悕绉�" />
         </NFormItem>
-        <NFormItem label="鐗╂枡鐗屽彿浠g爜" path="matCode">
-          <NInput v-model:value="model.matCode" placeholder="璇疯緭鍏ョ墿鏂欑墝鍙蜂唬鐮�" />
-        </NFormItem>
-        <NFormItem label="鐗╂枡鐗屽彿" path="matName">
-          <NInput v-model:value="model.matName" placeholder="璇疯緭鍏ョ墿鏂欑墝鍙�" />
-        </NFormItem>
         <NFormItem label="鐗╂枡绫诲瀷" path="category">
           <NSelect v-model:value="model.category" :options="categoryOptions" placeholder="璇烽�夋嫨鐗╂枡绫诲瀷" />
         </NFormItem>
+        <NFormItem label="鐗╂枡鐗屽彿" path="matName">
+          <NSelect
+            v-model:value="model.matCode"
+            :options="matOptions"
+            placeholder="璇烽�夋嫨鐗╂枡鐗屽彿"
+            :disabled="model.category === 1"
+          />
+        </NFormItem>
         <NFormItem label="鐘舵��" path="status">
           <NSelect v-model:value="model.status" :options="statusOptions" placeholder="璇烽�夋嫨鐘舵��" />
         </NFormItem>
diff --git a/ruoyi-plus-soybean/src/views/qm/judge/modules/judge-search.vue b/ruoyi-plus-soybean/src/views/qm/judge/modules/judge-search.vue
index 235b8a3..ba7c5dd 100644
--- a/ruoyi-plus-soybean/src/views/qm/judge/modules/judge-search.vue
+++ b/ruoyi-plus-soybean/src/views/qm/judge/modules/judge-search.vue
@@ -1,6 +1,7 @@
 <script setup lang="ts">
-import { toRaw } from 'vue';
+import { onMounted, ref, toRaw, watch } from 'vue';
 import { jsonClone } from '@sa/utils';
+import { fetchGetMatList } from '@/service/api/md/mat';
 import { useNaiveForm } from '@/hooks/common/form';
 import { $t } from '@/locales';
 
@@ -19,6 +20,43 @@
 const model = defineModel<Api.Qm.JudgeSearchParams>('model', { required: true });
 
 const defaultModel = jsonClone(toRaw(model.value));
+
+const matOptions = ref<CommonType.Option[]>([]);
+
+async function getMatOptions() {
+  if (model.value.category !== 0) {
+    matOptions.value = [];
+    model.value.matName = null;
+    model.value.matCode = null;
+    return;
+  }
+  const { data } = await fetchGetMatList({ tid: 1, pageSize: 1000 });
+  if (data) {
+    matOptions.value = data.rows.map(item => ({
+      label: item.name,
+      value: item.code
+    }));
+  }
+}
+
+watch(
+  () => model.value.category,
+  newVal => {
+    if (newVal === 0) {
+      getMatOptions();
+    } else {
+      matOptions.value = [];
+      model.value.matName = null;
+      model.value.matCode = null;
+    }
+  }
+);
+
+onMounted(() => {
+  if (model.value.category === 0) {
+    getMatOptions();
+  }
+});
 
 function resetModel() {
   Object.assign(model.value, defaultModel);
@@ -53,11 +91,15 @@
               />
             </NFormItemGi>
 
-            <NFormItemGi span="24 s:12 m:6" label="鐗╂枡鐗屽彿浠g爜" label-width="auto" path="matCode" class="pr-24px">
-              <NInput v-model:value="model.matCode" placeholder="璇疯緭鍏ョ墿鏂欑墝鍙蜂唬鐮�" />
-            </NFormItemGi>
-            <NFormItemGi span="24 s:12 m:6" label="鐗╂枡鐗屽彿" label-width="auto" path="matName" class="pr-24px">
-              <NInput v-model:value="model.matName" placeholder="璇疯緭鍏ョ墿鏂欑墝鍙�" />
+            <NFormItemGi span="24 s:12 m:6" label="鐗╂枡鐗屽彿" label-width="auto" path="matCode" class="pr-24px">
+              <NSelect
+                v-model:value="model.matCode"
+                :options="matOptions"
+                placeholder="璇烽�夋嫨鐗╂枡鐗屽彿"
+                :disabled="model.category !== 0"
+                clearable
+                filterable
+              />
             </NFormItemGi>
             <NFormItemGi span="24 s:12 m:6" label="鍒ゅ畾鍚嶇О" label-width="auto" path="judgeName" class="pr-24px">
               <NInput v-model:value="model.judgeName" placeholder="璇疯緭鍏ュ垽瀹氬悕绉�" />

--
Gitblit v1.9.3