Merge branch 'dev' into test
This commit is contained in:
8
pom.xml
8
pom.xml
@@ -18,7 +18,7 @@
|
||||
<module>zt-module-infra</module>
|
||||
<!-- <module>zt-module-bpm</module>-->
|
||||
<module>zt-module-report</module>
|
||||
<!-- <module>zt-module-mp</module>-->
|
||||
<!--<module>zt-module-mp</module>-->
|
||||
<!-- <module>zt-module-ai</module>-->
|
||||
<!-- <module>zt-module-template</module>-->
|
||||
<!-- <module>zt-module-iot</module>-->
|
||||
@@ -274,6 +274,12 @@
|
||||
<config.namespace>chenbowen</config.namespace>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>qsj</id>
|
||||
<properties>
|
||||
<config.namespace>qsj</config.namespace>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
<podam.version>8.0.2.RELEASE</podam.version>
|
||||
<jedis-mock.version>1.1.4</jedis-mock.version>
|
||||
<mockito-inline.version>5.2.0</mockito-inline.version>
|
||||
<okhttp3.version>4.12.0</okhttp3.version>
|
||||
<!-- Bpm 工作流相关 -->
|
||||
<flowable.version>7.0.1</flowable.version>
|
||||
<!-- 工具类相关 -->
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<dependency>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<artifactId>zt-spring-boot-starter-biz-ip</artifactId>
|
||||
<optional>true</optional> <!-- 设置为 optional,只有在 AreaConvert 的时候使用 -->
|
||||
<!--<optional>true</optional>--> <!-- 设置为 optional,只有在 AreaConvert 的时候使用 -->
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
|
||||
@@ -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<String, String> formData = buildCreateForm(reqVO);
|
||||
appendFormExtras(formData, reqVO.getFormExtras());
|
||||
String responseBody = executeFormRequest(properties.getPaths().getCreateWorkflow(), appId, session, formData);
|
||||
Map<String, Object> 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<String, String> formData = buildVoidForm(reqVO);
|
||||
appendFormExtras(formData, reqVO.getFormExtras());
|
||||
String responseBody = executeFormRequest(properties.getPaths().getVoidWorkflow(), appId, session, formData);
|
||||
Map<String, Object> 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<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) {
|
||||
return new Headers.Builder()
|
||||
.set(properties.getHeaders().getAppId(), appId)
|
||||
@@ -361,18 +340,19 @@ public class IWorkIntegrationServiceImpl implements IWorkIntegrationService {
|
||||
return payload;
|
||||
}
|
||||
|
||||
private MultiValueMap<String, String> buildCreateForm(IWorkWorkflowCreateReqVO reqVO) {
|
||||
MultiValueMap<String, String> 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<String, Object> buildCreatePayload(IWorkWorkflowCreateReqVO reqVO) {
|
||||
Map<String, Object> 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<String, String> buildVoidForm(IWorkWorkflowVoidReqVO reqVO) {
|
||||
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
|
||||
formData.add("requestId", reqVO.getRequestId());
|
||||
private Map<String, Object> buildVoidPayload(IWorkWorkflowVoidReqVO reqVO) {
|
||||
Map<String, Object> 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<String, String> formData, Map<String, String> extras) {
|
||||
private void appendPayloadExtras(Map<String, Object> payload, Map<String, String> 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) {
|
||||
}
|
||||
|
||||
|
||||
@@ -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<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 ObjectMapper objectMapper;
|
||||
@@ -179,30 +180,34 @@ public class IWorkOrgRestServiceImpl implements IWorkOrgRestService {
|
||||
}
|
||||
|
||||
private IWorkOrgRespVO invokeParamsEndpoint(String path, Map<String, Object> params) {
|
||||
String payload = toJson(params);
|
||||
return executeForm(path, "params", payload);
|
||||
Map<String, Object> 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<String, Object> 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<String, Object> payload) {
|
||||
assertOrgConfigured(path);
|
||||
FormBody.Builder formBuilder = new FormBody.Builder(StandardCharsets.UTF_8);
|
||||
if (StringUtils.hasText(fieldName) && StringUtils.hasText(jsonPayload)) {
|
||||
formBuilder.add(fieldName, jsonPayload);
|
||||
Map<String, Object> 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<String, String> 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<String, String> 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("'", "'\"'\"'");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user