From abd339106ed3a6465293edccd33e5f87bd43bdde Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 20 十月 2026 18:01:42 +0800
Subject: [PATCH] feat: 质量监控/人员培训对齐程序文件,体系文件控制附件格式放开
---
cnas-process/src/main/java/com/ruoyi/process/service/impl/QualityMonitorServiceImpl.java | 218 +++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 174 insertions(+), 44 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..b27630c 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);
+ }
+
/**
* 瀵煎叆鐩戞帶璁″垝
@@ -103,53 +211,25 @@
* @return
*/
@Override
- public boolean importQualityMonitor(MultipartFile file, QualityMonitor monitor) {
+ public QualityMonitor importQualityMonitor(MultipartFile file, QualityMonitor monitor) {
// 褰撳墠鐧诲綍鐢ㄦ埛
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("DRAFT");
baseMapper.insert(qualityMonitor);
-
- if (monitor.getExamineUserId() == null) {
- throw new ErrorException("缂哄皯瀹℃牳浜�");
- }
-
- User user = userMapper.selectById(userId);
- // 娑堟伅鍙戦��
- InformationNotification info = new InformationNotification();
- // 鍙戦�佷汉
- info.setCreateUser(user.getName());
- info.setMessageType("6");
- info.setTheme("CNAS璐ㄩ噺鐩戞帶璁″垝瀹℃牳閫氱煡");
- info.setContent(fileName + "璐ㄩ噺鐩戞帶璁″垝寰呭鏍�");
- info.setSenderId(userId);
- // 鎺ユ敹浜�
- info.setConsigneeId(monitor.getExamineUserId());
- info.setJumpPath(MenuJumpPathConstants.QUALITY_MONITOR);
- informationNotificationService.addInformationNotification(info);
-
- // 鍙戦�佷紒涓氬井淇¢�氱煡
- threadPoolTaskExecutor.execute(() -> {
- // 鏌ヨ鍙戦�佷汉
- User people = userMapper.selectById(monitor.getExamineUserId());
- String message = "";
- message += "CNAS璐ㄩ噺鐩戞帶璁″垝瀹℃牳閫氱煡";
- message += "\n璇峰幓杩囩▼瑕佹眰-璐ㄩ噺鐩戞帶璁″垝";
- message += "\n" + fileName + "璐ㄩ噺鐩戞帶璁″垝寰呭鏍�";
- //鍙戦�佷紒涓氬井淇℃秷鎭�氱煡
- try {
- WxCpUtils.inform(people.getAccount(), message, null);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- });
-
List<QualityMonitorDetails> detailsUploadList = new ArrayList<>();
@@ -159,14 +239,28 @@
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.setMonitorWay(normalizeMonitorWay(detailsUpload.getMonitorWay()));
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);
}
@@ -181,7 +275,21 @@
} catch (IOException e) {
throw new RuntimeException(e);
}
- return true;
+ return qualityMonitor;
+ }
+
+ /**
+ * 璐ㄦ帶鏂瑰紡缁熶竴鐢ㄢ�溿�佲�濆垎闅旓紝鍏煎瀵煎叆妯℃澘閲屽父瑙佺殑閫楀彿/鍒嗗彿鍐欐硶銆�
+ */
+ private String normalizeMonitorWay(String value) {
+ if (StringUtils.isBlank(value)) {
+ return value;
+ }
+ return java.util.Arrays.stream(value.split("[銆�,锛�;锛沒"))
+ .map(String::trim)
+ .filter(StringUtils::isNotBlank)
+ .distinct()
+ .collect(Collectors.joining("銆�"));
}
/**
@@ -191,8 +299,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 +318,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 +367,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;
}
@@ -513,7 +643,7 @@
try {
response.setContentType("application/msword");
String fileName = URLEncoder.encode(
- "璐ㄩ噺鐩戞帶瀹炴柦璁″垝", "UTF-8");
+ "璐ㄩ噺鎺у埗鎺柦", "UTF-8");
response.setHeader("Content-disposition",
"attachment;filename=" + fileName + ".docx");
OutputStream os = response.getOutputStream();
@@ -727,7 +857,7 @@
try {
response.setContentType("application/msword");
String fileName = URLEncoder.encode(
- "鐩戞帶璇勪环", "UTF-8");
+ "璐ㄩ噺鎺у埗璇勪环璁板綍", "UTF-8");
response.setHeader("Content-disposition",
"attachment;filename=" + fileName + ".docx");
OutputStream os = response.getOutputStream();
--
Gitblit v1.9.3