From 0da38080ca294328bda11c33cd2845b89b882be8 Mon Sep 17 00:00:00 2001 From: funny <834502597@qq.com> Date: Wed, 29 Apr 2026 16:38:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(qms):=20=E5=AE=8C=E5=96=84=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E5=A4=84=E7=90=86=E6=B5=81=E7=A8=8B=E5=8F=8A=E9=A2=86?= =?UTF-8?q?=E5=AF=BC=E5=AE=A1=E6=89=B9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 异步新增工单处理时推送待办消息,整合新增及推送操作 - 新增领导暂存与提交接口及对应服务方法,支持领导审批逻辑 - 提交工单处理时校验审批状态,支持根据审批结果推送待办 - 领导提交工单处理时校验审批结果,支持驳回和同意两种流程 - 同意领导审批时,自动检测工单所有处理记录完成状态,更新工单状态 - 领导暂存时保存审批意见和审批结果,写入领导用户信息 - 检测任务完成时增加是否延期状态标记 - 删除冗余同步推送待办代码,优化代码结构 --- .../QmsIssueTicketProcessController.java | 19 +++ .../QmsIssueTicketControllerService.java | 19 +-- ...msIssueTicketProcessControllerService.java | 149 +++++++++++++++++- ...TicketProcessMeasureControllerService.java | 21 +++ ...PdiInspectionResultsControllerService.java | 5 +- .../QmsIssueTicketProcessLeaderDraftQO.java | 27 ++++ 6 files changed, 217 insertions(+), 23 deletions(-) create mode 100644 nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsIssueTicketProcessLeaderDraftQO.java diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsIssueTicketProcessController.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsIssueTicketProcessController.java index e5804e86..88cc218d 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsIssueTicketProcessController.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsIssueTicketProcessController.java @@ -5,6 +5,7 @@ import com.nflg.qms.admin.service.QmsIssueTicketProcessMeasureControllerService; import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessAddQO; import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessDraftQO; +import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessLeaderDraftQO; import com.nflg.wms.starter.BaseController; import jakarta.annotation.Resource; import jakarta.validation.Valid; @@ -52,4 +53,22 @@ public class QmsIssueTicketProcessController extends BaseController { issueTicketProcessControllerService.submit(request); return ApiResult.success(); } + + /** + * 领导暂存工单处理 + */ + @PostMapping("leaderDraft") + public ApiResult leaderDraft(@Valid @RequestBody QmsIssueTicketProcessLeaderDraftQO request) { + issueTicketProcessMeasureControllerService.leaderDraft(request); + return ApiResult.success(); + } + + /** + * 领导提交工单处理 + */ + @PostMapping("leaderSubmit") + public ApiResult leaderSubmit(@Valid @RequestBody QmsIssueTicketProcessLeaderDraftQO request) { + issueTicketProcessControllerService.leaderSubmit(request); + return ApiResult.success(); + } } diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketControllerService.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketControllerService.java index 1783c06d..128e57cb 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketControllerService.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketControllerService.java @@ -208,26 +208,13 @@ public class QmsIssueTicketControllerService { issueTicketService.save(entity); - // 异步新增工单处理记录 + // 异步新增工单处理记录并推送待办 issueTicketProcessControllerService.addAsync( entity.getId(), request.getHandlerUserId(), - request.getInspectionResultIds() + request.getInspectionResultIds(), + ticketNo ); - - // 推送待办消息 - Long sourceTypeId = dictionaryItemService.getIdByCode("MessageType", "PDIDefectiveProductHandling"); - VUtil.trueThrowBusinessError(Objects.isNull(sourceTypeId)).throwMessage("消息类型不存在"); - User handlerUser = userService.getById(request.getHandlerUserId()); - QmsTodoItem todoItem = new QmsTodoItem() - .setCode(ticketNo) - .setIsRead(false) - .setSourceTypeId(sourceTypeId) - .setSourceId(entity.getId()) - .setCreateUserId(request.getHandlerUserId()) - .setCreateUserName(handlerUser != null ? handlerUser.getUserName() : userName) - .setCreateTime(now); - todoItemService.save(todoItem); } /** diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketProcessControllerService.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketProcessControllerService.java index 0edfe3c7..ae3fe98c 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketProcessControllerService.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketProcessControllerService.java @@ -4,9 +4,16 @@ import com.nflg.wms.common.constant.STATE; import com.nflg.wms.common.exception.NflgException; import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessAddQO; import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessDraftQO; +import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessLeaderDraftQO; +import com.nflg.wms.common.util.VUtil; +import com.nflg.wms.repository.entity.QmsIssueTicket; import com.nflg.wms.repository.entity.QmsIssueTicketProcess; +import com.nflg.wms.repository.entity.QmsTodoItem; import com.nflg.wms.repository.entity.User; +import com.nflg.wms.repository.service.IDictionaryItemService; import com.nflg.wms.repository.service.IQmsIssueTicketProcessService; +import com.nflg.wms.repository.service.IQmsIssueTicketService; +import com.nflg.wms.repository.service.IQmsTodoItemService; import com.nflg.wms.repository.service.IUserService; import jakarta.annotation.Resource; import jakarta.validation.Valid; @@ -14,7 +21,9 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; /** @@ -32,6 +41,15 @@ public class QmsIssueTicketProcessControllerService { @Resource private QmsIssueTicketProcessMeasureControllerService issueTicketProcessMeasureControllerService; + @Resource + private IQmsIssueTicketService issueTicketService; + + @Resource + private IQmsTodoItemService todoItemService; + + @Resource + private IDictionaryItemService dictionaryItemService; + /** * 新增工单处理(同步,供 Controller 直接调用) */ @@ -40,14 +58,27 @@ public class QmsIssueTicketProcessControllerService { } /** - * 异步新增工单处理(供内部服务调用) + * 异步新增工单处理并推送待办(供内部服务调用) */ @Async("ticketTaskExecutor") - public void addAsync(Long issueTicketId, Long handlerUserId, List taskResultIds) { - doAdd(issueTicketId, handlerUserId, taskResultIds); + public void addAsync(Long issueTicketId, Long handlerUserId, List taskResultIds, String ticketNo) { + Long processId = doAdd(issueTicketId, handlerUserId, taskResultIds); + + // 推送待办消息 + Long sourceTypeId = dictionaryItemService.getIdByCode("MessageType", "PDIDefectiveProductHandling"); + User handlerUser = userService.getById(handlerUserId); + QmsTodoItem todoItem = new QmsTodoItem() + .setCode(ticketNo) + .setIsRead(false) + .setSourceTypeId(sourceTypeId) + .setSourceId(processId) + .setCreateUserId(handlerUserId) + .setCreateUserName(handlerUser != null ? handlerUser.getUserName() : null) + .setCreateTime(LocalDateTime.now()); + todoItemService.save(todoItem); } - private void doAdd(Long issueTicketId, Long handlerUserId, List taskResultIds) { + private Long doAdd(Long issueTicketId, Long handlerUserId, List taskResultIds) { User user = userService.getById(handlerUserId); if (user == null) { throw new NflgException(STATE.BusinessError, "处理人用户不存在"); @@ -62,14 +93,120 @@ public class QmsIssueTicketProcessControllerService { .collect(Collectors.joining(","))); issueTicketProcessService.save(entity); + return entity.getId(); } /** - * 提交工单处理:更新工单处理记录,有措施内容则新增一条措施记录 - * TODO: 后续补充推送到下一级的逻辑 + * 提交工单处理: + * 1. 校验 approvalStatus 必传 + * 2. 执行保存逻辑(复用 draft) + * 3. approvalStatus=1(驳回):推送待办给工单创建人 + * 4. approvalStatus=0(通过):推送给当前用户所在部门负责人(TODO: 部门负责人字段暂无,后续补充) */ @Transactional(rollbackFor = Exception.class) public void submit(@Valid QmsIssueTicketProcessDraftQO request) { + // 1. 校验审批状态必传 + VUtil.trueThrowBusinessError(Objects.isNull(request.getApprovalStatus())) + .throwMessage("提交时审批状态不能为空"); + + // 2. 保存数据 issueTicketProcessMeasureControllerService.draft(request); + + // 3. 查询工单处理记录,获取关联的工单 + QmsIssueTicketProcess process = issueTicketProcessService.getById(request.getId()); + QmsIssueTicket ticket = issueTicketService.getById(process.getIssueTicketId()); + VUtil.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("关联的质量问题工单不存在"); + + Long sourceTypeId = dictionaryItemService.getIdByCode("MessageType", "RejectedPDIDefectiveProductHandling"); + LocalDateTime now = LocalDateTime.now(); + + if (request.getApprovalStatus() == 1) { + // 驳回:推送待办给工单创建人(分配任务的user) + User creator = userService.getById(ticket.getCreateUserId()); + QmsTodoItem todoItem = new QmsTodoItem() + .setCode(ticket.getTicketNo()) + .setIsRead(false) + .setSourceTypeId(sourceTypeId) + .setSourceId(process.getId()) + .setCreateUserId(ticket.getCreateUserId()) + .setCreateUserName(creator != null ? creator.getUserName() : null) + .setCreateTime(now); + todoItemService.save(todoItem); + } else if (request.getApprovalStatus() == 0) { + // 通过:推送给当前用户所在部门负责人 + // TODO: Department 表暂无负责人字段,后续补充 + } + } + + /** + * 领导提交工单处理: + * 1. 校验 leaderApprovalResult 必传 + * 2. 执行保存逻辑(复用 leaderDraft)+ 写入审批时间 + * 3. leaderApprovalResult=0(驳回):推送待办给处理人 + * 4. leaderApprovalResult=1(同意):结束流程 + */ + @Transactional(rollbackFor = Exception.class) + public void leaderSubmit(@Valid QmsIssueTicketProcessLeaderDraftQO request) { + // 1. 校验领导审批结果必传 + VUtil.trueThrowBusinessError(Objects.isNull(request.getLeaderApprovalResult())) + .throwMessage("提交时领导审批结果不能为空"); + + // 2. 保存数据 + issueTicketProcessMeasureControllerService.leaderDraft(request); + + // 3. 写入领导审批时间 + LocalDateTime now = LocalDateTime.now(); + issueTicketProcessService.lambdaUpdate() + .eq(QmsIssueTicketProcess::getId, request.getId()) + .set(QmsIssueTicketProcess::getLeaderApprovalTime, now) + .update(); + + if (request.getLeaderApprovalResult() == 0) { + // 驳回:推送待办给处理人 + QmsIssueTicketProcess process = issueTicketProcessService.getById(request.getId()); + QmsIssueTicket ticket = issueTicketService.getById(process.getIssueTicketId()); + VUtil.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("关联的质量问题工单不存在"); + + Long sourceTypeId = dictionaryItemService.getIdByCode("MessageType", "RejectedPDIDefectiveProductHandling"); + User handler = userService.getById(process.getHandlerUserId()); + QmsTodoItem todoItem = new QmsTodoItem() + .setCode(ticket.getTicketNo()) + .setIsRead(false) + .setSourceTypeId(sourceTypeId) + .setSourceId(process.getId()) + .setCreateUserId(process.getHandlerUserId()) + .setCreateUserName(handler != null ? handler.getUserName() : null) + .setCreateTime(now); + todoItemService.save(todoItem); + } else if (request.getLeaderApprovalResult() == 1) { + // 同意:检查同一工单下所有处理记录是否都已完成 + QmsIssueTicketProcess current = issueTicketProcessService.getById(request.getId()); + Long issueTicketId = current.getIssueTicketId(); + + // 查询同一工单下是否存在未完成的记录 + // 完成条件:leaderApprovalResult=1 或(leaderApprovalResult为空 且 approvalStatus=1) + // 未完成:不满足以上任一条件的记录 + long notCompleted = issueTicketProcessService.lambdaQuery() + .eq(QmsIssueTicketProcess::getIssueTicketId, issueTicketId) + .and(w -> w + // 排除 leaderApprovalResult=1 的(已完成) + .ne(true, QmsIssueTicketProcess::getLeaderApprovalResult, (short) 1) + .or() + .isNull(QmsIssueTicketProcess::getLeaderApprovalResult)) + // 在 leaderApprovalResult 不为1的记录中,排除 approvalStatus=1 的(处理人驳回,也算完成) + .and(w -> w + .ne(true, QmsIssueTicketProcess::getApprovalStatus, (short) 1) + .or() + .isNull(QmsIssueTicketProcess::getApprovalStatus)) + .count(); + + if (notCompleted == 0) { + // 所有处理记录都已完成,更新工单状态为已完成(2) + issueTicketService.lambdaUpdate() + .eq(QmsIssueTicket::getId, issueTicketId) + .set(QmsIssueTicket::getStatus, (short) 2) + .update(); + } + } } } diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketProcessMeasureControllerService.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketProcessMeasureControllerService.java index 1ae0a983..78de40a8 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketProcessMeasureControllerService.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketProcessMeasureControllerService.java @@ -2,6 +2,8 @@ package com.nflg.qms.admin.service; import cn.hutool.core.util.StrUtil; import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessDraftQO; +import com.nflg.wms.common.pojo.qo.QmsIssueTicketProcessLeaderDraftQO; +import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.common.util.VUtil; import com.nflg.wms.repository.entity.QmsIssueTicketProcess; import com.nflg.wms.repository.entity.QmsIssueTicketProcessMeasure; @@ -51,4 +53,23 @@ public class QmsIssueTicketProcessMeasureControllerService { issueTicketProcessMeasureService.save(measure); } } + + /** + * 领导暂存:更新领导审批意见、审批结果,写入领导信息 + */ + @Transactional(rollbackFor = Exception.class) + public void leaderDraft(@Valid QmsIssueTicketProcessLeaderDraftQO request) { + QmsIssueTicketProcess process = issueTicketProcessService.getById(request.getId()); + VUtil.trueThrowBusinessError(Objects.isNull(process)).throwMessage("工单处理记录不存在"); + + issueTicketProcessService.lambdaUpdate() + .eq(QmsIssueTicketProcess::getId, request.getId()) + .set(request.getLeaderApprovalOpinion() != null, + QmsIssueTicketProcess::getLeaderApprovalOpinion, request.getLeaderApprovalOpinion()) + .set(request.getLeaderApprovalResult() != null, + QmsIssueTicketProcess::getLeaderApprovalResult, request.getLeaderApprovalResult()) + .set(QmsIssueTicketProcess::getLeaderUserId, UserUtil.getUserId()) + .set(QmsIssueTicketProcess::getLeaderUserName, UserUtil.getUserName()) + .update(); + } } diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPdiInspectionResultsControllerService.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPdiInspectionResultsControllerService.java index d543088d..de533e08 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPdiInspectionResultsControllerService.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPdiInspectionResultsControllerService.java @@ -192,10 +192,13 @@ public class QmsPdiInspectionResultsControllerService { request.getOverallResult() != null && request.getOverallResult()) .update(); - // 5. 设置检测完成时间,状态改为已完成 + // 5. 设置检测完成时间、是否延期、状态改为已完成 + boolean overdue = taskRecord.getRequiredCompletionTime() != null + && now.isAfter(taskRecord.getRequiredCompletionTime()); taskRecordService.lambdaUpdate() .eq(QmsPdiTaskRecord::getId, taskRecord.getId()) .set(QmsPdiTaskRecord::getDetectionCompletionTime, now) + .set(QmsPdiTaskRecord::getOverdue, overdue) .set(QmsPdiTaskRecord::getInspectionEnable, 2) .update(); diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsIssueTicketProcessLeaderDraftQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsIssueTicketProcessLeaderDraftQO.java new file mode 100644 index 00000000..f53dbfc4 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsIssueTicketProcessLeaderDraftQO.java @@ -0,0 +1,27 @@ +package com.nflg.wms.common.pojo.qo; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 质量问题工单处理 领导暂存/提交参数 + */ +@Data +public class QmsIssueTicketProcessLeaderDraftQO { + + /** + * 工单处理ID(QmsIssueTicketProcess.ID) + */ + @NotNull(message = "工单处理ID不能为空") + private Long id; + + /** + * 领导审批意见(可选) + */ + private String leaderApprovalOpinion; + + /** + * 领导审批结果(可选):0=驳回,1=同意 + */ + private Short leaderApprovalResult; +}