From 993095c3d36d62e52aaa6cb229c309231205f343 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期一, 19 十月 2026 17:11:52 +0800
Subject: [PATCH] feat(qualityMonitor): 实现质量监控检验任务完整流程 - 新增年度质量监控计划创建、提交审核及按年度查询接口 - 新增质量监控检验任务下发、查询及取消接口 - 新增质量监控检验评价提交与批准/退回流程 - 在检验订单中增加任务来源和质量监控明细ID字段 - 增加质控任务认领、原始记录填写、提交、复核等环节的权限校验 - 质控任务复核通过后发送评价通知给指定评价人 - 质控任务不生成检验报告,由评价环节完成归档 - 新增从已复核质控原始记录读取检测数据和上下文信息的方法 - 增加标准方法验证中实时查看所选设备校准证书的功能 - 补充质量监控计划明细的模板ID规范化及字段校验逻辑 - 在样品查询SQL中关联质控明细表返回任务来源和评价状态

---
 cnas-process/src/main/java/com/ruoyi/process/controller/QualityMonitorController.java |  165 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 165 insertions(+), 0 deletions(-)

diff --git a/cnas-process/src/main/java/com/ruoyi/process/controller/QualityMonitorController.java b/cnas-process/src/main/java/com/ruoyi/process/controller/QualityMonitorController.java
index 31fc4a1..6b9805b 100644
--- a/cnas-process/src/main/java/com/ruoyi/process/controller/QualityMonitorController.java
+++ b/cnas-process/src/main/java/com/ruoyi/process/controller/QualityMonitorController.java
@@ -8,9 +8,14 @@
 import com.ruoyi.process.dto.QualityMonitorDetailsDto;
 import com.ruoyi.process.dto.QualityMonitorDto;
 import com.ruoyi.process.mapper.QualityMonitorDetailsEvaluateFileMapper;
+import com.ruoyi.process.mapper.QualityMonitorDetailsEvaluateMapper;
 import com.ruoyi.process.pojo.*;
 import com.ruoyi.process.service.QualityMonitorDetailsService;
 import com.ruoyi.process.service.QualityMonitorService;
+import com.ruoyi.process.service.QualityMonitorTaskService;
+import com.ruoyi.process.service.QualityMonitorInspectionEvaluationService;
+import com.ruoyi.inspect.pojo.InsOrder;
+import com.ruoyi.system.mapper.UserMapper;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.Operation;
 import lombok.AllArgsConstructor;
@@ -19,8 +24,11 @@
 
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletResponse;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 
 /**
@@ -35,6 +43,24 @@
 @RequestMapping("/qualityMonitor")
 public class QualityMonitorController {
 
+    @Operation(summary = "鏂板缓骞村害璐ㄩ噺鎺у埗璁″垝")
+    @PostMapping("/createAnnualPlan")
+    public Result<QualityMonitorDto> createAnnualPlan(@RequestBody QualityMonitor qualityMonitor) {
+        return Result.success(qualityMonitorService.createAnnualPlan(qualityMonitor));
+    }
+
+    @Operation(summary = "鎸夊勾搴︽煡璇㈠綋鍓嶈川閲忔帶鍒惰鍒�")
+    @GetMapping("/getAnnualPlan")
+    public Result<QualityMonitorDto> getAnnualPlan(String monitorYear, Integer qualityMonitorId) {
+        return Result.success(qualityMonitorService.getAnnualPlan(monitorYear, qualityMonitorId));
+    }
+
+    @Operation(summary = "鎻愪氦骞村害璐ㄩ噺鎺у埗璁″垝瀹℃牳")
+    @PostMapping("/submitAnnualPlan")
+    public Result submitAnnualPlan(@RequestBody Map<String, Integer> request) {
+        return Result.success(qualityMonitorService.submitAnnualPlan(request.get("qualityMonitorId")));
+    }
+
     @Resource
     private QualityMonitorService qualityMonitorService;
 
@@ -43,6 +69,58 @@
 
     @Resource
     private QualityMonitorDetailsEvaluateFileMapper qualityMonitorDetailsEvaluateFileMapper;
+
+    @Resource
+    private QualityMonitorDetailsEvaluateMapper qualityMonitorDetailsEvaluateMapper;
+
+    @Resource
+    private QualityMonitorTaskService qualityMonitorTaskService;
+
+    @Resource
+    private QualityMonitorInspectionEvaluationService inspectionEvaluationService;
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Operation(summary = "鑾峰彇璐ㄩ噺鐩戞帶妫�楠岃瘎浠�")
+    @GetMapping("/getInspectionEvaluation")
+    public Result<QualityMonitorDetailsEvaluate> getInspectionEvaluation(Integer qualityMonitorDetailsId) {
+        return Result.success(inspectionEvaluationService.get(qualityMonitorDetailsId));
+    }
+
+    @Operation(summary = "鎻愪氦璐ㄩ噺鐩戞帶妫�楠岃瘎浠�")
+    @PostMapping("/submitInspectionEvaluation")
+    public Result<QualityMonitorDetailsEvaluate> submitInspectionEvaluation(@RequestBody QualityMonitorDetailsEvaluate evaluation) {
+        return Result.success(inspectionEvaluationService.submit(evaluation));
+    }
+
+    @Operation(summary = "鎵瑰噯鎴栭��鍥炶川閲忕洃鎺ф楠岃瘎浠�")
+    @PostMapping("/approveInspectionEvaluation")
+    public Result approveInspectionEvaluation(@RequestBody Map<String, Object> request) {
+        Integer detailId = (Integer) request.get("qualityMonitorDetailsId");
+        boolean approved = Boolean.TRUE.equals(request.get("approved"));
+        inspectionEvaluationService.approve(detailId, approved, (String) request.get("opinion"));
+        return Result.success();
+    }
+
+    @Operation(summary = "涓嬪彂璐ㄩ噺鐩戞帶妫�楠屼换鍔�")
+    @PostMapping("/dispatchInspectionTask")
+    public Result<InsOrder> dispatchInspectionTask(@RequestBody Map<String, Integer> request) {
+        return Result.success(qualityMonitorTaskService.dispatch(request.get("qualityMonitorDetailsId")));
+    }
+
+    @Operation(summary = "鏌ヨ璐ㄩ噺鐩戞帶鏄庣粏鍏宠仈鐨勬楠屼换鍔�")
+    @GetMapping("/getInspectionTask")
+    public Result<InsOrder> getInspectionTask(Integer qualityMonitorDetailsId) {
+        return Result.success(qualityMonitorTaskService.getTask(qualityMonitorDetailsId));
+    }
+
+    @Operation(summary = "鍙栨秷鏈紑濮嬬殑璐ㄩ噺鐩戞帶妫�楠屼换鍔�")
+    @PostMapping("/cancelInspectionTask")
+    public Result cancelInspectionTask(@RequestBody Map<String, Integer> request) {
+        qualityMonitorTaskService.cancel(request.get("qualityMonitorDetailsId"));
+        return Result.success();
+    }
 
     /**
      * 瀵煎叆鐩戞帶璁″垝
@@ -116,6 +194,14 @@
         if (qualityMonitorDetails.getQualityMonitorId() == null) {
             throw new ErrorException("缂哄皯鐩戞帶璁″垝涓昏〃id");
         }
+        qualityMonitorService.validateDetailEditable(qualityMonitorDetails.getQualityMonitorId());
+        normalizeTemplateIds(qualityMonitorDetails);
+        validateAnnualDetail(qualityMonitorDetails);
+        if (qualityMonitorDetails.getSortNo() == null) {
+            qualityMonitorDetails.setSortNo((int) qualityMonitorDetailsService.count(
+                    com.baomidou.mybatisplus.core.toolkit.Wrappers.<QualityMonitorDetails>lambdaQuery()
+                            .eq(QualityMonitorDetails::getQualityMonitorId, qualityMonitorDetails.getQualityMonitorId())) + 1);
+        }
         return Result.success(qualityMonitorDetailsService.save(qualityMonitorDetails));
     }
 
@@ -126,6 +212,15 @@
     @Operation(summary = "淇敼鐩戞帶璁″垝璇︽儏")
     @PostMapping("/updateQualityMonitorDetail")
     public Result updateQualityMonitorDetail(@RequestBody QualityMonitorDetails qualityMonitorDetails) {
+        QualityMonitorDetails stored = qualityMonitorDetailsService.getById(qualityMonitorDetails.getQualityMonitorDetailsId());
+        if (stored == null) throw new ErrorException("璐ㄦ帶椤圭洰涓嶅瓨鍦�");
+        qualityMonitorDetails.setQualityMonitorId(stored.getQualityMonitorId());
+        qualityMonitorService.validateDetailEditable(stored.getQualityMonitorId());
+        normalizeTemplateIds(qualityMonitorDetails);
+        validateAnnualDetail(qualityMonitorDetails);
+        if (qualityMonitorTaskService.getTask(qualityMonitorDetails.getQualityMonitorDetailsId()) != null) {
+            throw new ErrorException("宸蹭笅鍙戞楠屼换鍔$殑璁″垝鏄庣粏涓嶅彲鐩存帴淇敼");
+        }
         return Result.success(qualityMonitorDetailsService.updateById(qualityMonitorDetails));
     }
 
@@ -136,7 +231,64 @@
     @Operation(summary = "鍒犻櫎鐩戞帶璁″垝璇︽儏")
     @DeleteMapping("/delQualityMonitorDetail")
     public Result delQualityMonitorDetail(Integer qualityMonitorDetailsId) {
+        QualityMonitorDetails stored = qualityMonitorDetailsService.getById(qualityMonitorDetailsId);
+        if (stored == null) throw new ErrorException("璐ㄦ帶椤圭洰涓嶅瓨鍦�");
+        qualityMonitorService.validateDetailEditable(stored.getQualityMonitorId());
+        if (qualityMonitorTaskService.getTask(qualityMonitorDetailsId) != null) {
+            throw new ErrorException("宸蹭笅鍙戞楠屼换鍔$殑璁″垝鏄庣粏涓嶅彲鍒犻櫎");
+        }
         return Result.success(qualityMonitorDetailsService.removeById(qualityMonitorDetailsId));
+    }
+
+    private void validateAnnualDetail(QualityMonitorDetails detail) {
+        if (!org.springframework.util.StringUtils.hasText(detail.getMonitorProject())
+                || !org.springframework.util.StringUtils.hasText(detail.getTechnicalStandardText())
+                || !org.springframework.util.StringUtils.hasText(detail.getMonitorWay())
+                || !org.springframework.util.StringUtils.hasText(detail.getCompletionMonth())
+                || !detail.getCompletionMonth().matches("\\d{4}-\\d{2}")
+                || detail.getResponsibleUserId() == null) {
+            throw new ErrorException("璇疯ˉ榻愯川鎺ч」鐩�佹妧鏈爣鍑嗐�佽川鎺ф柟寮忋�佸畬鎴愭椂闄愬拰璐熻矗浜�");
+        }
+        QualityMonitor plan = qualityMonitorService.getById(detail.getQualityMonitorId());
+        if (plan == null || !detail.getCompletionMonth().startsWith(plan.getMonitorYear() + "-")) {
+            throw new ErrorException("瀹屾垚鏃堕檺蹇呴』灞炰簬褰撳墠璁″垝骞村害");
+        }
+        int month = Integer.parseInt(detail.getCompletionMonth().substring(5));
+        if (month < 1 || month > 12) throw new ErrorException("瀹屾垚鏃堕檺鏈堜唤涓嶆纭�");
+        if (userMapper.selectById(detail.getResponsibleUserId()) == null) {
+            throw new ErrorException("璐熻矗浜轰笉瀛樺湪");
+        }
+    }
+
+    private void normalizeTemplateIds(QualityMonitorDetails detail) {
+        String rawIds = detail.getTemplateIds();
+        if (!org.springframework.util.StringUtils.hasText(rawIds) && detail.getTemplateId() != null) {
+            rawIds = String.valueOf(detail.getTemplateId());
+        }
+        if (!org.springframework.util.StringUtils.hasText(rawIds)) {
+            detail.setTemplateIds(null);
+            detail.setTemplateId(null);
+            return;
+        }
+        Set<Integer> templateIds = new LinkedHashSet<>();
+        try {
+            for (String rawId : rawIds.split(",")) {
+                if (!org.springframework.util.StringUtils.hasText(rawId)) continue;
+                int templateId = Integer.parseInt(rawId.trim());
+                if (templateId <= 0) throw new NumberFormatException();
+                templateIds.add(templateId);
+            }
+        } catch (NumberFormatException exception) {
+            throw new ErrorException("鍘熷璁板綍妯℃澘鍙傛暟涓嶆纭�");
+        }
+        if (templateIds.size() > 50) throw new ErrorException("鍘熷璁板綍妯℃澘鏈�澶氶�夋嫨50涓�");
+        if (templateIds.isEmpty()) {
+            detail.setTemplateIds(null);
+            detail.setTemplateId(null);
+            return;
+        }
+        detail.setTemplateIds(templateIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
+        detail.setTemplateId(templateIds.iterator().next());
     }
 
     /**
@@ -211,6 +363,9 @@
     @Operation(summary = "鏂板鐩戞帶璇勪环")
     @PostMapping("/addQualityMonitorEvaluate")
     public Result addQualityMonitorEvaluate(@RequestBody QualityMonitorDetailsEvaluate qualityMonitorDetailsEvaluate) {
+        if (qualityMonitorTaskService.getTask(qualityMonitorDetailsEvaluate.getQualityMonitorDetailsId()) != null) {
+            throw new ErrorException("璐ㄩ噺鐩戞帶妫�楠岃瘎浠疯浣跨敤妫�楠岃瘎浠峰叆鍙�");
+        }
         return Result.success(qualityMonitorService.addQualityMonitorEvaluate(qualityMonitorDetailsEvaluate));
     }
 
@@ -231,6 +386,10 @@
     @Operation(summary = "鐩戞帶璇勪环鎵瑰噯鎰忚")
     @PostMapping("/addMonitorEvaluateOpinion")
     public Result addMonitorEvaluateOpinion(@RequestBody QualityMonitorDetailsEvaluate qualityMonitorDetailsEvaluate) {
+        QualityMonitorDetailsEvaluate stored = qualityMonitorDetailsEvaluateMapper.selectById(qualityMonitorDetailsEvaluate.getDetailsEvaluateId());
+        if (stored != null && qualityMonitorTaskService.getTask(stored.getQualityMonitorDetailsId()) != null) {
+            throw new ErrorException("璐ㄩ噺鐩戞帶妫�楠岃瘎浠疯浣跨敤妫�楠岃瘎浠峰鎵瑰叆鍙�");
+        }
         return Result.success(qualityMonitorService.addMonitorEvaluateOpinion(qualityMonitorDetailsEvaluate));
     }
 
@@ -279,6 +438,9 @@
     @Operation(summary = "涓婁紶鐩戞帶瀹屾垚鎶ュ憡")
     @PostMapping("/uploadFinishReport")
     public Result uploadFinishReport(MultipartFile file, Integer qualityMonitorDetailsId) {
+        if (qualityMonitorTaskService.getTask(qualityMonitorDetailsId) != null) {
+            throw new ErrorException("璐ㄩ噺鐩戞帶妫�楠屼换鍔℃棤闇�涓婁紶瀹屾垚鎶ュ憡");
+        }
         return Result.success(qualityMonitorService.uploadFinishReport(file, qualityMonitorDetailsId));
     }
 
@@ -290,6 +452,9 @@
     @Operation(summary = "鎵瑰噯瀹屾垚鎶ュ憡")
     @PostMapping("/ratifyFinishReport")
     public Result ratifyFinishReport(@RequestBody QualityMonitorDetails qualityMonitorDetails) {
+        if (qualityMonitorTaskService.getTask(qualityMonitorDetails.getQualityMonitorDetailsId()) != null) {
+            throw new ErrorException("璐ㄩ噺鐩戞帶妫�楠屼换鍔℃棤闇�鎵瑰噯瀹屾垚鎶ュ憡");
+        }
         return Result.success(qualityMonitorService.ratifyFinishReport(qualityMonitorDetails));
     }
 }

--
Gitblit v1.9.3