feat(REQ-5965) - 新增审批日志打印的数据接口

This commit is contained in:
wangli 2025-10-30 14:57:40 +08:00
parent cdbe89c05a
commit 388de9eb52
9 changed files with 292 additions and 2 deletions

View File

@ -4,8 +4,10 @@ import cn.axzo.workflow.client.annotation.WorkflowEngineFeignClient;
import cn.axzo.workflow.common.annotation.InvokeMode;
import cn.axzo.workflow.common.annotation.Manageable;
import cn.axzo.workflow.common.model.dto.print.PrintFieldDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.Print4ProcessLogDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintFieldQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigUpsertDTO;
import cn.axzo.workflow.common.model.response.bpmn.process.PrintData4LogVO;
import cn.azxo.framework.common.model.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.validation.annotation.Validated;
@ -66,7 +68,7 @@ public interface PrintAdminApi {
* 获取指定流程下用于替换打印的相关变量
*
* @param processInstanceId
* @return
* @return 仅是 kv 集合
*/
@Operation(summary = "获取指定流程下用于替换打印的相关变量")
@GetMapping("/api/print/admin/field/variables")
@ -74,4 +76,16 @@ public interface PrintAdminApi {
@InvokeMode(SYNC)
CommonResponse<Map<String, Object>> getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId,
@RequestParam(required = false, defaultValue = "true") Boolean throwException);
/**
* 获取用于打印审批日志公共模板的数据
*
* @param dto
* @return
*/
@Operation(summary = "获取用于打印审批日志公共模板的数据")
@PostMapping("/api/print/admin/process/log/data/v2")
@Manageable
@InvokeMode(SYNC)
CommonResponse<PrintData4LogVO> getPrintDataForProcessLog(@Validated @RequestBody Print4ProcessLogDTO dto);
}

View File

@ -29,14 +29,20 @@ public interface VariableConstants {
//=============== 打印时的变量集合中 key 的命名 =================
String VAR_PREFIX = "业务变量";
String PRINT_VAR_PROCESS_NAME = "processName";
String PRINT_VAR_PROCESS_NAME_DESC = "审批名称";
String PRINT_VAR_PROCESS_DEFINITION_KEY = "processDefinitionKey";
String PRINT_VAR_PROCESS_DEFINITION_KEY_DESC = "业务名称";
String PRINT_VAR_PROCESS_BELONG_TENANT_ID = "tenantId";
String PRINT_VAR_PROCESS_BELONG_TENANT_ID_DESC = "所属租户";
String PRINT_VAR_PROCESS_INSTANCE_ID = "processInstanceId";
String PRINT_VAR_PROCESS_INSTANCE_ID_DESC = "审批编号";
String PRINT_VAR_PROCESS_START_TIME = "startTime";
String PRINT_VAR_PROCESS_START_TIME_DESC = "发起时间";
String PRINT_VAR_PROCESS_END_TIME = "endTime";
String PRINT_VAR_PROCESS_END_TIME_DESC = "审批结束时间";
String PRINT_VAR_PROCESS_RESULT = "processResult";
String PRINT_VAR_PROCESS_RESULT_DESC = "审批结果";
String PRINT_VAR_PROCESS_INITIATOR = "initiator";
String PRINT_VAR_PROCESS_INITIATOR_DESC = "发起者";
String PRINT_VAR_PROCESS_INITIATOR_NAME = "initiatorName";

View File

@ -0,0 +1,32 @@
package cn.axzo.workflow.common.model.request.bpmn.print;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
/**
* 获取内置公共模板打印数据的入参模型
*
* @author wangli
* @since 2025-10-30 10:43
*/
@ApiModel("获取内置公共模板打印数据的入参模型")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Print4ProcessLogDTO {
/**
* 流程实例 ID
*/
@ApiModelProperty(value = "流程实例 ID")
@NotBlank(message = "流程实例 ID 不能为空")
private String processInstanceId;
}

View File

@ -0,0 +1,60 @@
package cn.axzo.workflow.common.model.response;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import java.util.List;
/**
* 审批日志项模型
*
* @author wangli
* @since 2025-10-30 14:22
*/
@Data
@Builder
public class ProcessLogItemDTO {
@Builder.Default
private String label = "审批流程";
/**
* 审批意见
*/
private String advice;
/**
* 节点名称
*/
@ApiModelProperty(value = "节点名称")
private String activityName;
/**
* 操作描述
*/
@ApiModelProperty(value = "操作描述")
private String operationDesc;
/**
* 图片列表
*/
@ApiModelProperty(value = "图片列表")
private List<AttachmentDTO> imageList;
/**
* 附件列表
*/
@ApiModelProperty(value = "附件列表")
private List<AttachmentDTO> fileList;
/**
* 手写签名地址
*/
@ApiModelProperty(value = "手写签名地址")
private String signatureUrl;
/**
* 操作时间
*/
@ApiModelProperty(value = "操作时间")
private String operationTime;
}

View File

@ -0,0 +1,31 @@
package cn.axzo.workflow.common.model.response;
import lombok.Builder;
import lombok.Data;
/**
* 审批日志公共打印模板的字段项模型
*
* @author wangli
* @since 2025-10-30 10:38
*/
@Data
@Builder
public class TableItemDTO {
/**
* 中文
*/
private String label;
/**
* 字段 code
*/
private String code;
/**
* 字段类型
*/
private String type;
/**
*
*/
private Object value;
}

View File

@ -0,0 +1,50 @@
package cn.axzo.workflow.common.model.response.bpmn.process;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.response.ProcessLogItemDTO;
import cn.axzo.workflow.common.model.response.TableItemDTO;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* 新版的审批日志公共模板的数据响应模型
*
* @author wangli
* @since 2025-10-30 10:28
*/
@ApiModel("新版的审批日志公共模板的数据响应模型")
@Data
@Accessors(chain = true)
public class PrintData4LogVO {
/**
* 标题
*/
private String processName;
/**
* 发起租户名称
*/
private String tenantName;
/**
* 创建时间
*/
private String createAt;
/**
* 审批状态
*/
private BpmnProcessInstanceResultEnum result;
/**
* 系统变量表格项
*/
private List<TableItemDTO> systemVarItems;
/**
* 审批日志表格项
*/
private List<ProcessLogItemDTO> logItems;
}

View File

@ -1,5 +1,6 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.dto.SignatureDTO;
import cn.axzo.workflow.core.common.utils.SpringContextUtils;
import cn.axzo.workflow.core.service.CategoryService;
@ -22,10 +23,13 @@ import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_MODEL_CATEGORY;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.SIGNATURE_COLLECTION;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_BELONG_TENANT_ID;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_DEFINITION_KEY;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_END_TIME;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INSTANCE_ID;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_NAME;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_RESULT;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_START_TIME;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
@ -63,9 +67,13 @@ public class CustomGetProcessInstanceVariablesCmd extends AbstractCommand<Map<St
HistoryService historyService = processEngineConfiguration.getHistoryService();
HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId).includeProcessVariables().singleResult();
variables.put(PRINT_VAR_PROCESS_NAME, instance.getName());
variables.put(PRINT_VAR_PROCESS_BELONG_TENANT_ID, instance.getTenantId());
// 添加流程开始时间
variables.put(PRINT_VAR_PROCESS_START_TIME, sdf.format(instance.getStartTime()));
variables.put(PRINT_VAR_PROCESS_END_TIME, Objects.nonNull(instance.getEndTime()) ? sdf.format(instance.getEndTime()) : null);
variables.put(PRINT_VAR_PROCESS_RESULT, BpmnProcessInstanceResultEnum.fromValue(instance.getBusinessStatus()));
// 添加流程业务 ID
addProcessDefinitionKey(variables, instance);

View File

@ -1814,7 +1814,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
});
}
public List<AttachmentDTO> getAttachmentByType(Map<String, List<Attachment>> attachmentByTaskMap, String
public static List<AttachmentDTO> getAttachmentByType(Map<String, List<Attachment>> attachmentByTaskMap, String
taskId, AttachmentTypeEnum type) {
return ListUtils.emptyIfNull(attachmentByTaskMap.get(taskId)).stream()
.filter(attachment -> Objects.equals(type.getType(), attachment.getType()))

View File

@ -4,29 +4,40 @@ import cn.axzo.maokai.api.client.OrganizationalNodeUserQueryApi;
import cn.axzo.maokai.api.vo.request.OrgNodeUserBriefInfoListReq;
import cn.axzo.maokai.api.vo.response.OrgNodeUserBriefInfoResp;
import cn.axzo.workflow.client.feign.manage.PrintAdminApi;
import cn.axzo.workflow.common.constant.VariableConstants;
import cn.axzo.workflow.common.enums.AttachmentTypeEnum;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.enums.VarTypeEnum;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.dto.print.FieldAttributeDTO;
import cn.axzo.workflow.common.model.dto.print.PrintFieldDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.Print4ProcessLogDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintFieldQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigUpsertDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.request.category.CategoryGroupVarSearchDto;
import cn.axzo.workflow.common.model.response.ProcessLogItemDTO;
import cn.axzo.workflow.common.model.response.TableItemDTO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO;
import cn.axzo.workflow.common.model.response.bpmn.process.PrintData4LogVO;
import cn.axzo.workflow.common.model.response.category.CategoryGroupVarItemVo;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.engine.cmd.CustomGetFormInstanceLatestValuesCmd;
import cn.axzo.workflow.core.engine.cmd.CustomGetProcessInstanceVariablesCmd;
import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
import cn.axzo.workflow.core.service.BpmnProcessDefinitionService;
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
import cn.axzo.workflow.core.service.BpmnProcessModelService;
import cn.axzo.workflow.core.service.CategoryGroupService;
import cn.axzo.workflow.core.service.ExtAxProcessLogService;
import cn.axzo.workflow.server.common.annotation.ErrorReporter;
import cn.axzo.workflow.server.common.util.RpcExternalUtil;
import cn.axzo.workflow.server.controller.web.bpmn.BpmnProcessInstanceController;
import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@ -35,6 +46,8 @@ import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
import org.flowable.engine.TaskService;
import org.flowable.engine.task.Attachment;
import org.flowable.form.api.FormInfo;
import org.flowable.form.api.FormRepositoryService;
import org.flowable.form.model.FormContainer;
@ -80,6 +93,7 @@ import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCE
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR_POSITION;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR_POSITION_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR_UNIT;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR_UNIT_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INSTANCE_ID;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INSTANCE_ID_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOGS;
@ -104,12 +118,15 @@ import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCE
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_SIGNATURE_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_UNIT;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_UNIT_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_NAME;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_RESULT;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_START_TIME;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_START_TIME_DESC;
import static cn.axzo.workflow.common.enums.PrintFieldCategoryEnum.form;
import static cn.axzo.workflow.common.enums.PrintFieldCategoryEnum.sign;
import static cn.axzo.workflow.common.enums.PrintFieldCategoryEnum.signature;
import static cn.axzo.workflow.common.enums.PrintFieldCategoryEnum.system;
import static cn.axzo.workflow.core.service.impl.BpmnProcessInstanceServiceImpl.getAttachmentByType;
import static cn.azxo.framework.common.model.CommonResponse.success;
/**
@ -141,6 +158,10 @@ public class PrintAdminController implements PrintAdminApi {
private CategoryGroupService categoryGroupService;
@Resource
private BpmnProcessModelService bpmnProcessModelService;
@Resource
private ExtAxProcessLogService processLogService;
@Resource
private TaskService taskService;
/**
* 查询指定流程实例是否能使用打印
@ -456,4 +477,72 @@ public class PrintAdminController implements PrintAdminApi {
return users.stream().sorted(Comparator.comparing(OrgNodeUserBriefInfoResp::getExited).reversed())
.collect(Collectors.toList()).stream().findFirst();
}
@Operation(summary = "获取用于打印审批日志公共模板的数据")
@PostMapping("/process/log/data/v2")
@Override
public CommonResponse<PrintData4LogVO> getPrintDataForProcessLog(@Validated @RequestBody Print4ProcessLogDTO dto) {
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
Map<String, Object> variables = commandExecutor.execute(new CustomGetProcessInstanceVariablesCmd(dto.getProcessInstanceId()));
PrintData4LogVO vo = new PrintData4LogVO();
vo.setProcessName((String) variables.getOrDefault(PRINT_VAR_PROCESS_NAME, ""));
vo.setTenantName(String.valueOf(variables.get(VariableConstants.PRINT_VAR_PROCESS_BELONG_TENANT_ID)));
vo.setCreateAt(String.valueOf(variables.get(VariableConstants.PRINT_VAR_PROCESS_START_TIME)));
vo.setResult((BpmnProcessInstanceResultEnum) variables.get(PRINT_VAR_PROCESS_RESULT));
List<TableItemDTO> systemVarItems = new ArrayList<>();
systemVarItems.add(TableItemDTO.builder()
.label(PRINT_VAR_PROCESS_INSTANCE_ID_DESC)
.code(PRINT_VAR_PROCESS_INSTANCE_ID)
.type(FORM_FIELD_TYPE_INPUT)
.value(variables.get(PRINT_VAR_PROCESS_INSTANCE_ID))
.build());
// 解析发起人
BpmnTaskDelegateAssigner initiator = BpmnTaskDelegateAssigner.toObjectCompatible(variables.getOrDefault(PRINT_VAR_PROCESS_INITIATOR, null));
if (Objects.nonNull(initiator)) {
Optional<OrgNodeUserBriefInfoResp> user = getUserInfo(initiator);
systemVarItems.add(TableItemDTO.builder()
.label(PRINT_VAR_PROCESS_INITIATOR_NAME_DESC)
.code(PRINT_VAR_PROCESS_INITIATOR_NAME)
.type(FORM_FIELD_TYPE_INPUT)
.value(user.isPresent() ? user.get().getRealName() : "")
.build());
systemVarItems.add(TableItemDTO.builder()
.label(PRINT_VAR_PROCESS_INITIATOR_UNIT_DESC)
.code(PRINT_VAR_PROCESS_INITIATOR_UNIT_DESC)
.type(FORM_FIELD_TYPE_INPUT)
.value(user.isPresent() ? user.get().getOrganizationalUnitName() : "")
.build());
}
vo.setSystemVarItems(systemVarItems);
// 审批日志
List<ProcessLogItemDTO> logItems = new ArrayList<>();
Map<String, List<Attachment>> attachmentByTaskMap =
taskService.getProcessInstanceAttachments(dto.getProcessInstanceId()).stream()
.collect(Collectors.groupingBy(Attachment::getTaskId));
ExtAxProcessLog query = new ExtAxProcessLog();
query.setProcessInstanceId(dto.getProcessInstanceId());
processLogService.genericQuery(query).stream()
.sorted(Comparator.comparing(ExtAxProcessLog::getEndTime, Comparator.nullsLast(Comparator.naturalOrder())))
.collect(Collectors.toList())
.forEach(log -> {
logItems.add(ProcessLogItemDTO.builder()
.advice(log.getAdvice())
.activityName(log.getActivityName())
.operationDesc(log.getOperationDesc())
.imageList(getAttachmentByType(attachmentByTaskMap, log.getTaskId(), AttachmentTypeEnum.image))
.fileList(getAttachmentByType(attachmentByTaskMap, log.getTaskId(), AttachmentTypeEnum.file))
.signatureUrl(getAttachmentByType(attachmentByTaskMap, log.getTaskId(), AttachmentTypeEnum.signature).stream().findFirst().orElse(new AttachmentDTO()).getUrl())
.operationTime(DateUtil.format(log.getEndTime(), "yyyy.MM.dd HH:mm:ss"))
.build());
});
vo.setLogItems(logItems);
return success(vo);
}
}