diff --git a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessInstanceApi.java b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessInstanceApi.java index 82cda512c..837b5b496 100644 --- a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessInstanceApi.java +++ b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessInstanceApi.java @@ -17,11 +17,13 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCre import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO; +import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceVariablesUpdateDTO; import cn.axzo.workflow.common.model.request.bpmn.process.SuperBpmnProcessInstanceCancelDTO; import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO; import cn.axzo.workflow.common.model.request.bpmn.process.doc.ChangeApproverReadStatusDTO; import cn.axzo.workflow.common.model.request.bpmn.process.doc.ProcessDocQueryDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO; +import cn.axzo.workflow.common.model.request.form.ConditionPermissionMetaInfo; import cn.axzo.workflow.common.model.request.form.instance.FormVariablesUpdateDTO; import cn.axzo.workflow.common.model.response.BpmPageResult; import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO; @@ -180,6 +182,17 @@ public interface ProcessInstanceApi { CommonResponse> getProcessVariables(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId); + /** + * 更新流程实例中的业务自定义变量集合 + * + * @param dto + * @return + */ + @Operation(summary = "更新流程实例中的业务自定义变量集合") + @PostMapping("/api/process/instance/biz/custom/variables/update") + @InvokeMode(SYNC) + CommonResponse updateProcessBizCustomVariables(@Validated @RequestBody BpmnProcessInstanceVariablesUpdateDTO dto); + /** * 查询所有的审批流 * @@ -358,4 +371,15 @@ public interface ProcessInstanceApi { @Manageable @InvokeMode(SYNC) CommonResponse> getProcessLogByInstanceIdAndPersonId(@Validated @RequestBody LogApproveSearchDTO dto); + + /** + * 获取流程实例的条件字段信息,仅用于同意抽屉展示 + * + * @param processInstanceId + * @return + */ + @Operation(summary = "获取流程实例的条件字段信息, 仅用于同意抽屉展示") + @GetMapping("/api/process/instance/conditions") + @InvokeMode(SYNC) + CommonResponse> getConditions(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId); } diff --git a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/manage/PrintAdminApi.java b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/manage/PrintAdminApi.java index 9dec9a0a9..a3b91683f 100644 --- a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/manage/PrintAdminApi.java +++ b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/manage/PrintAdminApi.java @@ -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> 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 getPrintDataForProcessLog(@Validated @RequestBody Print4ProcessLogDTO dto); } diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java index 97f0b30f2..0daac19ab 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java @@ -117,6 +117,7 @@ public interface BpmnConstants { String CONFIG_ACTIVITY_SIGNATURE = "signature"; String CONFIG_FIELD_META = "field"; String CONFIG_FIELD_PERMISSION = "fieldPermission"; + String CONFIG_CONDITION_PERMISSION = "conditionPermission"; String CONFIG_FIELD_OPTION = "option"; String CONFIG_NODE_TYPE = "nodeType"; String CONFIG_BUTTON_TYPE_INITIATOR = "initiator"; @@ -126,6 +127,7 @@ public interface BpmnConstants { String CONFIG_SIGN_TYPE = "signType"; String CONFIG_AREA_FILTER_ENABLE = "areaFilterEnable"; String CONFIG_SPECIALTY_FILTER_ENABLE = "specialtyFilterEnable"; + String CONFIG_ONLY_IN_PROJECT_ENABLE = "onlyInProjectEnable"; String ELEMENT_ATTRIBUTE_NAME = "name"; String ELEMENT_ATTRIBUTE_VALUE = "value"; String ELEMENT_ATTRIBUTE_DESC = "desc"; @@ -259,7 +261,11 @@ public interface BpmnConstants { /** * 签署业务自定义文档的顺序位置类型 */ - String SIGN_BIZ_CUSTOM_DOC_ADD_TYPE = "[_SIGN_BIZ_CUSTOM_DOC_ADD_TYPE_]"; + String SIGN_BIZ_CUSTOM_DOC_ADD_ORDER_TYPE = "[_SIGN_BIZ_CUSTOM_DOC_ADD_ORDER_TYPE_]"; + /** + * 签署业务,业务对所有文档顺序排序 + */ + String SIGN_BIZ_BASED_FILE_TAG_ORDER = "[_SIGN_BIZ_BASED_FILE_TAG_ORDER_]"; /** * 签署业务,基于业务自定义变量的传入 */ diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/VariableConstants.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/VariableConstants.java index e9853631b..d8a6ed3ff 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/VariableConstants.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/VariableConstants.java @@ -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"; @@ -54,7 +60,7 @@ public interface VariableConstants { String PRINT_VAR_PROCESS_LOG_ACTIVITY_NAME = "activityName"; String PRINT_VAR_PROCESS_LOG_ACTIVITY_NAME_DESC = "节点名称"; String PRINT_VAR_PROCESS_LOG_APPROVER_NAME = "approverName"; - String PRINT_VAR_PROCESS_LOG_APPROVER_NAME_DESC = "审批人"; + String PRINT_VAR_PROCESS_LOG_APPROVER_NAME_DESC = "姓名"; String PRINT_VAR_PROCESS_LOG_UNIT = "unit"; String PRINT_VAR_PROCESS_LOG_UNIT_DESC = "单位"; String PRINT_VAR_PROCESS_LOG_POSITION = "position"; @@ -66,7 +72,9 @@ public interface VariableConstants { String PRINT_VAR_PROCESS_LOG_SIGNATURE = "signature"; String PRINT_VAR_PROCESS_LOG_SIGNATURE_DESC = "电子签名"; String PRINT_VAR_PROCESS_LOG_ACTIVITY_RESULT = "activityResult"; - String PRINT_VAR_PROCESS_LOG_ACTIVITY_RESULT_DESC = "节点状态"; + String PRINT_VAR_PROCESS_LOG_ACTIVITY_RESULT_DESC = "审批结果"; + String PRINT_VAR_PROCESS_LOG_ACTIVITY_OPERATION_TIME = "activityOperationTime"; + String PRINT_VAR_PROCESS_LOG_ACTIVITY_OPERATION_TIME_DESC = "日期"; String PRINT_VAR_PROCESS_LOG_OPERATION = "operationDesc"; String PRINT_VAR_PROCESS_LOG_OPERATION_DESC = "操作描述"; } diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CooperationOrgDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CooperationOrgDTO.java index 0106ffb23..64f53ee47 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CooperationOrgDTO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CooperationOrgDTO.java @@ -40,6 +40,11 @@ public class CooperationOrgDTO implements Serializable { */ private List includeSpecialtyCodes; + /** + * 控制仅支持工程内人员参与审批 + */ + private List projectIds; + /** * 企业组织架构范围 **/ diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CustomDocDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CustomDocDTO.java index 40d4f5de5..c61b3b7ef 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CustomDocDTO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CustomDocDTO.java @@ -8,6 +8,7 @@ import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import java.io.Serializable; /** @@ -29,8 +30,9 @@ public class CustomDocDTO implements Serializable { */ private Long id; /** - * 文件名称,可能会包含变量 + * 文件名称 */ + @NotBlank(message = "业务自定义文件名称不能为空") private String fileName; /** @@ -39,20 +41,21 @@ public class CustomDocDTO implements Serializable { private String fileTag; /** - * 文件 wps code + * 如果业务是使用在线文档,则一定会有 wps code,如果有则传入 *

* wps 文件的标识,通过{@link cn.axzo.nanopart.doc.api.anonymous.DocAnonymousDatabaseApi#createFile(cn.axzo.nanopart.doc.api.anonymous.request.AnonymousCreateFileRequest)} 接口创建文件后返回的 fileCode */ private String fileCode; /** - * oss 地址的文件标识 + * 不管是在线文件还是本地上传,必须包含 oss 地址的文件标识 */ - @NotBlank(message = "文件的 oss key 不能为空") + @NotBlank(message = "业务自定义文件的 oss key 不能为空") private String fileKey; /** * 文件的类型 */ + @NotNull(message = "业务自定义文件的类型不能为空") private FileTypeEnum fileType; } diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java index ca44ab03c..6e1183625 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java @@ -10,6 +10,7 @@ import cn.axzo.workflow.common.enums.BpmnFlowNodeMode; import cn.axzo.workflow.common.enums.CooperateShipTypeEnum; import cn.axzo.workflow.common.enums.InitiatorSpecifiedRangeEnum; import cn.axzo.workflow.common.enums.SignApproverOrgLimitEnum; +import cn.axzo.workflow.common.model.request.form.ConditionPermissionMetaInfo; import cn.axzo.workflow.common.model.request.form.FormPermissionMetaInfo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -201,6 +202,12 @@ public class BpmnJsonNodeProperty { @ApiModelProperty(value = "表单字段权限控制") private List fieldPermission; + /** + * 条件字段权限配置 + */ + @ApiModelProperty(value = "条件字段权限控制") + private List conditionPermission; + /** * 区域过滤开关 */ @@ -213,4 +220,9 @@ public class BpmnJsonNodeProperty { @ApiModelProperty(value = "专业过滤开关", notes = "true: 开启专业过滤, false: 关闭专业过滤") private Boolean specialtyFilterEnable; + /** + * 工程内人员开关 + */ + @ApiModelProperty(value = "仅工程内人员开关", notes = "true: 仅工程内人员, false: 非仅工程内人员") + private Boolean onlyInProjectEnable; } diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/print/Print4ProcessLogDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/print/Print4ProcessLogDTO.java new file mode 100644 index 000000000..87dc3ae33 --- /dev/null +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/print/Print4ProcessLogDTO.java @@ -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; + +} diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceCreateDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceCreateDTO.java index 88cfab976..dea65772e 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceCreateDTO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceCreateDTO.java @@ -131,12 +131,20 @@ public class BpmnProcessInstanceCreateDTO extends BpmnProcessInstanceCreateWithF private List customDocs; /** - * "签字业务"专用,自定义文档的顺序位置信息,在流程模板配置文档之前还是之后 + * "签字业务"专用,自定义文档的顺序位置信息,在流程模板配置文档之前还是之后, 该属性与{@link BpmnProcessInstanceCreateDTO#basedFileTagOrder} 互斥 *

* 可选值:first(之前)、last(之后), 如果为空,默认为 last */ @ApiModelProperty(value = "自定义文档顺序位置", notes = "可选值:first(之前)、last(之后), 如果为空,默认为 last") - private String docAddType; + private String docAddOrderType = "last"; + + /** + * "签字业务"专用, 该属性与{@link BpmnProcessInstanceCreateDTO#docAddOrderType} 互斥 + *

+ * 业务对所有文档的顺序覆盖,必须对全量文档进行设置 + */ + @ApiModelProperty(value = "业务对所有文档的顺序覆盖") + public List basedFileTagOrder; /** * 仅针对签署业务,设置审批完成后的最终签署人列表,该属性仅为透传,业务消费时,请从 MQ 广播事件中的 variables 中通过 key= {@link BpmnConstants#SIGNATORIES } 获取 diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceVariablesUpdateDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceVariablesUpdateDTO.java new file mode 100644 index 000000000..758142593 --- /dev/null +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceVariablesUpdateDTO.java @@ -0,0 +1,38 @@ +package cn.axzo.workflow.common.model.request.bpmn.process; + +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import java.util.Map; + +/** + * 更新流程实例中变量集合的入参模型 + * + * @author wangli + * @since 2025-10-24 10:56 + */ +@ApiModel("更新流程实例中变量集合的入参模型") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BpmnProcessInstanceVariablesUpdateDTO { + + /** + * 流程实例 ID + */ + @NotBlank(message = "流程实例 ID 不能为空") + private String processInstanceId; + + /** + * 业务管理中定义变量的入参, 如果 key 在创建时已存在,则进行覆盖更新,否则新增变量 + *

+ * 对应创建流程实例中的 {@link BpmnProcessInstanceCreateDTO#bizCustomVariables} 属性 + */ + private Map bizCustomVariables; + +} diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/form/ConditionPermissionMetaInfo.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/form/ConditionPermissionMetaInfo.java new file mode 100644 index 000000000..daad1dd0b --- /dev/null +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/form/ConditionPermissionMetaInfo.java @@ -0,0 +1,105 @@ +package cn.axzo.workflow.common.model.request.form; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 表单字段权限信息 + * + * @author wangli + * @since 2024-11-07 11:09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class ConditionPermissionMetaInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 条件标识 + */ + private String conditionCode; + + /** + * 条件名称 + */ + private String conditionName; + + /** + * 单选框 + * 条件类型(text/number/checkbox/radio) + */ + private String conditionType; + /** + * 可编辑必填 + */ + @Builder.Default + private Boolean required = false; + + /** + * 可编辑非必填 + */ + @Builder.Default + private Boolean editable = false; + + /** + * 只读 + */ + @Builder.Default + private Boolean readonly = true; + + /** + * 隐藏 + */ + @Builder.Default + private Boolean hidden = false; + + /** + * 前端回显字段,后端不做任何消费逻辑 + */ + private String value; + + /** + * 类型是单选复选时的选项值 + */ + private String options; + + + // 将对象的属性转换为对应的整数表示 + public int toBinary() { + int binaryValue = 0; + binaryValue |= (required ? 1 : 0) << 3; + binaryValue |= (editable ? 1 : 0) << 2; + binaryValue |= (readonly ? 1 : 0) << 1; + binaryValue |= (hidden ? 1 : 0); + return binaryValue; + } + + // 从整数表示还原出对象 + public static ConditionPermissionMetaInfo fromBinary(String conditionCode, String conditionName, String conditionType, int binaryValue) { + boolean required = ((binaryValue >> 3) & 1) == 1; + boolean editable = ((binaryValue >> 2) & 1) == 1; + boolean readonly = ((binaryValue >> 1) & 1) == 1; + boolean hidden = (binaryValue & 1) == 1; + return new ConditionPermissionMetaInfo(conditionCode, conditionName, conditionType, required, editable, readonly, hidden, null, null); + } + + public ConditionPermissionMetaInfo toReadonly() { + if (required || editable || readonly) { + setRequired(false); + setEditable(false); + setReadonly(true); + setHidden(false); + } + return this; + } + + public String toBinaryString() { + return String.format("%04d", Integer.parseInt(Integer.toBinaryString(toBinary()), 10)); + } +} diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/ProcessLogItemDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/ProcessLogItemDTO.java new file mode 100644 index 000000000..cc556ce48 --- /dev/null +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/ProcessLogItemDTO.java @@ -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 imageList; + /** + * 附件列表 + */ + @ApiModelProperty(value = "附件列表") + private List fileList; + /** + * 手写签名地址 + */ + @ApiModelProperty(value = "手写签名地址") + private String signatureUrl; + + /** + * 操作时间 + */ + @ApiModelProperty(value = "操作时间") + private String operationTime; +} diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/TableItemDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/TableItemDTO.java new file mode 100644 index 000000000..c3ba57e8d --- /dev/null +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/TableItemDTO.java @@ -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; +} diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/PrintData4LogVO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/PrintData4LogVO.java new file mode 100644 index 000000000..d71def5d9 --- /dev/null +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/PrintData4LogVO.java @@ -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 systemVarItems; + + /** + * 审批日志表格项 + */ + private List logItems; +} + diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java index b0217a7e0..af85769b5 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java @@ -31,6 +31,7 @@ import cn.axzo.workflow.common.model.request.bpmn.BpmnSignConf; import cn.axzo.workflow.common.model.request.bpmn.BpmnSignPendingProperty; import cn.axzo.workflow.common.model.request.bpmn.BpmnSmsProperty; import cn.axzo.workflow.common.model.request.bpmn.BpmnUpgradeApprovalConf; +import cn.axzo.workflow.common.model.request.form.ConditionPermissionMetaInfo; import cn.axzo.workflow.common.model.request.form.FormPermissionMetaInfo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; @@ -82,6 +83,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPIE import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPY; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPY_OBJECT; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPY_SPECIFY; +import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CONDITION_PERMISSION; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD_META; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD_OPTION; @@ -93,6 +95,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SP import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SPECIFIED_RANGE; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_NODE_TYPE; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_NOTICE; +import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_ONLY_IN_PROJECT_ENABLE; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_SIGN; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_SIGN_APPROVER_LIMIT; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_SIGN_APPROVER_ORG_LIMIT; @@ -648,6 +651,10 @@ public final class BpmnMetaParserHelper { return defaultValid(flowElement, CONFIG_SPECIALTY_FILTER_ENABLE).map(element -> Boolean.valueOf(element.getAttributeValue(null, ELEMENT_ATTRIBUTE_CHECKED))).orElse(false); } + public static Boolean getOnlyInProjectEnable(FlowElement flowElement) { + return defaultValid(flowElement, CONFIG_ONLY_IN_PROJECT_ENABLE).map(element -> Boolean.valueOf(element.getAttributeValue(null, ELEMENT_ATTRIBUTE_CHECKED))).orElse(false); + } + private static Optional defaultValid(FlowElement flowElement, String elementName) { if (Objects.isNull(flowElement)) { return Optional.empty(); @@ -692,6 +699,10 @@ public final class BpmnMetaParserHelper { }.getType())); } + public static Optional> getConditionPermissionConf(FlowElement flowElement) { + return defaultValid(flowElement, CONFIG_CONDITION_PERMISSION).map(element -> JSON.parseObject(element.getElementText(), new TypeReference>() { + }.getType())); + } public static Optional> getFormFieldPermissionForCalc(FlowElement flowElement) { List fieldMetaInfos = getFormFieldPermissionConf(flowElement).orElse(new ArrayList<>()); return getFormFieldPermissionForModel(fieldMetaInfos); diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java index acca4c4c1..53fc11e8e 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java @@ -2,6 +2,7 @@ package cn.axzo.workflow.core.conf; import cn.axzo.workflow.core.common.utils.SpringContextUtils; import cn.axzo.workflow.core.engine.behavior.CustomActivityBehaviorFactory; +import cn.axzo.workflow.core.engine.cfg.CustomDefaultInternalJobManager; import cn.axzo.workflow.core.engine.cmd.CustomCommandContextFactory; import cn.axzo.workflow.core.engine.formhandler.CustomFormFieldHandler; import cn.axzo.workflow.core.engine.id.BasedNacosSnowflakeIdGenerator; @@ -143,6 +144,7 @@ public class FlowableConfiguration { configuration.setFormFieldValidationEnabled(true); configuration.setFormFieldHandler(new CustomFormFieldHandler()); configuration.setConfigurators(Lists.newArrayList(new CustomJobServiceConfiguration())); + configuration.setInternalJobManager(new CustomDefaultInternalJobManager(configuration)); }; } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/converter/json/ServiceTaskJsonConverter.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/converter/json/ServiceTaskJsonConverter.java index 100756b9b..c41dda0ec 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/converter/json/ServiceTaskJsonConverter.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/converter/json/ServiceTaskJsonConverter.java @@ -25,6 +25,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPIE import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPY; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPY_OBJECT; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPY_SPECIFY; +import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CONDITION_PERMISSION; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD_PERMISSION; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_LEADER_RANGE_UNIT; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SPECIFIED_EXCLUDE_COOPERATE_TYPES; @@ -68,6 +69,8 @@ public class ServiceTaskJsonConverter extends AbstractBpmnJsonConverter { setApprovalExtensionElement(node, userTask); // "表单权限设置" setFormFieldExtensionElement(node, userTask); + // "条件权限设置" + setConditionExtensionElement(node, userTask); // "高级设置",包含按钮配置,自动过审配置 setAdvancedExtensionElement(node, userTask); // "待办消息模板配置" @@ -183,6 +187,14 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter { specialtyFilterEnableElement.addAttribute(specialtyFilterEnableAttribute); userTask.addExtensionElement(specialtyFilterEnableElement); + ExtensionElement onlyInProjectEnableElement = new ExtensionElement(); + onlyInProjectEnableElement.setName(CONFIG_ONLY_IN_PROJECT_ENABLE); + ExtensionAttribute onlyInProjectEnableAttribute = new ExtensionAttribute(); + onlyInProjectEnableAttribute.setName(ELEMENT_ATTRIBUTE_CHECKED); + onlyInProjectEnableAttribute.setValue(String.valueOf(Boolean.TRUE.equals(node.getProperty().getOnlyInProjectEnable()))); + onlyInProjectEnableElement.addAttribute(onlyInProjectEnableAttribute); + userTask.addExtensionElement(onlyInProjectEnableElement); + //添加自动审批配置 ExtensionElement autoApprovalExtensionElement = new ExtensionElement(); ExtensionAttribute pendingMessageAttribute = new ExtensionAttribute(); @@ -191,6 +203,17 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter { userTask.addExtensionElement(autoApprovalExtensionElement); } + private static void setConditionExtensionElement(BpmnJsonNode node, UserTask userTask) { + if (Objects.isNull(node.getProperty()) || CollectionUtils.isEmpty(node.getProperty().getConditionPermission())) { + return; + } + ExtensionElement fieldElement = new ExtensionElement(); + fieldElement.setName(CONFIG_CONDITION_PERMISSION); + fieldElement.setElementText(Objects.nonNull(node.getProperty().getConditionPermission()) ? + JSON.toJSONString(node.getProperty().getConditionPermission()) : null); + userTask.addExtensionElement(fieldElement); + } + private static void setFormFieldExtensionElement(BpmnJsonNode node, UserTask userTask) { if (Objects.isNull(node.getProperty()) || CollectionUtils.isEmpty(node.getProperty().getFieldPermission())) { return; diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cfg/CustomDefaultInternalJobManager.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cfg/CustomDefaultInternalJobManager.java new file mode 100644 index 000000000..b573e1f83 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cfg/CustomDefaultInternalJobManager.java @@ -0,0 +1,31 @@ +package cn.axzo.workflow.core.engine.cfg; + +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.impl.cfg.DefaultInternalJobManager; +import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.job.api.Job; + +/** + * 为解决引擎底层定时任务的 NPE 问题 + * + * @author wangli + * @since 2025-10-24 17:42 + */ +@Slf4j +public class CustomDefaultInternalJobManager extends DefaultInternalJobManager { + public CustomDefaultInternalJobManager(ProcessEngineConfigurationImpl processEngineConfiguration) { + super(processEngineConfiguration); + } + + @Override + protected void handleJobDeleteInternal(Job job) { + ExecutionEntity executionEntity = getExecutionEntityManager().findById(job.getExecutionId()); + log.info("handleJobDeleteInternal job.eId:{}, job.piId:{} ", job.getExecutionId(), job.getProcessInstanceId()); + if (executionEntity == null) { + log.warn("handleJobDeleteInternal executionEntity is null for job.eId:{}, job.piId:{} ", job.getExecutionId(), job.getProcessInstanceId()); + return; + } + super.handleJobDeleteInternal(job); + } +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java index 30bcbcdc9..99992115d 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java @@ -161,6 +161,7 @@ public class CustomApproveTaskCmd extends AbstractCommand implements Seria } task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + taskId, APPROVED.getStatus()); + // 更新流程内的变量 runtimeService.setVariables(task.getProcessInstanceId(), variables); // 记录电子签名的图片 recordSignature(task, runtimeService); diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskWithFormCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskWithFormCmd.java index 050ee28fc..4b3a31795 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskWithFormCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskWithFormCmd.java @@ -180,6 +180,7 @@ public class CustomApproveTaskWithFormCmd extends AbstractCommand implemen nextApprover); } task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + taskId, APPROVED.getStatus()); + // 更新流程实例变量 runtimeService.setVariables(task.getProcessInstanceId(), variables); // 记录电子签名的图片 recordSignature(task, runtimeService); diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomGetConditionPermissionsCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomGetConditionPermissionsCmd.java new file mode 100644 index 000000000..3f81e7318 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomGetConditionPermissionsCmd.java @@ -0,0 +1,64 @@ +package cn.axzo.workflow.core.engine.cmd; + +import cn.axzo.workflow.common.model.request.form.ConditionPermissionMetaInfo; +import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper; +import com.alibaba.fastjson.JSON; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; +import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.engine.impl.util.ProcessDefinitionUtil; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.task.api.Task; +import org.springframework.util.CollectionUtils; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * 获取指定流程节点配置的条件权限信息 + * + * @author wangli + * @since 2025-10-29 18:02 + */ +public class CustomGetConditionPermissionsCmd extends AbstractCommand> { + private final String processInstanceId; + + public CustomGetConditionPermissionsCmd(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("processInstanceId", processInstanceId); + return JSON.toJSONString(params); + } + + @Override + public List execute(CommandContext commandContext) { + ProcessEngineConfigurationImpl processEngineConfiguration = + CommandContextUtil.getProcessEngineConfiguration(commandContext); + RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); + if (Objects.isNull(processInstance)) { + return Collections.emptyList(); + } + TaskService taskService = processEngineConfiguration.getTaskService(); + List tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).active().list(); + if (CollectionUtils.isEmpty(tasks)) { + return Collections.emptyList(); + } + BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(processInstance.getProcessDefinitionId()); + FlowElement flowElement = bpmnModel.getFlowElement(tasks.get(0).getId()); + List conditions = BpmnMetaParserHelper.getConditionPermissionConf(flowElement).orElse(Collections.emptyList()); + conditions.forEach(e -> e.setValue(null)); + return conditions; + } +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomGetProcessInstanceVariablesCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomGetProcessInstanceVariablesCmd.java index bd84f4cf0..80ffb959a 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomGetProcessInstanceVariablesCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomGetProcessInstanceVariablesCmd.java @@ -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 implements Serializable { + private static final long serialVersionUID = 1L; + private final String processInstanceId; + private final Map variables; + + public CustomOverrideProcessVariablesCmd(String processInstanceId, Map variables) { + this.processInstanceId = processInstanceId; + this.variables = variables; + } + + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("processInstanceId", processInstanceId); + params.put("formVariables", variables); + return JSON.toJSONString(params); + } + + @Override + public Void executeInternal(CommandContext commandContext) { + if (CollectionUtils.isEmpty(variables)) { + return null; + } + ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(); + RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); + + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); + if (Objects.nonNull(processInstance)) { + throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS); + } + + runtimeService.setVariables(processInstanceId, variables); + return null; + } +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessInstanceService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessInstanceService.java index 7432d5fb7..9195fce8d 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessInstanceService.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessInstanceService.java @@ -10,10 +10,12 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCre import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO; +import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceVariablesUpdateDTO; import cn.axzo.workflow.common.model.request.bpmn.process.HistoricProcessInstanceSearchDTO; import cn.axzo.workflow.common.model.request.bpmn.process.SuperBpmnProcessInstanceCancelDTO; import cn.axzo.workflow.common.model.request.bpmn.process.doc.ProcessDocQueryDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO; +import cn.axzo.workflow.common.model.request.form.ConditionPermissionMetaInfo; import cn.axzo.workflow.common.model.request.form.instance.FormVariablesUpdateDTO; import cn.axzo.workflow.common.model.response.BpmPageResult; import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO; @@ -211,4 +213,8 @@ public interface BpmnProcessInstanceService { boolean hasPrintTemplate(String processInstanceId, String processDefinitionId); List processInstanceSelectDocs(ProcessDocQueryDTO dto); + + void overrideProcessVariables(BpmnProcessInstanceVariablesUpdateDTO dto); + + List getConditions(String processInstanceId); } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java index 0f07c01a1..ded8de75e 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java @@ -30,6 +30,7 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCre import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO; +import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceVariablesUpdateDTO; import cn.axzo.workflow.common.model.request.bpmn.process.HistoricProcessInstanceSearchDTO; import cn.axzo.workflow.common.model.request.bpmn.process.SuperBpmnProcessInstanceCancelDTO; import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO; @@ -39,6 +40,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.common.model.request.bpmn.task.ExtHiTaskSearchDTO; import cn.axzo.workflow.common.model.request.category.CategorySearchDTO; +import cn.axzo.workflow.common.model.request.form.ConditionPermissionMetaInfo; import cn.axzo.workflow.common.model.request.form.instance.FormVariablesUpdateDTO; import cn.axzo.workflow.common.model.response.BpmPageResult; import cn.axzo.workflow.common.model.response.bpmn.BatchOperationItemResultVO; @@ -65,8 +67,10 @@ import cn.axzo.workflow.core.engine.cmd.CustomCancelProcessInstanceAsyncCmd; import cn.axzo.workflow.core.engine.cmd.CustomCancelProcessInstanceCmd; import cn.axzo.workflow.core.engine.cmd.CustomCarbonCopyUserSelectorCmd; import cn.axzo.workflow.core.engine.cmd.CustomForecastUserTaskAssigneeCmd; +import cn.axzo.workflow.core.engine.cmd.CustomGetConditionPermissionsCmd; import cn.axzo.workflow.core.engine.cmd.CustomGetModelDocsCmd; import cn.axzo.workflow.core.engine.cmd.CustomOverrideFormVariablesByLatestInstanceCmd; +import cn.axzo.workflow.core.engine.cmd.CustomOverrideProcessVariablesCmd; import cn.axzo.workflow.core.engine.listener.EngineExecutionStartListener; import cn.axzo.workflow.core.repository.entity.ExtAxBpmnFormRelation; import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst; @@ -190,8 +194,9 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.OLD_INTERNAL_INITIA import static cn.axzo.workflow.common.constant.BpmnConstants.PENDING_TEMPLATE_VARIABLE; import static cn.axzo.workflow.common.constant.BpmnConstants.PROCESS_OWNERSHIP_APPLICATION; import static cn.axzo.workflow.common.constant.BpmnConstants.SIGNATORIES; +import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_BIZ_BASED_FILE_TAG_ORDER; import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_BIZ_CUSTOM_DOCS; -import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_BIZ_CUSTOM_DOC_ADD_TYPE; +import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_BIZ_CUSTOM_DOC_ADD_ORDER_TYPE; import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_PROCESS_ENABLE_DOC_IDS; import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_VARIABLE; import static cn.axzo.workflow.common.constant.BpmnConstants.WORKFLOW_ENGINE_VERSION; @@ -500,8 +505,12 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic dto.getVariables().put(SIGN_PROCESS_ENABLE_DOC_IDS, dto.getDocIds()); dto.getVariables().put(SIGN_VARIABLE, dto.getBizCustomVariables()); dto.getVariables().put(SIGNATORIES, dto.getSignatories()); + // 业务自定义文档 dto.getVariables().put(SIGN_BIZ_CUSTOM_DOCS, dto.getCustomDocs()); - dto.getVariables().put(SIGN_BIZ_CUSTOM_DOC_ADD_TYPE, StringUtils.hasText(dto.getDocAddType()) ? dto.getDocAddType() : "last"); + // 业务自定义文档追加顺序类型 + dto.getVariables().put(SIGN_BIZ_CUSTOM_DOC_ADD_ORDER_TYPE, StringUtils.hasText(dto.getDocAddOrderType()) ? dto.getDocAddOrderType() : "last"); + // 基于业务的标签排序 + dto.getVariables().put(SIGN_BIZ_BASED_FILE_TAG_ORDER, dto.getBasedFileTagOrder()); } }); dto.getVariables().put(INTERNAL_INITIATOR, dto.getInitiator().toJson()); @@ -1805,7 +1814,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic }); } - public List getAttachmentByType(Map> attachmentByTaskMap, String + public static List getAttachmentByType(Map> attachmentByTaskMap, String taskId, AttachmentTypeEnum type) { return ListUtils.emptyIfNull(attachmentByTaskMap.get(taskId)).stream() .filter(attachment -> Objects.equals(type.getType(), attachment.getType())) @@ -1914,7 +1923,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic List bizCustomDocs = Optional.ofNullable( runtimeService.getVariable(processInstanceId, SIGN_BIZ_CUSTOM_DOCS, List.class)) .orElse(Collections.emptyList()); - String customAddType = runtimeService.getVariable(processInstanceId, SIGN_BIZ_CUSTOM_DOC_ADD_TYPE, String.class); + String customAddType = runtimeService.getVariable(processInstanceId, SIGN_BIZ_CUSTOM_DOC_ADD_ORDER_TYPE, String.class); boolean appendLast = "last".equals(customAddType); Comparator orderComparator = Comparator.comparing( @@ -1951,4 +1960,16 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic return docs; } + + @Override + public void overrideProcessVariables(BpmnProcessInstanceVariablesUpdateDTO dto) { + CommandExecutor commandExecutor = springProcessEngineConfiguration.getCommandExecutor(); + commandExecutor.execute(new CustomOverrideProcessVariablesCmd(dto.getProcessInstanceId(), dto.getBizCustomVariables())); + } + + @Override + public List getConditions(String processInstanceId) { + CommandExecutor commandExecutor = springProcessEngineConfiguration.getCommandExecutor(); + return commandExecutor.execute(new CustomGetConditionPermissionsCmd(processInstanceId)); + } } diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedIdentityV2TaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedIdentityV2TaskAssigneeSelector.java index d62a73644..f86d05307 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedIdentityV2TaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedIdentityV2TaskAssigneeSelector.java @@ -39,6 +39,7 @@ import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprove import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecifyRangeOrgLimit; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecifyValueV2; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getAreaFilterEnable; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getOnlyInProjectEnable; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getSpecialtyFilterEnable; /** @@ -76,6 +77,7 @@ public class BasedIdentityV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne .initiatorPersonId(initiator.parsePersonId()) .areaCodes(getAreaFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeAreaCodes())) : Sets.newHashSet()) .specialtyCodes(getSpecialtyFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeSpecialtyCodes())) : Sets.newHashSet()) + .projectIds(getOnlyInProjectEnable(flowElement) ? Sets.newHashSet(orgDTO.getProjectIds()) : Sets.newHashSet()) .querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin)).isPresent()); switch (optRange.get()) { case within_the_project: diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedInitiatorLeaderV2TaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedInitiatorLeaderV2TaskAssigneeSelector.java index 47a2f50c3..9161ef04c 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedInitiatorLeaderV2TaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedInitiatorLeaderV2TaskAssigneeSelector.java @@ -28,6 +28,7 @@ import static cn.axzo.workflow.common.enums.ApproverSpecifyRangeUnitEnum.in_proj import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getAreaFilterEnable; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getInitiatorLeaderRangeUnit; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getOnlyInProjectEnable; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getSpecialtyFilterEnable; /** @@ -69,6 +70,7 @@ public class BasedInitiatorLeaderV2TaskAssigneeSelector extends AbstractBpmnTask .initiatorPersonId(initiator.parsePersonId()) .areaCodes(getAreaFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeAreaCodes())) : Sets.newHashSet()) .specialtyCodes(getSpecialtyFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeSpecialtyCodes())) : Sets.newHashSet()) + .projectIds(getOnlyInProjectEnable(flowElement) ? Sets.newHashSet(orgDTO.getProjectIds()) : Sets.newHashSet()) .querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin)).isPresent()); FlowTaskAssignerV2Req request = v2ReqBuilder.build(); diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedPositionV2TaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedPositionV2TaskAssigneeSelector.java index 3ccff50b5..31eed2e82 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedPositionV2TaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedPositionV2TaskAssigneeSelector.java @@ -42,6 +42,7 @@ import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprove import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecifyValueV2; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getAreaFilterEnable; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCooperateShipType; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getOnlyInProjectEnable; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getSpecialtyFilterEnable; /** @@ -80,6 +81,7 @@ public class BasedPositionV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne .initiatorPersonId(initiator.parsePersonId()) .areaCodes(getAreaFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeAreaCodes())) : Sets.newHashSet()) .specialtyCodes(getSpecialtyFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeSpecialtyCodes())) : Sets.newHashSet()) + .projectIds(getOnlyInProjectEnable(flowElement) ? Sets.newHashSet(orgDTO.getProjectIds()) : Sets.newHashSet()) .querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin)).isPresent()); switch (optRange.get()) { case within_the_project: diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedRoleV2TaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedRoleV2TaskAssigneeSelector.java index 3827b1b39..c4f3574a6 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedRoleV2TaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedRoleV2TaskAssigneeSelector.java @@ -43,6 +43,7 @@ import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprove import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecifyValueV2; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getAreaFilterEnable; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCooperateShipType; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getOnlyInProjectEnable; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getSpecialtyFilterEnable; /** @@ -82,6 +83,7 @@ public class BasedRoleV2TaskAssigneeSelector extends AbstractBpmnTaskAssigneeSel .initiatorPersonId(initiator.parsePersonId()) .areaCodes(getAreaFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeAreaCodes())) : Sets.newHashSet()) .specialtyCodes(getSpecialtyFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeSpecialtyCodes())) : Sets.newHashSet()) + .projectIds(getOnlyInProjectEnable(flowElement) ? Sets.newHashSet(orgDTO.getProjectIds()) : Sets.newHashSet()) .querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin)).isPresent()); switch (optRange.get()) { case within_the_project: diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/FirstCopyTemplateFileTaskEvent_105_Listener.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/FirstCopyTemplateFileTaskEvent_105_Listener.java index 29f567740..ee504d38f 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/FirstCopyTemplateFileTaskEvent_105_Listener.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/FirstCopyTemplateFileTaskEvent_105_Listener.java @@ -37,12 +37,17 @@ import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_BIZ_BASED_FILE_TAG_ORDER; import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_BIZ_CUSTOM_DOCS; -import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_BIZ_CUSTOM_DOC_ADD_TYPE; +import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_BIZ_CUSTOM_DOC_ADD_ORDER_TYPE; import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER; /** @@ -118,12 +123,24 @@ public class FirstCopyTemplateFileTaskEvent_105_Listener extends AbstractBpmnEve .fileType(customDoc.getFileType()) .build()); } + List basedFileTagOrder = runtimeService.getVariable(processInstanceId, SIGN_BIZ_BASED_FILE_TAG_ORDER, List.class); + if (Objects.nonNull(basedFileTagOrder)) { + // 基于 fileTag 排序 + Map fileTagOrderMap = IntStream.range(0, basedFileTagOrder.size()) + .boxed() + .collect(Collectors.toMap(basedFileTagOrder::get, i -> i, (a, b) -> a)); - String customAddType = runtimeService.getVariable(processInstanceId, SIGN_BIZ_CUSTOM_DOC_ADD_TYPE, String.class); - if (Objects.equals("last", customAddType)) { - docTemplates.addAll(customDocTemplates); + docTemplates.sort(Comparator.comparing(d -> fileTagOrderMap.getOrDefault(d.getFileTag(), Integer.MAX_VALUE))); + docTemplates = docTemplates.stream().sorted(Comparator.comparingInt(d -> fileTagOrderMap.getOrDefault(d.getFileTag(), Integer.MAX_VALUE))) + .collect(Collectors.toList()); } else { - docTemplates.addAll(0, customDocTemplates); + // 基于前插还是后插排序 + String customAddType = runtimeService.getVariable(processInstanceId, SIGN_BIZ_CUSTOM_DOC_ADD_ORDER_TYPE, String.class); + if (Objects.equals("last", customAddType)) { + docTemplates.addAll(customDocTemplates); + } else { + docTemplates.addAll(0, customDocTemplates); + } } processSign.setDocTemplate(docTemplates); diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java index 6cf182166..6f66a0110 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java @@ -21,6 +21,7 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCre import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO; +import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceVariablesUpdateDTO; import cn.axzo.workflow.common.model.request.bpmn.process.HistoricProcessInstanceSearchDTO; import cn.axzo.workflow.common.model.request.bpmn.process.SuperBpmnProcessInstanceCancelDTO; import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO; @@ -28,6 +29,7 @@ import cn.axzo.workflow.common.model.request.bpmn.process.doc.ChangeApproverRead import cn.axzo.workflow.common.model.request.bpmn.process.doc.ProcessDocQueryDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; +import cn.axzo.workflow.common.model.request.form.ConditionPermissionMetaInfo; import cn.axzo.workflow.common.model.request.form.instance.FormVariablesUpdateDTO; import cn.axzo.workflow.common.model.response.BpmPageResult; import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO; @@ -384,6 +386,15 @@ public class BpmnProcessInstanceController extends BasicPopulateAvatarController return success(processInstance.getProcessVariables()); } + @Override + @Operation(summary = "更新流程实例中的业务自定义变量集合") + @PostMapping("/biz/custom/variables/update") + public CommonResponse updateProcessBizCustomVariables(@Validated @RequestBody BpmnProcessInstanceVariablesUpdateDTO dto) { + log.info("更新流程实例中的业务自定义变量集合 updateProcessBizCustomVariables===>>>参数:{}", JSONUtil.toJsonStr(dto)); + bpmnProcessInstanceService.overrideProcessVariables(dto); + return success(true); + } + /** * 枢智业务(审批台账专用) * @@ -602,4 +613,17 @@ public class BpmnProcessInstanceController extends BasicPopulateAvatarController return logVO; }).collect(Collectors.toList())); } + + /** + * 获取流程实例的条件字段信息 + * + * @param processInstanceId + * @return + */ + @Operation(summary = "获取流程实例的条件字段信息, 仅用于同意抽屉展示") + @GetMapping("/conditions") + @Override + public CommonResponse> getConditions(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId) { + return success(bpmnProcessInstanceService.getConditions(processInstanceId)); + } } diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/manage/PrintAdminController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/manage/PrintAdminController.java index 0dd28f209..8b14a5521 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/manage/PrintAdminController.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/manage/PrintAdminController.java @@ -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; @@ -87,7 +101,10 @@ import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCE import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ACTIVITY_NAME; import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ACTIVITY_NAME_DESC; import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ACTIVITY_NODE_TYPE; +import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ACTIVITY_OPERATION_TIME; +import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ACTIVITY_OPERATION_TIME_DESC; import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ACTIVITY_RESULT; +import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ACTIVITY_RESULT_DESC; import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ADVICE; import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ADVICE_DESC; import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_APPROVER_NAME; @@ -101,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; /** @@ -138,6 +158,10 @@ public class PrintAdminController implements PrintAdminApi { private CategoryGroupService categoryGroupService; @Resource private BpmnProcessModelService bpmnProcessModelService; + @Resource + private ExtAxProcessLogService processLogService; + @Resource + private TaskService taskService; /** * 查询指定流程实例是否能使用打印 @@ -322,8 +346,13 @@ public class PrintAdminController implements PrintAdminApi { .setCode(activity.getId()) .setFieldCategoryType(signature) .setFieldFormType("signature") - .setAttributes(Lists.newArrayList(new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_SIGNATURE).setName(PRINT_VAR_PROCESS_LOG_SIGNATURE_DESC).setFieldFormType(FORM_FIELD_TYPE_INPUT), - new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_ADVICE).setName(PRINT_VAR_PROCESS_LOG_ADVICE_DESC).setFieldFormType(FORM_FIELD_TYPE_INPUT)))) + .setAttributes(Lists.newArrayList( + new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_APPROVER_NAME).setName(PRINT_VAR_PROCESS_LOG_APPROVER_NAME_DESC).setFieldFormType(FORM_FIELD_TYPE_INPUT), + new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_ACTIVITY_RESULT).setName(PRINT_VAR_PROCESS_LOG_ACTIVITY_RESULT_DESC).setFieldFormType(FORM_FIELD_TYPE_INPUT), + new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_ADVICE).setName(PRINT_VAR_PROCESS_LOG_ADVICE_DESC).setFieldFormType(FORM_FIELD_TYPE_INPUT), + new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_SIGNATURE).setName(PRINT_VAR_PROCESS_LOG_SIGNATURE_DESC).setFieldFormType(FORM_FIELD_TYPE_INPUT), + new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_ACTIVITY_OPERATION_TIME).setName(PRINT_VAR_PROCESS_LOG_ACTIVITY_OPERATION_TIME_DESC).setFieldFormType(FORM_FIELD_TYPE_INPUT) + ))) .collect(Collectors.toList()) ); @@ -448,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 getPrintDataForProcessLog(@Validated @RequestBody Print4ProcessLogDTO dto) { + CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor(); + Map 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 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 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 logItems = new ArrayList<>(); + Map> 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); + } + } diff --git a/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java b/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java index 883e85801..5bba3119e 100644 --- a/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java +++ b/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java @@ -3,6 +3,7 @@ package cn.axzo.workflow.starter.api; import cn.axzo.workflow.common.annotation.InvokeMode; import cn.axzo.workflow.common.model.dto.SignFileDTO; import cn.axzo.workflow.common.model.dto.SimpleDocDTO; +import cn.axzo.workflow.common.model.dto.print.PrintFieldDTO; import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutCallbackDTO; import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO; import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigUpsertDTO; @@ -15,6 +16,7 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceChe import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO; +import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceVariablesUpdateDTO; import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO; import cn.axzo.workflow.common.model.request.bpmn.process.doc.ChangeApproverReadStatusDTO; import cn.axzo.workflow.common.model.request.bpmn.process.doc.ProcessDocQueryDTO; @@ -36,6 +38,8 @@ import cn.axzo.workflow.common.model.request.feature.DingTalkStarterAlterDTO; import cn.axzo.workflow.common.model.request.form.definition.StartFormSearchDTO; import cn.axzo.workflow.common.model.request.form.instance.FormDetailDTO; import cn.axzo.workflow.common.model.request.form.instance.FormVariablesUpdateDTO; +import cn.axzo.workflow.common.model.request.form.instance.FromDataSearchDTO; +import cn.axzo.workflow.common.model.request.form.model.WpsFileConfigVariableDTO; import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO; import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO; import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO; @@ -43,6 +47,7 @@ import cn.axzo.workflow.common.model.response.bpmn.process.NodesByModelVO; import cn.axzo.workflow.common.model.response.bpmn.process.doc.DocPendingVO; import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskButtonVo; import cn.axzo.workflow.common.model.response.form.definition.FormDefinitionVO; +import cn.axzo.workflow.common.model.response.form.instance.FormDataVO; import cn.axzo.workflow.common.model.response.form.instance.FormInstanceVO; import cn.axzo.workflow.common.util.ThreadUtil; import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration; @@ -152,6 +157,7 @@ public interface WorkflowCoreService { /** * 获取指定审批业务的流程表单设置, + * * @param dto * @return */ @@ -172,6 +178,26 @@ public interface WorkflowCoreService { @InvokeMode(SYNC) FormInstanceVO getFormInstance(@Validated @RequestBody FormDetailDTO dto); + /** + * 获取指定表单审批的实例数据 + * + * @param dto + * @return + */ + @PostMapping("/api/form/admin/instance/form/data") + @InvokeMode(SYNC) + List getFormData(@Validated @RequestBody FromDataSearchDTO dto); + + /** + * 获取 WPS 文档中所有可配置的流程相关变量 + * + * @param dto + * @return + */ + @PostMapping("/api/form/admin/wps/file/config/variables") + @InvokeMode(SYNC) + List getWpsFileConfigVariables(@Validated @RequestBody WpsFileConfigVariableDTO dto); + /** * 创建流程前的节点列表 * 用于发起人自选 @@ -283,6 +309,17 @@ public interface WorkflowCoreService { @InvokeMode(SYNC) Map getProcessVariables(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId); + /** + * 更新流程实例中的业务自定义变量集合 + * + * @param dto + * @return + */ + @Operation(summary = "更新流程实例中的业务自定义变量集合") + @PostMapping("/api/process/instance/biz/custom/variables/update") + @InvokeMode(SYNC) + Boolean updateProcessBizCustomVariables(@Validated @RequestBody BpmnProcessInstanceVariablesUpdateDTO dto); + /** * 校验指定流程实例下,是否存在指定的审批人正处理待审批 * diff --git a/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowManageService.java b/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowManageService.java index 8a7f95145..fc13dd518 100644 --- a/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowManageService.java +++ b/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowManageService.java @@ -120,7 +120,7 @@ public interface WorkflowManageService { @GetMapping("/api/print/admin/field/variables") @Manageable @InvokeMode(SYNC) - Map getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId); + Map getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId, @RequestParam(required = false, defaultValue = "true") Boolean throwException); /** * 查询管理员