Commit 57daf8e6 authored by Rensq's avatar Rensq

优化危险作业详情流程流转历史接口

parent 809d7376
......@@ -157,4 +157,55 @@ ALTER TABLE t_sys_duty ALTER COLUMN duty_date TYPE varchar(255) USING duty_date:
# 20250611上线
# 教育培训人员类型支持多选
ALTER TABLE t_train_project
ALTER COLUMN visit_type TYPE varchar(1000);
\ No newline at end of file
ALTER COLUMN visit_type TYPE varchar(1000);
# 修改 act_id_group
CREATE OR REPLACE VIEW ACT_ID_GROUP AS
SELECT NULL
:: text AS REV_,
concat_text (
VARIADIC ARRAY [( r.tree_level ):: text, '-' :: text, ( r.role_id ):: text ]) AS ID_,
CASE
WHEN ( r.tree_level = ( 1 ):: NUMERIC ) THEN
concat_text (
VARIADIC ARRAY [ '总公司' :: text, '-' :: text, ( r.role_name ):: text ])
WHEN ( r.tree_level = ( 2 ):: NUMERIC ) THEN
concat_text (
VARIADIC ARRAY [ '大区/平台' :: text, '-' :: text, ( r.role_name ):: text ])
WHEN ( r.tree_level = ( 3 ):: NUMERIC ) THEN
concat_text (
VARIADIC ARRAY [ '经营部' :: text, '-' :: text, ( r.role_name ):: text ])
WHEN ( r.tree_level = ( 4 ):: NUMERIC ) THEN
concat_text (
VARIADIC ARRAY [ '基层企业' :: text, '-' :: text, ( r.role_name ):: text ])
ELSE ( r.role_name ):: text
END AS NAME_,
r.tree_level AS TYPE_
FROM
t_sys_role r
WHERE
(((
r.STATUS
):: INTEGER = 0
)
AND ( r.tree_level IS NOT NULL ))
ORDER BY
r.tree_level NULLS FIRST;
# 修改 act_id_user
CREATE OR REPLACE VIEW act_id_user AS
SELECT
su.user_id AS ID_,
NULL :: text AS REV_,
su.user_name AS FIRST_,
su.phone_no :: text AS LAST_,
su.email AS EMAIL_,
su.login_pwd AS PWD_,
NULL :: text AS PICTURE_ID_
FROM
t_sys_user su;
\ No newline at end of file
......@@ -190,6 +190,19 @@ public class THazardWorkPlanController extends SuperController
return baseResponse;
}
@ApiOperation(
value = "根据流程实例ID获取任务历史",
notes = "根据流程实例ID获取任务历史"
)
@GetMapping({"/getAllTaskApprovers"})
public BaseResponse<List<TaskInfoDTO>> getAllTaskApprovers(String processInstanceId,String planId) {
BaseResponse<List<TaskInfoDTO>> baseResponse = new BaseResponse<>();
List<TaskInfoDTO> allTaskApprovers = tHazardWorkPlanService.getAllTaskApprovers(processInstanceId, planId);
baseResponse.setData(allTaskApprovers);
return baseResponse;
}
@ApiOperation(value = "修改 危险作业计划 ", notes = "Update THazardWorkPlan By Id")
@PutMapping(value = "/update")
public BaseResponse<THazardWorkPlan> updateEntity(@RequestBody THazardWorkPlan updateRequest){
......
package com.testor.module.hazard.model.dto;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.datetime.DatetimeHelper;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Data
public class TaskInfoDTO {
private String taskId;
private String taskName;
private String status; // COMPLETED, ASSIGNED, UNCLAIMED
private String assignee;
private Date startTime;
private Date endTime;
private LocalDateTime completeTime;
private String comment;
@ApiModelProperty("可签收的用户")
private List<String> candidateUsers; // 可签收的用户
@ApiModelProperty("可签收的组")
private List<String> candidateGroups; // 可签收的组
private Map<String,Object> vars;
public void setEndTime(Date endTime) {
this.endTime = endTime;
if (ObjectHelper.isNotEmpty(endTime)) {
this.completeTime = DatetimeHelper.of(endTime.getTime());
}
}
}
\ No newline at end of file
......@@ -4,10 +4,7 @@ package com.testor.module.hazard.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.module.hazard.model.domain.THazardWorkPlan;
import com.testor.module.hazard.model.dto.HisTaskDTO;
import com.testor.module.hazard.model.dto.THazardWorkPlanDTO;
import com.testor.module.hazard.model.dto.THazardWorkPlanParam;
import com.testor.module.hazard.model.dto.TodoTaskDTO;
import com.testor.module.hazard.model.dto.*;
import com.testor.module.wf.vo.HisTasksResponseDTO;
import com.tongtech.tfw.backend.common.models.supers.SuperService;
import com.tongtech.tfw.workflow.apis.task.model.dto.*;
......@@ -90,4 +87,6 @@ public interface THazardWorkPlanService extends SuperService<THazardWorkPlan> {
IPage<HisTaskDTO> hisTaskList(HisTaskListRequest hisTaskListRequest);
boolean exportJobTicket(HttpServletResponse response, THazardWorkPlanParam param);
List<TaskInfoDTO> getAllTaskApprovers(String processInstanceId, String planId);
}
......@@ -65,8 +65,17 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.xmlbeans.XmlOptions;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.engine.HistoryService;
import org.flowable.engine.IdentityService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.idm.api.Group;
import org.flowable.idm.api.User;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -1184,6 +1193,27 @@ public class THazardWorkPlanServiceImpl extends SuperServiceImpl<THazardWorkPlan
return true;
}
@Override
public List<TaskInfoDTO> getAllTaskApprovers(String processInstanceId, String planId) {
List<TaskInfoDTO> allTaskApprovers = ruTaskService.getAllTaskApprovers(processInstanceId);
List<Object> processIds = tHazardConditionConfirmationRecordService.listObjs(new LambdaQueryWrapper<THazardConditionConfirmationRecord>().select(THazardConditionConfirmationRecord::getProcessId).isNotNull(THazardConditionConfirmationRecord::getProcessId).eq(THazardConditionConfirmationRecord::getPlanId, planId));
if (processIds != null && processIds.size() > 0) {
for (Object processId : processIds) {
List<TaskInfoDTO> data = ruTaskService.getAllTaskApprovers(processId.toString());
List<TaskInfoDTO> filteredData = data.stream()
.filter(task -> !"startEvent".equals(task.getTaskName()))
.collect(Collectors.toList());
allTaskApprovers.addAll(filteredData);
}
}
List<TaskInfoDTO> filteredData = allTaskApprovers.stream()
.filter(task -> !"基本信息".equals(task.getTaskName())).sorted(Comparator.comparing(
task -> task.getEndTime() != null ? task.getEndTime() : task.getStartTime(),
Comparator.nullsFirst(Comparator.naturalOrder())
)).collect(Collectors.toList());
return filteredData;
}
@SneakyThrows
private void buildDisclosure(List<XWPFDocument> wordList, THazardWorkPlanDTO planDTO, SimpleDateFormat sdf,
Integer index) {
......
......@@ -2,6 +2,7 @@ package com.testor.module.wf.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.module.hazard.model.dto.TaskInfoDTO;
import com.testor.module.wf.vo.ProcessDefListRequestVO;
import com.testor.module.wf.vo.ZlmyProcessInsListRequest;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
......@@ -56,4 +57,6 @@ public interface RuTaskService {
*/
void stopProcess(String processInstanceId);
List<TaskInfoDTO> getAllTaskApprovers(String processInstanceId);
}
......@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import com.testor.common.core.exception.ServiceException;
import com.testor.common.core.utils.StringUtils;
import com.testor.module.hazard.model.dto.TaskInfoDTO;
import com.testor.module.hazard.model.enums.WorkPlanStatusEnum;
import com.testor.module.wf.dao.RuTaskDao;
import com.testor.module.wf.service.RuTaskService;
......@@ -35,10 +36,14 @@ import org.flowable.engine.*;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.idm.api.Group;
import org.flowable.idm.api.User;
import org.flowable.task.api.Task;
import com.tongtech.tfw.workflow.apis.task.model.dto.*;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -302,6 +307,133 @@ public class RuTaskServiceImpl implements RuTaskService {
}
@Override
public List<TaskInfoDTO> getAllTaskApprovers(String processInstanceId) {
List<TaskInfoDTO> result = new ArrayList<>();
// 1. 获取已完成的任务(历史记录)
List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId)
.finished() // 只查询已完成的任务
.orderByHistoricTaskInstanceEndTime().asc()
.list();
// 2. 获取当前可处理的任务(运行时任务)
List<Task> activeTasks = taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.list();
// 3. 合并结果
result.addAll(convertHistoricTasks(historicTasks));
result.addAll(convertActiveTasks(activeTasks));
return result;
}
private List<TaskInfoDTO> convertHistoricTasks(List<HistoricTaskInstance> tasks) {
return tasks.stream().map(task -> {
TaskInfoDTO dto = new TaskInfoDTO();
dto.setTaskId(task.getId());
dto.setTaskName(task.getName());
dto.setAssignee(getUserDisplayName(task.getAssignee()));
dto.setStartTime(task.getStartTime());
dto.setEndTime(task.getEndTime());
getStatus(dto, task.getId());
dto.setVars(getMap(task.getId()));
// 获取审批意见
List<Comment> comments = taskService.getTaskComments(task.getId(),"6");
if (!comments.isEmpty()) {
dto.setStatus("已取消");
dto.setComment(comments.get(0).getFullMessage());
}
return dto;
}).collect(Collectors.toList());
}
private List<TaskInfoDTO> convertActiveTasks(List<Task> tasks) {
return tasks.stream().map(task -> {
TaskInfoDTO dto = new TaskInfoDTO();
dto.setTaskId(task.getId());
dto.setTaskName(task.getName());
dto.setStatus("审批中");
dto.setAssignee(getUserDisplayName(task.getAssignee()));
dto.setStartTime(task.getCreateTime());
// 获取当前任务的候选人和候选组
if (StringUtils.isBlank(task.getAssignee())) {
List<IdentityLink> identityLinks = taskService.getIdentityLinksForTask(task.getId());
List<String> candidateUsers = new ArrayList<>();
List<String> candidateGroups = new ArrayList<>();
for (IdentityLink link : identityLinks) {
if (link.getUserId() != null) {
String userDisplayName = getUserDisplayName(link.getUserId());
if (StringUtils.isNotBlank(userDisplayName)) {
candidateUsers.add(userDisplayName);
}
}
if (link.getGroupId() != null && link.getGroupId().contains("-")) {
candidateGroups.add(getGroupDisplayName(link.getGroupId()));
}
}
dto.setCandidateUsers(candidateUsers);
dto.setCandidateGroups(candidateGroups);
}
getStatus(dto, task.getId());
//Map<String, Object> map = getMap(task.getId());
//dto.setMap(map);
return dto;
}).collect(Collectors.toList());
}
private void getStatus(TaskInfoDTO dto, String id) {
Map<String, Object> map = getMap(id);
Object rejected = null;
if (map != null) {
rejected = map.get("rejected");
if (rejected != null) {
String rejectedString = rejected.toString();
if ("0".equals(rejectedString)){
dto.setStatus("通过");
}else {
dto.setStatus("驳回");
}
}else {
dto.setStatus("通过");
}
}else {
dto.setStatus("审批中");
}
}
private String getUserDisplayName(String userId) {
if (userId == null) return null;
User user = identityService.createUserQuery().userId(userId).singleResult();
return user != null ? user.getFirstName() + String.format("(%s)",user.getLastName()) : userId;
}
private String getGroupDisplayName(String groupId) {
Group group = identityService.createGroupQuery().groupId(groupId).singleResult();
return group != null ? group.getName() : groupId;
}
private Map<String,Object> getMap(String taskId) {
if (StringHelper.isNotBlank(taskId)) {
try {
List<HistoricVariableInstance> taskVarList = this.historyService.createHistoricVariableInstanceQuery().taskId(taskId).list();
if (!taskVarList.isEmpty()) {
return taskVarList.stream().collect(Collectors.toMap(HistoricVariableInstance::getVariableName, (ex) -> ex.getValue() == null ? "" : ex.getValue(), (k1, k2) -> k1));
}
} catch (Exception e) {
log.error(e.toString());
}
}
return null;
}
/**
* 获取下一任务节点集合
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment