diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOperationRespVO.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOperationRespVO.java index d108d3c2..2b01e0a6 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOperationRespVO.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkOperationRespVO.java @@ -14,9 +14,6 @@ public class IWorkOperationRespVO { @Schema(description = "iWork 返回的原始数据") private Map payload; - @Schema(description = "iWork 返回的原始字符串") - private String rawBody; - @Schema(description = "是否判断为成功") private boolean success; diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkUserInfoRespVO.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkUserInfoRespVO.java index 429c2d8d..e3a70559 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkUserInfoRespVO.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkUserInfoRespVO.java @@ -14,9 +14,6 @@ public class IWorkUserInfoRespVO { @Schema(description = "iWork 返回的原始数据") private Map payload; - @Schema(description = "iWork 返回的原始字符串") - private String rawBody; - @Schema(description = "是否判断为成功") private boolean success; diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkWorkflowCreateReqVO.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkWorkflowCreateReqVO.java index 8d804cde..2b7efc6b 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkWorkflowCreateReqVO.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkWorkflowCreateReqVO.java @@ -1,15 +1,9 @@ package com.zt.plat.module.system.controller.admin.integration.iwork.vo; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotEmpty; import lombok.Data; import lombok.EqualsAndHashCode; -import java.util.List; -import java.util.Map; - /** * 发起 iWork 流程的请求体。 */ @@ -17,25 +11,36 @@ import java.util.Map; @EqualsAndHashCode(callSuper = true) public class IWorkWorkflowCreateReqVO extends IWorkBaseReqVO { - @Schema(description = "流程标题", example = "测试流程") - @NotBlank(message = "流程标题不能为空") - private String requestName; + @Schema(description = "用印申请人(iWork 人员 ID)", example = "1001") + private String jbr; - @Schema(description = "流程模板编号,可为空使用默认配置", example = "54") - private Long workflowId; + @Schema(description = "用印部门 ID", example = "2001") + private String yybm; - @Schema(description = "主表字段") - @NotEmpty(message = "主表字段不能为空") - @Valid - private List mainFields; + @Schema(description = "用印单位(分部 ID)", example = "3001") + private String fb; - @Schema(description = "明细表数据") - @Valid - private List detailTables; + @Schema(description = "申请时间,格式 yyyy-MM-dd", example = "2025-01-01") + private String sqsj; - @Schema(description = "额外参数") - private Map otherParams; + @Schema(description = "用印去向") + private String yyqx; - @Schema(description = "额外 Form 数据") - private Map formExtras; + @Schema(description = "用印依据附件 URL") + private String yyfkUrl; + + @Schema(description = "用印事由或内容摘要") + private String yysy; + + @Schema(description = "用印材料附件 URL(必填)") + private String xyywjUrl; + + @Schema(description = "用印事项") + private String yysx; + + @Schema(description = "业务系统单据编号(用于派生流程标题)", example = "DJ-2025-0001") + private String ywxtdjbh; + + @Schema(description = "流程模板编号(必填)", example = "54") + private String workflowId; } diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationErrorCodeConstants.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationErrorCodeConstants.java index a7a1f39d..9faf4e1c 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationErrorCodeConstants.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkIntegrationErrorCodeConstants.java @@ -18,4 +18,5 @@ public interface IWorkIntegrationErrorCodeConstants { ErrorCode IWORK_WORKFLOW_ID_MISSING = new ErrorCode(1_010_200_008, "缺少 iWork 流程模板编号"); ErrorCode IWORK_ORG_IDENTIFIER_MISSING = new ErrorCode(1_010_200_009, "iWork 人力组织接口缺少认证标识"); ErrorCode IWORK_ORG_REMOTE_FAILED = new ErrorCode(1_010_200_010, "iWork 人力组织接口请求失败{}"); + ErrorCode IWORK_SEAL_REQUIRED_FIELD_MISSING = new ErrorCode(1_010_200_011, "缺少用印必填字段:{}"); } 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 82df7f69..dabb6d54 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 @@ -128,7 +128,7 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken())); Map payload = buildCreatePayload(reqVO); - String responseBody = executeJsonRequest(properties.getPaths().getCreateWorkflow(), null, appId, session, payload); + String responseBody = executeFormRequest(properties.getPaths().getCreateWorkflow(), null, appId, session, payload); return buildOperationResponse(responseBody); } @@ -324,6 +324,39 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { return executeRequest(request, IWORK_REMOTE_REQUEST_FAILED); } + private String executeFormRequest(String path, + Map queryParams, + String appId, + IWorkSession session, + Map formFields) { + HttpUrl baseUrl = HttpUrl.parse(resolveUrl(path)); + if (baseUrl == null) { + throw ServiceExceptionUtil.exception(IWORK_REMOTE_REQUEST_FAILED, "非法的 URL"); + } + HttpUrl.Builder urlBuilder = baseUrl.newBuilder(); + if (queryParams != null) { + queryParams.forEach((key, value) -> { + if (value != null) { + urlBuilder.addQueryParameter(key, String.valueOf(value)); + } + }); + } + FormBody.Builder bodyBuilder = new FormBody.Builder(); + if (formFields != null) { + formFields.forEach((key, value) -> { + if (StringUtils.hasText(key) && value != null) { + bodyBuilder.add(key, toFormValue(value)); + } + }); + } + Request request = new Request.Builder() + .url(urlBuilder.build()) + .headers(authHeaders(appId, session).build()) + .post(bodyBuilder.build()) + .build(); + return executeRequest(request, IWORK_REMOTE_REQUEST_FAILED); + } + private Headers.Builder authHeaders(String appId, IWorkSession session) { return new Headers.Builder() .set(properties.getHeaders().getAppId(), appId) @@ -331,6 +364,19 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { .set(properties.getHeaders().getUserId(), session.getEncryptedUserId()); } + private String toFormValue(Object value) { + if (value == null) { + return ""; + } + if (value instanceof CharSequence || value instanceof Number || value instanceof Boolean) { + return String.valueOf(value); + } + if (value.getClass().isArray() || value instanceof Collection || value instanceof Map) { + return toJsonString(value); + } + return value.toString(); + } + private Map buildUserPayload(IWorkUserInfoReqVO reqVO) { Map payload = new HashMap<>(); if (reqVO.getPayload() != null) { @@ -342,27 +388,81 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { private Map buildCreatePayload(IWorkWorkflowCreateReqVO reqVO) { Map payload = new LinkedHashMap<>(); - payload.put("requestName", reqVO.getRequestName()); - payload.put("workflowId", resolveWorkflowId(reqVO.getWorkflowId())); - payload.put("mainData", convertFormFields(reqVO.getMainFields())); - if (reqVO.getDetailTables() != null && !reqVO.getDetailTables().isEmpty()) { - payload.put("detailData", convertDetailTables(reqVO.getDetailTables())); - } - if (reqVO.getOtherParams() != null && !reqVO.getOtherParams().isEmpty()) { - payload.put("otherParams", reqVO.getOtherParams()); - } - appendPayloadExtras(payload, reqVO.getFormExtras()); + SealRequestFields fields = resolveSealFields(reqVO); + payload.put("requestName", buildRequestName(fields.ywxtdjbh())); + payload.put("workflowId", parseWorkflowId(fields.workflowId())); + payload.put("mainData", buildSealMainData(fields)); return payload; } - private long resolveWorkflowId(Long requestWorkflowId) { - if (requestWorkflowId != null) { - return requestWorkflowId; + private String buildRequestName(String billNo) { + return "用印-" + billNo; + } + + private long parseWorkflowId(String workflowId) { + try { + return Long.parseLong(workflowId); + } catch (NumberFormatException ex) { + throw ServiceExceptionUtil.exception(IWORK_SEAL_REQUIRED_FIELD_MISSING, "workflowId"); } - if (properties.getWorkflowId() != null) { - return properties.getWorkflowId(); + } + + private List> buildSealMainData(SealRequestFields fields) { + List> main = new ArrayList<>(); + addField(main, "jbr", fields.jbr()); + addField(main, "yybm", fields.yybm()); + addField(main, "fb", fields.fb()); + addField(main, "sqsj", fields.sqsj()); + addField(main, "yyqx", fields.yyqx()); + addField(main, "yyfk", fields.yyfkUrl()); + addField(main, "yysy", fields.yysy()); + addField(main, "xyywj", fields.xyywjUrl()); + addField(main, "yysx", fields.yysx()); + addField(main, "lclx", SealRequestFields.DEFAULT_FLOW_TYPE); + addField(main, "qsdz", SealRequestFields.DEFAULT_SIGN_ACTION); + addField(main, "ywxtdjbh", fields.ywxtdjbh()); + return main; + } + + private void addField(List> target, String name, String value) { + if (!StringUtils.hasText(value)) { + return; } - throw ServiceExceptionUtil.exception(IWORK_WORKFLOW_ID_MISSING); + Map map = new HashMap<>(2); + map.put("fieldName", name); + map.put("fieldValue", value); + target.add(map); + } + + private SealRequestFields resolveSealFields(IWorkWorkflowCreateReqVO reqVO) { + String jbr = requireSealField(reqVO.getJbr(), "jbr"); + String yybm = requireSealField(reqVO.getYybm(), "yybm"); + String fb = requireSealField(reqVO.getFb(), "fb"); + String sqsj = requireSealField(reqVO.getSqsj(), "sqsj"); + String yyqx = requireSealField(reqVO.getYyqx(), "yyqx"); + String xyywjUrl = requireSealField(reqVO.getXyywjUrl(), "xyywjUrl"); + String yysx = requireSealField(reqVO.getYysx(), "yysx"); + String billNo = requireSealField(reqVO.getYwxtdjbh(), "ywxtdjbh"); + String workflowId = requireSealField(reqVO.getWorkflowId(), "workflowId"); + String yyfkUrl = trimToNull(reqVO.getYyfkUrl()); + String yysy = trimToNull(reqVO.getYysy()); + return new SealRequestFields(jbr, yybm, fb, sqsj, yyqx, yyfkUrl, yysy, xyywjUrl, yysx, billNo, workflowId); + } + + private String requireSealField(String value, String fieldName) { + String trimmed = trimToNull(value); + if (trimmed == null) { + throw ServiceExceptionUtil.exception(IWORK_SEAL_REQUIRED_FIELD_MISSING, fieldName); + } + return trimmed; + } + + private String trimToNull(String value) { + if (!StringUtils.hasText(value)) { + return null; + } + String trimmed = value.trim(); + return trimmed.isEmpty() ? null : trimmed; } private Map buildVoidPayload(IWorkWorkflowVoidReqVO reqVO) { @@ -389,35 +489,8 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { }); } - private List> convertFormFields(List fields) { - return fields.stream().map(field -> { - Map map = new HashMap<>(2); - map.put("fieldName", field.getFieldName()); - map.put("fieldValue", field.getFieldValue()); - return map; - }).toList(); - } - - private List> convertDetailTables(List tables) { - return tables.stream().map(table -> { - Map tableMap = new HashMap<>(2); - tableMap.put("tableDBName", table.getTableDBName()); - List> records = table.getRecords().stream().map(record -> { - Map recordMap = new HashMap<>(2); - if (record.getRecordOrder() != null) { - recordMap.put("recordOrder", record.getRecordOrder()); - } - recordMap.put("workflowRequestTableFields", convertFormFields(record.getFields())); - return recordMap; - }).toList(); - tableMap.put("workflowRequestTableRecords", records); - return tableMap; - }).toList(); - } - private IWorkUserInfoRespVO buildUserInfoResponse(String responseBody) { IWorkUserInfoRespVO respVO = new IWorkUserInfoRespVO(); - respVO.setRawBody(responseBody); if (!StringUtils.hasText(responseBody)) { return respVO; } @@ -432,7 +505,6 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { private IWorkOperationRespVO buildOperationResponse(String responseBody) { IWorkOperationRespVO respVO = new IWorkOperationRespVO(); - respVO.setRawBody(responseBody); if (!StringUtils.hasText(responseBody)) { return respVO; } @@ -666,6 +738,21 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { return value.replace("'", "'\"'\"'"); } + private record SealRequestFields(String jbr, + String yybm, + String fb, + String sqsj, + String yyqx, + String yyfkUrl, + String yysy, + String xyywjUrl, + String yysx, + String ywxtdjbh, + String workflowId) { + private static final String DEFAULT_FLOW_TYPE = "2979600781334966993"; + private static final String DEFAULT_SIGN_ACTION = "CORPORATE"; + } + private record RegistrationState(String secret, String spk, ClientKeyPair clientKeyPair) { } diff --git a/zt-module-system/zt-module-system-server/src/main/resources/application.yaml b/zt-module-system/zt-module-system-server/src/main/resources/application.yaml index 30293fe0..b7ecf93c 100644 --- a/zt-module-system/zt-module-system-server/src/main/resources/application.yaml +++ b/zt-module-system/zt-module-system-server/src/main/resources/application.yaml @@ -109,7 +109,6 @@ iwork: base-url: http://172.16.36.233:8080 # app-id: f47ac10b-58cc-4372-a567-0e02b2c3d479 app-id: f47ac10b-58cc-4372-a567-0e02b2c3d479 - client-public-key: user-id: 9869 workflow-id: 1753 paths: