项目任意退回功能开发
parent
3dd06d3da9
commit
c3a19e7975
|
@ -11,6 +11,23 @@ public class ActConstant {
|
|||
public static final String PROC_INS_ID="procInsId";
|
||||
public static final String PROC_DEF_KEY="procDefKey";
|
||||
|
||||
|
||||
/**
|
||||
* 结束节点
|
||||
*/
|
||||
public static final int TASK_INDEX_END= -1;
|
||||
|
||||
|
||||
/**
|
||||
* 0-未知或者其他节点
|
||||
*/
|
||||
public static final int TASK_INDEX_OTHER= 0;
|
||||
|
||||
/**
|
||||
* 开始节点
|
||||
*/
|
||||
public static final int TASK_INDEX_START= 1;
|
||||
|
||||
/**
|
||||
* 发起审批节点
|
||||
*/
|
||||
|
|
|
@ -763,6 +763,24 @@ public class ProjectController extends BaseController {
|
|||
return projectService.batchUpdateApprove(json);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退回到指定节点
|
||||
* 1、完结的项目允许重启并指定回退节点
|
||||
* 2、跨流程(概算、预算等)退回
|
||||
* 3、不跨流程退回(例如:仅在预算的审批流中退回某个节点)
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping("/rollbackToRecord")
|
||||
public ResponseMsg rollbackToRecord(@RequestBody String json) {
|
||||
try {
|
||||
projectService.rollbackToRecord(json);
|
||||
return ResponseMsg.buildSuccessMsg("回退成功");
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
return ResponseMsg.buildSuccessMsg("回退失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看审核流程
|
||||
*/
|
||||
|
|
|
@ -31,6 +31,9 @@ public interface ProjectRepository extends JpaRepository<Project,Integer> {
|
|||
Project findById(int id);
|
||||
|
||||
|
||||
@Query(value = "select * from project where approve_id = ?", nativeQuery = true)
|
||||
List<Project> findByApproveId(int adminId);
|
||||
|
||||
@Modifying
|
||||
@Transactional(rollbackOn = Exception.class)
|
||||
@Query(value = "update project set approve_id=?, approve_name=? where approve_id = ?", nativeQuery = true)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package cn.palmte.work.model;
|
||||
|
||||
import cn.palmte.work.bean.StatusEnum;
|
||||
import cn.palmte.work.config.activiti.ActConstant;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 项目审批任务记录
|
||||
|
@ -14,6 +15,9 @@ import java.util.List;
|
|||
@Table(name = "project_task_record")
|
||||
public class ProjectTaskRecord {
|
||||
|
||||
public static final int STATUS_ROLLBACK = 4;//管理员退回
|
||||
public static final int STATUS_RE_ASSIGNEE = 5; //指定承接人
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private int id;
|
||||
|
@ -35,6 +39,8 @@ public class ProjectTaskRecord {
|
|||
|
||||
/**
|
||||
* @see cn.palmte.work.bean.ApproveStatusEnum#approveStatus
|
||||
*
|
||||
* 状态 1-提交审批 2-审批通过 3-审批不通过 4-管理员退回 5-指定承接人
|
||||
*/
|
||||
@Column(name = "task_status")
|
||||
private int taskStatus;
|
||||
|
@ -75,4 +81,73 @@ public class ProjectTaskRecord {
|
|||
@Column(name = "file_url")
|
||||
private String fileUrl;
|
||||
|
||||
|
||||
/**
|
||||
* 退回 project_task_record表id
|
||||
*/
|
||||
@Column(name = "rollback_record_id")
|
||||
private int rollbackRecordId;
|
||||
|
||||
/**
|
||||
* 退回到哪里 保存快照信息
|
||||
*/
|
||||
@Column(name = "rollback_desc")
|
||||
private String rollbackDesc;
|
||||
|
||||
|
||||
/**
|
||||
* 是否运行管理员退回
|
||||
*/
|
||||
@Transient
|
||||
private boolean canRollback = false;
|
||||
|
||||
@Transient
|
||||
private String procDefName = "";
|
||||
|
||||
@Transient
|
||||
private String procDefKey= "";
|
||||
|
||||
public StatusEnum getStatusByProDefId() {
|
||||
if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_BUDGET)) {
|
||||
return StatusEnum.BUDGET_ACCOUNTS;
|
||||
}if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_SETTLE)) {
|
||||
return StatusEnum.SETTLE_ACCOUNTS;
|
||||
}if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_FINAL)) {
|
||||
return StatusEnum.FINAL_ACCOUNTS;
|
||||
}else{
|
||||
return StatusEnum.ESTIMATE_ACCOUNTS;
|
||||
}
|
||||
}
|
||||
|
||||
public String getProcDefName() {
|
||||
if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_BUDGET)) {
|
||||
return "预算审批流程";
|
||||
}if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_SETTLE)) {
|
||||
return "结算审批流程";
|
||||
}if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_FINAL)) {
|
||||
return "决算审批流程";
|
||||
}else{
|
||||
return "概算审批流程";
|
||||
}
|
||||
}
|
||||
|
||||
public void setProcDefName(String procDefName) {
|
||||
this.procDefName = procDefName;
|
||||
}
|
||||
|
||||
public String getProcDefKey() {
|
||||
if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_BUDGET)) {
|
||||
return ActConstant.PROCESS_DEFKEY_BUDGET;
|
||||
}if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_SETTLE)) {
|
||||
return ActConstant.PROCESS_DEFKEY_SETTLE;
|
||||
}if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_FINAL)) {
|
||||
return ActConstant.PROCESS_DEFKEY_FINAL;
|
||||
}else{
|
||||
return ActConstant.PROCESS_DEFKEY_ESTIMATE;
|
||||
}
|
||||
}
|
||||
|
||||
public void setProcDefKey(String procDefKey) {
|
||||
this.procDefKey = procDefKey;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,12 @@ package cn.palmte.work.service;
|
|||
import cn.palmte.work.bean.ApproveStatusEnum;
|
||||
import cn.palmte.work.config.activiti.ActConstant;
|
||||
import cn.palmte.work.model.ActTaskDefRepository;
|
||||
import cn.palmte.work.model.ProjectTaskRecord;
|
||||
import cn.palmte.work.pojo.ActProcIns;
|
||||
import cn.palmte.work.utils.ActUtil;
|
||||
import cn.palmte.work.utils.InterfaceUtil;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.bpmn.model.FlowNode;
|
||||
import org.activiti.bpmn.model.Process;
|
||||
import org.activiti.bpmn.model.SequenceFlow;
|
||||
import org.activiti.engine.HistoryService;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
|
@ -68,7 +68,7 @@ public class ActProcInsService {
|
|||
|
||||
|
||||
/**
|
||||
* 启动流程实列
|
||||
* 正常启动流程实列
|
||||
*
|
||||
* @param procDefKey
|
||||
* @param variables
|
||||
|
@ -105,7 +105,49 @@ public class ActProcInsService {
|
|||
taskService.complete(taskId);
|
||||
|
||||
projectTaskRecordService.saveTaskRecord(Integer.parseInt(instance.getBusinessKey()),
|
||||
task, ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus(), ActConstant.TASK_INDEX_FIRST_USER_TASK, comment, "");
|
||||
task, ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus(), ActConstant.TASK_INDEX_FIRST_USER_TASK, comment);
|
||||
|
||||
return instance.getId();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 系统启动流程实列
|
||||
*
|
||||
* @param procDefKey
|
||||
* @param businessKey
|
||||
* @param variables
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public String startProcessInstanceBySystem(String procDefKey, String businessKey, Map<String, Object> variables,
|
||||
ProjectTaskRecord taskRecord) throws Exception {
|
||||
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().processDefinitionKey(procDefKey).active().orderByProcessDefinitionVersion().desc().list();
|
||||
if (list == null || list.isEmpty()) {
|
||||
throw new Exception("procDefKey(" + procDefKey + ")未定义");
|
||||
}
|
||||
|
||||
//取最新版本的流程定义进行启动流程实列
|
||||
ProcessDefinition processDefinition = list.get(0);
|
||||
|
||||
String adminId = "-1";
|
||||
variables.put(ActConstant.START_PROCESS_USERID, adminId);
|
||||
//启动流程
|
||||
ProcessInstance instance = runtimeService.startProcessInstanceById(processDefinition.getId(), businessKey, variables);
|
||||
logger.info("startProcessInstanceSuccess procInsId:{}, procDefKey:{}, procDefName:{}", instance.getId(), instance.getProcessDefinitionKey(), instance.getProcessDefinitionName());
|
||||
|
||||
String procInsId = instance.getProcessInstanceId();
|
||||
Task task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
|
||||
if (task == null) {
|
||||
throw new Exception("procDefKey(" + procDefKey + ")启动异常");
|
||||
}
|
||||
|
||||
String taskId = task.getId();
|
||||
String comment = "系统提交" + processDefinition.getName();
|
||||
Authentication.setAuthenticatedUserId(adminId);
|
||||
taskService.addComment(taskId, procInsId, comment);
|
||||
|
||||
taskService.setAssignee(taskId, taskRecord.getAssigneeId() + "");
|
||||
|
||||
return instance.getId();
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ public class ActTaskDefService {
|
|||
|
||||
|
||||
//保存审批记录
|
||||
projectTaskRecordService.saveTaskRecord(Integer.parseInt(processInstance.getBusinessKey()),
|
||||
projectTaskRecordService.saveTaskRecordWithFileUrl(Integer.parseInt(processInstance.getBusinessKey()),
|
||||
currentTask, type, actTaskDef.getTaskIndex(), message, fileUrl);
|
||||
}
|
||||
|
||||
|
@ -125,12 +125,36 @@ public class ActTaskDefService {
|
|||
}
|
||||
|
||||
|
||||
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, "任务由系统自动审批通过",
|
||||
ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());
|
||||
|
||||
task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
|
||||
logger.info("skipTaskByProcInsIdAndTaskName currentTaskName:{}, skipToTaskName:{}", task.getName(), skipToTaskName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void completeSkipTask(Task task, ProcessInstance processInstance, String message, int type) {
|
||||
String taskId = task.getId();
|
||||
ActTaskDef actTaskDef = findFirstByProcDefIdAndTaskKey(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
|
||||
|
||||
Authentication.setAuthenticatedUserId("-1");
|
||||
taskService.addComment(taskId, processInstance.getProcessInstanceId(), message);
|
||||
if (actTaskDef.getTaskIndex() != ActConstant.TASK_INDEX_FIRST_USER_TASK) {
|
||||
//不是发起节点 增加comment
|
||||
Authentication.setAuthenticatedUserId("-1");
|
||||
taskService.addComment(taskId, processInstance.getProcessInstanceId(), message);
|
||||
}
|
||||
|
||||
taskService.setAssignee(taskId, "-1");
|
||||
|
||||
if (ActConstant.TASK_TYPE_SINGE == actTaskDef.getTaskType()) {
|
||||
|
@ -376,4 +400,18 @@ public class ActTaskDefService {
|
|||
}
|
||||
|
||||
|
||||
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, ActConstant.TASK_INDEX_OTHER,
|
||||
"指定承接人【" + targetAdmin.getRealName() + "]");
|
||||
}else{
|
||||
logger.error("setTaskAssignAndSaveRecordError task is null, projectId:{}", projectId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -99,6 +99,24 @@ public class ProjectInstanceService {
|
|||
logger.info("startProcess processDefkey:{}, businessKey:{}", processDefkey, businessKey);
|
||||
String processInstanceId = actProcInsService.startProcessInstance(processDefkey, businessKey, variables);
|
||||
|
||||
saveProjectInstance(project, processDefkey, processInstanceId);
|
||||
}
|
||||
|
||||
|
||||
public String startProcessBySystem(Project project, String processDefkey, ProjectTaskRecord taskRecord) throws Exception {
|
||||
HashMap<String, Object> variables = new HashMap<>();
|
||||
variables.put(ActConstant.KEY_PROJECT_TYPE, project.getType());
|
||||
String businessKey = String.valueOf(project.getId());
|
||||
logger.info("startProcessBySystem processDefkey:{}, businessKey:{}", processDefkey, businessKey);
|
||||
|
||||
String processInstanceId = actProcInsService.startProcessInstanceBySystem(
|
||||
processDefkey, businessKey, variables, taskRecord);
|
||||
|
||||
saveProjectInstance(project, processDefkey, processInstanceId);
|
||||
return processInstanceId;
|
||||
}
|
||||
|
||||
private void saveProjectInstance(Project project, String processDefkey, String processInstanceId) {
|
||||
//保存流程实例id与项目的关联关系
|
||||
ProjectInstanceRelation relation = new ProjectInstanceRelation();
|
||||
relation.setProjectId(project.getId());
|
||||
|
|
|
@ -5,6 +5,8 @@ import cn.palmte.work.model.*;
|
|||
import cn.palmte.work.utils.InterfaceUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -23,6 +25,7 @@ import java.util.stream.Collectors;
|
|||
*/
|
||||
@Service
|
||||
public class ProjectService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProjectService.class);
|
||||
@Autowired
|
||||
private Pagination pagination;
|
||||
@Autowired
|
||||
|
@ -49,6 +52,10 @@ public class ProjectService {
|
|||
private ProjectBudgetService projectBudgetService;
|
||||
@Autowired
|
||||
private NumSeqService numSeqService;
|
||||
@Autowired
|
||||
private ProjectTaskRecordRepository projectTaskRecordRepository;
|
||||
@Autowired
|
||||
private ProjectTaskRecordService projectTaskRecordService;
|
||||
|
||||
private QueryHelper getQueryHelper(Map<String, String> searchInfo) {
|
||||
/*"CASE p.type WHEN 1 THEN '工程集成类' WHEN 2 THEN '设备集成类' WHEN 3 THEN '战略合作类' ELSE '未知' AS typeDesc," +
|
||||
|
@ -543,10 +550,132 @@ public class ProjectService {
|
|||
* @return
|
||||
*/
|
||||
public ResponseMsg batchUpdateApprove(String json) {
|
||||
int myAdminId = InterfaceUtil.getAdminId();
|
||||
List<Project> projectList = projectRepository.findByApproveId(myAdminId);
|
||||
if (projectList.isEmpty()) {
|
||||
return ResponseMsg.buildSuccessMsg("当前没有审批项目需要承接");
|
||||
}
|
||||
|
||||
JSONObject obj = JSON.parseObject(json);
|
||||
int adminId = obj.getIntValue("adminId");
|
||||
Admin targetAdmin = adminRepository.findOne(adminId);
|
||||
projectRepository.batchUpdateApprove(targetAdmin.getId(), targetAdmin.getRealName(), InterfaceUtil.getAdminId());
|
||||
return ResponseMsg.buildSuccessMsg("指定成功");
|
||||
|
||||
projectRepository.batchUpdateApprove(targetAdmin.getId(), targetAdmin.getRealName(), myAdminId);
|
||||
|
||||
for (Project project : projectList) {
|
||||
actTaskDefService.setTaskAssignAndSaveRecord(project.getId(), targetAdmin);
|
||||
}
|
||||
|
||||
return ResponseMsg.buildSuccessMsg("指定承接人成功");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 退回到指定节点
|
||||
* 1、完结的项目允许重启并指定回退节点
|
||||
* 2、跨流程(概算、预算等)退回
|
||||
* 3、不跨流程退回(例如:仅在预算的审批流中退回某个节点)
|
||||
*
|
||||
* 因为要跨流程和重启结束流程 所以全部采用重新发起一个流程的方式
|
||||
*/
|
||||
public void rollbackToRecord(String json) throws Exception{
|
||||
JSONObject obj = JSON.parseObject(json);
|
||||
int taskRecordId = obj.getIntValue("taskRecordId");
|
||||
String message = obj.getString("message");
|
||||
String rollbackDesc = obj.getString("rollbackDesc");
|
||||
|
||||
ProjectTaskRecord one = projectTaskRecordRepository.findOne(taskRecordId);
|
||||
logger.info("rollbackTask queryTaskRecord : {}", JSONObject.toJSONString(one));
|
||||
|
||||
int projectId = one.getProjectId();
|
||||
int taskStatus = one.getTaskStatus();
|
||||
StatusEnum statusEnum = one.getStatusByProDefId();
|
||||
String proDefKey = one.getProcDefKey();
|
||||
|
||||
//是否回退到发起节点
|
||||
boolean isStartTask = (taskStatus == 1);
|
||||
|
||||
Project project = projectRepository.findOne(projectId);
|
||||
//项目退回到指定状态
|
||||
project.setStatus(statusEnum.getStatus());
|
||||
project.setStatusDesc(statusEnum.getStatusDesc());
|
||||
project.setLastUpdateTime(new Date());
|
||||
|
||||
//指定审批人
|
||||
if (isStartTask) {
|
||||
//退回到发起节点 审批人设置为空
|
||||
project.setApproveId(0);
|
||||
project.setApproveName("");
|
||||
}else{
|
||||
project.setApproveId(Integer.parseInt(one.getAssigneeId()));
|
||||
project.setApproveName(one.getAssigneeName());
|
||||
}
|
||||
|
||||
//先全部默认为未知 后面再根据情况更新
|
||||
setApproveStatus(statusEnum, isStartTask, project);
|
||||
|
||||
//修改项目
|
||||
projectRepository.saveAndFlush(project);
|
||||
logger.info("rollbackTask updateProject : {}", JSONObject.toJSONString(project));
|
||||
|
||||
//保存退回审批记录
|
||||
projectTaskRecordService.saveTaskRecordWithRollback(projectId, one, message, rollbackDesc);
|
||||
|
||||
//启动流程
|
||||
String processInstanceId = projectInstanceService.startProcessBySystem(project, proDefKey, one);
|
||||
logger.info("rollbackTask startProcessBySystem : {}", processInstanceId);
|
||||
|
||||
|
||||
//跳到退回任务
|
||||
actTaskDefService.skipTaskByProcInsIdAndTaskName(processInstanceId, one.getTaskName());
|
||||
logger.info("rollbackTask skipTaskByProcInsIdAndTaskName : success");
|
||||
}
|
||||
|
||||
private void setApproveStatus(StatusEnum statusEnum, boolean isStartTask, Project project) {
|
||||
project.setApproveStatusEstimate(-1);
|
||||
project.setApproveStatusBudget(-1);
|
||||
project.setApproveStatusSettle(-1);
|
||||
project.setApproveStatusFinal(-1);
|
||||
|
||||
if (statusEnum == StatusEnum.ESTIMATE_ACCOUNTS) {
|
||||
if (isStartTask) {
|
||||
//退回到发起节点 状态设置为审批未通过
|
||||
project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_UNPASS.getApproveStatus());
|
||||
}else{
|
||||
project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
|
||||
}
|
||||
} else if (statusEnum == StatusEnum.BUDGET_ACCOUNTS) {
|
||||
project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());
|
||||
|
||||
if (isStartTask) {
|
||||
project.setApproveStatusBudget(ApproveStatusEnum.APPROVAL_UNPASS.getApproveStatus());
|
||||
}else{
|
||||
project.setApproveStatusBudget(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
|
||||
}
|
||||
|
||||
}else if (statusEnum == StatusEnum.SETTLE_ACCOUNTS) {
|
||||
project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());
|
||||
project.setApproveStatusBudget(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());
|
||||
|
||||
if (isStartTask) {
|
||||
project.setApproveStatusSettle(ApproveStatusEnum.APPROVAL_UNPASS.getApproveStatus());
|
||||
}else{
|
||||
project.setApproveStatusSettle(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
|
||||
}
|
||||
|
||||
}else if (statusEnum == StatusEnum.FINAL_ACCOUNTS) {
|
||||
project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());
|
||||
project.setApproveStatusBudget(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());
|
||||
project.setApproveStatusSettle(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());
|
||||
|
||||
if (isStartTask) {
|
||||
project.setApproveStatusFinal(ApproveStatusEnum.APPROVAL_UNPASS.getApproveStatus());
|
||||
}else{
|
||||
project.setApproveStatusFinal(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package cn.palmte.work.service;
|
||||
|
||||
import cn.palmte.work.config.activiti.ActConstant;
|
||||
import cn.palmte.work.model.ProjectTaskRecord;
|
||||
import cn.palmte.work.model.ProjectTaskRecordRepository;
|
||||
import cn.palmte.work.utils.ActUtil;
|
||||
import cn.palmte.work.utils.InterfaceUtil;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -12,8 +12,7 @@ import org.springframework.stereotype.Service;
|
|||
import top.jfunc.common.db.QueryHelper;
|
||||
import top.jfunc.common.db.utils.Pagination;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@Service
|
||||
|
@ -25,9 +24,6 @@ public class ProjectTaskRecordService {
|
|||
@Autowired
|
||||
Pagination pagination;
|
||||
|
||||
@Autowired
|
||||
private ActUtil actUtil;
|
||||
|
||||
|
||||
/**
|
||||
* 保存审批任务记录
|
||||
|
@ -36,8 +32,46 @@ public class ProjectTaskRecordService {
|
|||
* @param status
|
||||
* @param comment
|
||||
*/
|
||||
public void saveTaskRecord(int projectId, Task task, int status, int taskIndex, String comment, String fileUrl) {
|
||||
task.getProcessDefinitionId();
|
||||
public void saveTaskRecord(int projectId, Task task, int status, int taskIndex, String comment) {
|
||||
ProjectTaskRecord record = getProjectTaskRecord(projectId, task, status, taskIndex, comment);
|
||||
saveTaskRecord(record);
|
||||
}
|
||||
|
||||
public void saveTaskRecordWithFileUrl(int projectId, Task task, int status,
|
||||
int taskIndex, String comment, String fileUrl) {
|
||||
ProjectTaskRecord record = getProjectTaskRecord(projectId, task, status, taskIndex, comment);
|
||||
record.setFileUrl(fileUrl);
|
||||
saveTaskRecord(record);
|
||||
}
|
||||
|
||||
public void saveTaskRecordWithRollback(int projectId, ProjectTaskRecord oldRecord, String comment, String rollbackDesc) {
|
||||
ProjectTaskRecord record = new ProjectTaskRecord();
|
||||
record.setProjectId(projectId);
|
||||
record.setProcDefId(oldRecord.getProcDefId());
|
||||
record.setProcInsId(oldRecord.getProcInsId());
|
||||
record.setTaskDefKey(oldRecord.getTaskDefKey());
|
||||
record.setTaskName(oldRecord.getTaskName());
|
||||
record.setTaskComment(comment);
|
||||
record.setTaskStatus(ProjectTaskRecord.STATUS_ROLLBACK);
|
||||
record.setAssigneeId(InterfaceUtil.getAdminId() + "");
|
||||
record.setAssigneeName(InterfaceUtil.getAdmin().getRealName());
|
||||
record.setTaskIndex(ActConstant.TASK_INDEX_OTHER);
|
||||
record.setCreateTime(new Date());
|
||||
record.setRollbackRecordId(oldRecord.getId());
|
||||
record.setRollbackDesc(rollbackDesc);
|
||||
|
||||
saveTaskRecord(record);
|
||||
}
|
||||
|
||||
private void saveTaskRecord(ProjectTaskRecord record) {
|
||||
try {
|
||||
projectTaskRecordRepository.save(record);
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ProjectTaskRecord getProjectTaskRecord(int projectId, Task task, int status, int taskIndex, String comment) {
|
||||
ProjectTaskRecord record = new ProjectTaskRecord();
|
||||
record.setProjectId(projectId);
|
||||
record.setProcDefId(task.getProcessDefinitionId());
|
||||
|
@ -50,12 +84,7 @@ public class ProjectTaskRecordService {
|
|||
record.setAssigneeName(InterfaceUtil.getAdmin().getRealName());
|
||||
record.setTaskIndex(taskIndex);
|
||||
record.setCreateTime(new Date());
|
||||
record.setFileUrl(fileUrl);
|
||||
try {
|
||||
projectTaskRecordRepository.save(record);
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,8 +99,38 @@ public class ProjectTaskRecordService {
|
|||
QueryHelper queryHelper = new QueryHelper(select, " project_task_record tr LEFT JOIN sys_user su on su.id=tr.assignee_id ");
|
||||
queryHelper.addCondition("tr.project_id=?", projectId);
|
||||
queryHelper.addOrderProperty("tr.create_time", true);
|
||||
return pagination.find(queryHelper.getSql(), ProjectTaskRecord.class);
|
||||
List<ProjectTaskRecord> projectTaskRecords = pagination.find(queryHelper.getSql(), ProjectTaskRecord.class);
|
||||
|
||||
//设置哪些任务能退回 admin才能退回
|
||||
if (!projectTaskRecords.isEmpty() && "admin".equals(InterfaceUtil.getAdmin().getRealName())) {
|
||||
//预算流程可能有多个 找到最新的一个预算流程 最新的预算流程才能退回
|
||||
String lastProcInsId = "";
|
||||
Optional<String> lastProcInsIdOp = projectTaskRecords.stream()
|
||||
.filter(r -> r.getProcDefId().startsWith(ActConstant.PROCESS_DEFKEY_BUDGET))
|
||||
.map(ProjectTaskRecord::getProcInsId).max(Comparator.naturalOrder());
|
||||
if (lastProcInsIdOp.isPresent()) {
|
||||
lastProcInsId = lastProcInsIdOp.get();
|
||||
}
|
||||
|
||||
for (ProjectTaskRecord record : projectTaskRecords) {
|
||||
if (record.getTaskStatus() == ProjectTaskRecord.STATUS_ROLLBACK) {
|
||||
//已退回记录 不能再退回
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!record.getProcDefId().startsWith(ActConstant.PROCESS_DEFKEY_BUDGET)) {
|
||||
//非预算流程全部支持退回
|
||||
record.setCanRollback(true);
|
||||
} else {
|
||||
//预算最后一个流程支持退回
|
||||
if (record.getProcInsId().equals(lastProcInsId)) {
|
||||
record.setCanRollback(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return projectTaskRecords;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ public class ActUtil {
|
|||
return null;
|
||||
}
|
||||
ProjectInstanceRelation projectInstanceRelation = relationList.get(0);
|
||||
logger.info("getCurrentTask projectId:{}, procInsId:{}", projectId, projectInstanceRelation.getProcessInsId());
|
||||
return taskService.createTaskQuery().processInstanceId(projectInstanceRelation.getProcessInsId()).singleResult();
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
|
|
|
@ -2231,6 +2231,22 @@
|
|||
<div class="time-axis-title"> ${node.roleName}-${node.assigneeName}:
|
||||
<#if node.taskIndex!=2 && node.taskStatus==2>审核通过</#if>
|
||||
<#if node.taskIndex!=2 && node.taskStatus==3>审核不通过</#if>
|
||||
|
||||
<#if node.canRollback>
|
||||
<button type="button"
|
||||
class="am-btn am-btn-default am-btn-xs am-text-secondary"
|
||||
onclick="openRollbackToRecordModal('${node.id}', '${node.procDefName}-${node.taskName}-${node.assigneeName}')">
|
||||
退回
|
||||
</button>
|
||||
</#if>
|
||||
|
||||
|
||||
|
||||
<#if node.taskStatus==4>
|
||||
退回到【${node.rollbackDesc!}】
|
||||
</#if>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="time-axis-title">
|
||||
${node.taskComment}
|
||||
|
@ -2771,6 +2787,52 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<#--管理员退回弹窗-->
|
||||
<div class="am-modal am-modal-prompt" style="width: 600px;max-height:400px;overflow-y:auto;"
|
||||
tabindex="-1" id="rollbackToRecordModal">
|
||||
<div class="am-modal-dialog">
|
||||
<div class="modal-header">
|
||||
<h2 style="padding-top: 20px;font-size: x-large;">您正在进行退回功能</h2>
|
||||
<h5 >项目名称:<span style="color: red">${project.name}</span></h5>
|
||||
<h5 >退回到:<span id="rbTaskDesc" style="color: red"></span></h5>
|
||||
</div>
|
||||
|
||||
<div class="am-modal-bd" style="border-bottom: none">
|
||||
<form method="post" class="am-form" id="tmpForm" action="">
|
||||
<div class="am-tabs am-margin" style="border-top: 1px solid #ddd;" data-am-tabs>
|
||||
<div class="am-tabs-bd">
|
||||
<div class="am-tab-panel am-fade am-in am-active" id="tab1">
|
||||
<input type="hidden" id="rbTaskRecordId" name="rbTaskRecordId" value=''/>
|
||||
|
||||
<div class="am-g am-form-group am-margin-top" style="display: flex;">
|
||||
<div class="am-u-sm-2 am-u-md-2 am-text-right">
|
||||
<span style="color: red;">*</span>退回意见</div>
|
||||
<div class="am-u-sm-10 am-u-md-10">
|
||||
<textarea id="rollbackTextarea" minlength="1" rows="3" cols="40" maxlength="300" class="am-input"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="am-modal-footer">
|
||||
<button type="button"
|
||||
class="am-btn am-btn-default am-btn-xs am-text-secondary"
|
||||
onclick="$('#rollbackToRecordModal').modal('close')">
|
||||
取消
|
||||
</button>
|
||||
<span style="margin-left: 100px"></span>
|
||||
<button type="button"
|
||||
class="am-btn am-btn-default am-btn-xs am-text-secondary"
|
||||
onclick="rollbackToRecord()">
|
||||
确定
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!--选项卡(tabs)end-->
|
||||
<div class="am-margin">
|
||||
|
@ -2917,4 +2979,52 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开退回弹窗
|
||||
*/
|
||||
var openRollbackToRecordModal= function(taskRecordId, rbTaskDesc) {
|
||||
$("#rbTaskRecordId").val(taskRecordId);
|
||||
$("#rbTaskDesc").html(rbTaskDesc);
|
||||
|
||||
$('#rollbackToRecordModal').modal({
|
||||
relatedElement: this,
|
||||
onConfirm: function() {
|
||||
console.log("提交");
|
||||
},
|
||||
onCancel: function() {
|
||||
console.log("取消");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 退回
|
||||
*/
|
||||
var rollbackToRecord = function () {
|
||||
var message = $("#rollbackTextarea").val();
|
||||
var rbTaskDesc = $("#rbTaskDesc").text();
|
||||
var rbTaskRecordId = $("#rbTaskRecordId").val();
|
||||
var params = {
|
||||
taskRecordId: rbTaskRecordId,
|
||||
message: message,
|
||||
rollbackDesc: rbTaskDesc
|
||||
};
|
||||
$.ajax({
|
||||
url: '${base}/project/rollbackToRecord',
|
||||
data: JSON.stringify(params),
|
||||
dataType: "json",
|
||||
contentType: "application/json",
|
||||
type: 'post',
|
||||
async: false,
|
||||
success: function (data) {
|
||||
if (data.status == 0) {
|
||||
alert(data.msg);
|
||||
window.location.href = window.location.href;
|
||||
} else if (data.status == 1) {
|
||||
alert(data.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
|
@ -30,6 +30,10 @@
|
|||
<div class="time-axis-title"> ${node.roleName}-${node.assigneeName}:
|
||||
<#if node.taskIndex!=2 && node.taskStatus==2>审核通过</#if>
|
||||
<#if node.taskIndex!=2 && node.taskStatus==3>审核不通过</#if>
|
||||
|
||||
<#if node.taskStatus==4>
|
||||
退回到【${node.rollbackDesc!}】
|
||||
</#if>
|
||||
</div>
|
||||
<div class="time-axis-title">
|
||||
${node.taskComment}
|
||||
|
@ -105,20 +109,3 @@
|
|||
</@defaultLayout.layout>
|
||||
|
||||
<script type="text/javascript" src="${base}/assets/js/jquery-3.4.1.min.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue