!1424 feat: 代码评审修改

Merge pull request !1424 from Lesan/feature/bpm-打印
This commit is contained in:
芋道源码
2025-09-07 09:11:09 +00:00
committed by Gitee
7 changed files with 100 additions and 103 deletions

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
@ -26,6 +27,7 @@ import jakarta.validation.Valid;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -34,9 +36,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS;
@Tag(name = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请”
@RestController
@ -203,7 +207,19 @@ public class BpmProcessInstanceController {
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
public CommonResult<BpmProcessPrintDataRespVO> getProcessInstancePrintData(
@RequestParam("processInstanceId") String processInstanceId) {
return success(processInstanceService.getProcessInstancePrintData(getLoginUserId(), processInstanceId));
HistoricProcessInstance historicProcessInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
if (historicProcessInstance == null) {
throw exception(PROCESS_INSTANCE_NOT_EXISTS);
}
AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(historicProcessInstance.getStartUserId()));
DeptRespDTO dept = deptApi.getDept(startUser.getDeptId());
List<HistoricTaskInstance> tasks = taskService.getFinishedTaskListByProcessInstanceIdWithoutCancel(processInstanceId);
Set<Long> userIds = convertSet(tasks, item -> Long.valueOf(item.getAssignee()));
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstancePrintData(historicProcessInstance,
processDefinitionService.getProcessDefinitionInfo(historicProcessInstance.getProcessDefinitionId()),
tasks, userMap,
new UserSimpleBaseVO().setNickname(startUser.getNickname()).setDeptName(dept.getName())));
}
}

View File

@ -11,44 +11,29 @@ import java.util.Map;
@Data
public class BpmProcessPrintDataRespVO {
@Schema(description = "流程实例数据")
private BpmProcessInstanceRespVO processInstance;
@Schema(description = "是否开启自定义打印模板")
private Boolean printTemplateEnable;
// TODO @lesan要不 processStatus、processInstanceId、processBusinessKey、processBusinessKey、startUser、endTime、processVariables 使用 BpmProcessInstanceRespVO ?虽然这个 VO 大了点,但是收一收字段。嘿嘿;进而只有 processInstance、tasks、formFields、printTemplateHtml 这些字段;
private Integer processStatus;
private String processInstanceId;
private String processBusinessKey;
private String processName;
private UserSimpleBaseVO startUser;
private String startTime;
private String endTime;
// TODO @lesan变量要不改成 tasks
private List<ApproveNode> approveNodes;
private List<String> formFields;
@Schema(description = "自定义打印模板HTML")
private String printTemplateHtml;
private Map<String, Object> processVariables;
@Schema(description = "审批任务列表")
private List<ApproveTask> tasks;
// TODO @lesan类名要不要改成 tasks ?然后 id、name、signUrl、description感觉理解成本低点
@Data
public static class ApproveNode {
public static class ApproveTask {
private String nodeName;
private String id;
private String nodeDesc;
private String name;
private String description;
private String signUrl;
private String nodeId;
}
}

View File

@ -1,23 +1,29 @@
package cn.iocoder.yudao.module.bpm.convert.task;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceBpmnModelViewRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessPrintDataRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
@ -35,10 +41,7 @@ import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@ -292,4 +295,49 @@ public interface BpmProcessInstanceConvert {
.setActivityNodes(activityNodes);
}
default BpmProcessPrintDataRespVO buildProcessInstancePrintData(HistoricProcessInstance historicProcessInstance,
BpmProcessDefinitionInfoDO processDefinitionInfo,
List<HistoricTaskInstance> tasks,
Map<Long, AdminUserRespDTO> userMap,
UserSimpleBaseVO startUser) {
BpmModelMetaInfoVO.PrintTemplateSetting printTemplateSetting = processDefinitionInfo.getPrintTemplateSetting();
BpmProcessPrintDataRespVO printData = new BpmProcessPrintDataRespVO();
// 打印模板是否开启
printData.setPrintTemplateEnable(printTemplateSetting != null && Boolean.TRUE.equals(printTemplateSetting.getEnable()));
// 流程相关数据
BpmProcessInstanceRespVO processInstance = new BpmProcessInstanceRespVO();
processInstance.setStatus(FlowableUtils.getProcessInstanceStatus(historicProcessInstance));
processInstance.setId(historicProcessInstance.getId());
processInstance.setName(historicProcessInstance.getName());
processInstance.setBusinessKey(historicProcessInstance.getBusinessKey());
processInstance.setStartTime(DateUtils.of(historicProcessInstance.getStartTime()));
processInstance.setEndTime(DateUtils.of(historicProcessInstance.getEndTime()));
processInstance.setFormVariables(historicProcessInstance.getProcessVariables());
processInstance.setStartUser(startUser);
processInstance.setProcessDefinition(BeanUtils.toBean(processDefinitionInfo, BpmProcessDefinitionRespVO.class));
printData.setProcessInstance(processInstance);
// 审批历史
List<BpmProcessPrintDataRespVO.ApproveTask> approveTasks = new ArrayList<>(tasks.size());
tasks.forEach(item -> {
Map<String, Object> taskLocalVariables = item.getTaskLocalVariables();
BpmProcessPrintDataRespVO.ApproveTask approveTask = new BpmProcessPrintDataRespVO.ApproveTask();
approveTask.setName(item.getName());
approveTask.setId(item.getId());
approveTask.setSignUrl((String) taskLocalVariables.getOrDefault(BpmnVariableConstants.TASK_SIGN_PIC_URL, ""));
approveTask.setDescription(StrUtil.format("{} / {} / {} / {} / {}",
userMap.get(Long.valueOf(item.getAssignee())).getNickname(),
item.getName(),
DateUtil.formatDateTime(item.getEndTime()),
BpmTaskStatusEnum.valueOf((Integer) taskLocalVariables.get(BpmnVariableConstants.TASK_VARIABLE_STATUS)).getName(),
taskLocalVariables.get(BpmnVariableConstants.TASK_VARIABLE_REASON)));
approveTasks.add(approveTask);
});
printData.setTasks(approveTasks);
// 自定义模板
if (printData.getPrintTemplateEnable() && printTemplateSetting != null) {
printData.setPrintTemplateHtml(printTemplateSetting.getTemplate());
}
return printData;
}
}

View File

@ -113,14 +113,6 @@ public interface BpmProcessInstanceService {
*/
BpmProcessInstanceBpmnModelViewRespVO getProcessInstanceBpmnModelView(String id);
/**
* 获取流程打印所需数据
* @param loginUserId 打印人
* @param processInstanceId 流程实例id
* @return 打印所需数据
*/
BpmProcessPrintDataRespVO getProcessInstancePrintData(Long loginUserId, String processInstanceId);
// ========== Update 写入相关方法 ==========
/**

View File

@ -728,69 +728,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
userMap, deptMap);
}
// TODO @lesan这个可以放在 controller + convert 哇?保证 Service 只尽量处理写逻辑;
@Override
public BpmProcessPrintDataRespVO getProcessInstancePrintData(Long loginUserId, String processInstanceId) {
// 1 数据准备
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(processInstanceId);
if (historicProcessInstance == null) {
throw exception(PROCESS_INSTANCE_NOT_EXISTS);
}
BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService
.getProcessDefinitionInfo(historicProcessInstance.getProcessDefinitionId());
BpmModelMetaInfoVO.PrintTemplateSetting printTemplateSetting = processDefinitionInfo.getPrintTemplateSetting();
// 2 获取打印所需数据
BpmProcessPrintDataRespVO printData = new BpmProcessPrintDataRespVO();
// 2.1 打印模板是否开启
printData.setPrintTemplateEnable(printTemplateSetting != null && Boolean.TRUE.equals(printTemplateSetting.getEnable()));
// 2.2 流程相关数据
printData.setProcessStatus(FlowableUtils.getProcessInstanceStatus(historicProcessInstance));
printData.setProcessInstanceId(historicProcessInstance.getId());
printData.setProcessName(historicProcessInstance.getName());
printData.setProcessBusinessKey(historicProcessInstance.getBusinessKey());
printData.setStartTime(DatePattern.NORM_DATETIME_MINUTE_FORMAT.format(historicProcessInstance.getStartTime()));
printData.setEndTime(Objects.isNull(historicProcessInstance.getEndTime()) ?
"" : DatePattern.NORM_DATETIME_MINUTE_FORMAT.format(historicProcessInstance.getEndTime()));
printData.setProcessVariables(historicProcessInstance.getProcessVariables());
// 2.3 发起人
AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(historicProcessInstance.getStartUserId()));
DeptRespDTO dept = deptApi.getDept(startUser.getDeptId());
printData.setStartUser(new UserSimpleBaseVO().setNickname(startUser.getNickname()).setDeptName(dept.getName()));
// 2.4 审批历史
List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()
.finished()
.includeTaskLocalVariables()
.processInstanceId(processInstanceId)
.taskVariableValueNotEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS,
BpmTaskStatusEnum.CANCEL.getStatus())
.orderByHistoricTaskInstanceStartTime().asc().list();
Set<Long> userIds = convertSet(tasks, item -> Long.valueOf(item.getAssignee()));
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
List<BpmProcessPrintDataRespVO.ApproveNode> approveNodes = new ArrayList<>(tasks.size());
tasks.forEach(item -> {
Map<String, Object> taskLocalVariables = item.getTaskLocalVariables();
BpmProcessPrintDataRespVO.ApproveNode approveNode = new BpmProcessPrintDataRespVO.ApproveNode();
approveNode.setNodeName(item.getName());
approveNode.setNodeId(item.getId());
approveNode.setSignUrl((String) taskLocalVariables.getOrDefault(BpmnVariableConstants.TASK_SIGN_PIC_URL, ""));
approveNode.setNodeDesc(StrUtil.format("{} / {} / {} / {} / {}",
userMap.get(Long.valueOf(item.getAssignee())).getNickname(),
item.getName(),
DateUtil.formatDateTime(item.getEndTime()),
BpmTaskStatusEnum.valueOf((Integer) taskLocalVariables.get(BpmnVariableConstants.TASK_VARIABLE_STATUS)).getName(),
taskLocalVariables.get(BpmnVariableConstants.TASK_VARIABLE_REASON)));
approveNodes.add(approveNode);
});
printData.setApproveNodes(approveNodes);
// 2.5 表单数据
printData.setFormFields(processDefinitionInfo.getFormFields());
// 2.6 自定义模板
if (printData.getPrintTemplateEnable() && printTemplateSetting != null) {
printData.setPrintTemplateHtml(printTemplateSetting.getTemplate());
}
return printData;
}
// ========== Update 写入相关方法 ==========
@Override

View File

@ -176,6 +176,14 @@ public interface BpmTaskService {
*/
List<HistoricActivityInstance> getHistoricActivityListByExecutionId(String executionId);
/**
* 获得指定流程实例的已完成的流程任务列表,不包含取消状态
*
* @param processInstanceId 流程实例的编号
* @return 流程任务列表
*/
List<HistoricTaskInstance> getFinishedTaskListByProcessInstanceIdWithoutCancel(String processInstanceId);
// ========== Update 写入相关方法 ==========
/**

View File

@ -491,6 +491,17 @@ public class BpmTaskServiceImpl implements BpmTaskService {
return historyService.createHistoricActivityInstanceQuery().executionId(executionId).list();
}
@Override
public List<HistoricTaskInstance> getFinishedTaskListByProcessInstanceIdWithoutCancel(String processInstanceId) {
return historyService.createHistoricTaskInstanceQuery()
.finished()
.includeTaskLocalVariables()
.processInstanceId(processInstanceId)
.taskVariableValueNotEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS,
BpmTaskStatusEnum.CANCEL.getStatus())
.orderByHistoricTaskInstanceStartTime().asc().list();
}
/**
* 判断指定用户,是否是当前任务的审批人
*