diff --git a/sql/dm/iwork_workflow_log.sql b/sql/dm/iwork_workflow_log.sql new file mode 100644 index 00000000..6af5cd50 --- /dev/null +++ b/sql/dm/iwork_workflow_log.sql @@ -0,0 +1,38 @@ +-- iWork 流程创建日志表(达梦数据库) +CREATE TABLE system_iwork_workflow_log ( + id BIGINT NOT NULL, + request_id VARCHAR(64) NOT NULL, + workflow_id BIGINT, + business_code VARCHAR(128), + biz_callback_key VARCHAR(255), + raw_request VARCHAR(2000), + status VARCHAR(32), + creator VARCHAR(64) DEFAULT '', + create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updater VARCHAR(64) DEFAULT '', + update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted SMALLINT NOT NULL DEFAULT 0, + tenant_id BIGINT NOT NULL DEFAULT 0, + PRIMARY KEY (id) +); + +-- 添加注释 +COMMENT ON TABLE system_iwork_workflow_log IS 'iWork 流程创建日志'; +COMMENT ON COLUMN system_iwork_workflow_log.id IS '主键'; +COMMENT ON COLUMN system_iwork_workflow_log.request_id IS 'iWork 返回的请求编号'; +COMMENT ON COLUMN system_iwork_workflow_log.workflow_id IS '流程模板 ID'; +COMMENT ON COLUMN system_iwork_workflow_log.business_code IS '业务编码'; +COMMENT ON COLUMN system_iwork_workflow_log.biz_callback_key IS '业务回调标识'; +COMMENT ON COLUMN system_iwork_workflow_log.raw_request IS '创建请求原始参数'; +COMMENT ON COLUMN system_iwork_workflow_log.status IS '流程状态'; +COMMENT ON COLUMN system_iwork_workflow_log.creator IS '创建者'; +COMMENT ON COLUMN system_iwork_workflow_log.create_time IS '创建时间'; +COMMENT ON COLUMN system_iwork_workflow_log.updater IS '更新者'; +COMMENT ON COLUMN system_iwork_workflow_log.update_time IS '更新时间'; +COMMENT ON COLUMN system_iwork_workflow_log.deleted IS '是否删除'; +COMMENT ON COLUMN system_iwork_workflow_log.tenant_id IS '租户编号'; + +-- 创建唯一索引 +CREATE UNIQUE INDEX uk_request_id ON system_iwork_workflow_log(request_id); + + diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/mq/iwork/IWorkBizCallbackMessage.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/mq/iwork/IWorkBizCallbackMessage.java index 4eb80a2b..68387e01 100644 --- a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/mq/iwork/IWorkBizCallbackMessage.java +++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/mq/iwork/IWorkBizCallbackMessage.java @@ -1,10 +1,14 @@ package com.zt.plat.module.system.mq.iwork; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Data @Builder +@NoArgsConstructor +@AllArgsConstructor public class IWorkBizCallbackMessage { /** 统一回调主题 */ diff --git a/zt-module-system/zt-module-system-server-app/src/main/resources/application.yaml b/zt-module-system/zt-module-system-server-app/src/main/resources/application.yaml index 1b3abadf..9950d584 100644 --- a/zt-module-system/zt-module-system-server-app/src/main/resources/application.yaml +++ b/zt-module-system/zt-module-system-server-app/src/main/resources/application.yaml @@ -229,6 +229,7 @@ zt: - system_seq_dtl - system_seq_rcd - system_sync_log + - system_iwork_seal_log ignore-caches: - user_role_ids - permission_menu_ids diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java index e5262fa2..4918aa6d 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java @@ -77,10 +77,16 @@ public class IWorkIntegrationController { return success(integrationService.createWorkflow(reqVO)); } + @PostMapping("/workflow/create-generic") + @Operation(summary = "通用流程创建:支持透传任意业务参数和调用不同的 workflowId") + public CommonResult createGenericWorkflow(@Valid @RequestBody IWorkGenericWorkflowCreateReqVO reqVO) { + return success(integrationService.createGenericWorkflow(reqVO)); + } + @PermitAll @TenantIgnore @PostMapping("/callback/file") - @Operation(summary = "iWork 文件回调:根据文件 URL 保存为附件并创建业务附件关联") + @Operation(summary = "iWork 文件回调:根据文件 URL 保存为附件并创建业务附件关联,记录日志并发送 MQ 通知业务系统") public CommonResult callbackFile(@Valid @RequestBody IWorkFileCallbackReqVO reqVO) { return success(integrationService.handleFileCallback(reqVO)); } diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkGenericWorkflowCreateReqVO.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkGenericWorkflowCreateReqVO.java new file mode 100644 index 00000000..6ba8810d --- /dev/null +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkGenericWorkflowCreateReqVO.java @@ -0,0 +1,34 @@ + package com.zt.plat.module.system.controller.admin.integration.iwork.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Map; + +/** + * 通用 iWork 流程创建请求 VO + *

+ * 支持透传任意业务参数,直接将整个 payload 转发给 iWork + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Schema(description = "通用 iWork 流程创建请求") +public class IWorkGenericWorkflowCreateReqVO extends IWorkBaseReqVO { + + @Schema(description = "流程模板 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "54") + @NotNull(message = "流程模板 ID 不能为空") + private Long workflowId; + + @Schema(description = "透传给 iWork 的业务参数,直接作为请求体发送", requiredMode = Schema.RequiredMode.REQUIRED, + example = "{\"requestName\":\"用印-DJ-2025-0001\",\"mainData\":[{\"fieldName\":\"jbr\",\"fieldValue\":\"1001\"}]}") + @NotNull(message = "业务参数不能为空") + private Map payload; + + @Schema(description = "业务编码,用于回调时关联业务数据", example = "DJ-2025-0001") + private String ywxtdjbh; + + @Schema(description = "业务回调标识,用于 MQ 消息路由到对应业务消费者", example = "seal-callback") + private String bizCallbackKey; +} diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/dataobject/iwork/IWorkWorkflowLogDO.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/dataobject/iwork/IWorkWorkflowLogDO.java new file mode 100644 index 00000000..516d2bfa --- /dev/null +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/dataobject/iwork/IWorkWorkflowLogDO.java @@ -0,0 +1,55 @@ +package com.zt.plat.module.system.dal.dataobject.iwork; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.zt.plat.framework.mybatis.core.dataobject.BaseDO; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +/** + * iWork 流程创建日志。 + * 用于记录流程创建时的关键信息,供回调时查询使用。 + */ +@TableName("system_iwork_workflow_log") +@KeySequence("system_iwork_workflow_log_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class IWorkWorkflowLogDO extends BaseDO { + + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * iWork 返回的请求编号,唯一业务标识。 + */ + private String requestId; + + /** + * 流程模板 ID。 + */ + private Long workflowId; + + /** + * 业务编码(用于关联业务数据)。 + */ + private String businessCode; + + /** + * 业务回调标识(用于 MQ 消息路由)。 + */ + private String bizCallbackKey; + + /** + * 创建请求的原始参数(JSON 格式,截断存储)。 + */ + private String rawRequest; + + /** + * 流程状态:CREATED-已创建, CALLBACK_RECEIVED-已收到回调, COMPLETED-已完成 + */ + private String status; +} diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/iwork/IWorkWorkflowLogMapper.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/iwork/IWorkWorkflowLogMapper.java new file mode 100644 index 00000000..c8158377 --- /dev/null +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/iwork/IWorkWorkflowLogMapper.java @@ -0,0 +1,13 @@ +package com.zt.plat.module.system.dal.mysql.iwork; + +import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX; +import com.zt.plat.module.system.dal.dataobject.iwork.IWorkWorkflowLogDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface IWorkWorkflowLogMapper extends BaseMapperX { + + default IWorkWorkflowLogDO selectByRequestId(String requestId) { + return selectOne(IWorkWorkflowLogDO::getRequestId, requestId); + } +} diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/mq/iwork/IWorkBizCallbackTestConsumer.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/mq/iwork/IWorkBizCallbackTestConsumer.java new file mode 100644 index 00000000..2ab70f0b --- /dev/null +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/mq/iwork/IWorkBizCallbackTestConsumer.java @@ -0,0 +1,67 @@ +package com.zt.plat.module.system.mq.iwork; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.apache.rocketmq.spring.core.RocketMQTemplate; +import org.springframework.stereotype.Component; + +/** + * iWork 业务回调消息测试消费者 + *

+ * 用于测试 IWorkBizCallbackMessage 消息的消费, + * 消费成功后会发送 IWorkBizCallbackResultMessage 通知 system 模块。 + *

+ * 注意:这是一个测试消费者,生产环境应由具体业务模块实现自己的消费者。 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@RocketMQMessageListener( + topic = IWorkBizCallbackMessage.TOPIC, + consumerGroup = IWorkBizCallbackMessage.TOPIC + "_ceshi_bz_01", + selectorExpression = "ceshi_bz_01" // 只订阅 tag=ceshi_bz_01 的消息 +) +public class IWorkBizCallbackTestConsumer implements RocketMQListener { + + private final RocketMQTemplate rocketMQTemplate; + + @Override + public void onMessage(IWorkBizCallbackMessage message) { + log.info("[IWorkBizCallbackTestConsumer] 收到回调消息: requestId={}, bizCallbackKey={}, attempt={}/{}", + message.getRequestId(), + message.getBizCallbackKey(), + message.getAttempt(), + message.getMaxAttempts()); + log.info("[IWorkBizCallbackTestConsumer] payload={}", message.getPayload()); + + // 模拟业务处理 + boolean success = processCallback(message); + + // 发送处理结果给 system 模块 + IWorkBizCallbackResultMessage result = IWorkBizCallbackResultMessage.builder() + .requestId(message.getRequestId()) + .bizCallbackKey(message.getBizCallbackKey()) + .payload(message.getPayload()) + .attempt(message.getAttempt()) + .maxAttempts(message.getMaxAttempts()) + .success(success) + .errorMessage(success ? null : "测试模拟失败") + .build(); + + log.info("[IWorkBizCallbackTestConsumer] 准备发送结果到 topic={}", IWorkBizCallbackResultMessage.TOPIC); + rocketMQTemplate.syncSend(IWorkBizCallbackResultMessage.TOPIC+":123", result); + log.info("[IWorkBizCallbackTestConsumer] 已发送处理结果: success={}, requestId={}", success, message.getRequestId()); + } + + /** + * 模拟业务处理逻辑 + */ + private boolean processCallback(IWorkBizCallbackMessage message) { + // 随机返回成功或失败,用于测试重试逻辑 + boolean success = Math.random() > 0.5; + log.info("[IWorkBizCallbackTestConsumer] 模拟处理结果: {}", success ? "成功" : "失败"); + return success; + } +} diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationService.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationService.java index 5988e851..6fbcee9c 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationService.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationService.java @@ -5,6 +5,7 @@ import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkAuth import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkAuthTokenReqVO; import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkAuthTokenRespVO; import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkFileCallbackReqVO; +import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkGenericWorkflowCreateReqVO; import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkOperationRespVO; import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkOaCheckTokenReqVO; import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkOaRawResponse; @@ -39,6 +40,11 @@ public interface IWorkIntegrationService { */ IWorkOperationRespVO createWorkflow(IWorkWorkflowCreateReqVO reqVO); + /** + * 通用流程创建:支持透传任意业务参数和调用不同的 workflowId + */ + IWorkOperationRespVO createGenericWorkflow(IWorkGenericWorkflowCreateReqVO reqVO); + /** * 在 iWork 中对已有流程执行作废或干预。 */ diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkWorkflowLogService.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkWorkflowLogService.java new file mode 100644 index 00000000..fd577337 --- /dev/null +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkWorkflowLogService.java @@ -0,0 +1,24 @@ +package com.zt.plat.module.system.service.integration.iwork; + +import com.zt.plat.module.system.dal.dataobject.iwork.IWorkWorkflowLogDO; + +/** + * iWork 流程创建日志 Service + */ +public interface IWorkWorkflowLogService { + + /** + * 保存流程创建日志 + */ + void saveWorkflowLog(IWorkWorkflowLogDO logDO); + + /** + * 根据 requestId 查询流程创建日志 + */ + IWorkWorkflowLogDO getByRequestId(String requestId); + + /** + * 更新流程状态 + */ + void updateStatus(String requestId, String status); +} diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImpl.java index d06b0adf..fcf0bd56 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImpl.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImpl.java @@ -18,7 +18,12 @@ import com.zt.plat.module.infra.api.file.dto.FileCreateReqDTO; import com.zt.plat.module.infra.api.file.dto.FileRespDTO; import com.zt.plat.module.system.controller.admin.integration.iwork.vo.*; import com.zt.plat.module.system.framework.integration.iwork.config.IWorkProperties; +import com.zt.plat.module.system.mq.iwork.IWorkBizCallbackMessage; +import com.zt.plat.module.system.mq.iwork.IWorkBizCallbackProducer; +import com.zt.plat.module.system.service.integration.iwork.IWorkCallbackLogService; import com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationService; +import com.zt.plat.module.system.service.integration.iwork.IWorkWorkflowLogService; +import com.zt.plat.module.system.dal.dataobject.iwork.IWorkWorkflowLogDO; import com.zt.plat.framework.tenant.core.util.TenantUtils; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -60,6 +65,9 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { private final FileApi fileApi; private final BusinessFileApi businessFileApi; + private final IWorkCallbackLogService callbackLogService; + private final IWorkWorkflowLogService workflowLogService; + private final IWorkBizCallbackProducer bizCallbackProducer; private final Cache registrationCache = Caffeine.newBuilder() .maximumSize(32) @@ -141,7 +149,45 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { Map payload = buildCreatePayload(reqVO); String createWorkflowPath = requireConfiguredPath(properties.getPaths().getCreateWorkflow(), "iwork.paths.create-workflow"); String responseBody = executeFormRequest(createWorkflowPath, null, appId, session, payload); - return buildOperationResponse(responseBody); + IWorkOperationRespVO respVO = buildOperationResponse(responseBody); + + // 创建成功后记录日志 + if (respVO.isSuccess() && respVO.getPayload() != null + && respVO.getPayload().getData() != null + && respVO.getPayload().getData().getRequestId() != null) { + saveWorkflowLog(respVO, reqVO); + } + + return respVO; + } + + @Override + public IWorkOperationRespVO createGenericWorkflow(IWorkGenericWorkflowCreateReqVO reqVO) { + assertConfigured(); + String appId = resolveAppId(); + ClientKeyPair clientKeyPair = resolveClientKeyPair(appId, Boolean.TRUE.equals(reqVO.getForceRefreshToken())); + String operatorUserId = resolveOperatorUserId(reqVO.getOperatorUserId()); + IWorkSession session = createSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken())); + + // 构建透传参数,将 workflowId 加入 payload + Map payload = new LinkedHashMap<>(); + payload.put("workflowId", reqVO.getWorkflowId()); + if (reqVO.getPayload() != null) { + payload.putAll(reqVO.getPayload()); + } + + String createWorkflowPath = requireConfiguredPath(properties.getPaths().getCreateWorkflow(), "iwork.paths.create-workflow"); + String responseBody = executeFormRequest(createWorkflowPath, null, appId, session, payload); + IWorkOperationRespVO respVO = buildOperationResponse(responseBody); + + // 创建成功后记录日志,保存 requestId、businessCode、bizCallbackKey + if (respVO.isSuccess() && respVO.getPayload() != null + && respVO.getPayload().getData() != null + && respVO.getPayload().getData().getRequestId() != null) { + saveWorkflowCreateLog(respVO, reqVO); + } + + return respVO; } @Override @@ -175,6 +221,14 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { throw new ServiceException(IWORK_CONFIGURATION_INVALID.getCode(), "业务编码不能为空"); } + // 1. 通过 requestId 查询流程创建日志,获取 bizCallbackKey(iWork 回调不会回传此字段) + String bizCallbackKey = null; + IWorkWorkflowLogDO workflowLog = workflowLogService.getByRequestId(reqVO.getRequestId()); + if (workflowLog != null && StringUtils.hasText(workflowLog.getBizCallbackKey())) { + bizCallbackKey = workflowLog.getBizCallbackKey(); + } + + // 2. 保存文件附件 BusinessFileRespDTO referenceBusinessFile = loadBusinessFileByBusinessCode(businessCode); Long tenantId = referenceBusinessFile.getTenantId(); if (tenantId == null) { @@ -183,7 +237,113 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { AtomicReference attachmentIdRef = new AtomicReference<>(); TenantUtils.execute(tenantId, () -> attachmentIdRef.set(saveCallbackAttachment(fileUrl, reqVO.getFileName(), referenceBusinessFile))); - return attachmentIdRef.get(); + Long attachmentId = attachmentIdRef.get(); + + // 3. 更新回调日志 + int maxRetry = properties.getCallback().getRetry().getMaxAttempts(); + String rawBody = buildCallbackRawBody(reqVO); + IWorkWorkflowCallbackReqVO logReqVO = buildCallbackLogReqVO(reqVO); + if (StringUtils.hasText(bizCallbackKey)) { + logReqVO.setBizCallbackKey(bizCallbackKey); + } + callbackLogService.upsertOnCallback(logReqVO, maxRetry, rawBody); + + // 4. 更新流程创建日志状态 + if (workflowLog != null) { + String status = StringUtils.hasText(reqVO.getStatus()) ? reqVO.getStatus() : "CALLBACK_RECEIVED"; + workflowLogService.updateStatus(reqVO.getRequestId(), status); + log.info("[handleFileCallback] 已更新流程状态: requestId={}, status={}", reqVO.getRequestId(), status); + } + + // 5. 发送 MQ 通知业务系统(仅当 bizCallbackKey 存在时发送) + if (StringUtils.hasText(bizCallbackKey)) { + IWorkBizCallbackMessage message = IWorkBizCallbackMessage.builder() + .requestId(reqVO.getRequestId()) + .bizCallbackKey(bizCallbackKey) + .payload(reqVO) + .attempt(0) + .maxAttempts(maxRetry) + .build(); + bizCallbackProducer.send(message); + log.info("[handleFileCallback] 已发送 MQ 通知,requestId={}, bizCallbackKey={}", + reqVO.getRequestId(), bizCallbackKey); + } else { + log.warn("[handleFileCallback] 未找到 bizCallbackKey,跳过 MQ 通知,requestId={}", + reqVO.getRequestId()); + } + + return attachmentId; + } + + private IWorkWorkflowCallbackReqVO buildCallbackLogReqVO(IWorkFileCallbackReqVO reqVO) { + IWorkWorkflowCallbackReqVO logReqVO = new IWorkWorkflowCallbackReqVO(); + logReqVO.setRequestId(reqVO.getRequestId()); + logReqVO.setBusinessCode(reqVO.getBusinessCode()); + logReqVO.setBizCallbackKey(reqVO.getBizCallbackKey()); + logReqVO.setStatus(reqVO.getStatus()); + logReqVO.setRawBody(reqVO.getRawBody()); + return logReqVO; + } + + private String buildCallbackRawBody(IWorkFileCallbackReqVO reqVO) { + if (StringUtils.hasText(reqVO.getRawBody())) { + return reqVO.getRawBody(); + } + try { + return objectMapper.writeValueAsString(reqVO); + } catch (JsonProcessingException e) { + log.warn("[buildCallbackRawBody] 序列化回调请求失败", e); + return null; + } + } + + private void saveWorkflowCreateLog(IWorkOperationRespVO respVO, IWorkGenericWorkflowCreateReqVO reqVO) { + try { + String requestId = String.valueOf(respVO.getPayload().getData().getRequestId()); + String rawRequest = objectMapper.writeValueAsString(reqVO); + + IWorkWorkflowLogDO logDO = new IWorkWorkflowLogDO(); + logDO.setRequestId(requestId); + logDO.setWorkflowId(reqVO.getWorkflowId()); + logDO.setBusinessCode(reqVO.getYwxtdjbh()); + logDO.setBizCallbackKey(reqVO.getBizCallbackKey()); + logDO.setRawRequest(truncateRawRequest(rawRequest)); + logDO.setStatus("CREATED"); + + workflowLogService.saveWorkflowLog(logDO); + log.info("[createGenericWorkflow] 已记录流程创建日志,requestId={}, businessCode={}, bizCallbackKey={}", + requestId, reqVO.getYwxtdjbh(), reqVO.getBizCallbackKey()); + } catch (Exception e) { + log.warn("[createGenericWorkflow] 记录流程创建日志失败", e); + } + } + + private void saveWorkflowLog(IWorkOperationRespVO respVO, IWorkWorkflowCreateReqVO reqVO) { + try { + String requestId = String.valueOf(respVO.getPayload().getData().getRequestId()); + String rawRequest = objectMapper.writeValueAsString(reqVO); + + IWorkWorkflowLogDO logDO = new IWorkWorkflowLogDO(); + logDO.setRequestId(requestId); + logDO.setWorkflowId(Long.parseLong(properties.getWorkflow().getSealWorkflowId())); + logDO.setBusinessCode(reqVO.getYwxtdjbh()); + logDO.setBizCallbackKey(reqVO.getBizCallbackKey()); + logDO.setRawRequest(truncateRawRequest(rawRequest)); + logDO.setStatus("CREATED"); + + workflowLogService.saveWorkflowLog(logDO); + log.info("[createWorkflow] 已记录流程创建日志,requestId={}, workflowId={}, businessCode={}, bizCallbackKey={}", + requestId, properties.getWorkflow().getSealWorkflowId(), reqVO.getYwxtdjbh(), reqVO.getBizCallbackKey()); + } catch (Exception e) { + log.warn("[createWorkflow] 记录流程创建日志失败", e); + } + } + + private String truncateRawRequest(String raw) { + if (!StringUtils.hasText(raw)) { + return raw; + } + return raw.length() > 2000 ? raw.substring(0, 2000) : raw; } @Override @@ -760,7 +920,7 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { return value.booleanValue(); } String text = value.asText(); - return Objects.equals("0", text) || Objects.equals("1", text) || Objects.equals("success", text); + return Objects.equals("0", text) || Objects.equals("1", text) || Objects.equals("success", text) || Objects.equals("SUCCESS", text); } private String resolveMessage(JsonNode node) { diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkWorkflowLogServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkWorkflowLogServiceImpl.java new file mode 100644 index 00000000..6f3bd117 --- /dev/null +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkWorkflowLogServiceImpl.java @@ -0,0 +1,35 @@ +package com.zt.plat.module.system.service.integration.iwork.impl; + +import com.zt.plat.module.system.dal.dataobject.iwork.IWorkWorkflowLogDO; +import com.zt.plat.module.system.dal.mysql.iwork.IWorkWorkflowLogMapper; +import com.zt.plat.module.system.service.integration.iwork.IWorkWorkflowLogService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class IWorkWorkflowLogServiceImpl implements IWorkWorkflowLogService { + + private final IWorkWorkflowLogMapper workflowLogMapper; + + @Override + public void saveWorkflowLog(IWorkWorkflowLogDO logDO) { + workflowLogMapper.insert(logDO); + } + + @Override + public IWorkWorkflowLogDO getByRequestId(String requestId) { + return workflowLogMapper.selectByRequestId(requestId); + } + + @Override + public void updateStatus(String requestId, String status) { + IWorkWorkflowLogDO existing = workflowLogMapper.selectByRequestId(requestId); + if (existing != null) { + IWorkWorkflowLogDO update = new IWorkWorkflowLogDO(); + update.setId(existing.getId()); + update.setStatus(status); + workflowLogMapper.updateById(update); + } + } +} diff --git a/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/controller/admin/contract/DemoContractController.java b/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/controller/admin/contract/DemoContractController.java index 9044aa69..c98ea6db 100644 --- a/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/controller/admin/contract/DemoContractController.java +++ b/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/controller/admin/contract/DemoContractController.java @@ -15,6 +15,7 @@ import com.zt.plat.module.bpm.api.task.BpmProcessInstanceApi; import com.zt.plat.module.bpm.api.task.BpmTaskApi; import com.zt.plat.module.infra.api.businessfile.BusinessFileApi; import com.zt.plat.module.infra.api.file.FileApi; +import com.zt.plat.module.infra.api.file.dto.FileRespDTO; import com.zt.plat.module.system.api.dept.DeptApi; import com.zt.plat.module.system.api.iwork.dto.IWorkOperationRespDTO; import com.zt.plat.module.system.api.permission.PermissionApi; @@ -128,7 +129,12 @@ public class DemoContractController extends AbstractFileUploadController impleme @Parameter(name = "id", description = "编号", required = true, example = "1024") public CommonResult getDemoContract(@RequestParam("id") Long id) { DemoContractDO demoContract = demoContractService.getDemoContract(id); - return success(BeanUtils.toBean(demoContract, DemoContractRespVO.class)); + DemoContractRespVO respVO = BeanUtils.toBean(demoContract, DemoContractRespVO.class); + // 查询业务附件 + if (respVO != null && respVO.getId() != null) { + respVO.setFiles(demoContractService.getContractFiles(respVO.getId())); + } + return success(respVO); } @GetMapping("/page") diff --git a/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/controller/admin/contract/vo/DemoContractRespVO.java b/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/controller/admin/contract/vo/DemoContractRespVO.java index be09739a..200170e2 100644 --- a/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/controller/admin/contract/vo/DemoContractRespVO.java +++ b/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/controller/admin/contract/vo/DemoContractRespVO.java @@ -1,5 +1,6 @@ package com.zt.plat.module.template.controller.admin.contract.vo; +import com.zt.plat.module.infra.api.businessfile.dto.BusinessFileWithUrlRespDTO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; @@ -77,4 +78,7 @@ public class DemoContractRespVO { @ExcelProperty("岗位ID") private Long postId; + @Schema(description = "附件列表") + private List files; + } \ No newline at end of file diff --git a/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/service/contract/DemoContractService.java b/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/service/contract/DemoContractService.java index 306350c4..cb34c4c3 100644 --- a/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/service/contract/DemoContractService.java +++ b/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/service/contract/DemoContractService.java @@ -6,6 +6,7 @@ import com.zt.plat.module.template.controller.admin.contract.vo.*; import com.zt.plat.module.template.dal.dataobject.contract.DemoContractDO; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.pojo.PageParam; +import com.zt.plat.module.infra.api.businessfile.dto.BusinessFileWithUrlRespDTO; /** * 合同 Service 接口 @@ -59,4 +60,12 @@ public interface DemoContractService { */ PageResult getDemoContractPage(DemoContractPageReqVO pageReqVO); + /** + * 获取合同附件列表 + * + * @param contractId 合同ID + * @return 附件列表 + */ + List getContractFiles(Long contractId); + } \ No newline at end of file diff --git a/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/service/contract/DemoContractServiceImpl.java b/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/service/contract/DemoContractServiceImpl.java index 84ca3efa..b13bd744 100644 --- a/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/service/contract/DemoContractServiceImpl.java +++ b/zt-module-template/zt-module-template-server/src/main/java/com/zt/plat/module/template/service/contract/DemoContractServiceImpl.java @@ -4,6 +4,9 @@ import cn.hutool.core.collection.CollUtil; import com.zt.plat.framework.common.pojo.CommonResult; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.module.infra.api.businessfile.BusinessFileApi; +import com.zt.plat.module.infra.api.businessfile.dto.BusinessFilePageReqDTO; +import com.zt.plat.module.infra.api.businessfile.dto.BusinessFileWithUrlRespDTO; import com.zt.plat.module.system.api.sequence.SequenceApi; import com.zt.plat.module.template.controller.admin.contract.vo.DemoContractPageReqVO; import com.zt.plat.module.template.controller.admin.contract.vo.DemoContractRespVO; @@ -34,6 +37,9 @@ public class DemoContractServiceImpl implements DemoContractService { @Resource private SequenceApi sequenceApi; + @Resource + private BusinessFileApi businessFileApi; + @Override public DemoContractRespVO createDemoContract(DemoContractSaveReqVO createReqVO) { // 插入 @@ -93,4 +99,20 @@ public class DemoContractServiceImpl implements DemoContractService { return demoContractMapper.selectPage(pageReqVO); } + @Override + public List getContractFiles(Long contractId) { + if (contractId == null) { + return List.of(); + } + BusinessFilePageReqDTO reqDTO = new BusinessFilePageReqDTO(); + reqDTO.setBusinessId(contractId); + reqDTO.setPageNo(1); + reqDTO.setPageSize(100); + CommonResult> result = businessFileApi.getBusinessFilePageWithUrl(reqDTO); + if (result == null || !result.isSuccess() || result.getData() == null) { + return List.of(); + } + return result.getData().getList(); + } + } \ No newline at end of file