483 lines
20 KiB
Java
483 lines
20 KiB
Java
package cn.palmte.work.service;
|
|
|
|
import cn.palmte.work.bean.ResponseMsg;
|
|
import cn.palmte.work.config.activiti.*;
|
|
|
|
import cn.palmte.work.model.*;
|
|
import cn.palmte.work.model.enums.ProcessStatus;
|
|
import cn.palmte.work.pojo.ActHisTask;
|
|
import cn.palmte.work.utils.ActUtil;
|
|
import cn.palmte.work.utils.InterfaceUtil;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import org.activiti.engine.*;
|
|
import org.activiti.engine.impl.identity.Authentication;
|
|
import org.activiti.engine.runtime.ProcessInstance;
|
|
import org.activiti.engine.task.Task;
|
|
import org.apache.commons.lang.StringUtils;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
import top.jfunc.common.db.QueryHelper;
|
|
import top.jfunc.common.db.bean.Record;
|
|
import top.jfunc.common.db.utils.Pagination;
|
|
|
|
import java.util.*;
|
|
|
|
|
|
@Service
|
|
public class ActTaskDefService {
|
|
private static final Logger logger = LoggerFactory.getLogger(ActTaskDefService.class);
|
|
@Autowired
|
|
private ProjectTaskRecordService projectTaskRecordService;
|
|
@Autowired
|
|
private HistoryService historyService;
|
|
@Autowired
|
|
private TaskService taskService; //任务管理 与正在执行的任务管理相关的Service
|
|
@Autowired
|
|
private ActTaskDefRepository actTaskDefRepository;
|
|
@Autowired
|
|
private AccountService accountService;
|
|
@Autowired
|
|
Pagination pagination;
|
|
@Autowired
|
|
private ActUtil actUtil;
|
|
@Autowired
|
|
private ProjectInstanceService projectInstanceService;
|
|
@Autowired
|
|
private RuntimeService runtimeService;
|
|
@Autowired
|
|
private ProjectProcessService projectProcessService;
|
|
|
|
|
|
/**
|
|
* 管理员完成某个任务
|
|
*
|
|
* @param json
|
|
*/
|
|
public void completeTask(JSONObject json) {
|
|
String taskId = json.getString("taskId");
|
|
String procInsId = json.getString("procInsId");
|
|
String message = json.getString("message");
|
|
int type = json.getInteger("type");
|
|
|
|
completeTask(taskId, procInsId, message, ActApproveTypeEnum.ofType(type), "");
|
|
}
|
|
|
|
private void completeTask(String taskId, String procInsId, String message, ActApproveTypeEnum approveEnum, String fileUrl) {
|
|
String userId = InterfaceUtil.getAdminId() + "";
|
|
Authentication.setAuthenticatedUserId(userId);
|
|
taskService.addComment(taskId, procInsId, message);
|
|
|
|
Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult();
|
|
ActTaskDef actTaskDef = findFirstByProcDefIdAndTaskKey(currentTask.getProcessDefinitionId(), currentTask.getTaskDefinitionKey());
|
|
|
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInsId).singleResult();
|
|
taskService.setAssignee(taskId, userId);
|
|
if (ActConstant.TASK_TYPE_SINGE == actTaskDef.getTaskType()) {
|
|
handleSinge(processInstance, taskId, approveEnum, actTaskDef);
|
|
}
|
|
|
|
|
|
//保存审批记录
|
|
projectTaskRecordService.saveTaskRecordWithFileUrl(Integer.parseInt(processInstance.getBusinessKey()),
|
|
currentTask, approveEnum.getType(), actTaskDef.getTaskIndex(), message, fileUrl);
|
|
}
|
|
|
|
|
|
/**
|
|
* 通过流程实列id完成任务
|
|
*
|
|
* @param procInsId
|
|
* @param approveEnum
|
|
* @param comment
|
|
*/
|
|
public void completeTaskByProcInsId(String procInsId, ActApproveTypeEnum approveEnum, String comment) {
|
|
List<Task> taskList = taskService.createTaskQuery().processInstanceId(procInsId).list();
|
|
for (Task task : taskList) {
|
|
completeTask(task.getId(), procInsId, comment, approveEnum, "");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 预算跳过剩下审批任务直接到执行董事节点
|
|
*
|
|
* @param procInsId
|
|
*/
|
|
public ResponseMsg skipTaskByProcInsId(String procInsId, String fileUrl, String comment) {
|
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInsId).singleResult();
|
|
if (!ActProcessKeyEnum.BUDGET.getKey().equals(processInstance.getProcessDefinitionKey())) {
|
|
return ResponseMsg.buildFailedMsg("只有预算审批流程才能执行会签");
|
|
}
|
|
|
|
//完成当前任务
|
|
Task task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
|
|
if ("执行董事".equals(task.getName())) {
|
|
return ResponseMsg.buildFailedMsg("当前状态不能用会签功能,请使用审批功能。");
|
|
}
|
|
completeTask(task.getId(), procInsId, comment, ActApproveTypeEnum.APPROVAL_PASSED, fileUrl);
|
|
|
|
//非执行董事节点自动跳过
|
|
task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
|
|
while (!"执行董事".equals(task.getName())) {
|
|
completeSkipTask(task, processInstance, "会签,任务自动审批通过");
|
|
task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
|
|
}
|
|
|
|
return ResponseMsg.buildSuccessMsg("会签成功");
|
|
}
|
|
|
|
|
|
public void skipTaskByProcInsIdAndTaskName(String procInsId, String skipToTaskName) {
|
|
logger.info("skipTaskByProcInsIdAndTaskName procInsId:{}, skipToTaskName:{}", procInsId, skipToTaskName);
|
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInsId).singleResult();
|
|
|
|
//非指定节点自动跳过
|
|
Task task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
|
|
logger.info("skipTaskByProcInsIdAndTaskName currentTaskName:{}, skipToTaskName:{}", task.getName(), skipToTaskName);
|
|
while (!skipToTaskName.equals(task.getName())) {
|
|
logger.info("skipTaskByProcInsIdAndTaskName completeSkipTask:{}", task.getName());
|
|
|
|
completeSkipTask(task, processInstance, "任务由系统自动审批通过");
|
|
|
|
task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
|
|
logger.info("skipTaskByProcInsIdAndTaskName currentTaskName:{}, skipToTaskName:{}", task.getName(), skipToTaskName);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private void completeSkipTask(Task task, ProcessInstance processInstance, String message) {
|
|
String taskId = task.getId();
|
|
ActTaskDef actTaskDef = findFirstByProcDefIdAndTaskKey(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
|
|
|
|
if (actTaskDef.getTaskIndex() != ActTaskIndexEnum.FIRST_USER_TASK.getIndex()) {
|
|
//不是发起节点 增加comment
|
|
Authentication.setAuthenticatedUserId("-1");
|
|
taskService.addComment(taskId, processInstance.getProcessInstanceId(), message);
|
|
}
|
|
|
|
taskService.setAssignee(taskId, "-1");
|
|
|
|
if (ActConstant.TASK_TYPE_SINGE == actTaskDef.getTaskType()) {
|
|
handleSinge(processInstance, taskId, ActApproveTypeEnum.APPROVAL_PASSED, actTaskDef);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 或签处理
|
|
*
|
|
* @param taskId
|
|
* @param processInstance
|
|
* @param approveEnum
|
|
* @param actTaskDef
|
|
*/
|
|
private void handleSinge(ProcessInstance processInstance, String taskId, ActApproveTypeEnum approveEnum, ActTaskDef actTaskDef) {
|
|
String procDefKey = actTaskDef.getProcDefKey();
|
|
if (ActApproveTypeEnum.APPROVAL_PASSED == approveEnum) {
|
|
//审批通过
|
|
taskService.complete(taskId);
|
|
|
|
if (actUtil.isFourcalProcess(processInstance.getProcessDefinitionId())) {
|
|
//四算项目 最后一个任务完成后 更新项目状态为审批通过 其他项目通过监听器更新
|
|
updateProjectPassed(processInstance, actTaskDef, procDefKey);
|
|
}
|
|
} else if (ActApproveTypeEnum.APPROVAL_UN_PASS == approveEnum) {
|
|
//驳回
|
|
String rollbackTaskKey = actTaskDef.getRollbackTaskKey();
|
|
actUtil.jumpToTargetTask(taskId, rollbackTaskKey);
|
|
|
|
//驳回后 更新项目状态为审批不通过
|
|
int projectId = Integer.parseInt(processInstance.getBusinessKey());
|
|
if (actUtil.isFourcalProcess(processInstance.getProcessDefinitionId())) {
|
|
projectInstanceService.updateApproveStatus(projectId, procDefKey, ActApproveTypeEnum.APPROVAL_UN_PASS);
|
|
} else if (actUtil.isNewProcess(processInstance.getProcessDefinitionId())) {
|
|
projectProcessService.updateProcessStatus(projectId, ProcessStatus.audit_not_passed);
|
|
}
|
|
logger.info("updateProjectUnPassed projectId:{}, proDefKey:{}", projectId, procDefKey);
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 最后一个任务完成后 更新项目状态为审批通过
|
|
*
|
|
* @param processInstance
|
|
* @param actTaskDef
|
|
* @param procDefKey
|
|
*/
|
|
private void updateProjectPassed(ProcessInstance processInstance, ActTaskDef actTaskDef, String procDefKey) {
|
|
int projectId = Integer.parseInt(processInstance.getBusinessKey());
|
|
if (ActProcessKeyEnum.SETTLE.getKey().equals(procDefKey)) {
|
|
//结算流程 财务总监审批完流程结束
|
|
if ("财务总监".equals(actTaskDef.getTaskName())) {
|
|
logger.info("updateProjectPassed1 projectId:{}, proDefKey:{}", projectId, procDefKey);
|
|
projectInstanceService.updateApproveStatus(projectId, procDefKey, ActApproveTypeEnum.APPROVAL_PASSED);
|
|
}
|
|
} else {
|
|
//其余流程 执行董事审批完流程结束
|
|
if ("执行董事".equals(actTaskDef.getTaskName())) {
|
|
logger.info("updateProjectPassed2 projectId:{}, proDefKey:{}", projectId, procDefKey);
|
|
projectInstanceService.updateApproveStatus(projectId, procDefKey, ActApproveTypeEnum.APPROVAL_PASSED);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* 审批过程任务查询
|
|
*
|
|
* @param procIncId
|
|
* @return
|
|
*/
|
|
public List<ActHisTask> hisTaskList(String procIncId) {
|
|
String select = "select ht.PROC_DEF_ID_ as procDefId, ht.PROC_INST_ID_ as procInsId, ht.EXECUTION_ID_ as executionId," +
|
|
" ht.ID_ as taskId, ht.NAME_ as taskName, " +
|
|
" ht.ASSIGNEE_ as assign, ht.START_TIME_ as startTime, ht.END_TIME_ as endTime, " +
|
|
"ht.DURATION_ as duration, ht.DELETE_REASON_ as deleteReason, hc.MESSAGE_ AS comments";
|
|
QueryHelper queryHelper = new QueryHelper(select, " ACT_HI_TASKINST ht " +
|
|
" LEFT JOIN ACT_HI_COMMENT hc on ht.ID_ = hc.TASK_ID_ and hc.type_='comment' ");
|
|
queryHelper.addCondition("ht.PROC_INST_ID_ =?", procIncId);
|
|
queryHelper.addOrderProperty("ht.start_time_", true);
|
|
List<ActHisTask> taskList = pagination.find(queryHelper.getSql(), ActHisTask.class);
|
|
for (ActHisTask actHisTask : taskList) {
|
|
setAssign(actHisTask);
|
|
|
|
//办理用时
|
|
String duration = actHisTask.getDuration();
|
|
if (StringUtils.isNotBlank(duration)) {
|
|
Long ztime = Long.parseLong(duration);
|
|
Long day = ztime / (1000 * 60 * 60 * 24);
|
|
Long hour = (ztime % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
|
|
Long minute = (ztime % (1000 * 60 * 60 * 24)) % (1000 * 60 * 60) / (1000 * 60);
|
|
Long second = (ztime % (1000 * 60 * 60 * 24)) % (1000 * 60 * 60) % (1000 * 60) / 1000;
|
|
actHisTask.setDuration(day + "天" + hour + "时" + minute + "分" + second + "秒");
|
|
} else {
|
|
actHisTask.setDuration("正在处理。。。");
|
|
}
|
|
|
|
if (StringUtils.isNotBlank(actHisTask.getDeleteReason())) {
|
|
actHisTask.setComments("【审核不通过】" + actHisTask.getComments());
|
|
}
|
|
}
|
|
|
|
return taskList;
|
|
}
|
|
|
|
|
|
/**
|
|
* 根据流程定义查询任务
|
|
*
|
|
* @param procDefId
|
|
* @return
|
|
*/
|
|
public List<ActTaskDef> findByProcDefId(String procDefId) {
|
|
List<ActTaskDef> list = actTaskDefRepository.findByProcDefId(procDefId);
|
|
for (ActTaskDef actTaskDef : list) {
|
|
candidatesHandle(actTaskDef);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
|
|
/**
|
|
* 根据流程定义和任务key查询任务
|
|
*
|
|
* @param procDefId
|
|
* @param taskKey
|
|
* @return
|
|
*/
|
|
public ActTaskDef findFirstByProcDefIdAndTaskKey(String procDefId, String taskKey) {
|
|
ActTaskDef def = actTaskDefRepository.findFirstByProcDefIdAndTaskKey(procDefId, taskKey);
|
|
candidatesHandle(def);
|
|
return def;
|
|
}
|
|
|
|
|
|
/**
|
|
* 保存任务配置
|
|
*
|
|
* @param taskDef
|
|
*/
|
|
public void saveConfig(ActTaskDef taskDef) {
|
|
ActTaskDef one = actTaskDefRepository.findOne(taskDef.getId());
|
|
one.setCandidateUsers(taskDef.getCandidateUsers());
|
|
one.setCandidateRoles(taskDef.getCandidateRoles());
|
|
one.setCandidateTypes(taskDef.getCandidateTypes());
|
|
//one.setRollbackTaskKey(taskDef.getRollbackTaskKey());
|
|
one.setLastUpdatedTime(new Date());
|
|
|
|
actTaskDefRepository.save(one);
|
|
logger.info("saveTaskConfig uerId:{}, config:{}", InterfaceUtil.getAdminId(), JSONObject.toJSONString(one));
|
|
}
|
|
|
|
|
|
/**
|
|
* 查找任务配置的审批人
|
|
*
|
|
* @param procDefId
|
|
* @param procInsId
|
|
* @param taskDefKey
|
|
* @return
|
|
*/
|
|
public List<String> findCandidateUsers(String procDefId, String procInsId, String taskDefKey) {
|
|
ActTaskDef taskDef = findFirstByProcDefIdAndTaskKey(procDefId, taskDefKey);
|
|
if (taskDef.getTaskIndex() == ActTaskIndexEnum.FIRST_USER_TASK.getIndex()) {
|
|
//任务驳回到发起节点 审批人设置为发起人
|
|
String startUserId = actUtil.getStartUserId(procInsId);
|
|
List<String> res = new ArrayList<>(1);
|
|
logger.info("findCandidateUsers-0-task:{}, startUserId:{}", taskDef.getTaskName(), startUserId);
|
|
res.add(startUserId);
|
|
return res;
|
|
}
|
|
|
|
//去重
|
|
Set<String> res = new HashSet<>();
|
|
|
|
//通过人员id查询
|
|
List<String> candidateUserList = taskDef.getCandidateUserList();
|
|
logger.info("findCandidateUsers-1-task:{}, userList:{}", taskDef.getTaskName(), candidateUserList);
|
|
if (!candidateUserList.isEmpty()) {
|
|
res.addAll(candidateUserList);
|
|
}
|
|
|
|
//通过角色id查询
|
|
List<String> candidateRoleList = taskDef.getCandidateRoleList();
|
|
logger.info("findCandidateUsers-2-task:{}, roleList:{}", taskDef.getTaskName(), candidateRoleList);
|
|
List<String> list = accountService.getUserIsByRole(candidateRoleList);
|
|
logger.info("findCandidateUsers-3-task:{}, userIdListByRole:{}", taskDef.getTaskName(), list);
|
|
if (!list.isEmpty()) {
|
|
res.addAll(list);
|
|
}
|
|
|
|
//通过特殊类型查询
|
|
List<String> candidateTypeList = taskDef.getCandidateTypeList();
|
|
logger.info("findCandidateUsers-type-task:{}, typeList:{}", taskDef.getTaskName(), candidateTypeList);
|
|
List<String> userListByType = queryCandidatesByTypes(candidateTypeList, procInsId);
|
|
logger.info("findCandidateUsers-type-task:{}, userListByType:{}", taskDef.getTaskName(), userListByType);
|
|
if (!userListByType.isEmpty()) {
|
|
res.addAll(userListByType);
|
|
}
|
|
|
|
List<String> resList = new ArrayList<>(res);
|
|
logger.info("findCandidateUsers-4-task:{}, resIds:{}", taskDef.getTaskName(), resList);
|
|
return resList;
|
|
}
|
|
|
|
/**
|
|
* 通过类型查找审批人
|
|
*
|
|
* @param types
|
|
* @param procInsId
|
|
* @return
|
|
*/
|
|
private List<String> queryCandidatesByTypes(List<String> types, String procInsId) {
|
|
if (types == null || types.isEmpty()) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
List<String> userIdList = new ArrayList<>();
|
|
for (String typeStr : types) {
|
|
|
|
ActCandidateTypeEnum candidateTypeEnum = ActCandidateTypeEnum.ofType(Integer.parseInt(typeStr));
|
|
if (ActCandidateTypeEnum.STARTER_LEADER == candidateTypeEnum) {
|
|
//查找发起人部门主管
|
|
String startUserId = actUtil.getStartUserId(procInsId);
|
|
int leaderId = accountService.getOneLevelDeptManagerId(Integer.parseInt(startUserId));
|
|
logger.info("queryCandidatesByType startLeader:{}, procInsId:{} ", leaderId, procInsId);
|
|
if (leaderId != 0) {
|
|
userIdList.add(String.valueOf(leaderId));
|
|
}
|
|
} else if (ActCandidateTypeEnum.DEPT_LEADER == candidateTypeEnum) {
|
|
Record record = actUtil.getVariable(ActConstant.DEPT_LEADER_ID, procInsId);
|
|
if (record != null) {
|
|
String deptLeaderId = record.getStr("text");
|
|
userIdList.add(deptLeaderId);
|
|
logger.info("queryCandidatesByType deptLeader:{}, procInsId:{} ", deptLeaderId, procInsId);
|
|
}else{
|
|
logger.error("queryCandidatesByType not find deptLeader procInsId:{} ", procInsId);
|
|
}
|
|
}
|
|
}
|
|
|
|
return userIdList;
|
|
}
|
|
|
|
|
|
/**
|
|
* 任务审批人列表从sring转成list
|
|
*
|
|
* @param actTaskDef
|
|
*/
|
|
private void candidatesHandle(ActTaskDef actTaskDef) {
|
|
String candidateUsers = actTaskDef.getCandidateUsers();
|
|
List<String> userIdList = new ArrayList<>();
|
|
if (StringUtils.isNotBlank(candidateUsers)) {
|
|
userIdList = Arrays.asList(candidateUsers.split("#"));
|
|
}
|
|
actTaskDef.setCandidateUserList(userIdList);
|
|
|
|
String candidateRoles = actTaskDef.getCandidateRoles();
|
|
List<String> roleIdList = new ArrayList<>();
|
|
if (StringUtils.isNotBlank(candidateRoles)) {
|
|
roleIdList = Arrays.asList(candidateRoles.split("#"));
|
|
}
|
|
actTaskDef.setCandidateRoleList(roleIdList);
|
|
|
|
String candidateTypes = actTaskDef.getCandidateTypes();
|
|
List<String> typeIdList = new ArrayList<>();
|
|
if (StringUtils.isNotBlank(candidateTypes)) {
|
|
typeIdList = Arrays.asList(candidateTypes.split("#"));
|
|
}
|
|
actTaskDef.setCandidateTypeList(typeIdList);
|
|
}
|
|
|
|
|
|
/**
|
|
* 设置历史任务审批人
|
|
*
|
|
* @param actHisTask
|
|
*/
|
|
private void setAssign(ActHisTask actHisTask) {
|
|
if (StringUtils.isNotBlank(actHisTask.getAssign())) {
|
|
if ("-1".equals(actHisTask.getAssign())) {
|
|
actHisTask.setAssign("系统");
|
|
return;
|
|
}
|
|
|
|
String userName = accountService.getNameById(Integer.parseInt(actHisTask.getAssign()));
|
|
actHisTask.setAssign(userName);
|
|
return;
|
|
}
|
|
|
|
Task task = taskService.createTaskQuery().taskId(actHisTask.getTaskId()).singleResult();
|
|
if (task == null) {
|
|
return;
|
|
}
|
|
|
|
if (StringUtils.isNotBlank(task.getAssignee())) {
|
|
actHisTask.setAssign(task.getAssignee());
|
|
return;
|
|
}
|
|
|
|
actHisTask.setAssign(actUtil.getAssigneeByIdentityLink(task.getId()));
|
|
}
|
|
|
|
|
|
public void setTaskAssignAndSaveRecord(int projectId, Admin targetAdmin) {
|
|
Task currentTask = actUtil.getCurrentTask(projectId);
|
|
if (currentTask != null) {
|
|
//设置审批人到流程
|
|
taskService.setAssignee(currentTask.getId(), targetAdmin.getId() + "");
|
|
|
|
//保存一条指定承接人记录
|
|
projectTaskRecordService.saveTaskRecord(projectId, currentTask,
|
|
ProjectTaskRecord.STATUS_RE_ASSIGNEE, ActTaskIndexEnum.COMMON.getIndex(),
|
|
"指定承接人【" + targetAdmin.getRealName() + "]");
|
|
} else {
|
|
logger.error("setTaskAssignAndSaveRecordError task is null, projectId:{}", projectId);
|
|
}
|
|
}
|
|
|
|
}
|