diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/controller/ImprovementProposalController.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/controller/ImprovementProposalController.java index cfdc25a..f70d08d 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/controller/ImprovementProposalController.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/controller/ImprovementProposalController.java @@ -27,6 +27,7 @@ import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.improvementproposal.entity.ImprovementDeptScore; import org.jeecg.modules.improvementproposal.entity.ImprovementInstituteVote; import org.jeecg.modules.improvementproposal.entity.ImprovementProposal; +import org.jeecg.modules.improvementproposal.dto.ImprovementProposalBpmActionDTO; import org.jeecg.modules.improvementproposal.vo.ImprovementProposalPage; import org.jeecg.modules.improvementproposal.service.IImprovementProposalService; import org.jeecg.modules.improvementproposal.service.IImprovementDeptScoreService; @@ -149,6 +150,48 @@ public class ImprovementProposalController { return Result.error(e.getMessage()); } } + + @PostMapping(value = "/bpm/initialReview") + @Operation(summary = "保存部门精益专员初审结果") + public Result saveInitialReview(@RequestBody ImprovementProposalBpmActionDTO action) { + return handleBpmAction(() -> improvementProposalService.saveInitialReview(action, currentUser())); + } + + @PostMapping(value = "/bpm/leaderAward") + @Operation(summary = "保存部门负责人确认奖项") + public Result saveLeaderAward(@RequestBody ImprovementProposalBpmActionDTO action) { + return handleBpmAction(() -> improvementProposalService.saveLeaderAward(action, currentUser())); + } + + @PostMapping(value = "/bpm/archiveAward") + @Operation(summary = "保存归档最终奖项") + public Result saveArchiveAward(@RequestBody ImprovementProposalBpmActionDTO action) { + return handleBpmAction(() -> improvementProposalService.saveArchiveAward(action, currentUser())); + } + + @PostMapping(value = "/bpm/instituteVote") + @Operation(summary = "记录所级评委投票") + public Result castInstituteVote(@RequestBody ImprovementProposalBpmActionDTO action) { + return handleBpmAction(() -> improvementProposalService.castInstituteVote(action, currentUser())); + } + + private LoginUser currentUser() { + return (LoginUser) SecurityUtils.getSubject().getPrincipal(); + } + + private Result handleBpmAction(BpmAction action) { + try { + action.run(); + return Result.OK("保存成功"); + } catch (IllegalStateException e) { + return Result.error(e.getMessage()); + } + } + + @FunctionalInterface + private interface BpmAction { + void run(); + } /** * 通过id删除 diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/dto/ImprovementProposalBpmActionDTO.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/dto/ImprovementProposalBpmActionDTO.java new file mode 100644 index 0000000..be088d3 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/dto/ImprovementProposalBpmActionDTO.java @@ -0,0 +1,38 @@ +package org.jeecg.modules.improvementproposal.dto; + +import java.io.Serializable; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 改善提案流程节点办理数据。 + * + *

节点由后端根据 taskId 校验,不允许客户端通过该对象指定节点或办理人。

+ */ +@Data +@Schema(description = "改善提案流程节点办理数据") +public class ImprovementProposalBpmActionDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @Schema(description = "改善提案主表ID") + private String mainId; + + @Schema(description = "流程实例ID") + private String processInstanceId; + + @Schema(description = "当前流程任务ID") + private String taskId; + + @Schema(description = "初步评定奖项:0金奖、1银奖、2铜奖、3参与奖") + private String initialAward; + + @Schema(description = "部门负责人确认奖项:0金奖、1银奖、2铜奖、3参与奖") + private String leaderFinalAward; + + @Schema(description = "归档最终奖项:0金奖、1银奖、2铜奖、3参与奖") + private String finalAward; + + @Schema(description = "投票结果:agree/disagree") + private String voteResult; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/entity/ImprovementProposal.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/entity/ImprovementProposal.java index 650146a..cf536df 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/entity/ImprovementProposal.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/entity/ImprovementProposal.java @@ -100,11 +100,11 @@ public class ImprovementProposal implements Serializable { @Excel(name = "部门精益专员初步评定奖项", width = 15) @Schema(description = "部门精益专员初步评定奖项") private String initialAward; - /**是否需要部门评议打分:Y/N*/ + /**是否需要部门评议打分:1需要,0不需要*/ @Excel(name = "是否需要部门评议打分:1/0", width = 15) @Schema(description = "是否需要部门评议打分:1/0") private String needDeptScore; - /**是否需要部门评议打分:Y/N*/ + /**是否需要所级评议投票:1需要,0不需要*/ @Excel(name = "是否需要所级评议小组投票:1/0", width = 15) @Schema(description = "是否需要所级评议小组投票:1/0") private String isneedvote; diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/service/IImprovementProposalService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/service/IImprovementProposalService.java index c3b4deb..33b1031 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/service/IImprovementProposalService.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/improvementproposal/service/IImprovementProposalService.java @@ -3,6 +3,8 @@ package org.jeecg.modules.improvementproposal.service; import org.jeecg.modules.improvementproposal.entity.ImprovementDeptScore; import org.jeecg.modules.improvementproposal.entity.ImprovementInstituteVote; import org.jeecg.modules.improvementproposal.entity.ImprovementProposal; +import org.jeecg.modules.improvementproposal.dto.ImprovementProposalBpmActionDTO; +import org.jeecg.common.system.vo.LoginUser; import com.baomidou.mybatisplus.extension.service.IService; import java.io.Serializable; import java.util.Collection; @@ -57,6 +59,18 @@ public interface IImprovementProposalService extends IService idList); + /** 保存部门精益专员初审结果,并写入部门评分网关变量。 */ + void saveInitialReview(ImprovementProposalBpmActionDTO action, LoginUser loginUser); + + /** 保存部门负责人确认奖项,并写入所级投票网关变量。 */ + void saveLeaderAward(ImprovementProposalBpmActionDTO action, LoginUser loginUser); + + /** 保存经办人归档确认的最终奖项。 */ + void saveArchiveAward(ImprovementProposalBpmActionDTO action, LoginUser loginUser); + + /** 记录当前所级评委的投票结果。 */ + void castInstituteVote(ImprovementProposalBpmActionDTO action, LoginUser loginUser); + /** * 获取指定年度最新提案编号中的XXXX部分 * @@ -64,5 +78,5 @@ public interface IImprovementProposalService extends IService loginUser.getId().equals(item.getVoterId())) + .findFirst() + .orElseThrow(() -> new IllegalStateException("当前用户不在所级评议投票名单中")); + if ("voted".equals(vote.getVoteStatus())) { + throw new IllegalStateException("您已完成投票,不能重复修改"); + } + int updated = improvementInstituteVoteMapper.update(null, new LambdaUpdateWrapper() + .eq(ImprovementInstituteVote::getId, vote.getId()) + .eq(ImprovementInstituteVote::getVoteStatus, "pending") + .set(ImprovementInstituteVote::getVoteResult, action.getVoteResult()) + .set(ImprovementInstituteVote::getVoteStatus, "voted") + .set(ImprovementInstituteVote::getVoteTime, new Date()) + .set(ImprovementInstituteVote::getProcessTaskId, action.getTaskId())); + if (updated != 1) { + throw new IllegalStateException("投票状态已变化,请刷新后重试"); + } + } + + private ImprovementProposal validateRunningTask(ImprovementProposalBpmActionDTO action, LoginUser loginUser, String expectedTaskDefKey) { + if (action == null || oConvertUtils.isEmpty(action.getMainId()) || oConvertUtils.isEmpty(action.getProcessInstanceId()) + || oConvertUtils.isEmpty(action.getTaskId())) { + throw new IllegalStateException("流程办理参数不完整"); + } + ImprovementProposal proposal = improvementProposalMapper.selectById(action.getMainId()); + if (proposal == null || !action.getProcessInstanceId().equals(proposal.getProcessInstanceId())) { + throw new IllegalStateException("提案与流程实例不匹配"); + } + Task task = taskService.createTaskQuery().taskId(action.getTaskId()).singleResult(); + if (task == null || !action.getProcessInstanceId().equals(task.getProcessInstanceId()) || !expectedTaskDefKey.equals(task.getTaskDefinitionKey())) { + throw new IllegalStateException("当前任务节点已变化,请刷新后重试"); + } + // 已签收任务必须由签收人操作;候选任务仍由通用办理接口在提交时执行权限校验。 + if (oConvertUtils.isNotEmpty(task.getAssignee()) && !loginUser.getUsername().equals(task.getAssignee())) { + throw new IllegalStateException("当前任务不属于登录用户"); + } + return proposal; + } + + private void validateAward(String award) { + if (!AWARD_GOLD.equals(award) && !AWARD_SILVER.equals(award) && !AWARD_BRONZE.equals(award) && !AWARD_PARTICIPATION.equals(award)) { + throw new IllegalStateException("请选择有效的奖项"); + } + } + + private boolean needsDeptScore(String award) { + return AWARD_GOLD.equals(award) || AWARD_SILVER.equals(award); + } + /** * 任何会改变主表生命周期的操作都必须先锁定并确认仍是未发起草稿, * 这样并发的“发起流程”和“编辑/删除”不会让流程与业务数据脱节。 @@ -178,11 +298,11 @@ public class ImprovementProposalServiceImpl extends ServiceImpl