Merge branch 'refs/heads/master' into wsq-20260727
This commit is contained in:
+56
@@ -27,6 +27,8 @@ 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.ImprovementDeptScoreBpmDTO;
|
||||
import org.jeecg.modules.improvementproposal.dto.ImprovementInstituteVoteCandidateDTO;
|
||||
import org.jeecg.modules.improvementproposal.dto.ImprovementProposalBpmActionDTO;
|
||||
import org.jeecg.modules.improvementproposal.vo.ImprovementProposalPage;
|
||||
import org.jeecg.modules.improvementproposal.service.IImprovementProposalService;
|
||||
@@ -157,12 +159,60 @@ public class ImprovementProposalController {
|
||||
return handleBpmAction(() -> improvementProposalService.saveInitialReview(action, currentUser()));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/bpm/myDeptScore")
|
||||
@Operation(summary = "查询当前部门评委个人评分")
|
||||
public Result<ImprovementDeptScore> getMyDeptScore(@RequestParam String mainId, @RequestParam String processInstanceId,
|
||||
@RequestParam String taskId) {
|
||||
ImprovementProposalBpmActionDTO action = new ImprovementProposalBpmActionDTO();
|
||||
action.setMainId(mainId);
|
||||
action.setProcessInstanceId(processInstanceId);
|
||||
action.setTaskId(taskId);
|
||||
try {
|
||||
return Result.OK(improvementProposalService.getMyDeptScore(action, currentUser()));
|
||||
} catch (IllegalStateException e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value = "/bpm/deptScore")
|
||||
@Operation(summary = "保存当前部门评委个人评分草稿")
|
||||
public Result<String> saveDeptScore(@RequestBody ImprovementDeptScoreBpmDTO score) {
|
||||
return handleBpmAction(() -> improvementProposalService.saveDeptScore(score, currentUser()));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/bpm/submitDeptScore")
|
||||
@Operation(summary = "锁定当前部门评委个人评分")
|
||||
public Result<String> submitDeptScore(@RequestBody ImprovementProposalBpmActionDTO action) {
|
||||
return handleBpmAction(() -> improvementProposalService.submitDeptScore(action, currentUser()));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/bpm/leaderAward")
|
||||
@Operation(summary = "保存部门负责人确认奖项")
|
||||
public Result<String> saveLeaderAward(@RequestBody ImprovementProposalBpmActionDTO action) {
|
||||
return handleBpmAction(() -> improvementProposalService.saveLeaderAward(action, currentUser()));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/bpm/instituteVoteCandidates")
|
||||
@Operation(summary = "查询所级评议投票候选人")
|
||||
public Result<List<ImprovementInstituteVoteCandidateDTO>> getInstituteVoteCandidates(@RequestParam String mainId,
|
||||
@RequestParam String processInstanceId, @RequestParam String taskId) {
|
||||
ImprovementProposalBpmActionDTO action = new ImprovementProposalBpmActionDTO();
|
||||
action.setMainId(mainId);
|
||||
action.setProcessInstanceId(processInstanceId);
|
||||
action.setTaskId(taskId);
|
||||
try {
|
||||
return Result.OK(improvementProposalService.getInstituteVoteCandidates(action, currentUser()));
|
||||
} catch (IllegalStateException e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value = "/bpm/instituteVoteMembers")
|
||||
@Operation(summary = "保存所级评议投票人员")
|
||||
public Result<String> saveInstituteVoteMembers(@RequestBody ImprovementProposalBpmActionDTO action) {
|
||||
return handleBpmAction(() -> improvementProposalService.saveInstituteVoteMembers(action, currentUser()));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/bpm/archiveAward")
|
||||
@Operation(summary = "保存归档最终奖项")
|
||||
public Result<String> saveArchiveAward(@RequestBody ImprovementProposalBpmActionDTO action) {
|
||||
@@ -175,6 +225,12 @@ public class ImprovementProposalController {
|
||||
return handleBpmAction(() -> improvementProposalService.castInstituteVote(action, currentUser()));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/bpm/submitInstituteVote")
|
||||
@Operation(summary = "确认所级评委投票并直接完成流程任务")
|
||||
public Result<String> submitInstituteVote(@RequestBody ImprovementProposalBpmActionDTO action, HttpServletRequest request) {
|
||||
return handleBpmAction(() -> improvementProposalService.submitInstituteVoteAndComplete(action, currentUser(), request));
|
||||
}
|
||||
|
||||
private LoginUser currentUser() {
|
||||
return (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
}
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package org.jeecg.modules.improvementproposal.dto;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 部门评议评委提交个人评分时使用的流程节点参数。
|
||||
*/
|
||||
@Data
|
||||
public class ImprovementDeptScoreBpmDTO {
|
||||
|
||||
@Schema(description = "改善提案主表ID")
|
||||
private String mainId;
|
||||
|
||||
@Schema(description = "流程实例ID")
|
||||
private String processInstanceId;
|
||||
|
||||
@Schema(description = "当前流程任务ID")
|
||||
private String taskId;
|
||||
|
||||
@Schema(description = "安全得分,0-100")
|
||||
private BigDecimal safetyScore;
|
||||
|
||||
@Schema(description = "质量得分,0-100")
|
||||
private BigDecimal qualityScore;
|
||||
|
||||
@Schema(description = "效率得分,0-100")
|
||||
private BigDecimal efficiencyScore;
|
||||
|
||||
@Schema(description = "成本得分,0-100")
|
||||
private BigDecimal costScore;
|
||||
|
||||
@Schema(description = "可推广度得分,0-100")
|
||||
private BigDecimal promotionScore;
|
||||
|
||||
@Schema(description = "独创性得分,0-100")
|
||||
private BigDecimal originalityScore;
|
||||
|
||||
@Schema(description = "努力度得分,0-100")
|
||||
private BigDecimal effortScore;
|
||||
|
||||
@Schema(description = "评分意见")
|
||||
private String scoreOpinion;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package org.jeecg.modules.improvementproposal.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 所级评议投票候选人。
|
||||
* 仅暴露名单选择和 Flowable 多实例所需的最小用户信息。
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "所级评议投票候选人")
|
||||
public class ImprovementInstituteVoteCandidateDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "用户ID")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "登录用户名")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "真实姓名")
|
||||
private String realname;
|
||||
}
|
||||
+8
@@ -1,6 +1,7 @@
|
||||
package org.jeecg.modules.improvementproposal.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -35,4 +36,11 @@ public class ImprovementProposalBpmActionDTO implements Serializable {
|
||||
|
||||
@Schema(description = "投票结果:agree/disagree")
|
||||
private String voteResult;
|
||||
|
||||
/**
|
||||
* 精益管理部门经办人在所级评议节点选择的投票人 ID 列表。
|
||||
* 服务端会按固定角色重新校验该列表,不能将其作为投票人身份的信任来源。
|
||||
*/
|
||||
@Schema(description = "所级评议投票人ID列表")
|
||||
private List<String> voterIds;
|
||||
}
|
||||
|
||||
+16
@@ -50,6 +50,22 @@ public class ImprovementDeptScore implements Serializable {
|
||||
@Excel(name = "评分状态:pending/completed", width = 15)
|
||||
@Schema(description = "评分状态:pending/completed")
|
||||
private String scoreStatus;
|
||||
/**安全得分*/
|
||||
@Excel(name = "安全得分", width = 15)
|
||||
@Schema(description = "安全得分")
|
||||
private java.math.BigDecimal safetyScore;
|
||||
/**质量得分*/
|
||||
@Excel(name = "质量得分", width = 15)
|
||||
@Schema(description = "质量得分")
|
||||
private java.math.BigDecimal qualityScore;
|
||||
/**效率得分*/
|
||||
@Excel(name = "效率得分", width = 15)
|
||||
@Schema(description = "效率得分")
|
||||
private java.math.BigDecimal efficiencyScore;
|
||||
/**成本得分*/
|
||||
@Excel(name = "成本得分", width = 15)
|
||||
@Schema(description = "成本得分")
|
||||
private java.math.BigDecimal costScore;
|
||||
/**改善效果得分*/
|
||||
@Excel(name = "改善效果得分", width = 15)
|
||||
@Schema(description = "改善效果得分")
|
||||
|
||||
+7
-3
@@ -125,6 +125,10 @@ public class ImprovementProposal implements Serializable {
|
||||
@Schema(description = "最终奖项")
|
||||
@Dict(dicCode = "proposal_prize")
|
||||
private String finalAward;
|
||||
/**所级评议领导名单*/
|
||||
@Excel(name = "所级评议领导名单", width = 15)
|
||||
@Schema(description = "所级评议领导名单")
|
||||
private Integer instituteVoters;
|
||||
/**所级评议应投票人数*/
|
||||
@Excel(name = "所级评议应投票人数", width = 15)
|
||||
@Schema(description = "所级评议应投票人数")
|
||||
@@ -137,9 +141,9 @@ public class ImprovementProposal implements Serializable {
|
||||
@Excel(name = "所级评议不同意票数", width = 15)
|
||||
@Schema(description = "所级评议不同意票数")
|
||||
private Integer instituteDisagreeCount;
|
||||
/**所级评议结果:passed/failed*/
|
||||
@Excel(name = "所级评议结果:passed/failed", width = 15)
|
||||
@Schema(description = "所级评议结果:passed/failed")
|
||||
/**所级评议结果:通过/不通过*/
|
||||
@Excel(name = "所级评议结果:通过/不通过", width = 15)
|
||||
@Schema(description = "所级评议结果:通过/不通过")
|
||||
private String instituteVoteResult;
|
||||
/**金奖未通过后的经办人手动确认结果*/
|
||||
@Excel(name = "金奖未通过后的经办人手动确认结果", width = 15)
|
||||
|
||||
+3
@@ -28,4 +28,7 @@ public interface ImprovementInstituteVoteMapper extends BaseMapper<ImprovementIn
|
||||
* @return List<ImprovementInstituteVote>
|
||||
*/
|
||||
public List<ImprovementInstituteVote> selectByMainId(@Param("mainId") String mainId);
|
||||
|
||||
/** 任务尚未进入投票节点时,仅失效本轮待投票记录,保留已投票历史。 */
|
||||
int logicalDeletePendingByMainId(@Param("mainId") String mainId);
|
||||
}
|
||||
|
||||
+5
@@ -2,8 +2,10 @@ package org.jeecg.modules.improvementproposal.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.jeecg.modules.improvementproposal.dto.ImprovementInstituteVoteCandidateDTO;
|
||||
import org.jeecg.modules.improvementproposal.entity.ImprovementProposal;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: improvement_proposal
|
||||
@@ -20,4 +22,7 @@ public interface ImprovementProposalMapper extends BaseMapper<ImprovementProposa
|
||||
@Select("SELECT * FROM improvement_proposal WHERE id = #{id} AND del_flag = '0' FOR UPDATE")
|
||||
ImprovementProposal selectByIdForUpdate(@Param("id") String id);
|
||||
|
||||
/** 查询指定角色下可供所级评议选择的有效用户。 */
|
||||
List<ImprovementInstituteVoteCandidateDTO> selectInstituteVoteCandidates(@Param("roleCode") String roleCode);
|
||||
|
||||
}
|
||||
|
||||
+12
-1
@@ -12,5 +12,16 @@
|
||||
SELECT *
|
||||
FROM improvement_institute_vote
|
||||
WHERE
|
||||
main_id = #{mainId} </select>
|
||||
main_id = #{mainId}
|
||||
AND del_flag = '0'
|
||||
</select>
|
||||
|
||||
<!-- Task_improve004 重试保存名单时,只替换尚未投票的有效记录。 -->
|
||||
<update id="logicalDeletePendingByMainId" parameterType="java.lang.String">
|
||||
UPDATE improvement_institute_vote
|
||||
SET del_flag = '1'
|
||||
WHERE main_id = #{mainId}
|
||||
AND del_flag = '0'
|
||||
AND vote_status = 'pending'
|
||||
</update>
|
||||
</mapper>
|
||||
|
||||
+13
@@ -10,4 +10,17 @@
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<!-- 角色名单由服务端查询,前端只能从该受控集合中选择。 -->
|
||||
<select id="selectInstituteVoteCandidates" resultType="org.jeecg.modules.improvementproposal.dto.ImprovementInstituteVoteCandidateDTO">
|
||||
SELECT DISTINCT u.id, u.username, u.realname
|
||||
FROM sys_role r
|
||||
INNER JOIN sys_user_role ur ON ur.role_id = r.id
|
||||
INNER JOIN sys_user u ON u.id = ur.user_id
|
||||
WHERE r.role_code = #{roleCode}
|
||||
AND u.del_flag = 0
|
||||
AND u.username IS NOT NULL
|
||||
AND u.username != ''
|
||||
ORDER BY u.realname, u.username
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
+24
@@ -3,9 +3,12 @@ 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.ImprovementDeptScoreBpmDTO;
|
||||
import org.jeecg.modules.improvementproposal.dto.ImprovementInstituteVoteCandidateDTO;
|
||||
import org.jeecg.modules.improvementproposal.dto.ImprovementProposalBpmActionDTO;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -62,15 +65,36 @@ public interface IImprovementProposalService extends IService<ImprovementProposa
|
||||
/** 保存部门精益专员初审结果,并写入部门评分网关变量。 */
|
||||
void saveInitialReview(ImprovementProposalBpmActionDTO action, LoginUser loginUser);
|
||||
|
||||
/** 获取当前部门评委在当前流程任务下的个人评分,不返回其他评委数据。 */
|
||||
ImprovementDeptScore getMyDeptScore(ImprovementProposalBpmActionDTO action, LoginUser loginUser);
|
||||
|
||||
/** 保存当前部门评委的四维度评分草稿,流程任务提交前允许修改。 */
|
||||
void saveDeptScore(ImprovementDeptScoreBpmDTO score, LoginUser loginUser);
|
||||
|
||||
/** 锁定当前评委的已保存评分,并在全部评委完成时汇总部门评议结果。 */
|
||||
void submitDeptScore(ImprovementProposalBpmActionDTO action, LoginUser loginUser);
|
||||
|
||||
/** 保存部门负责人确认奖项,并写入所级投票网关变量。 */
|
||||
void saveLeaderAward(ImprovementProposalBpmActionDTO action, LoginUser loginUser);
|
||||
|
||||
/** 查询所级评议节点可选择的角色成员。 */
|
||||
List<ImprovementInstituteVoteCandidateDTO> getInstituteVoteCandidates(ImprovementProposalBpmActionDTO action, LoginUser loginUser);
|
||||
|
||||
/** 保存所级评议名单、待投票记录及多实例流程变量。 */
|
||||
void saveInstituteVoteMembers(ImprovementProposalBpmActionDTO action, LoginUser loginUser);
|
||||
|
||||
/** 保存经办人归档确认的最终奖项。 */
|
||||
void saveArchiveAward(ImprovementProposalBpmActionDTO action, LoginUser loginUser);
|
||||
|
||||
/** 记录当前所级评委的投票结果。 */
|
||||
void castInstituteVote(ImprovementProposalBpmActionDTO action, LoginUser loginUser);
|
||||
|
||||
/** 锁定当前所级评委的投票并在全员完成后汇总投票结果。 */
|
||||
void submitInstituteVote(ImprovementProposalBpmActionDTO action, LoginUser loginUser);
|
||||
|
||||
/** 锁定投票后,使用通用流程办理能力直接完成当前所级评委任务。 */
|
||||
void submitInstituteVoteAndComplete(ImprovementProposalBpmActionDTO action, LoginUser loginUser, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 获取指定年度最新提案编号中的XXXX部分
|
||||
*
|
||||
|
||||
+439
-9
@@ -3,6 +3,8 @@ package org.jeecg.modules.improvementproposal.service.impl;
|
||||
import org.jeecg.modules.improvementproposal.entity.ImprovementProposal;
|
||||
import org.jeecg.modules.improvementproposal.entity.ImprovementDeptScore;
|
||||
import org.jeecg.modules.improvementproposal.entity.ImprovementInstituteVote;
|
||||
import org.jeecg.modules.improvementproposal.dto.ImprovementDeptScoreBpmDTO;
|
||||
import org.jeecg.modules.improvementproposal.dto.ImprovementInstituteVoteCandidateDTO;
|
||||
import org.jeecg.modules.improvementproposal.dto.ImprovementProposalBpmActionDTO;
|
||||
import org.jeecg.modules.improvementproposal.mapper.ImprovementDeptScoreMapper;
|
||||
import org.jeecg.modules.improvementproposal.mapper.ImprovementInstituteVoteMapper;
|
||||
@@ -12,22 +14,31 @@ import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.modules.extbpm.process.service.impl.BpmBaseExtApiImpl;
|
||||
import org.jeecg.modules.extbpm.process.service.IExtActTaskCcService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.HistoryService;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.jeecg.modules.system.entity.SysRole;
|
||||
import org.jeecg.modules.system.service.ISysRoleService;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @Description: improvement_proposal
|
||||
@@ -43,13 +54,18 @@ public class ImprovementProposalServiceImpl extends ServiceImpl<ImprovementPropo
|
||||
private static final String FLOW_NAME = "改善提案审批";
|
||||
private static final String BPM_FORM_URL = "gh/improvementProposal/components/ImprovementProposalBPMForm";
|
||||
private static final String TASK_INITIAL_REVIEW = "Task_improve001";
|
||||
private static final String TASK_DEPT_SCORE = "Task_improve002";
|
||||
private static final String TASK_LEADER_AWARD = "Task_improve003";
|
||||
private static final String TASK_INSTITUTE_REVIEW = "Task_improve004";
|
||||
private static final String TASK_INSTITUTE_VOTE = "Task_improve005";
|
||||
private static final String TASK_ARCHIVE = "Task_improve006";
|
||||
private static final String INSTITUTE_VOTE_ROLE_CODE = "improve_suoleader";
|
||||
private static final String AWARD_GOLD = "0";
|
||||
private static final String AWARD_SILVER = "1";
|
||||
private static final String AWARD_BRONZE = "2";
|
||||
private static final String AWARD_PARTICIPATION = "3";
|
||||
private static final String INSTITUTE_VOTE_RESULT_PASSED = "通过";
|
||||
private static final String INSTITUTE_VOTE_RESULT_FAILED = "不通过";
|
||||
|
||||
@Autowired
|
||||
private ImprovementProposalMapper improvementProposalMapper;
|
||||
@@ -62,7 +78,13 @@ public class ImprovementProposalServiceImpl extends ServiceImpl<ImprovementPropo
|
||||
@Autowired
|
||||
private RuntimeService runtimeService;
|
||||
@Autowired
|
||||
private HistoryService historyService;
|
||||
@Autowired
|
||||
private TaskService taskService;
|
||||
@Autowired
|
||||
private ISysRoleService sysRoleService;
|
||||
@Autowired
|
||||
private IExtActTaskCcService extActTaskCcService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -201,11 +223,104 @@ public class ImprovementProposalServiceImpl extends ServiceImpl<ImprovementPropo
|
||||
runtimeService.setVariable(action.getProcessInstanceId(), "need_dept_score", needDeptScore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImprovementDeptScore getMyDeptScore(ImprovementProposalBpmActionDTO action, LoginUser loginUser) {
|
||||
ImprovementProposal proposal = validateDeptScoreTask(action, loginUser);
|
||||
return findDeptScore(proposal.getId(), loginUser.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveDeptScore(ImprovementDeptScoreBpmDTO scoreAction, LoginUser loginUser) {
|
||||
validateScoreValues(scoreAction);
|
||||
ImprovementProposalBpmActionDTO action = toBpmAction(scoreAction);
|
||||
ImprovementProposal proposal = validateDeptScoreTask(action, loginUser);
|
||||
|
||||
// 锁定主表后再查询个人记录,未设置数据库唯一约束时也能阻止同一评委并发生成重复评分。
|
||||
ImprovementProposal lockedProposal = improvementProposalMapper.selectByIdForUpdate(proposal.getId());
|
||||
if (lockedProposal == null || !scoreAction.getProcessInstanceId().equals(lockedProposal.getProcessInstanceId())) {
|
||||
throw new IllegalStateException("提案流程状态已变化,请刷新后重试");
|
||||
}
|
||||
ImprovementDeptScore existingScore = findDeptScore(lockedProposal.getId(), loginUser.getId());
|
||||
if (existingScore != null && "completed".equals(existingScore.getScoreStatus())) {
|
||||
throw new IllegalStateException("评分已锁定,请重新提交流程办理");
|
||||
}
|
||||
|
||||
// 改善效果由四个子项在服务端计算,避免前端篡改汇总得分或加权总分。
|
||||
BigDecimal effectScore = calculateEffectScore(scoreAction);
|
||||
BigDecimal totalScore = calculateTotalScore(scoreAction, effectScore);
|
||||
if (existingScore == null) {
|
||||
ImprovementDeptScore newScore = new ImprovementDeptScore();
|
||||
newScore.setMainId(lockedProposal.getId());
|
||||
newScore.setProcessTaskId(scoreAction.getTaskId());
|
||||
newScore.setScorerId(loginUser.getId());
|
||||
newScore.setScorerName(loginUser.getRealname());
|
||||
fillDeptScoreDraft(newScore, scoreAction, effectScore, totalScore);
|
||||
// 草稿阶段记录最近保存时间,供评委在当前节点实时查看。
|
||||
newScore.setScoreTime(new Date());
|
||||
improvementDeptScoreMapper.insert(newScore);
|
||||
} else {
|
||||
// 草稿保存只能更新 pending 记录,避免流程已提交后通过接口修改最终评分。
|
||||
int updated = improvementDeptScoreMapper.update(null, new LambdaUpdateWrapper<ImprovementDeptScore>()
|
||||
.eq(ImprovementDeptScore::getId, existingScore.getId())
|
||||
.eq(ImprovementDeptScore::getScoreStatus, "pending")
|
||||
.set(ImprovementDeptScore::getProcessTaskId, scoreAction.getTaskId())
|
||||
.set(ImprovementDeptScore::getSafetyScore, scoreAction.getSafetyScore())
|
||||
.set(ImprovementDeptScore::getQualityScore, scoreAction.getQualityScore())
|
||||
.set(ImprovementDeptScore::getEfficiencyScore, scoreAction.getEfficiencyScore())
|
||||
.set(ImprovementDeptScore::getCostScore, scoreAction.getCostScore())
|
||||
.set(ImprovementDeptScore::getEffectScore, effectScore)
|
||||
.set(ImprovementDeptScore::getPromotionScore, scoreAction.getPromotionScore())
|
||||
.set(ImprovementDeptScore::getOriginalityScore, scoreAction.getOriginalityScore())
|
||||
.set(ImprovementDeptScore::getEffortScore, scoreAction.getEffortScore())
|
||||
.set(ImprovementDeptScore::getTotalScore, totalScore)
|
||||
.set(ImprovementDeptScore::getScoreOpinion, scoreAction.getScoreOpinion())
|
||||
.set(ImprovementDeptScore::getScoreStatus, "pending")
|
||||
.set(ImprovementDeptScore::getScoreTime, new Date()));
|
||||
if (updated != 1) {
|
||||
throw new IllegalStateException("评分状态已变化,请刷新后重试");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void submitDeptScore(ImprovementProposalBpmActionDTO action, LoginUser loginUser) {
|
||||
ImprovementProposal proposal = validateDeptScoreTask(action, loginUser);
|
||||
ImprovementProposal lockedProposal = improvementProposalMapper.selectByIdForUpdate(proposal.getId());
|
||||
if (lockedProposal == null || !action.getProcessInstanceId().equals(lockedProposal.getProcessInstanceId())) {
|
||||
throw new IllegalStateException("提案流程状态已变化,请刷新后重试");
|
||||
}
|
||||
ImprovementDeptScore score = findDeptScore(lockedProposal.getId(), loginUser.getId());
|
||||
if (score == null) {
|
||||
throw new IllegalStateException("请先保存个人评分");
|
||||
}
|
||||
validateSavedScore(score);
|
||||
|
||||
// 通用流程办理可能因网络重试再次调用 beforeHandle;已锁定时保持幂等,让任务能够再次提交完成。
|
||||
if (!"completed".equals(score.getScoreStatus())) {
|
||||
int updated = improvementDeptScoreMapper.update(null, new LambdaUpdateWrapper<ImprovementDeptScore>()
|
||||
.eq(ImprovementDeptScore::getId, score.getId())
|
||||
.eq(ImprovementDeptScore::getScoreStatus, "pending")
|
||||
.set(ImprovementDeptScore::getScoreStatus, "completed")
|
||||
.set(ImprovementDeptScore::getScoreTime, new Date())
|
||||
.set(ImprovementDeptScore::getProcessTaskId, action.getTaskId()));
|
||||
if (updated != 1) {
|
||||
throw new IllegalStateException("评分状态已变化,请刷新后重试");
|
||||
}
|
||||
}
|
||||
updateDeptScoreSummaryIfComplete(lockedProposal, action.getProcessInstanceId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveLeaderAward(ImprovementProposalBpmActionDTO action, LoginUser loginUser) {
|
||||
validateAward(action.getLeaderFinalAward());
|
||||
ImprovementProposal proposal = validateRunningTask(action, loginUser, TASK_LEADER_AWARD);
|
||||
String awardBase = resolveLeaderAwardBase(proposal);
|
||||
if (awardRank(action.getLeaderFinalAward()) < awardRank(awardBase)) {
|
||||
throw new IllegalStateException("负责人确认奖项只能选择当前档位或降档奖项");
|
||||
}
|
||||
String needInstituteVote = AWARD_GOLD.equals(action.getLeaderFinalAward()) ? "1" : "0";
|
||||
ImprovementProposal update = new ImprovementProposal();
|
||||
update.setId(proposal.getId());
|
||||
@@ -215,6 +330,75 @@ public class ImprovementProposalServiceImpl extends ServiceImpl<ImprovementPropo
|
||||
runtimeService.setVariable(action.getProcessInstanceId(), "isneedvote", needInstituteVote);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ImprovementInstituteVoteCandidateDTO> getInstituteVoteCandidates(ImprovementProposalBpmActionDTO action, LoginUser loginUser) {
|
||||
validateRunningTask(action, loginUser, TASK_INSTITUTE_REVIEW);
|
||||
return loadInstituteVoteCandidates();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveInstituteVoteMembers(ImprovementProposalBpmActionDTO action, LoginUser loginUser) {
|
||||
ImprovementProposal proposal = validateRunningTask(action, loginUser, TASK_INSTITUTE_REVIEW);
|
||||
ImprovementProposal lockedProposal = improvementProposalMapper.selectByIdForUpdate(proposal.getId());
|
||||
if (lockedProposal == null || !action.getProcessInstanceId().equals(lockedProposal.getProcessInstanceId())) {
|
||||
throw new IllegalStateException("提案流程状态已变化,请刷新后重试");
|
||||
}
|
||||
|
||||
List<ImprovementInstituteVoteCandidateDTO> candidates = loadInstituteVoteCandidates();
|
||||
Map<String, ImprovementInstituteVoteCandidateDTO> candidateById = new LinkedHashMap<>();
|
||||
for (ImprovementInstituteVoteCandidateDTO candidate : candidates) {
|
||||
candidateById.put(candidate.getId(), candidate);
|
||||
}
|
||||
if (action.getVoterIds() == null || action.getVoterIds().isEmpty()) {
|
||||
throw new IllegalStateException("请至少选择一名所级评议人员");
|
||||
}
|
||||
|
||||
LinkedHashSet<String> selectedUserIds = new LinkedHashSet<>();
|
||||
for (String voterId : action.getVoterIds()) {
|
||||
if (oConvertUtils.isEmpty(voterId) || !selectedUserIds.add(voterId)) {
|
||||
throw new IllegalStateException("所级评议人员选择数据不合法");
|
||||
}
|
||||
}
|
||||
LinkedHashSet<String> usernames = new LinkedHashSet<>();
|
||||
for (String voterId : selectedUserIds) {
|
||||
ImprovementInstituteVoteCandidateDTO candidate = candidateById.get(voterId);
|
||||
if (candidate == null) {
|
||||
throw new IllegalStateException("所选人员不属于所级评议小组");
|
||||
}
|
||||
if (!usernames.add(candidate.getUsername())) {
|
||||
throw new IllegalStateException("所级评议人员用户名重复");
|
||||
}
|
||||
}
|
||||
|
||||
List<ImprovementInstituteVote> activeVotes = improvementInstituteVoteMapper.selectByMainId(lockedProposal.getId());
|
||||
if (activeVotes.stream().anyMatch(item -> !"pending".equals(item.getVoteStatus()))) {
|
||||
throw new IllegalStateException("所级评议已开始投票,不能重新选择人员");
|
||||
}
|
||||
// beforeHandle 可能因网络重试重复调用;先失效未投票记录再重建,确保有效名单始终和流程变量一致。
|
||||
improvementInstituteVoteMapper.logicalDeletePendingByMainId(lockedProposal.getId());
|
||||
for (String voterId : selectedUserIds) {
|
||||
ImprovementInstituteVoteCandidateDTO candidate = candidateById.get(voterId);
|
||||
ImprovementInstituteVote vote = new ImprovementInstituteVote();
|
||||
vote.setMainId(lockedProposal.getId());
|
||||
vote.setVoterId(candidate.getId());
|
||||
vote.setVoterName(oConvertUtils.isEmpty(candidate.getRealname()) ? candidate.getUsername() : candidate.getRealname());
|
||||
vote.setVoteStatus("pending");
|
||||
vote.setSysOrgCode(lockedProposal.getSysOrgCode());
|
||||
vote.setDelFlag(NORMAL_DEL_FLAG);
|
||||
improvementInstituteVoteMapper.insert(vote);
|
||||
}
|
||||
|
||||
ImprovementProposal update = new ImprovementProposal();
|
||||
update.setId(lockedProposal.getId());
|
||||
update.setInstituteTotalVoters(selectedUserIds.size());
|
||||
update.setInstituteAgreeCount(null);
|
||||
update.setInstituteDisagreeCount(null);
|
||||
update.setInstituteVoteResult(null);
|
||||
improvementProposalMapper.updateById(update);
|
||||
runtimeService.setVariable(action.getProcessInstanceId(), "suoleadervotelist", String.join(",", usernames));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveArchiveAward(ImprovementProposalBpmActionDTO action, LoginUser loginUser) {
|
||||
@@ -225,7 +409,7 @@ public class ImprovementProposalServiceImpl extends ServiceImpl<ImprovementPropo
|
||||
update.setFinalAward(action.getFinalAward());
|
||||
update.setArchiveBy(loginUser.getId());
|
||||
update.setArchiveTime(new Date());
|
||||
if (AWARD_GOLD.equals(proposal.getLeaderFinalAward()) && "failed".equals(proposal.getInstituteVoteResult())) {
|
||||
if (AWARD_GOLD.equals(proposal.getLeaderFinalAward()) && INSTITUTE_VOTE_RESULT_FAILED.equals(proposal.getInstituteVoteResult())) {
|
||||
update.setManualConfirmResult("confirmed");
|
||||
}
|
||||
improvementProposalMapper.updateById(update);
|
||||
@@ -238,25 +422,252 @@ public class ImprovementProposalServiceImpl extends ServiceImpl<ImprovementPropo
|
||||
throw new IllegalStateException("投票结果只能是同意或不同意");
|
||||
}
|
||||
ImprovementProposal proposal = validateRunningTask(action, loginUser, TASK_INSTITUTE_VOTE);
|
||||
ImprovementInstituteVote vote = improvementInstituteVoteMapper.selectByMainId(proposal.getId()).stream()
|
||||
.filter(item -> 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<ImprovementInstituteVote>()
|
||||
.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) {
|
||||
if (!"agree".equals(action.getVoteResult()) && !"disagree".equals(action.getVoteResult())) {
|
||||
throw new IllegalStateException("投票结果只能是同意或不同意");
|
||||
}
|
||||
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 (!action.getVoteResult().equals(vote.getVoteResult())) {
|
||||
throw new IllegalStateException("投票已确认,不能修改投票结果");
|
||||
}
|
||||
} else {
|
||||
int updated = improvementInstituteVoteMapper.update(null, new LambdaUpdateWrapper<ImprovementInstituteVote>()
|
||||
.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("投票状态已变化,请刷新后重试");
|
||||
}
|
||||
}
|
||||
updateInstituteVoteSummaryIfComplete(lockedProposal, action.getProcessInstanceId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void submitInstituteVoteAndComplete(ImprovementProposalBpmActionDTO action, LoginUser loginUser, HttpServletRequest request) {
|
||||
submitInstituteVote(action, loginUser);
|
||||
|
||||
// 复用通用办理服务,确保审批日志、流程状态及多实例收敛逻辑与普通办理保持一致。
|
||||
HashMap<String, String> processParams = new HashMap<>(4);
|
||||
processParams.put("taskId", action.getTaskId());
|
||||
processParams.put("processModel", "1");
|
||||
processParams.put("nextCodeCount", "1");
|
||||
// Task5 只有正常流转分支;通用办理服务以 end + 单分支执行 taskService.complete。
|
||||
processParams.put("nextnode", "end");
|
||||
Result<Object> result = extActTaskCcService.processComplete(processParams, request);
|
||||
if (result == null || !result.isSuccess()) {
|
||||
throw new IllegalStateException(result == null || oConvertUtils.isEmpty(result.getMessage())
|
||||
? "投票已确认,但流程办理失败"
|
||||
: result.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
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<ImprovementInstituteVote> 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
|
||||
? INSTITUTE_VOTE_RESULT_PASSED
|
||||
: INSTITUTE_VOTE_RESULT_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 或角色配置已变更。
|
||||
*/
|
||||
private List<ImprovementInstituteVoteCandidateDTO> loadInstituteVoteCandidates() {
|
||||
SysRole role = sysRoleService.getRoleNoTenant(INSTITUTE_VOTE_ROLE_CODE);
|
||||
if (role == null) {
|
||||
throw new IllegalStateException("未配置所级评议小组角色:" + INSTITUTE_VOTE_ROLE_CODE);
|
||||
}
|
||||
List<ImprovementInstituteVoteCandidateDTO> candidates = improvementProposalMapper.selectInstituteVoteCandidates(INSTITUTE_VOTE_ROLE_CODE);
|
||||
if (candidates == null || candidates.isEmpty()) {
|
||||
throw new IllegalStateException("所级评议小组角色未配置有效用户");
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
private ImprovementProposalBpmActionDTO toBpmAction(ImprovementDeptScoreBpmDTO scoreAction) {
|
||||
ImprovementProposalBpmActionDTO action = new ImprovementProposalBpmActionDTO();
|
||||
action.setMainId(scoreAction.getMainId());
|
||||
action.setProcessInstanceId(scoreAction.getProcessInstanceId());
|
||||
action.setTaskId(scoreAction.getTaskId());
|
||||
return action;
|
||||
}
|
||||
|
||||
private ImprovementProposal validateDeptScoreTask(ImprovementProposalBpmActionDTO action, LoginUser loginUser) {
|
||||
ImprovementProposal proposal = validateRunningTask(action, loginUser, TASK_DEPT_SCORE);
|
||||
Task task = taskService.createTaskQuery().taskId(action.getTaskId()).singleResult();
|
||||
// 部门评议必须使用并行多实例的直接办理人任务,避免候选组任务被未分配人员越权评分。
|
||||
if (task == null || !loginUser.getUsername().equals(task.getAssignee())) {
|
||||
throw new IllegalStateException("当前用户不是本评分任务的办理人");
|
||||
}
|
||||
return proposal;
|
||||
}
|
||||
|
||||
private ImprovementDeptScore findDeptScore(String mainId, String scorerId) {
|
||||
return improvementDeptScoreMapper.selectByMainId(mainId).stream()
|
||||
.filter(item -> scorerId.equals(item.getScorerId()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private void validateScoreValues(ImprovementDeptScoreBpmDTO scoreAction) {
|
||||
if (scoreAction == null) {
|
||||
throw new IllegalStateException("评分参数不能为空");
|
||||
}
|
||||
validateScoreValue(scoreAction.getSafetyScore(), "安全");
|
||||
validateScoreValue(scoreAction.getQualityScore(), "质量");
|
||||
validateScoreValue(scoreAction.getEfficiencyScore(), "效率");
|
||||
validateScoreValue(scoreAction.getCostScore(), "成本");
|
||||
validateScoreValue(scoreAction.getPromotionScore(), "可推广度");
|
||||
validateScoreValue(scoreAction.getOriginalityScore(), "独创性");
|
||||
validateScoreValue(scoreAction.getEffortScore(), "努力度");
|
||||
}
|
||||
|
||||
private void validateScoreValue(BigDecimal score, String dimensionName) {
|
||||
if (score == null || score.scale() > 2 || score.compareTo(BigDecimal.ZERO) < 0 || score.compareTo(BigDecimal.valueOf(100)) > 0) {
|
||||
throw new IllegalStateException(dimensionName + "得分必须是 0 到 100 之间且最多两位小数的数值");
|
||||
}
|
||||
}
|
||||
|
||||
private BigDecimal calculateEffectScore(ImprovementDeptScoreBpmDTO scoreAction) {
|
||||
return calculateEffectScore(scoreAction.getSafetyScore(), scoreAction.getQualityScore(), scoreAction.getEfficiencyScore(), scoreAction.getCostScore());
|
||||
}
|
||||
|
||||
private BigDecimal calculateEffectScore(BigDecimal safetyScore, BigDecimal qualityScore, BigDecimal efficiencyScore, BigDecimal costScore) {
|
||||
return safetyScore.add(qualityScore).add(efficiencyScore).add(costScore).divide(BigDecimal.valueOf(4), 2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private BigDecimal calculateTotalScore(ImprovementDeptScoreBpmDTO scoreAction, BigDecimal effectScore) {
|
||||
return effectScore.multiply(new BigDecimal("0.50"))
|
||||
.add(scoreAction.getPromotionScore().multiply(new BigDecimal("0.20")))
|
||||
.add(scoreAction.getOriginalityScore().multiply(new BigDecimal("0.20")))
|
||||
.add(scoreAction.getEffortScore().multiply(new BigDecimal("0.10")))
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private void fillDeptScoreDraft(ImprovementDeptScore target, ImprovementDeptScoreBpmDTO source, BigDecimal effectScore, BigDecimal totalScore) {
|
||||
target.setSafetyScore(source.getSafetyScore());
|
||||
target.setQualityScore(source.getQualityScore());
|
||||
target.setEfficiencyScore(source.getEfficiencyScore());
|
||||
target.setCostScore(source.getCostScore());
|
||||
target.setEffectScore(effectScore);
|
||||
target.setPromotionScore(source.getPromotionScore());
|
||||
target.setOriginalityScore(source.getOriginalityScore());
|
||||
target.setEffortScore(source.getEffortScore());
|
||||
target.setTotalScore(totalScore);
|
||||
target.setScoreOpinion(source.getScoreOpinion());
|
||||
target.setScoreStatus("pending");
|
||||
target.setScoreTime(null);
|
||||
}
|
||||
|
||||
private void validateSavedScore(ImprovementDeptScore score) {
|
||||
validateScoreValue(score.getSafetyScore(), "安全");
|
||||
validateScoreValue(score.getQualityScore(), "质量");
|
||||
validateScoreValue(score.getEfficiencyScore(), "效率");
|
||||
validateScoreValue(score.getCostScore(), "成本");
|
||||
validateScoreValue(score.getPromotionScore(), "可推广度");
|
||||
validateScoreValue(score.getOriginalityScore(), "独创性");
|
||||
validateScoreValue(score.getEffortScore(), "努力度");
|
||||
BigDecimal calculatedEffectScore = calculateEffectScore(score.getSafetyScore(), score.getQualityScore(), score.getEfficiencyScore(), score.getCostScore());
|
||||
if (score.getEffectScore() == null || score.getEffectScore().compareTo(calculatedEffectScore) != 0 || score.getTotalScore() == null) {
|
||||
throw new IllegalStateException("请先保存完整个人评分");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDeptScoreSummaryIfComplete(ImprovementProposal proposal, String processInstanceId) {
|
||||
long expectedScorerCount = historyService.createHistoricTaskInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.taskDefinitionKey(TASK_DEPT_SCORE)
|
||||
.count();
|
||||
List<ImprovementDeptScore> scoreList = improvementDeptScoreMapper.selectByMainId(proposal.getId());
|
||||
boolean allCompleted = expectedScorerCount > 0 && scoreList.size() == expectedScorerCount
|
||||
&& scoreList.stream().allMatch(item -> "completed".equals(item.getScoreStatus()) && item.getTotalScore() != null);
|
||||
if (!allCompleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
BigDecimal totalScore = scoreList.stream()
|
||||
.map(ImprovementDeptScore::getTotalScore)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal averageScore = totalScore.divide(BigDecimal.valueOf(expectedScorerCount), 2, RoundingMode.HALF_UP);
|
||||
ImprovementProposal summary = new ImprovementProposal();
|
||||
summary.setId(proposal.getId());
|
||||
summary.setDeptAvgScore(averageScore);
|
||||
summary.setSuggestedAward(resolveSuggestedAward(averageScore));
|
||||
improvementProposalMapper.updateById(summary);
|
||||
}
|
||||
|
||||
private String resolveSuggestedAward(BigDecimal averageScore) {
|
||||
if (averageScore.compareTo(BigDecimal.valueOf(80)) >= 0) {
|
||||
return AWARD_GOLD;
|
||||
}
|
||||
if (averageScore.compareTo(BigDecimal.valueOf(60)) >= 0) {
|
||||
return AWARD_SILVER;
|
||||
}
|
||||
if (averageScore.compareTo(BigDecimal.valueOf(40)) >= 0) {
|
||||
return AWARD_BRONZE;
|
||||
}
|
||||
return AWARD_PARTICIPATION;
|
||||
}
|
||||
|
||||
private ImprovementProposal validateRunningTask(ImprovementProposalBpmActionDTO action, LoginUser loginUser, String expectedTaskDefKey) {
|
||||
if (action == null || oConvertUtils.isEmpty(action.getMainId()) || oConvertUtils.isEmpty(action.getProcessInstanceId())
|
||||
|| oConvertUtils.isEmpty(action.getTaskId())) {
|
||||
@@ -278,11 +689,30 @@ public class ImprovementProposalServiceImpl extends ServiceImpl<ImprovementPropo
|
||||
}
|
||||
|
||||
private void validateAward(String award) {
|
||||
if (!AWARD_GOLD.equals(award) && !AWARD_SILVER.equals(award) && !AWARD_BRONZE.equals(award) && !AWARD_PARTICIPATION.equals(award)) {
|
||||
if (!isValidAward(award)) {
|
||||
throw new IllegalStateException("请选择有效的奖项");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isValidAward(String award) {
|
||||
return AWARD_GOLD.equals(award) || AWARD_SILVER.equals(award) || AWARD_BRONZE.equals(award) || AWARD_PARTICIPATION.equals(award);
|
||||
}
|
||||
|
||||
/**
|
||||
* 负责人只能在当前评定档位内确认或降档:经过评分时以系统建议奖项为准,未评分时以初评奖项为准。
|
||||
*/
|
||||
private String resolveLeaderAwardBase(ImprovementProposal proposal) {
|
||||
String awardBase = "1".equals(proposal.getNeedDeptScore()) ? proposal.getSuggestedAward() : proposal.getInitialAward();
|
||||
if (!isValidAward(awardBase)) {
|
||||
throw new IllegalStateException("部门评议建议奖项尚未生成,不能确认负责人奖项");
|
||||
}
|
||||
return awardBase;
|
||||
}
|
||||
|
||||
private int awardRank(String award) {
|
||||
return Integer.parseInt(award);
|
||||
}
|
||||
|
||||
private boolean needsDeptScore(String award) {
|
||||
return AWARD_GOLD.equals(award) || AWARD_SILVER.equals(award);
|
||||
}
|
||||
|
||||
+3
-3
@@ -128,9 +128,9 @@ public class ImprovementProposalPage {
|
||||
@Excel(name = "所级评议不同意票数", width = 15)
|
||||
@Schema(description = "所级评议不同意票数")
|
||||
private Integer instituteDisagreeCount;
|
||||
/**所级评议结果:passed/failed*/
|
||||
@Excel(name = "所级评议结果:passed/failed", width = 15)
|
||||
@Schema(description = "所级评议结果:passed/failed")
|
||||
/**所级评议结果:通过/不通过*/
|
||||
@Excel(name = "所级评议结果:通过/不通过", width = 15)
|
||||
@Schema(description = "所级评议结果:通过/不通过")
|
||||
private String instituteVoteResult;
|
||||
/**金奖未通过后的经办人手动确认结果*/
|
||||
@Excel(name = "金奖未通过后的经办人手动确认结果", width = 15)
|
||||
|
||||
Reference in New Issue
Block a user