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 7ce05cf..16af363 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 @@ -225,6 +225,12 @@ public class ImprovementProposalController { return handleBpmAction(() -> improvementProposalService.castInstituteVote(action, currentUser())); } + @PostMapping(value = "/bpm/submitInstituteVote") + @Operation(summary = "锁定所级评委投票并汇总结果") + public Result submitInstituteVote(@RequestBody ImprovementProposalBpmActionDTO action) { + return handleBpmAction(() -> improvementProposalService.submitInstituteVote(action, currentUser())); + } + private LoginUser currentUser() { return (LoginUser) SecurityUtils.getSubject().getPrincipal(); } 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 cf41ad1..fa800f1 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 @@ -88,6 +88,9 @@ public interface IImprovementProposalService extends IService loginUser.getId().equals(item.getVoterId())) - .findFirst() - .orElseThrow(() -> new IllegalStateException("当前用户不在所级评议投票名单中")); + ImprovementInstituteVote vote = findInstituteVote(proposal.getId(), loginUser.getId()); if ("voted".equals(vote.getVoteStatus())) { - throw new IllegalStateException("您已完成投票,不能重复修改"); + 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::getVoteTime, null) .set(ImprovementInstituteVote::getProcessTaskId, action.getTaskId())); if (updated != 1) { throw new IllegalStateException("投票状态已变化,请刷新后重试"); } } + @Override + @Transactional(rollbackFor = Exception.class) + public void submitInstituteVote(ImprovementProposalBpmActionDTO action, LoginUser loginUser) { + ImprovementProposal proposal = validateRunningTask(action, loginUser, TASK_INSTITUTE_VOTE); + ImprovementProposal lockedProposal = improvementProposalMapper.selectByIdForUpdate(proposal.getId()); + if (lockedProposal == null || !action.getProcessInstanceId().equals(lockedProposal.getProcessInstanceId())) { + throw new IllegalStateException("提案流程状态已变化,请刷新后重试"); + } + ImprovementInstituteVote vote = findInstituteVote(lockedProposal.getId(), loginUser.getId()); + if (!"voted".equals(vote.getVoteStatus())) { + if (!"agree".equals(vote.getVoteResult()) && !"disagree".equals(vote.getVoteResult())) { + throw new IllegalStateException("请先选择投票通过或投票反对"); + } + int updated = improvementInstituteVoteMapper.update(null, new LambdaUpdateWrapper() + .eq(ImprovementInstituteVote::getId, vote.getId()) + .eq(ImprovementInstituteVote::getVoteStatus, "pending") + .set(ImprovementInstituteVote::getVoteStatus, "voted") + .set(ImprovementInstituteVote::getVoteTime, new Date()) + .set(ImprovementInstituteVote::getProcessTaskId, action.getTaskId())); + if (updated != 1) { + throw new IllegalStateException("投票状态已变化,请刷新后重试"); + } + } + updateInstituteVoteSummaryIfComplete(lockedProposal, action.getProcessInstanceId()); + } + + private ImprovementInstituteVote findInstituteVote(String mainId, String voterId) { + return improvementInstituteVoteMapper.selectByMainId(mainId).stream() + .filter(item -> voterId.equals(item.getVoterId())) + .findFirst() + .orElseThrow(() -> new IllegalStateException("当前用户不在所级评议投票名单中")); + } + + /** + * 所级评议以名单确定时写入的应投票人数为分母。赞成票满足 agree * 3 >= total * 2 即通过,避免小数取整歧义。 + */ + private void updateInstituteVoteSummaryIfComplete(ImprovementProposal proposal, String processInstanceId) { + Integer totalVoters = proposal.getInstituteTotalVoters(); + if (totalVoters == null || totalVoters <= 0) { + throw new IllegalStateException("所级评议应投票人数未初始化"); + } + List votes = improvementInstituteVoteMapper.selectByMainId(proposal.getId()); + if (votes.size() != totalVoters) { + throw new IllegalStateException("所级评议投票名单与应投票人数不一致"); + } + if (votes.stream().anyMatch(item -> !"voted".equals(item.getVoteStatus()))) { + return; + } + long agreeCount = votes.stream().filter(item -> "agree".equals(item.getVoteResult())).count(); + long disagreeCount = votes.stream().filter(item -> "disagree".equals(item.getVoteResult())).count(); + if (agreeCount + disagreeCount != totalVoters) { + throw new IllegalStateException("所级评议投票结果不完整"); + } + String voteResult = agreeCount * 3 >= (long) totalVoters * 2 ? "passed" : "failed"; + ImprovementProposal update = new ImprovementProposal(); + update.setId(proposal.getId()); + update.setInstituteAgreeCount((int) agreeCount); + update.setInstituteDisagreeCount((int) disagreeCount); + update.setInstituteVoteResult(voteResult); + improvementProposalMapper.updateById(update); + runtimeService.setVariable(processInstanceId, "institute_vote_result", voteResult); + } + /** * 固定按角色编码读取名单,保存时再次查询以防前端伪造用户 ID 或角色配置已变更。 */