广丰卷烟厂数采质量分析系统
feat: 1.新增物料、物料类型、材料检验统计等表维护功能  2.完善判定依据-判断依据明细  3.新增判断依据、物料管理等字典翻译类  4.成品物料批次-原始数据维护页面
已添加3个文件
已修改25个文件
1235 ■■■■■ 文件已修改
RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/JudgeService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/MatService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/JudgeNameTranslationImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/controller/QmJudgeDetailsController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/QmJudgeDetails.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/bo/QmJudgeDetailsBo.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmBatchVo.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeDetailsVo.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/domain/vo/QmJudgeVo.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/IQmJudgeDetailsService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeDetailsServiceImpl.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/qm/service/impl/QmJudgeServiceImpl.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/router/elegant/imports.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/router/elegant/routes.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/router/elegant/transform.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/service/api/qm/judge-details.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/typings/api/qm.batch.api.d.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/typings/api/qm.judge-details.api.d.ts 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/typings/elegant-router.d.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/views/qm/batch/index.vue 199 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/views/qm/batch/modules/batch-operate-drawer.vue 280 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/views/qm/batch/modules/batch-search.vue 166 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/views/qm/judge-details/modules/judge-details-operate-drawer.vue 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/views/qm/judge/index.vue 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/views/qm/judge/modules/judge-operate-drawer.vue 59 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-plus-soybean/src/views/qm/judge/modules/judge-search.vue 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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转name
     * @param judgeCode
     * @return
     */
    String selectJudgeNameByCode(String judgeCode);
}
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转name
     * @param matCode
     * @return
     */
    String selectMatNameByCode(String matCode);
}
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转name
     */
    String MAT_CODE_TO_NAME = "mat_code_to_name";
    /**
     * åˆ¤å®šä¾æ®code转name
     */
    String JUDGE_CODE_TO_NAME = "judge_code_to_name";
}
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());
    }
}
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
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")
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 @@
    /**
     * åˆ†å€¼æ ‡å‡† (扣分标准,得分标准),比如不合格一次扣多少分
     */
    private Long stdscore;
    private Double stdscore;
    /**
     * æ ‡è®°æ­¤é¡¹æ˜¯å¦ä¸ºåˆæˆé¡¹ç›®ï¼Œæ¯”如外观,实际上关联了很多子项目
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 @@
    /**
     * åˆ†å€¼æ ‡å‡† (扣分标准,得分标准),比如不合格一次扣多少分
     */
    private Long stdscore;
    private Double stdscore;
    /**
     * æ ‡è®°æ­¤é¡¹æ˜¯å¦ä¸ºåˆæˆé¡¹ç›®ï¼Œæ¯”如外观,实际上关联了很多子项目
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;
    /**
     * åˆ¤å®šä¾æ®ä»£ç 
@@ -68,6 +77,10 @@
    @ExcelProperty(value = "判定依据代码")
    private String judgeCode;
    @ExcelProperty(value = "判定依据")
    @Translation(type = TransConstant.JUDGE_CODE_TO_NAME, mapper = "judgeCode")
    private String judgeName;
    /**
     * æ‰¹æ¬¡ç”Ÿæˆæ—¥æœŸ
     */
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 @@
     * åˆ†å€¼æ ‡å‡† (扣分标准,得分标准),比如不合格一次扣多少分
     */
    @ExcelProperty(value = "分值标准 (扣分标准,得分标准),比如不合格一次扣多少分")
    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;
}
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;
    /**
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 åˆ¤å®šæ¨¡æ¿æ˜Žç»†
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     å…³è”项ID
     * @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();
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;
    }
}
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"),
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',
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",
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>({
ruoyi-plus-soybean/src/typings/api/qm.batch.api.d.ts
@@ -24,6 +24,8 @@
      eqpCode: string;
      /** ç‰Œå· */
      matCode: string;
      /** ç‰Œå· */
      matName: string;
      /** åˆ¤å®šä¾æ®ä»£ç  */
      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'
ruoyi-plus-soybean/src/typings/api/qm.judge-details.api.d.ts
@@ -16,32 +16,54 @@
      id: CommonType.IdType;
      /** åˆ¤å®šä¸»æ ‡è¯† */
      judgeId: CommonType.IdType;
      /** åˆ¤å®šé¡¹ITEM */
      /** æ£€éªŒé¡¹ç›®ä»£ç  */
      itemCode: string;
      /** åˆ¤å®šé¡¹ITEM (兼容旧字段) */
      itemCod: string;
      /** åˆ¤å®šé¡¹NAME */
      /** æ£€éªŒé¡¹ç›®åç§° */
      itemName: string;
      /** å•位 */
      unit: string;
      /** å¯ç”¨ */
      enable: number;
      /** åˆ é™¤ */
      del: number;
      /** æ£€éªŒé¡¹æè¿° */
      itemDes: string;
      /** è§„程代码 */
      stdCode: string;
      /** ä»ªå™¨æè¿° */
      instrumentDes: string;
      /** æ ‡å‡†å€¼ */
      value3: number;
      /** åˆ¤å®šå€¼1 */
      value1: number;
      /** åˆ¤å®šå€¼2 */
      value2: number;
      /** ç¼ºé™·ä½ç½® */
      /** ç¼ºé™·ä½ç½®-外观用 */
      location: string;
      /** åˆ¤å®šçº§åˆ« (A,B,C,D) */
      /** åˆ†A,B,C,D四个级别 */
      checkLevel: string;
      /** åˆ¤å®šçº§åˆ« (A,B,C,D) (兼容旧字段) */
      cls: string;
      /** åˆ†å€¼æ ‡å‡† (扣分标准,得分标准),比如不合格一次扣多少分 */
      /** åˆ†å€¼ */
      score: number;
      /** åˆ†å€¼æ ‡å‡† (扣分标准,得分标准) (兼容旧字段) */
      stdscore: number;
      /** æ ‡è®°æ­¤é¡¹æ˜¯å¦ä¸ºåˆæˆé¡¹ç›®ï¼Œæ¯”如外观,实际上关联了很多子项目 */
      /** æ˜¯å¦åˆæˆé¡¹ */
      ismix: number;
      /** è‹¥æ­¤å­—段有UUID值,表明它可能为其他项目的子项,比如“空头”,它为烟支外观项目的子项 */
      /** å…³è”项ID */
      rid: CommonType.IdType;
      /** èŒƒå›´-备用 */
      /** ç±»åˆ« 0:成品 1辅料 */
      category: number;
      /** å¤‡æ³¨ */
      /** ä»ªå™¨ç¼–码 */
      instrumentCode: string;
      /** å¤‡æ³¨ (兼容旧字段) */
      decisionDes: string;
      /** ä¿®æ”¹äºº */
      updateUser: string;
      /** å­èŠ‚ç‚¹ */
      children?: Api.Qm.JudgeDetails[];
    }>;
    /** judge details search params */
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"
ruoyi-plus-soybean/src/views/qm/batch/index.vue
@@ -1,10 +1,12 @@
<script setup lang="tsx">
import { ref } from 'vue';
import { NDivider } from 'naive-ui';
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';
@@ -16,11 +18,137 @@
});
const appStore = useAppStore();
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': '未上传mes', '1': '已上传', '3': '从MES下载' };
const CATEGORY_MAP: Record<string, string> = { '0': '成品', '1': '辅材' };
@@ -28,6 +156,7 @@
  pageNum: 1,
  pageSize: 10,
  batchCode: null,
  isflag: '1',
  typ: null,
  eqpCode: null,
  matCode: null,
@@ -35,10 +164,14 @@
  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 } =
@@ -63,45 +196,20 @@
        render: (_, index) => index + 1
      },
      {
        key: 'id',
        title: '编码',
        align: 'center',
        minWidth: 120
      },
      {
        key: 'batchCode',
        title: '批次代码',
        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: '机台代码',
        align: 'center',
        minWidth: 120
      },
      {
        key: 'matCode',
        key: 'matName',
        title: '牌号',
        align: 'center',
        minWidth: 120
      },
      {
        key: 'judgeCode',
        title: '判定依据代码',
        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 => {
@@ -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"
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();
// ç±»åž‹é€‰é¡¹ï¼šA-制丝 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: '正常', value: '0' },
  { label: '停用', value: '1' }
];
// åé¦ˆMES选项:0-未上传mes 1-已上传 3-从MES下载
const flagOptions = [
  { label: '未上传mes', value: '0' },
  { label: '已上传', value: '1' },
  { label: '从MES下载', 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="批次代码" 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="机台代码" 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="判定依据代码" 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="从MES时间下载" 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>
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));
// ç±»åž‹é€‰é¡¹ï¼šA-制丝 B-成型 C-卷包 D-封箱 E-糖香料
const typOptions = [
  { label: '制丝', value: 'A' },
  { label: '成型', value: 'B' },
  { label: '卷包', value: 'C' },
  { label: '封箱', value: 'D' },
  { label: '糖香料', value: 'E' }
];
// åé¦ˆMES选项:0-未上传mes 1-已上传 3-从MES下载
const flagOptions = [
  { label: '未上传mes', value: '0' },
  { label: '已上传', value: '1' },
  { label: '从MES下载', 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="批次代码" 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="机台代码" 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="从MES时间下载" 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>
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="判定项ITEM" path="itemCod">
          <NInput v-model:value="model.itemCod" placeholder="请输入判定项ITEM" />
        </NFormItem>
        <NFormItem label="判定项NAME" 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="分值标准 (扣分标准,得分标准),比如不合格一次扣多少分" path="stdscore">
          <NInput
            v-model:value="model.stdscore"
            placeholder="请输入分值标准 (扣分标准,得分标准),比如不合格一次扣多少分"
          />
        </NFormItem>
        <NFormItem label="标记此项是否为合成项目,比如外观,实际上关联了很多子项目" path="ismix">
          <NInput
            v-model:value="model.ismix"
            placeholder="请输入标记此项是否为合成项目,比如外观,实际上关联了很多子项目"
          />
        </NFormItem>
        <NFormItem label="若此字段有UUID值,表明它可能为其他项目的子项,比如“空头”,它为烟支外观项目的子项" 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>
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,12 +280,30 @@
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">
    <div class="judge-content-area relative flex-col-stretch gap-16px sm:flex-1-hidden">
      <NCard
        title="判定依据列表"
        :bordered="false"
        size="small"
        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"
@@ -307,7 +329,8 @@
        remote
        :row-key="row => row.id"
        :pagination="mobilePagination"
        class="sm:h-full"
          :row-props="handleRowClick"
          class="flex-1-hidden"
      />
      <JudgeOperateDrawer
        v-model:visible="drawerVisible"
@@ -316,7 +339,15 @@
        @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>
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="物料牌号代码" 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>
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="物料牌号代码" 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="请输入判定名称" />