1. 修改请求 iwork 的传参方式
This commit is contained in:
@@ -17,10 +17,9 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import okhttp3.*;
|
import okhttp3.*;
|
||||||
|
import okio.Buffer;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
import org.springframework.util.MultiValueMap;
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
@@ -128,9 +127,8 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
|||||||
String operatorUserId = resolveOperatorUserId(reqVO.getOperatorUserId());
|
String operatorUserId = resolveOperatorUserId(reqVO.getOperatorUserId());
|
||||||
IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
||||||
|
|
||||||
MultiValueMap<String, String> formData = buildCreateForm(reqVO);
|
Map<String, Object> payload = buildCreatePayload(reqVO);
|
||||||
appendFormExtras(formData, reqVO.getFormExtras());
|
String responseBody = executeJsonRequest(properties.getPaths().getCreateWorkflow(), null, appId, session, payload);
|
||||||
String responseBody = executeFormRequest(properties.getPaths().getCreateWorkflow(), appId, session, formData);
|
|
||||||
return buildOperationResponse(responseBody);
|
return buildOperationResponse(responseBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,9 +143,8 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
|||||||
}
|
}
|
||||||
IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
IWorkSession session = ensureSession(appId, clientKeyPair, operatorUserId, Boolean.TRUE.equals(reqVO.getForceRefreshToken()));
|
||||||
|
|
||||||
MultiValueMap<String, String> formData = buildVoidForm(reqVO);
|
Map<String, Object> payload = buildVoidPayload(reqVO);
|
||||||
appendFormExtras(formData, reqVO.getFormExtras());
|
String responseBody = executeJsonRequest(properties.getPaths().getVoidWorkflow(), null, appId, session, payload);
|
||||||
String responseBody = executeFormRequest(properties.getPaths().getVoidWorkflow(), appId, session, formData);
|
|
||||||
return buildOperationResponse(responseBody);
|
return buildOperationResponse(responseBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,24 +324,6 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
|||||||
return executeRequest(request, IWORK_REMOTE_REQUEST_FAILED);
|
return executeRequest(request, IWORK_REMOTE_REQUEST_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String executeFormRequest(String path,
|
|
||||||
String appId,
|
|
||||||
IWorkSession session,
|
|
||||||
MultiValueMap<String, String> 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) {
|
private Headers.Builder authHeaders(String appId, IWorkSession session) {
|
||||||
return new Headers.Builder()
|
return new Headers.Builder()
|
||||||
.set(properties.getHeaders().getAppId(), appId)
|
.set(properties.getHeaders().getAppId(), appId)
|
||||||
@@ -361,18 +340,19 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
|||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MultiValueMap<String, String> buildCreateForm(IWorkWorkflowCreateReqVO reqVO) {
|
private Map<String, Object> buildCreatePayload(IWorkWorkflowCreateReqVO reqVO) {
|
||||||
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
|
Map<String, Object> payload = new LinkedHashMap<>();
|
||||||
formData.add("requestName", reqVO.getRequestName());
|
payload.put("requestName", reqVO.getRequestName());
|
||||||
formData.add("workflowId", String.valueOf(resolveWorkflowId(reqVO.getWorkflowId())));
|
payload.put("workflowId", resolveWorkflowId(reqVO.getWorkflowId()));
|
||||||
formData.add("mainData", toJsonString(convertFormFields(reqVO.getMainFields())));
|
payload.put("mainData", convertFormFields(reqVO.getMainFields()));
|
||||||
if (reqVO.getDetailTables() != null && !reqVO.getDetailTables().isEmpty()) {
|
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()) {
|
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) {
|
private long resolveWorkflowId(Long requestWorkflowId) {
|
||||||
@@ -385,29 +365,26 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
|||||||
throw ServiceExceptionUtil.exception(IWORK_WORKFLOW_ID_MISSING);
|
throw ServiceExceptionUtil.exception(IWORK_WORKFLOW_ID_MISSING);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MultiValueMap<String, String> buildVoidForm(IWorkWorkflowVoidReqVO reqVO) {
|
private Map<String, Object> buildVoidPayload(IWorkWorkflowVoidReqVO reqVO) {
|
||||||
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
|
Map<String, Object> payload = new LinkedHashMap<>();
|
||||||
formData.add("requestId", reqVO.getRequestId());
|
payload.put("requestId", reqVO.getRequestId());
|
||||||
if (StringUtils.hasText(reqVO.getReason())) {
|
if (StringUtils.hasText(reqVO.getReason())) {
|
||||||
formData.add("remark", reqVO.getReason());
|
payload.put("remark", reqVO.getReason());
|
||||||
}
|
}
|
||||||
if (reqVO.getExtraParams() != null && !reqVO.getExtraParams().isEmpty()) {
|
if (reqVO.getExtraParams() != null && !reqVO.getExtraParams().isEmpty()) {
|
||||||
reqVO.getExtraParams().forEach((key, value) -> {
|
payload.putAll(reqVO.getExtraParams());
|
||||||
if (value != null) {
|
|
||||||
formData.add(key, String.valueOf(value));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return formData;
|
appendPayloadExtras(payload, reqVO.getFormExtras());
|
||||||
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendFormExtras(MultiValueMap<String, String> formData, Map<String, String> extras) {
|
private void appendPayloadExtras(Map<String, Object> payload, Map<String, String> extras) {
|
||||||
if (extras == null || extras.isEmpty()) {
|
if (extras == null || extras.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
extras.forEach((key, value) -> {
|
extras.forEach((key, value) -> {
|
||||||
if (StringUtils.hasText(key) && value != null) {
|
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) {
|
private String executeRequest(Request request, ErrorCode errorCode) {
|
||||||
|
logCurlCommand(request);
|
||||||
try (Response response = okHttpClient().newCall(request).execute()) {
|
try (Response response = okHttpClient().newCall(request).execute()) {
|
||||||
String responseBody = response.body() != null ? response.body().string() : null;
|
String responseBody = response.body() != null ? response.body().string() : null;
|
||||||
if (!response.isSuccessful()) {
|
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) {
|
private record RegistrationState(String secret, String spk, ClientKeyPair clientKeyPair) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.framework.integration.iwork.config.IWorkProperties;
|
||||||
import com.zt.plat.module.system.service.integration.iwork.IWorkOrgRestService;
|
import com.zt.plat.module.system.service.integration.iwork.IWorkOrgRestService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import okhttp3.FormBody;
|
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
import okio.Buffer;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -46,6 +46,7 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService {
|
|||||||
|
|
||||||
private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<>() {
|
private static final TypeReference<Map<String, Object>> 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 IWorkProperties properties;
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
@@ -179,30 +180,34 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private IWorkOrgRespVO invokeParamsEndpoint(String path, Map<String, Object> params) {
|
private IWorkOrgRespVO invokeParamsEndpoint(String path, Map<String, Object> params) {
|
||||||
String payload = toJson(params);
|
Map<String, Object> payload = new HashMap<>();
|
||||||
return executeForm(path, "params", payload);
|
payload.put("params", params == null ? Collections.emptyMap() : params);
|
||||||
|
return executeJson(path, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IWorkOrgRespVO invokeDataEndpoint(String path, Object data) {
|
private IWorkOrgRespVO invokeDataEndpoint(String path, Object data) {
|
||||||
String payload = toJson(data);
|
Map<String, Object> payload = new HashMap<>();
|
||||||
return executeForm(path, "data", payload);
|
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<String, Object> payload) {
|
||||||
assertOrgConfigured(path);
|
assertOrgConfigured(path);
|
||||||
FormBody.Builder formBuilder = new FormBody.Builder(StandardCharsets.UTF_8);
|
Map<String, Object> body = new HashMap<>();
|
||||||
if (StringUtils.hasText(fieldName) && StringUtils.hasText(jsonPayload)) {
|
if (payload != null && !payload.isEmpty()) {
|
||||||
formBuilder.add(fieldName, jsonPayload);
|
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()
|
Request request = new Request.Builder()
|
||||||
.url(resolveUrl(path))
|
.url(resolveUrl(path))
|
||||||
.header("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
.header("Content-Type", MediaType.APPLICATION_JSON_VALUE)
|
||||||
.post(requestBody)
|
.post(requestBody)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
logCurlCommand(request);
|
||||||
try (Response response = okHttpClient().newCall(request).execute()) {
|
try (Response response = okHttpClient().newCall(request).execute()) {
|
||||||
String responseBody = response.body() != null ? response.body().string() : null;
|
String responseBody = response.body() != null ? response.body().string() : null;
|
||||||
if (!response.isSuccessful()) {
|
if (!response.isSuccessful()) {
|
||||||
@@ -216,7 +221,7 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildTokenJson() {
|
private Map<String, String> buildTokenPayload() {
|
||||||
String tokenSeed = StringUtils.trimWhitespace(orgConfig().getTokenSeed());
|
String tokenSeed = StringUtils.trimWhitespace(orgConfig().getTokenSeed());
|
||||||
if (!StringUtils.hasText(tokenSeed)) {
|
if (!StringUtils.hasText(tokenSeed)) {
|
||||||
throw ServiceExceptionUtil.exception(IWORK_ORG_IDENTIFIER_MISSING);
|
throw ServiceExceptionUtil.exception(IWORK_ORG_IDENTIFIER_MISSING);
|
||||||
@@ -225,11 +230,10 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService {
|
|||||||
String raw = tokenSeed + ts;
|
String raw = tokenSeed + ts;
|
||||||
// 通过 MD5(tokenSeed + ts) 计算 key,并转为大写以符合 PDF 约定
|
// 通过 MD5(tokenSeed + ts) 计算 key,并转为大写以符合 PDF 约定
|
||||||
String hashed = md5Upper(raw);
|
String hashed = md5Upper(raw);
|
||||||
Map<String, String> token = Map.of(
|
return Map.of(
|
||||||
"key", hashed,
|
"key", hashed,
|
||||||
"ts", String.valueOf(ts)
|
"ts", String.valueOf(ts)
|
||||||
);
|
);
|
||||||
return toJson(token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String md5Upper(String raw) {
|
private String md5Upper(String raw) {
|
||||||
@@ -368,4 +372,46 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService {
|
|||||||
}
|
}
|
||||||
return baseUrl + path;
|
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("'", "'\"'\"'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user