Merge branch 'feature/REQ-5965' into dev

This commit is contained in:
wangli 2025-11-04 09:52:27 +08:00
commit 3e79c7d9fd
16 changed files with 248 additions and 12 deletions

View File

@ -6,6 +6,7 @@ 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.PrintProcessLogPdfDTO;
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;
@ -88,4 +89,14 @@ public interface PrintAdminApi {
@Manageable
@InvokeMode(SYNC)
CommonResponse<PrintData4LogVO> getPrintDataForProcessLog(@Validated @RequestBody Print4ProcessLogDTO dto);
/**
* 后端请求指定流程日志 PDF 文件生成
*
* @return
*/
@Operation(summary = "后端请求指定流程日志 PDF 文件生成")
@PostMapping("/api/print/admin/process/log/pdf")
@InvokeMode(SYNC)
CommonResponse<String> createProcessLogPdf(@Validated @RequestBody PrintProcessLogPdfDTO dto);
}

View File

@ -44,6 +44,7 @@ public enum BpmnTaskRespCode implements IModuleRespCode {
REMIND_TASK_TOO_MANY("027", "催办任务数据异常"),
PROCESS_SET_ASSIGNEE_PARAM_ERROR("028", "当前审批业务审批人模型中 NodeId 必传topNodeId/nodeId均可, 触发 ID: 【{}】"),
TASK_OPERATION_PARAM_INVALID("029", "流程实例 ID 与任务 ID 必须二选一"),
COOPERATION_NOT_EXIST_WITH_NODE("030", "查询审批人时,组织不存在"),
;
private final String code;

View File

@ -160,6 +160,7 @@ public interface BpmnConstants {
String NUMBER_OF_INSTANCES = "nrOfInstances";
String MULTI_INSTANCE_LOOP_COUNTER = "loopCounter";
String TASK_COMPLETE_OPERATION_TYPE = "_TASK_COMPLETE_TYPE";
String TASK_LOG_NODE_HAS_BEEN_HIDDEN = "_TASK_LOG_HIDDEN";
String TASK_ATTACHMENTS_VAR_NAME = "TASK_ATTACHMENTS";
/**

View File

@ -19,6 +19,7 @@ public enum BpmnProcessInstanceResultEnum {
UPGRADED("UPGRADED", "已提级"),
COMMENTED("COMMENTED", "已评论"),
DELETED("DELETED", "已删除"),
HIDDEN("HIDDEN", "已隐藏"),
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知"),
;

View File

@ -0,0 +1,75 @@
package cn.axzo.workflow.common.exception;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.framework.domain.web.code.IRespCode;
import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
/**
* 流程内部计算审批人的异常
*
* @author wangli
* @since 2025-11-03 10:11
*/
@Slf4j
public class WorkflowApproverCalcException extends ServiceException {
private String code;
public WorkflowApproverCalcException(IRespCode code) {
super(code.getMessage());
this.code = code.getRespCode();
}
public WorkflowApproverCalcException(IRespCode code, String... params) {
super(doFormat(code.getCode(), code.getMessage(), params));
this.code = code.getRespCode();
}
public WorkflowApproverCalcException(IRespCode code, Throwable cause, String... params) {
super(doFormat(code.getCode(), code.getMessage(), params), cause);
this.code = code.getRespCode();
}
@Override
public String getCode() {
return this.code;
}
/**
* 将错误编号对应的消息使用 params 进行格式化
*
* @param code 错误编号
* @param messagePattern 消息模版
* @param params 参数
* @return 格式化后的提示
*/
@VisibleForTesting
private static String doFormat(String code, String messagePattern, Object... params) {
StringBuilder sbuf = new StringBuilder(messagePattern.length() + 50);
int i = 0;
int j;
int l;
for (l = 0; l < params.length; l++) {
j = messagePattern.indexOf("{}", i);
if (j == -1) {
log.warn("[doFormat][参数过多:错误码({})|错误内容({})|参数({})", code, messagePattern, params);
if (i == 0) {
return messagePattern;
} else {
sbuf.append(messagePattern.substring(i));
return sbuf.toString();
}
} else {
sbuf.append(messagePattern, i, j);
sbuf.append(params[l]);
i = j + 2;
}
}
if (messagePattern.indexOf("{}", i) != -1) {
log.warn("[doFormat][参数过少:错误码({})|错误内容({})|参数({})", code, messagePattern, params);
}
sbuf.append(messagePattern.substring(i));
return sbuf.toString();
}
}

View File

@ -53,7 +53,7 @@ public class CustomDocDTO implements Serializable {
private String fileKey;
/**
* 文件的类型
* 文件的类型,如果要替换变量支持 docx 格式doc 格式不支持
*/
@NotNull(message = "业务自定义文件的类型不能为空")
private FileTypeEnum fileType;

View File

@ -0,0 +1,36 @@
package cn.axzo.workflow.common.model.request.bpmn.print;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
/**
* 请求审批日志转 pdf 的入参模型
*
* @author wangli
* @since 2025-10-31 17:15
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PrintProcessLogPdfDTO {
/**
* 审批实例 ID
*/
@ApiModelProperty(value = "审批实例 ID")
@NotBlank(message = "审批实例 ID 不能为空")
private String processInstanceId;
/**
* 实例日志访问者的personId
*/
@ApiModelProperty(value = "访问者的 PersonId")
@NotBlank(message = "访问者的 personId 不能为空")
private String personId;
}

View File

@ -109,4 +109,7 @@ public class SupportRefreshProperties {
@Value("${workflow.ignoreMqAlterApplicationNames:}")
private List<String> ignoreMqAlterApplicationNames;
@Value("${workflow.processLogHtmlUrl:https://taskflow-web.axzo.cn/#/document/log?processInstanceId=%s&personId=%d}")
private String processLogHtmlUrl;
}

View File

@ -42,7 +42,9 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERAT
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_SPECIFY_NEXT_APPROVER;
import static cn.axzo.workflow.common.constant.BpmnConstants.SIGNATURE_COLLECTION;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_LOG_NODE_HAS_BEEN_HIDDEN;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.HIDDEN;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
@ -159,7 +161,12 @@ public class CustomApproveTaskCmd extends AbstractCommand<Void> implements Seria
runtimeService.setVariable(task.getProcessInstanceId(), INTERNAL_SPECIFY_NEXT_APPROVER,
nextApprover);
}
Boolean logNodeHidden = (Boolean) task.getTransientVariable(TASK_LOG_NODE_HAS_BEEN_HIDDEN);
if (logNodeHidden) {
task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + taskId, HIDDEN.getStatus());
} else {
task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + taskId, APPROVED.getStatus());
}
// 更新流程内的变量
runtimeService.setVariables(task.getProcessInstanceId(), variables);

View File

@ -7,6 +7,7 @@ import cn.axzo.karma.client.model.response.PersonProfileResp;
import cn.axzo.orggateway.api.nodeuser.resp.FlowTaskAssignerV2Resp;
import cn.axzo.workflow.common.enums.ApproverScopeEnum;
import cn.axzo.workflow.common.enums.CarbonCopyObjectType;
import cn.axzo.workflow.common.exception.WorkflowApproverCalcException;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
@ -45,6 +46,7 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.CALC_TASK_ASSIGNEE_ERROR;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.COOPERATION_NOT_EXIST_WITH_NODE;
import static cn.axzo.workflow.common.code.ConvertorRespCode.CONVERTOR_META_DATA_FORMAT_ERROR;
import static cn.axzo.workflow.common.code.FlowableEngineRespCode.ENGINE_USER_TASK_CALC_ERROR;
import static cn.axzo.workflow.common.code.FlowableEngineRespCode.ENGINE_USER_TASK_PARAM_ERROR;
@ -122,6 +124,40 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign
return Collections.emptyList();
}
protected final <T> T parseFoundationApiResultWithErrCode(Supplier<cn.axzo.foundation.result.ApiResult<T>> supplier, String operatorDesc,
String extInfo, Object... param) {
StopWatch stopWatch = new StopWatch(operatorDesc);
log.info("{}-Param: {}", operatorDesc, JSONUtil.toJsonStr(param));
stopWatch.start();
cn.axzo.foundation.result.ApiResult<T> result = supplier.get();
stopWatch.stop();
log.info("{}-Cost:{}, Result: {}", operatorDesc,
"API StopWatch '" + stopWatch.getId() + "': running time = " + stopWatch.getTotalTimeSeconds() + " 's",
JSONUtil.toJsonStr(result));
try {
if (stopWatch.getTotalTimeSeconds() > refreshProperties.getApiTimeout() && Boolean.TRUE.equals(refreshProperties.getSendDingTalk())) {
DingTalkUtils.sendDingTalkForSlowUrl(applicationContext.getEnvironment()
.getProperty("spring.profiles.active"),
stopWatch.getTotalTimeSeconds(),
extInfo,
param,
result);
}
} catch (Exception e) {
// ignore
}
Assert.notNull(result, "服务调用异常");
if (Objects.equals(30022100, result.getCode())) {
// 特殊需求组织不存在时抛得的异常码
throw new WorkflowApproverCalcException(COOPERATION_NOT_EXIST_WITH_NODE);
}
// 200自定义处理
if (HttpStatus.HTTP_OK != result.getCode()) {
throw new WorkflowEngineException(CALC_TASK_ASSIGNEE_ERROR, "[API:" + extInfo + "]" + result.getMsg());
}
return result.getData();
}
protected final <T> T parseFoundationApiResult(Supplier<cn.axzo.foundation.result.ApiResult<T>> supplier, String operatorDesc,
String extInfo, Object... param) {
StopWatch stopWatch = new StopWatch(operatorDesc);

View File

@ -9,9 +9,11 @@ import cn.axzo.orggateway.api.nodeuser.resp.FlowTaskAssignerV2Resp;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.enums.ApproverSpecifyRangeEnum;
import cn.axzo.workflow.common.enums.SignApproverOrgLimitEnum;
import cn.axzo.workflow.common.exception.WorkflowApproverCalcException;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
@ -21,6 +23,7 @@ import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@ -33,6 +36,7 @@ import static cn.axzo.workflow.common.code.FlowableEngineRespCode.ENGINE_USER_TA
import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION;
import static cn.axzo.workflow.common.constant.BpmnConstants.CLOSE_PROCESS_ASSIGNER;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_LOG_NODE_HAS_BEEN_HIDDEN;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdmin;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecifyRange;
@ -120,8 +124,14 @@ public class BasedIdentityV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
break;
}
FlowTaskAssignerV2Req request = v2ReqBuilder.build();
List<FlowTaskAssignerV2Resp> apiResultUsers = parseFoundationApiResult(() -> orgNodeUserApi.listFlowTaskAssignerV2(request), "新版查询身份下的人" + execution.getProcessInstanceId() + flowElement.getId(),
"cn.axzo.orggateway.api.nodeuser.OrgNodeUserApi.listFlowTaskAssignerV2", request);
List<FlowTaskAssignerV2Resp> apiResultUsers = new ArrayList<>();
try {
apiResultUsers.addAll(parseFoundationApiResultWithErrCode(() -> orgNodeUserApi.listFlowTaskAssignerV2(request), "新版查询身份下的人" + execution.getProcessInstanceId() + flowElement.getId(),
"cn.axzo.orggateway.api.nodeuser.OrgNodeUserApi.listFlowTaskAssignerV2", request));
} catch (WorkflowApproverCalcException e) {
log.warn("组织节点不存在, 入参:{}; 错误信息:{}", JSONUtil.toJsonStr(request), e.getMessage(), e);
execution.setVariable(TASK_LOG_NODE_HAS_BEEN_HIDDEN, true);
}
return convertApprover(apiResultUsers);
}

View File

@ -7,8 +7,10 @@ import cn.axzo.orggateway.api.nodeuser.req.FlowTaskAssignerV2Req;
import cn.axzo.orggateway.api.nodeuser.resp.FlowTaskAssignerV2Resp;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.enums.SignApproverOrgLimitEnum;
import cn.axzo.workflow.common.exception.WorkflowApproverCalcException;
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
@ -17,12 +19,14 @@ import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_LOG_NODE_HAS_BEEN_HIDDEN;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdmin;
import static cn.axzo.workflow.common.enums.ApproverSpecifyRangeUnitEnum.in_project;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
@ -74,8 +78,14 @@ public class BasedInitiatorLeaderV2TaskAssigneeSelector extends AbstractBpmnTask
.querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin)).isPresent());
FlowTaskAssignerV2Req request = v2ReqBuilder.build();
List<FlowTaskAssignerV2Resp> apiResultUsers = parseFoundationApiResult(() -> orgNodeUserApi.listFlowTaskAssignerV2(request), "新版查询发起人主管的审批人" + execution.getProcessInstanceId() + flowElement.getId(),
"cn.axzo.orggateway.api.nodeuser.OrgNodeUserApi.listFlowTaskAssignerV2", request);
List<FlowTaskAssignerV2Resp> apiResultUsers = new ArrayList<>();
try {
apiResultUsers.addAll(parseFoundationApiResultWithErrCode(() -> orgNodeUserApi.listFlowTaskAssignerV2(request), "新版查询发起人主管的审批人" + execution.getProcessInstanceId() + flowElement.getId(),
"cn.axzo.orggateway.api.nodeuser.OrgNodeUserApi.listFlowTaskAssignerV2", request));
} catch (WorkflowApproverCalcException e) {
log.warn("组织节点不存在, 入参:{}; 错误信息:{}", JSONUtil.toJsonStr(request), e.getMessage(), e);
execution.setVariable(TASK_LOG_NODE_HAS_BEEN_HIDDEN, true);
}
return convertApprover(apiResultUsers);
}

View File

@ -10,9 +10,11 @@ import cn.axzo.workflow.common.enums.ApproverSpecifyRangeEnum;
import cn.axzo.workflow.common.enums.ApproverSpecifyRangeUnitEnum;
import cn.axzo.workflow.common.enums.CooperateShipTypeEnum;
import cn.axzo.workflow.common.enums.SignApproverOrgLimitEnum;
import cn.axzo.workflow.common.exception.WorkflowApproverCalcException;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
@ -22,6 +24,7 @@ import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@ -33,6 +36,7 @@ import static cn.axzo.workflow.common.code.FlowableEngineRespCode.ENGINE_POSITIO
import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION;
import static cn.axzo.workflow.common.constant.BpmnConstants.CLOSE_PROCESS_ASSIGNER;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_LOG_NODE_HAS_BEEN_HIDDEN;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdmin;
import static cn.axzo.workflow.common.enums.ApproverSpecifyRangeUnitEnum.in_project;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
@ -143,8 +147,14 @@ public class BasedPositionV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
break;
}
FlowTaskAssignerV2Req request = v2ReqBuilder.build();
List<FlowTaskAssignerV2Resp> apiResultUsers = parseFoundationApiResult(() -> orgNodeUserApi.listFlowTaskAssignerV2(request), "新版查询岗位下的人" + execution.getProcessInstanceId() + flowElement.getId(),
"cn.axzo.orggateway.api.nodeuser.OrgNodeUserApi.listFlowTaskAssignerV2", request);
List<FlowTaskAssignerV2Resp> apiResultUsers = new ArrayList<>();
try {
apiResultUsers.addAll(parseFoundationApiResultWithErrCode(() -> orgNodeUserApi.listFlowTaskAssignerV2(request), "新版查询岗位下的人" + execution.getProcessInstanceId() + flowElement.getId(),
"cn.axzo.orggateway.api.nodeuser.OrgNodeUserApi.listFlowTaskAssignerV2", request));
} catch (WorkflowApproverCalcException e) {
log.warn("组织节点不存在, 入参:{}; 错误信息:{}", JSONUtil.toJsonStr(request), e.getMessage(), e);
execution.setVariable(TASK_LOG_NODE_HAS_BEEN_HIDDEN, true);
}
return convertApprover(apiResultUsers);
}

View File

@ -10,9 +10,11 @@ import cn.axzo.workflow.common.enums.ApproverSpecifyRangeEnum;
import cn.axzo.workflow.common.enums.ApproverSpecifyRangeUnitEnum;
import cn.axzo.workflow.common.enums.CooperateShipTypeEnum;
import cn.axzo.workflow.common.enums.SignApproverOrgLimitEnum;
import cn.axzo.workflow.common.exception.WorkflowApproverCalcException;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
@ -23,6 +25,7 @@ import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@ -34,6 +37,7 @@ import static cn.axzo.workflow.common.code.FlowableEngineRespCode.ENGINE_ROLE_V2
import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION;
import static cn.axzo.workflow.common.constant.BpmnConstants.CLOSE_PROCESS_ASSIGNER;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_LOG_NODE_HAS_BEEN_HIDDEN;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdmin;
import static cn.axzo.workflow.common.enums.ApproverSpecifyRangeUnitEnum.in_project;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
@ -146,8 +150,14 @@ public class BasedRoleV2TaskAssigneeSelector extends AbstractBpmnTaskAssigneeSel
break;
}
FlowTaskAssignerV2Req request = v2ReqBuilder.build();
List<FlowTaskAssignerV2Resp> apiResultUsers = parseFoundationApiResult(() -> orgNodeUserApi.listFlowTaskAssignerV2(request), "新版查询角色下的人" + execution.getProcessInstanceId() + flowElement.getId(),
"cn.axzo.orggateway.api.nodeuser.OrgNodeUserApi.listFlowTaskAssignerV2", request);
List<FlowTaskAssignerV2Resp> apiResultUsers = new ArrayList<>();
try {
apiResultUsers.addAll(parseFoundationApiResultWithErrCode(() -> orgNodeUserApi.listFlowTaskAssignerV2(request), "新版查询角色下的人" + execution.getProcessInstanceId() + flowElement.getId(),
"cn.axzo.orggateway.api.nodeuser.OrgNodeUserApi.listFlowTaskAssignerV2", request));
} catch (WorkflowApproverCalcException e) {
log.warn("组织节点不存在, 入参:{}; 错误信息:{}", JSONUtil.toJsonStr(request), e.getMessage(), e);
execution.setVariable(TASK_LOG_NODE_HAS_BEEN_HIDDEN, true);
}
return convertApprover(apiResultUsers);
}

View File

@ -3,6 +3,9 @@ package cn.axzo.workflow.server.controller.web.manage;
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.nanopart.doc.api.conversion.DocConversionApi;
import cn.axzo.nanopart.doc.api.conversion.req.SubmitConversionTaskRequest;
import cn.axzo.nanopart.doc.api.enums.DocConversionTypeEnum;
import cn.axzo.oss.http.api.ServerFileServiceApi;
import cn.axzo.oss.http.model.ApiSignUrlDownloadRequest;
import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse;
@ -16,6 +19,7 @@ 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.PrintProcessLogPdfDTO;
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;
@ -28,6 +32,7 @@ import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLo
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.conf.SupportRefreshProperties;
import cn.axzo.workflow.core.engine.cmd.CustomGetFormInstanceLatestValuesCmd;
import cn.axzo.workflow.core.engine.cmd.CustomGetProcessInstanceVariablesCmd;
import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
@ -46,7 +51,6 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
@ -59,6 +63,7 @@ import org.flowable.form.model.FormField;
import org.flowable.form.model.FormFieldTypes;
import org.flowable.form.model.SimpleFormModel;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.slf4j.Logger;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@ -139,13 +144,13 @@ import static cn.azxo.framework.common.model.CommonResponse.success;
* @author wangli
* @since 2025-01-16 17:48
*/
@Slf4j
@RequestMapping({"/web/v1/api/print/admin", "/api/print/admin"})
@RestController
@ErrorReporter
@Validated
public class PrintAdminController implements PrintAdminApi {
private static final Logger log = org.slf4j.LoggerFactory.getLogger(PrintAdminController.class);
@Resource
private FormRepositoryService formRepositoryService;
@Resource
@ -168,6 +173,10 @@ public class PrintAdminController implements PrintAdminApi {
private TaskService taskService;
@Resource
private ServerFileServiceApi serverFileServiceApi;
@Resource
private DocConversionApi docConversionApi;
@Resource
private SupportRefreshProperties refreshProperties;
/**
* 查询指定流程实例是否能使用打印
@ -575,4 +584,17 @@ public class PrintAdminController implements PrintAdminApi {
return RpcExternalUtil.rpcProcessor(() -> serverFileServiceApi.signUrlFetchDownload(request), "批量获取手写签私有访问地址", request);
}
@Operation(summary = "后端请求指定流程日志 PDF 文件生成")
@PostMapping("/process/log/pdf")
@Override
public CommonResponse<String> createProcessLogPdf(@Validated @RequestBody PrintProcessLogPdfDTO dto) {
SubmitConversionTaskRequest request = new SubmitConversionTaskRequest();
request.setBizCode("workflow-process-log");
request.setBizKey(dto.getProcessInstanceId());
request.setConversionType(DocConversionTypeEnum.HTML_URL_TO_PDF);
request.setFileName(String.format(refreshProperties.getProcessLogHtmlUrl(), dto.getProcessInstanceId(), dto.getPersonId()));
request.setFileKey(dto.getPersonId());
String taskId = RpcExternalUtil.rpcApiResultProcessor(() -> docConversionApi.submitConvertTask(request), "创建网页转 PDF 的异步任务", request);
return CommonResponse.success(taskId);
}
}

View File

@ -59,6 +59,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELAT
import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE;
import static cn.axzo.workflow.common.constant.BpmnConstants.SUPPORT_UPGRADE_VARIABLE;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_LOG_NODE_HAS_BEEN_HIDDEN;
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.nobody;
import static cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum.BACK_COUNTERSIGN;
import static cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum.FORWARD_COUNTERSIGN;
@ -291,6 +292,8 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
needDelete = true;
}
}
// 重置日志隐藏的标识为 false
taskEntity.setVariable(TASK_LOG_NODE_HAS_BEEN_HIDDEN, false);
update.setEndTime(new Date());
// 判断是否抄送节点如果是的话需要将抄送人集合放入对应字段