From 77c46acf9e356b46dff45b45ec549b620c715a82 Mon Sep 17 00:00:00 2001 From: chenbowen Date: Mon, 24 Nov 2025 15:51:45 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BF=AE=E6=94=B9=E8=AF=B7=E6=B1=82=20iwo?= =?UTF-8?q?rk=20=E7=9A=84=E4=BC=A0=E5=8F=82=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/IWorkIntegrationServiceImpl.java | 113 +++++++++++------- .../iwork/impl/IWorkOrgRestServiceImpl.java | 76 +++++++++--- 2 files changed, 128 insertions(+), 61 deletions(-) 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 f2084ebd..82df7f69 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 @@ -17,10 +17,9 @@ import lombok.RequiredArgsConstructor; import lombok.ToString; import lombok.extern.slf4j.Slf4j; import okhttp3.*; +import okio.Buffer; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; import javax.crypto.Cipher; @@ -128,9 +127,8 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { String operatorUserId = resolveOperatorUserId(reqVO.getOperatorUserId()); IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken())); - MultiValueMap formData = buildCreateForm(reqVO); - appendFormExtras(formData, reqVO.getFormExtras()); - String responseBody = executeFormRequest(properties.getPaths().getCreateWorkflow(), appId, session, formData); + Map payload = buildCreatePayload(reqVO); + String responseBody = executeJsonRequest(properties.getPaths().getCreateWorkflow(), null, appId, session, payload); return buildOperationResponse(responseBody); } @@ -145,9 +143,8 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { } IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken())); - MultiValueMap formData = buildVoidForm(reqVO); - appendFormExtras(formData, reqVO.getFormExtras()); - String responseBody = executeFormRequest(properties.getPaths().getVoidWorkflow(), appId, session, formData); + Map payload = buildVoidPayload(reqVO); + String responseBody = executeJsonRequest(properties.getPaths().getVoidWorkflow(), null, appId, session, payload); return buildOperationResponse(responseBody); } @@ -327,24 +324,6 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { return executeRequest(request, IWORK_REMOTE_REQUEST_FAILED); } - private String executeFormRequest(String path, - String appId, - IWorkSession session, - MultiValueMap formData) { - FormBody.Builder builder = new FormBody.Builder(); - formData.forEach((key, values) -> { - if (values != null) { - values.forEach(value -> builder.add(key, value)); - } - }); - Request request = new Request.Builder() - .url(resolveUrl(path)) - .headers(authHeaders(appId, session).build()) - .post(builder.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) @@ -361,18 +340,19 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { return payload; } - private MultiValueMap buildCreateForm(IWorkWorkflowCreateReqVO reqVO) { - MultiValueMap formData = new LinkedMultiValueMap<>(); - formData.add("requestName", reqVO.getRequestName()); - formData.add("workflowId", String.valueOf(resolveWorkflowId(reqVO.getWorkflowId()))); - formData.add("mainData", toJsonString(convertFormFields(reqVO.getMainFields()))); + 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()) { - formData.add("detailData", toJsonString(convertDetailTables(reqVO.getDetailTables()))); + payload.put("detailData", convertDetailTables(reqVO.getDetailTables())); } if (reqVO.getOtherParams() != null && !reqVO.getOtherParams().isEmpty()) { - formData.add("otherParams", toJsonString(reqVO.getOtherParams())); + payload.put("otherParams", reqVO.getOtherParams()); } - return formData; + appendPayloadExtras(payload, reqVO.getFormExtras()); + return payload; } private long resolveWorkflowId(Long requestWorkflowId) { @@ -385,29 +365,26 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { throw ServiceExceptionUtil.exception(IWORK_WORKFLOW_ID_MISSING); } - private MultiValueMap buildVoidForm(IWorkWorkflowVoidReqVO reqVO) { - MultiValueMap formData = new LinkedMultiValueMap<>(); - formData.add("requestId", reqVO.getRequestId()); + private Map buildVoidPayload(IWorkWorkflowVoidReqVO reqVO) { + Map payload = new LinkedHashMap<>(); + payload.put("requestId", reqVO.getRequestId()); if (StringUtils.hasText(reqVO.getReason())) { - formData.add("remark", reqVO.getReason()); + payload.put("remark", reqVO.getReason()); } if (reqVO.getExtraParams() != null && !reqVO.getExtraParams().isEmpty()) { - reqVO.getExtraParams().forEach((key, value) -> { - if (value != null) { - formData.add(key, String.valueOf(value)); - } - }); + payload.putAll(reqVO.getExtraParams()); } - return formData; + appendPayloadExtras(payload, reqVO.getFormExtras()); + return payload; } - private void appendFormExtras(MultiValueMap formData, Map extras) { + private void appendPayloadExtras(Map payload, Map extras) { if (extras == null || extras.isEmpty()) { return; } extras.forEach((key, value) -> { if (StringUtils.hasText(key) && value != null) { - formData.add(key, value); + payload.put(key, value); } }); } @@ -632,6 +609,7 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { } private String executeRequest(Request request, ErrorCode errorCode) { + logCurlCommand(request); try (Response response = okHttpClient().newCall(request).execute()) { String responseBody = response.body() != null ? response.body().string() : null; if (!response.isSuccessful()) { @@ -645,6 +623,49 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService { } } + private void logCurlCommand(Request request) { + if (request == null || !log.isInfoEnabled()) { + return; + } + try { + StringBuilder curl = new StringBuilder("curl"); + curl.append(" -X ").append(request.method()); + curl.append(" '").append(request.url()).append("'"); + + Headers headers = request.headers(); + for (int i = 0; i < headers.size(); i++) { + curl.append(" -H '") + .append(escapeSingleQuotes(headers.name(i))) + .append(": ") + .append(escapeSingleQuotes(headers.value(i))) + .append("'"); + } + + RequestBody body = request.body(); + if (body != null) { + Buffer buffer = new Buffer(); + body.writeTo(buffer); + String bodyString = buffer.readUtf8(); + if (StringUtils.hasText(bodyString)) { + curl.append(" --data '") + .append(escapeSingleQuotes(bodyString)) + .append("'"); + } + } + + log.info("[iWork] -> {}", curl); + } catch (Exception ex) { + log.warn("[iWork] failed to build curl log for {}: {}", request.url(), ex.getMessage()); + } + } + + private String escapeSingleQuotes(String value) { + if (value == null) { + return ""; + } + return value.replace("'", "'\"'\"'"); + } + private record RegistrationState(String secret, String spk, ClientKeyPair clientKeyPair) { } diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkOrgRestServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkOrgRestServiceImpl.java index c4d29cb1..dfd962e2 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkOrgRestServiceImpl.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkOrgRestServiceImpl.java @@ -15,11 +15,11 @@ import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkUser import com.zt.plat.module.system.framework.integration.iwork.config.IWorkProperties; import com.zt.plat.module.system.service.integration.iwork.IWorkOrgRestService; import lombok.extern.slf4j.Slf4j; -import okhttp3.FormBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +import okio.Buffer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; @@ -46,6 +46,7 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService { private static final TypeReference> MAP_TYPE = new TypeReference<>() { }; + private static final okhttp3.MediaType JSON_MEDIA_TYPE = okhttp3.MediaType.get("application/json; charset=UTF-8"); private final IWorkProperties properties; private final ObjectMapper objectMapper; @@ -179,30 +180,34 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService { } private IWorkOrgRespVO invokeParamsEndpoint(String path, Map params) { - String payload = toJson(params); - return executeForm(path, "params", payload); + Map payload = new HashMap<>(); + payload.put("params", params == null ? Collections.emptyMap() : params); + return executeJson(path, payload); } private IWorkOrgRespVO invokeDataEndpoint(String path, Object data) { - String payload = toJson(data); - return executeForm(path, "data", payload); + Map payload = new HashMap<>(); + payload.put("data", data == null ? Collections.emptyMap() : data); + return executeJson(path, payload); } - private IWorkOrgRespVO executeForm(String path, String fieldName, String jsonPayload) { + private IWorkOrgRespVO executeJson(String path, Map payload) { assertOrgConfigured(path); - FormBody.Builder formBuilder = new FormBody.Builder(StandardCharsets.UTF_8); - if (StringUtils.hasText(fieldName) && StringUtils.hasText(jsonPayload)) { - formBuilder.add(fieldName, jsonPayload); + Map body = new HashMap<>(); + if (payload != null && !payload.isEmpty()) { + body.putAll(payload); } - formBuilder.add("token", buildTokenJson()); + body.put("token", buildTokenPayload()); + String jsonBody = toJson(body); - RequestBody requestBody = formBuilder.build(); + RequestBody requestBody = RequestBody.create(JSON_MEDIA_TYPE, jsonBody); Request request = new Request.Builder() .url(resolveUrl(path)) - .header("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE) + .header("Content-Type", MediaType.APPLICATION_JSON_VALUE) .post(requestBody) .build(); + logCurlCommand(request); try (Response response = okHttpClient().newCall(request).execute()) { String responseBody = response.body() != null ? response.body().string() : null; if (!response.isSuccessful()) { @@ -216,7 +221,7 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService { } } - private String buildTokenJson() { + private Map buildTokenPayload() { String tokenSeed = StringUtils.trimWhitespace(orgConfig().getTokenSeed()); if (!StringUtils.hasText(tokenSeed)) { throw ServiceExceptionUtil.exception(IWORK_ORG_IDENTIFIER_MISSING); @@ -225,11 +230,10 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService { String raw = tokenSeed + ts; // 通过 MD5(tokenSeed + ts) 计算 key,并转为大写以符合 PDF 约定 String hashed = md5Upper(raw); - Map token = Map.of( + return Map.of( "key", hashed, "ts", String.valueOf(ts) ); - return toJson(token); } private String md5Upper(String raw) { @@ -368,4 +372,46 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService { } return baseUrl + path; } + + private void logCurlCommand(Request request) { + if (request == null || !log.isInfoEnabled()) { + return; + } + try { + StringBuilder curl = new StringBuilder("curl"); + curl.append(" -X ").append(request.method()); + curl.append(" '").append(request.url()).append("'"); + + for (int i = 0; i < request.headers().size(); i++) { + curl.append(" -H '") + .append(escapeSingleQuotes(request.headers().name(i))) + .append(": ") + .append(escapeSingleQuotes(request.headers().value(i))) + .append("'"); + } + + RequestBody body = request.body(); + if (body != null) { + Buffer buffer = new Buffer(); + body.writeTo(buffer); + String bodyString = buffer.readUtf8(); + if (StringUtils.hasText(bodyString)) { + curl.append(" --data '") + .append(escapeSingleQuotes(bodyString)) + .append("'"); + } + } + + log.info("[iWork-Org] -> {}", curl); + } catch (Exception ex) { + log.warn("[iWork-Org] 构建 curl 日志失败 {}: {}", request.url(), ex.getMessage()); + } + } + + private String escapeSingleQuotes(String value) { + if (value == null) { + return ""; + } + return value.replace("'", "'\"'\"'"); + } }