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/service/impl/QualityMonitorServiceImpl.java | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 153 insertions(+), 9 deletions(-)
diff --git a/cnas-process/src/main/java/com/ruoyi/process/service/impl/QualityMonitorServiceImpl.java b/cnas-process/src/main/java/com/ruoyi/process/service/impl/QualityMonitorServiceImpl.java
index a559f4b..bf60509 100644
--- a/cnas-process/src/main/java/com/ruoyi/process/service/impl/QualityMonitorServiceImpl.java
+++ b/cnas-process/src/main/java/com/ruoyi/process/service/impl/QualityMonitorServiceImpl.java
@@ -70,6 +70,9 @@
@Transactional(rollbackFor = Exception.class)
public class QualityMonitorServiceImpl extends ServiceImpl<QualityMonitorMapper, QualityMonitor> implements QualityMonitorService {
+ private static final Set<String> EDITABLE_PLAN_STATES = new HashSet<>(Arrays.asList(
+ "DRAFT", "REVIEW_REJECTED", "APPROVAL_REJECTED"));
+
@Resource
private QualityMonitorDetailsService qualityMonitorDetailsService;
@Resource
@@ -96,6 +99,111 @@
@Value("${wordUrl}")
private String wordUrl;
+ @Override
+ public QualityMonitorDto createAnnualPlan(QualityMonitor input) {
+ if (input == null || StringUtils.isBlank(input.getMonitorYear())
+ || !input.getMonitorYear().matches("\\d{4}")) {
+ throw new ErrorException("璇烽�夋嫨姝g‘鐨勮鍒掑勾搴�");
+ }
+ if (input.getExamineUserId() == null || userMapper.selectById(input.getExamineUserId()) == null) {
+ throw new ErrorException("璇烽�夋嫨鏈夋晥鐨勫鏍镐汉");
+ }
+ if (StringUtils.isBlank(input.getMonitorName())) {
+ throw new ErrorException("璇峰~鍐欒鍒掑悕绉�");
+ }
+ int userId = SecurityUtils.getUserId().intValue();
+ QualityMonitor plan = new QualityMonitor();
+ plan.setMonitorYear(input.getMonitorYear());
+ plan.setMonitorName(input.getMonitorName().trim());
+ plan.setWriteUserId(userId);
+ plan.setWriteTime(LocalDateTime.now());
+ plan.setExamineUserId(input.getExamineUserId());
+ plan.setWorkflowStatus("DRAFT");
+ baseMapper.insert(plan);
+ return baseMapper.selectPlanDtoById(plan.getQualityMonitorId());
+ }
+
+ @Override
+ public QualityMonitorDto getAnnualPlan(String monitorYear, Integer qualityMonitorId) {
+ QualityMonitor plan;
+ if (qualityMonitorId != null) {
+ plan = baseMapper.selectById(qualityMonitorId);
+ if (plan == null || (StringUtils.isNotBlank(monitorYear)
+ && !monitorYear.equals(plan.getMonitorYear()))) return null;
+ } else {
+ if (StringUtils.isBlank(monitorYear)) throw new ErrorException("璇烽�夋嫨璁″垝骞村害");
+ plan = baseMapper.selectOne(Wrappers.<QualityMonitor>lambdaQuery()
+ .eq(QualityMonitor::getMonitorYear, monitorYear)
+ .orderByDesc(QualityMonitor::getCreateTime, QualityMonitor::getQualityMonitorId)
+ .last("limit 1"));
+ }
+ return plan == null ? null : baseMapper.selectPlanDtoById(plan.getQualityMonitorId());
+ }
+
+ @Override
+ public boolean submitAnnualPlan(Integer qualityMonitorId) {
+ QualityMonitor plan = requirePlan(qualityMonitorId);
+ int current = SecurityUtils.getUserId().intValue();
+ if (!Integer.valueOf(current).equals(plan.getWriteUserId())) {
+ throw new ErrorException("鍙湁璁″垝缂栧埗浜哄彲浠ユ彁浜ゅ鏍�");
+ }
+ String state = effectiveStatus(plan);
+ if (!EDITABLE_PLAN_STATES.contains(state)) throw new ErrorException("褰撳墠璁″垝鐘舵�佷笉鑳芥彁浜ゅ鏍�");
+ if (qualityMonitorDetailsMapper.selectCount(Wrappers.<QualityMonitorDetails>lambdaQuery()
+ .eq(QualityMonitorDetails::getQualityMonitorId, qualityMonitorId)) == 0) {
+ throw new ErrorException("璇疯嚦灏戞柊澧炰竴鏉¤川鎺ч」鐩悗鍐嶆彁浜ゅ鏍�");
+ }
+ baseMapper.update(null, Wrappers.<QualityMonitor>lambdaUpdate()
+ .eq(QualityMonitor::getQualityMonitorId, qualityMonitorId)
+ .set(QualityMonitor::getWorkflowStatus, "PENDING_REVIEW")
+ .set(QualityMonitor::getExamineStatus, null)
+ .set(QualityMonitor::getExamineRemark, null)
+ .set(QualityMonitor::getRatifyStatus, null));
+ sendPlanNotice(plan, plan.getExamineUserId(), "CNAS璐ㄩ噺鐩戞帶璁″垝瀹℃牳閫氱煡", "璐ㄩ噺鐩戞帶璁″垝寰呭鏍�");
+ return true;
+ }
+
+ @Override
+ public void validateDetailEditable(Integer qualityMonitorId) {
+ QualityMonitor plan = requirePlan(qualityMonitorId);
+ if (!Integer.valueOf(SecurityUtils.getUserId().intValue()).equals(plan.getWriteUserId())) {
+ throw new ErrorException("鍙湁璁″垝缂栧埗浜哄彲浠ョ淮鎶よ川鎺ч」鐩�");
+ }
+ if (!EDITABLE_PLAN_STATES.contains(effectiveStatus(plan))) {
+ throw new ErrorException("褰撳墠璁″垝宸叉彁浜わ紝涓嶈兘淇敼璐ㄦ帶椤圭洰");
+ }
+ }
+
+ private QualityMonitor requirePlan(Integer id) {
+ QualityMonitor plan = id == null ? null : baseMapper.selectById(id);
+ if (plan == null) throw new ErrorException("骞村害璐ㄩ噺鎺у埗璁″垝涓嶅瓨鍦�");
+ return plan;
+ }
+
+ private String effectiveStatus(QualityMonitor plan) {
+ if (StringUtils.isNotBlank(plan.getWorkflowStatus())) return plan.getWorkflowStatus();
+ if (Integer.valueOf(1).equals(plan.getRatifyStatus())) return "APPROVED";
+ if (Integer.valueOf(0).equals(plan.getRatifyStatus())) return "APPROVAL_REJECTED";
+ if (Integer.valueOf(1).equals(plan.getExamineStatus())) return "PENDING_APPROVAL";
+ if (Integer.valueOf(0).equals(plan.getExamineStatus())) return "REVIEW_REJECTED";
+ return "DRAFT";
+ }
+
+ private void sendPlanNotice(QualityMonitor plan, Integer receiverId, String theme, String suffix) {
+ if (receiverId == null) return;
+ int sender = SecurityUtils.getUserId().intValue();
+ User senderUser = userMapper.selectById(sender);
+ InformationNotification info = new InformationNotification();
+ info.setCreateUser(senderUser == null ? "" : senderUser.getName());
+ info.setMessageType("6");
+ info.setTheme(theme);
+ info.setContent(plan.getMonitorName() + suffix);
+ info.setSenderId(sender);
+ info.setConsigneeId(receiverId);
+ info.setJumpPath(MenuJumpPathConstants.QUALITY_MONITOR);
+ informationNotificationService.addInformationNotification(info);
+ }
+
/**
* 瀵煎叆鐩戞帶璁″垝
@@ -108,17 +216,18 @@
Integer userId = SecurityUtils.getUserId().intValue();
// 鏂囦欢鍚嶇О
String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."));
+ if (monitor.getMonitorYear() == null || !monitor.getMonitorYear().matches("\\d{4}")) {
+ throw new ErrorException("璇烽�夋嫨姝g‘鐨勮鍒掑勾搴�");
+ }
+ if (monitor.getExamineUserId() == null) throw new ErrorException("缂哄皯瀹℃牳浜�");
QualityMonitor qualityMonitor = new QualityMonitor();
qualityMonitor.setMonitorName(fileName);
qualityMonitor.setMonitorYear(monitor.getMonitorYear());
qualityMonitor.setWriteUserId(userId);
qualityMonitor.setExamineUserId(monitor.getExamineUserId());
qualityMonitor.setWriteTime(LocalDateTime.now());
+ qualityMonitor.setWorkflowStatus("PENDING_REVIEW");
baseMapper.insert(qualityMonitor);
-
- if (monitor.getExamineUserId() == null) {
- throw new ErrorException("缂哄皯瀹℃牳浜�");
- }
User user = userMapper.selectById(userId);
// 娑堟伅鍙戦��
@@ -159,14 +268,27 @@
EasyExcel.read(file.getInputStream(), QualityMonitorDetailsUpload.class, new AnalysisEventListener<QualityMonitorDetailsUpload>() {
@Override
public void invoke(QualityMonitorDetailsUpload detailsUpload, AnalysisContext analysisContext) {
- // 鍒ゆ柇鏄惁涓虹┖
- if (StringUtils.isBlank(detailsUpload.getPlannedTime())) {
- throw new ErrorException("璁″垝寮�灞曟椂闂翠笉鑳戒负绌�");
+ if (StringUtils.isBlank(detailsUpload.getMonitorProject())
+ || StringUtils.isBlank(detailsUpload.getTechnicalStandardText())
+ || StringUtils.isBlank(detailsUpload.getMonitorWay())
+ || StringUtils.isBlank(detailsUpload.getCompletionMonth())) {
+ throw new ErrorException("璐ㄦ帶椤圭洰銆佹妧鏈爣鍑嗐�佽川鎺ф柟寮忓拰瀹屾垚鏃堕檺涓嶈兘涓虹┖");
}
// 瀵硅薄澶嶅埗
QualityMonitorDetails monitorDetails = new QualityMonitorDetails();
BeanUtils.copyProperties(detailsUpload, monitorDetails);
monitorDetails.setQualityMonitorId(qualityMonitor.getQualityMonitorId());
+ if (!detailsUpload.getCompletionMonth().matches("\\d{4}-\\d{2}")) {
+ throw new ErrorException("瀹屾垚鏃堕檺鏍煎紡搴斾负yyyy-MM");
+ }
+ if (StringUtils.isBlank(detailsUpload.getResponsibleName())) {
+ throw new ErrorException("璐熻矗浜轰笉鑳戒负绌�");
+ }
+ List<User> users = userMapper.selectList(Wrappers.<User>lambdaQuery()
+ .eq(User::getName, detailsUpload.getResponsibleName()));
+ if (users.size() != 1) throw new ErrorException("璐熻矗浜哄鍚嶄笉瀛樺湪鎴栦笉鍞竴锛�" + detailsUpload.getResponsibleName());
+ monitorDetails.setResponsibleUserId(users.get(0).getId());
+ monitorDetails.setItemKind("OTHER");
detailsUploadList.add(monitorDetails);
}
@@ -191,8 +313,16 @@
*/
@Override
public boolean examineQualityMonitor(QualityMonitor qualityMonitor) {
- if (qualityMonitor.getRatifyUserId() == null) {
- throw new ErrorException("缂哄皯鎵瑰噯浜�");
+ QualityMonitor stored = requirePlan(qualityMonitor.getQualityMonitorId());
+ int current = SecurityUtils.getUserId().intValue();
+ if (!Integer.valueOf(current).equals(stored.getExamineUserId())) {
+ throw new ErrorException("鍙湁鎸囧畾瀹℃牳浜哄彲浠ュ鏍歌鍒�");
+ }
+ if (!"PENDING_REVIEW".equals(effectiveStatus(stored))) {
+ throw new ErrorException("褰撳墠璁″垝涓嶅湪寰呭鏍哥姸鎬�");
+ }
+ if (Integer.valueOf(1).equals(qualityMonitor.getExamineStatus()) && qualityMonitor.getRatifyUserId() == null) {
+ throw new ErrorException("瀹℃牳閫氳繃鏃跺繀椤绘寚瀹氭壒鍑嗕汉");
}
// 褰撳墠鐧诲綍鐢ㄦ埛
@@ -202,7 +332,11 @@
.set(QualityMonitor::getExamineRemark, qualityMonitor.getExamineRemark())
.set(QualityMonitor::getExamineStatus, qualityMonitor.getExamineStatus())
.set(QualityMonitor::getExamineTime, LocalDateTime.now())
+ .set(QualityMonitor::getWorkflowStatus,
+ Integer.valueOf(1).equals(qualityMonitor.getExamineStatus()) ? "PENDING_APPROVAL" : "REVIEW_REJECTED")
);
+
+ if (!Integer.valueOf(1).equals(qualityMonitor.getExamineStatus())) return true;
QualityMonitor monitor = baseMapper.selectById(qualityMonitor.getQualityMonitorId());
@@ -247,12 +381,22 @@
*/
@Override
public boolean ratifyQualityMonitor(QualityMonitor qualityMonitor) {
+ QualityMonitor stored = requirePlan(qualityMonitor.getQualityMonitorId());
+ int current = SecurityUtils.getUserId().intValue();
+ if (!Integer.valueOf(current).equals(stored.getRatifyUserId())) {
+ throw new ErrorException("鍙湁鎸囧畾鎵瑰噯浜哄彲浠ユ壒鍑嗚鍒�");
+ }
+ if (!"PENDING_APPROVAL".equals(effectiveStatus(stored))) {
+ throw new ErrorException("褰撳墠璁″垝涓嶅湪寰呮壒鍑嗙姸鎬�");
+ }
// 褰撳墠鐧诲綍鐢ㄦ埛
baseMapper.update(null, Wrappers.<QualityMonitor>lambdaUpdate()
.eq(QualityMonitor::getQualityMonitorId, qualityMonitor.getQualityMonitorId())
.set(QualityMonitor::getRatifyRemark, qualityMonitor.getRatifyRemark())
.set(QualityMonitor::getRatifyStatus, qualityMonitor.getRatifyStatus())
.set(QualityMonitor::getRatifyTime, LocalDateTime.now())
+ .set(QualityMonitor::getWorkflowStatus,
+ Integer.valueOf(1).equals(qualityMonitor.getRatifyStatus()) ? "APPROVED" : "APPROVAL_REJECTED")
);
return true;
}
--
Gitblit v1.9.3