diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessInstanceController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessInstanceController.java index 42f33eb9b..3831c66a4 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessInstanceController.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessInstanceController.java @@ -3,14 +3,18 @@ package org.dromara.workflow.controller; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; +import org.dromara.common.core.domain.R; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.web.core.BaseController; import org.dromara.workflow.domain.bo.ProcessInstanceBo; +import org.dromara.workflow.domain.vo.ActHistoryInfoVo; import org.dromara.workflow.domain.vo.ProcessInstanceVo; import org.dromara.workflow.service.IActProcessInstanceService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.List; + /** * 流程实例管理 控制层 * @@ -54,4 +58,14 @@ public class ActProcessInstanceController extends BaseController { public void getHistoryProcessImage(@NotBlank(message = "流程实例id不能为空") @PathVariable String processInstanceId, HttpServletResponse response) { iActProcessInstanceService.getHistoryProcessImage(processInstanceId, response); } + + /** + * 获取审批记录 + * + * @param processInstanceId 流程实例id + */ + @GetMapping("/getHistoryRecord/{processInstanceId}") + public R> getHistoryRecord(@NotBlank(message = "流程实例id不能为空") @PathVariable String processInstanceId) { + return R.ok(iActProcessInstanceService.getHistoryRecord(processInstanceId)); + } } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ActHistoryInfoVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ActHistoryInfoVo.java new file mode 100644 index 000000000..093e65945 --- /dev/null +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ActHistoryInfoVo.java @@ -0,0 +1,75 @@ +package org.dromara.workflow.domain.vo; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 流程审批记录视图 + * + * @author may + */ +@Data +public class ActHistoryInfoVo implements Serializable { + + @Serial + private static final long serialVersionUID=1L; + /** + * 任务id + */ + private String id; + /** + * 节点id + */ + private String taskDefinitionKey; + /** + * 任务名称 + */ + private String name; + /** + * 流程实例id + */ + private String processInstanceId; + /** + * 开始时间 + */ + private Date startTime; + /** + * 结束时间 + */ + private Date endTime; + /** + * 运行时长 + */ + private String runDuration; + /** + * 状态 + */ + private String status; + /** + * 办理人id + */ + private String assignee; + + /** + * 办理人名称 + */ + private String nickName; + + /** + * 办理人id + */ + private String owner; + + /** + * 审批信息id + */ + private String commentId; + + /** + * 审批信息 + */ + private String comment; +} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessInstanceService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessInstanceService.java index 0d9450a93..faf0704a7 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessInstanceService.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessInstanceService.java @@ -3,8 +3,11 @@ package org.dromara.workflow.service; import jakarta.servlet.http.HttpServletResponse; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.workflow.domain.bo.ProcessInstanceBo; +import org.dromara.workflow.domain.vo.ActHistoryInfoVo; import org.dromara.workflow.domain.vo.ProcessInstanceVo; +import java.util.List; + /** * 流程实例 服务层 * @@ -34,4 +37,12 @@ public interface IActProcessInstanceService { * @return 结果 */ TableDataInfo getProcessInstanceFinishByPage(ProcessInstanceBo processInstanceBo); + + /** + * 获取审批记录 + * + * @param processInstanceId 流程实例id + * @return 结果 + */ + List getHistoryRecord(String processInstanceId); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java index 5517d07bc..7344de83a 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java @@ -1,6 +1,8 @@ package org.dromara.workflow.service.impl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @@ -9,8 +11,11 @@ import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.tenant.helper.TenantHelper; +import org.dromara.system.domain.vo.SysUserVo; +import org.dromara.system.service.ISysUserService; import org.dromara.workflow.common.constant.FlowConstant; import org.dromara.workflow.domain.bo.ProcessInstanceBo; +import org.dromara.workflow.domain.vo.ActHistoryInfoVo; import org.dromara.workflow.domain.vo.ProcessInstanceVo; import org.dromara.workflow.flowable.CustomDefaultProcessDiagramGenerator; import org.dromara.workflow.service.IActProcessInstanceService; @@ -18,20 +23,24 @@ import org.flowable.bpmn.model.BpmnModel; import org.flowable.engine.HistoryService; import org.flowable.engine.RepositoryService; import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; import org.flowable.engine.history.HistoricActivityInstance; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstanceQuery; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.engine.runtime.ProcessInstanceQuery; +import org.flowable.engine.task.Comment; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.awt.*; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; +import java.util.*; import java.util.List; -import java.util.Objects; +import java.util.stream.Collectors; /** * 流程实例 服务层实现 @@ -46,6 +55,8 @@ public class ActProcessInstanceServiceImpl implements IActProcessInstanceService private final RepositoryService repositoryService; private final RuntimeService runtimeService; private final HistoryService historyService; + private final ISysUserService iSysUserService; + private final TaskService taskService; @Value("${flowable.activity-font-name}") private String activityFontName; @@ -192,4 +203,78 @@ public class ActProcessInstanceServiceImpl implements IActProcessInstanceService } } } + + /** + * 获取审批记录 + * + * @param processInstanceId 流程实例id + */ + @Override + public List getHistoryRecord(String processInstanceId) { + //查询任务办理记录 + List list = historyService.createHistoricTaskInstanceQuery() + .processInstanceId(processInstanceId).taskTenantId(TenantHelper.getTenantId()).orderByHistoricTaskInstanceEndTime().desc().list(); + list = StreamUtils.sorted(list, Comparator.comparing(HistoricTaskInstance::getEndTime, Comparator.nullsFirst(Date::compareTo))); + List actHistoryInfoVoList = new ArrayList<>(); + for (HistoricTaskInstance historicTaskInstance : list) { + ActHistoryInfoVo actHistoryInfoVo = new ActHistoryInfoVo(); + BeanUtils.copyProperties(historicTaskInstance, actHistoryInfoVo); + actHistoryInfoVo.setStatus(actHistoryInfoVo.getEndTime() == null ? "待处理" : "已处理"); + List taskComments = taskService.getTaskComments(historicTaskInstance.getId()); + if (CollUtil.isNotEmpty(taskComments)) { + actHistoryInfoVo.setCommentId(taskComments.get(0).getId()); + String message = taskComments.stream().map(Comment::getFullMessage).collect(Collectors.joining("。")); + if (StringUtils.isNotBlank(message)) { + actHistoryInfoVo.setComment(message); + } + } + if (ObjectUtil.isNotEmpty(historicTaskInstance.getDurationInMillis())) { + actHistoryInfoVo.setRunDuration(getDuration(historicTaskInstance.getDurationInMillis())); + } + actHistoryInfoVoList.add(actHistoryInfoVo); + } + //翻译人员名称 + if (CollUtil.isNotEmpty(actHistoryInfoVoList)) { + actHistoryInfoVoList.forEach(e -> { + SysUserVo sysUserVo = iSysUserService.selectUserById(Long.valueOf(e.getAssignee())); + e.setNickName(ObjectUtil.isNotEmpty(sysUserVo) ? sysUserVo.getNickName() : ""); + }); + } + List collect = new ArrayList<>(); + //待办理 + List waitingTask = StreamUtils.filter(actHistoryInfoVoList, e -> e.getEndTime() == null); + //已办理 + List finishTask = StreamUtils.filter(actHistoryInfoVoList, e -> e.getEndTime() != null); + collect.addAll(waitingTask); + collect.addAll(finishTask); + return collect; + } + + /** + * 任务完成时间处理 + * + * @param time 时间 + */ + private String getDuration(long time) { + + long day = time / (24 * 60 * 60 * 1000); + long hour = (time / (60 * 60 * 1000) - day * 24); + long minute = ((time / (60 * 1000)) - day * 24 * 60 - hour * 60); + long second = (time / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60); + + if (day > 0) { + return day + "天" + hour + "小时" + minute + "分钟"; + } + if (hour > 0) { + return hour + "小时" + minute + "分钟"; + } + if (minute > 0) { + return minute + "分钟"; + } + if (second > 0) { + return second + "秒"; + } else { + return 0 + "秒"; + } + } }