diff --git a/sql/dm/数据总线API访问日志表结构_20251028.sql b/sql/dm/数据总线API访问日志表结构_20251028.sql index e69de29b..8ddec75a 100644 --- a/sql/dm/数据总线API访问日志表结构_20251028.sql +++ b/sql/dm/数据总线API访问日志表结构_20251028.sql @@ -0,0 +1,74 @@ +CREATE TABLE "RUOYI-VUE-PRO"."DATABUS_API_ACCESS_LOG" +( + "ID" BIGINT NOT NULL, + "TRACE_ID" VARCHAR(64) DEFAULT NULL, + "API_CODE" VARCHAR(128) DEFAULT NULL, + "API_VERSION" VARCHAR(32) DEFAULT NULL, + "REQUEST_METHOD" VARCHAR(16) DEFAULT NULL, + "REQUEST_PATH" VARCHAR(512) DEFAULT NULL, + "REQUEST_QUERY" TEXT, + "REQUEST_HEADERS" TEXT, + "REQUEST_BODY" TEXT, + "RESPONSE_STATUS" INT DEFAULT NULL, + "RESPONSE_MESSAGE" VARCHAR(500) DEFAULT NULL, + "RESPONSE_BODY" TEXT, + "STATUS" SMALLINT DEFAULT 3 NOT NULL, + "ERROR_CODE" VARCHAR(100) DEFAULT NULL, + "ERROR_MESSAGE" VARCHAR(1000) DEFAULT NULL, + "EXCEPTION_STACK" TEXT, + "CLIENT_IP" VARCHAR(64) DEFAULT NULL, + "USER_AGENT" VARCHAR(512) DEFAULT NULL, + "DURATION" BIGINT DEFAULT NULL, + "REQUEST_TIME" DATETIME(6) DEFAULT CURRENT_TIMESTAMP NOT NULL, + "RESPONSE_TIME" DATETIME(6) DEFAULT NULL, + "STEP_RESULTS" TEXT, + "EXTRA" TEXT, + "CREATOR" VARCHAR(64) DEFAULT '' NOT NULL, + "CREATE_TIME" DATETIME(6) DEFAULT CURRENT_TIMESTAMP NOT NULL, + "UPDATER" VARCHAR(64) DEFAULT '' NOT NULL, + "UPDATE_TIME" DATETIME(6) DEFAULT CURRENT_TIMESTAMP NOT NULL, + "DELETED" BIT DEFAULT '0' NOT NULL, + "TENANT_ID" BIGINT DEFAULT 0 NOT NULL, + NOT CLUSTER PRIMARY KEY("ID")) STORAGE(ON "MAIN", CLUSTERBTR) ; + +COMMENT ON TABLE "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG IS 'Databus API 访问日志表'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."API_CODE" IS 'API 编码'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."API_VERSION" IS 'API 版本'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."CLIENT_IP" IS '客户端 IP'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."CREATE_TIME" IS '创建时间'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."CREATOR" IS '创建者'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."DELETED" IS '是否删除'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."DURATION" IS '请求耗时(毫秒)'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."ERROR_CODE" IS '业务错误码'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."ERROR_MESSAGE" IS '错误信息'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."EXCEPTION_STACK" IS '异常堆栈'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."EXTRA" IS '额外调试信息(JSON 字符串)'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."ID" IS '日志主键'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."REQUEST_BODY" IS '请求体(JSON 字符串)'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."REQUEST_HEADERS" IS '请求头(JSON 字符串)'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."REQUEST_METHOD" IS '请求方法'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."REQUEST_PATH" IS '请求路径'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."REQUEST_QUERY" IS '请求查询参数(JSON 字符串)'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."REQUEST_TIME" IS '请求时间'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."RESPONSE_BODY" IS '响应体(JSON 字符串)'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."RESPONSE_MESSAGE" IS '响应提示信息'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."RESPONSE_STATUS" IS '响应 HTTP 状态码'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."RESPONSE_TIME" IS '响应时间'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."STATUS" IS '访问状态:0-成功 1-客户端错误 2-服务端错误 3-未知'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."STEP_RESULTS" IS '执行步骤结果(JSON 字符串)'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."TENANT_ID" IS '租户编号'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."TRACE_ID" IS '追踪 ID'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."UPDATER" IS '更新者'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."UPDATE_TIME" IS '更新时间'; +COMMENT ON COLUMN "RUOYI-VUE-PRO".DATABUS_API_ACCESS_LOG."USER_AGENT" IS 'User-Agent'; + + +CREATE OR REPLACE INDEX "IDX_DATABUS_API_ACCESS_LOG_TRACE" ON "RUOYI-VUE-PRO"."DATABUS_API_ACCESS_LOG"("TRACE_ID" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ; +CREATE OR REPLACE INDEX "IDX_DATABUS_API_ACCESS_LOG_CODE" ON "RUOYI-VUE-PRO"."DATABUS_API_ACCESS_LOG"("API_CODE" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ; +CREATE OR REPLACE INDEX "IDX_DATABUS_API_ACCESS_LOG_METHOD" ON "RUOYI-VUE-PRO"."DATABUS_API_ACCESS_LOG"("REQUEST_METHOD" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ; +CREATE OR REPLACE INDEX "IDX_DATABUS_API_ACCESS_LOG_STATUS" ON "RUOYI-VUE-PRO"."DATABUS_API_ACCESS_LOG"("STATUS" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ; +CREATE OR REPLACE INDEX "IDX_DATABUS_API_ACCESS_LOG_RESP_STATUS" ON "RUOYI-VUE-PRO"."DATABUS_API_ACCESS_LOG"("RESPONSE_STATUS" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ; +CREATE OR REPLACE INDEX "IDX_DATABUS_API_ACCESS_LOG_REQUEST_TIME" ON "RUOYI-VUE-PRO"."DATABUS_API_ACCESS_LOG"("REQUEST_TIME" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ; +CREATE OR REPLACE INDEX "IDX_DATABUS_API_ACCESS_LOG_CLIENT_IP" ON "RUOYI-VUE-PRO"."DATABUS_API_ACCESS_LOG"("CLIENT_IP" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ; +CREATE OR REPLACE INDEX "IDX_DATABUS_API_ACCESS_LOG_TENANT" ON "RUOYI-VUE-PRO"."DATABUS_API_ACCESS_LOG"("TENANT_ID" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ; + diff --git a/zt-framework/zt-spring-boot-starter-biz-business/src/main/java/com/zt/plat/framework/business/core/util/BusinessDeptHandleUtil.java b/zt-framework/zt-spring-boot-starter-biz-business/src/main/java/com/zt/plat/framework/business/core/util/BusinessDeptHandleUtil.java index ef47614e..03502d9c 100644 --- a/zt-framework/zt-spring-boot-starter-biz-business/src/main/java/com/zt/plat/framework/business/core/util/BusinessDeptHandleUtil.java +++ b/zt-framework/zt-spring-boot-starter-biz-business/src/main/java/com/zt/plat/framework/business/core/util/BusinessDeptHandleUtil.java @@ -182,8 +182,10 @@ public class BusinessDeptHandleUtil { if (loginUser != null) { loginUser.setVisitCompanyId(Long.valueOf(info.getCompanyId())); loginUser.setVisitCompanyName(info.getCompanyName()); + loginUser.setVisitCompanyCode(info.getCompanyName()); loginUser.setVisitDeptId(Long.valueOf(info.getDeptId())); loginUser.setVisitDeptName(info.getDeptName()); + loginUser.setVisitDeptCode(info.getDeptName()); } request.setAttribute(WebFrameworkUtils.HEADER_VISIT_COMPANY_ID, info.getCompanyId()); if (info.getCompanyName() != null) { diff --git a/zt-framework/zt-spring-boot-starter-security/src/main/java/com/zt/plat/framework/security/core/LoginUser.java b/zt-framework/zt-spring-boot-starter-security/src/main/java/com/zt/plat/framework/security/core/LoginUser.java index 6cc433ca..f9b739dd 100644 --- a/zt-framework/zt-spring-boot-starter-security/src/main/java/com/zt/plat/framework/security/core/LoginUser.java +++ b/zt-framework/zt-spring-boot-starter-security/src/main/java/com/zt/plat/framework/security/core/LoginUser.java @@ -73,9 +73,11 @@ public class LoginUser { private Long visitCompanyId; private String visitCompanyName; + private String visitCompanyCode; private Long visitDeptId; private String visitDeptName; + private String visitDeptCode; public void setContext(String key, Object value) { if (context == null) { diff --git a/zt-gateway/src/main/resources/logback-spring.xml b/zt-gateway/src/main/resources/logback-spring.xml index c23fa5d2..cd4992fa 100644 --- a/zt-gateway/src/main/resources/logback-spring.xml +++ b/zt-gateway/src/main/resources/logback-spring.xml @@ -5,6 +5,10 @@ + + + +       @@ -56,11 +60,29 @@ + + + ${LOG_DIR}-error.log + + ERROR + ACCEPT + DENY + + + ${LOG_DIR}-error.%d{yyyy-MM-dd}.log + 30 + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + @@ -70,6 +92,7 @@ + diff --git a/zt-module-infra/zt-module-infra-server/src/main/resources/logback-spring.xml b/zt-module-infra/zt-module-infra-server/src/main/resources/logback-spring.xml index 12667617..3acd4d89 100644 --- a/zt-module-infra/zt-module-infra-server/src/main/resources/logback-spring.xml +++ b/zt-module-infra/zt-module-infra-server/src/main/resources/logback-spring.xml @@ -5,6 +5,10 @@ + + + +       @@ -56,11 +60,29 @@ + + + ${LOG_DIR}-error.log + + ERROR + ACCEPT + DENY + + + ${LOG_DIR}-error.%d{yyyy-MM-dd}.log + 30 + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + @@ -75,6 +97,7 @@ + diff --git a/zt-module-mp/zt-module-mp-server/src/main/resources/logback-spring.xml b/zt-module-mp/zt-module-mp-server/src/main/resources/logback-spring.xml index 95e649be..74af7a31 100644 --- a/zt-module-mp/zt-module-mp-server/src/main/resources/logback-spring.xml +++ b/zt-module-mp/zt-module-mp-server/src/main/resources/logback-spring.xml @@ -5,6 +5,10 @@ + + + +       @@ -56,11 +60,29 @@ + + + ${LOG_DIR}-error.log + + ERROR + ACCEPT + DENY + + + ${LOG_DIR}-error.%d{yyyy-MM-dd}.log + 30 + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + @@ -75,6 +97,7 @@ + diff --git a/zt-module-report/zt-module-report-server/src/main/resources/logback-spring.xml b/zt-module-report/zt-module-report-server/src/main/resources/logback-spring.xml index 4d382fe0..65a3a338 100644 --- a/zt-module-report/zt-module-report-server/src/main/resources/logback-spring.xml +++ b/zt-module-report/zt-module-report-server/src/main/resources/logback-spring.xml @@ -5,6 +5,10 @@ + + + +       @@ -56,11 +60,29 @@ + + + ${LOG_DIR}-error.log + + ERROR + ACCEPT + DENY + + + ${LOG_DIR}-error.%d{yyyy-MM-dd}.log + 30 + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + @@ -75,6 +97,7 @@ + diff --git a/zt-module-system/zt-module-system-server/src/main/resources/logback-spring.xml b/zt-module-system/zt-module-system-server/src/main/resources/logback-spring.xml index df2f1c4b..74142cd7 100644 --- a/zt-module-system/zt-module-system-server/src/main/resources/logback-spring.xml +++ b/zt-module-system/zt-module-system-server/src/main/resources/logback-spring.xml @@ -5,6 +5,10 @@ + + + +       @@ -56,11 +60,29 @@ + + + ${LOG_DIR}-error.log + + ERROR + ACCEPT + DENY + + + ${LOG_DIR}-error.%d{yyyy-MM-dd}.log + 30 + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + @@ -75,6 +97,7 @@ + diff --git a/zt-module-system/zt-module-system-server/src/test/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImplTest.java b/zt-module-system/zt-module-system-server/src/test/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImplTest.java deleted file mode 100644 index 55273280..00000000 --- a/zt-module-system/zt-module-system-server/src/test/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkIntegrationServiceImplTest.java +++ /dev/null @@ -1,228 +0,0 @@ -package com.zt.plat.module.system.service.integration.iwork.impl; - -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkDetailRecordVO; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkDetailTableVO; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkFormFieldVO; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkOperationRespVO; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkUserInfoReqVO; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkUserInfoRespVO; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkWorkflowCreateReqVO; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkWorkflowVoidReqVO; -import com.zt.plat.module.system.framework.integration.iwork.config.IWorkProperties; -import com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationService; -import com.fasterxml.jackson.databind.ObjectMapper; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.web.reactive.function.client.WebClient; - -import javax.crypto.Cipher; -import java.nio.charset.StandardCharsets; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.X509EncodedKeySpec; -import java.time.Duration; -import java.util.Base64; -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; - -class IWorkIntegrationServiceImplTest { - - private static KeyPair serverKeyPair; - private static String serverPublicKeyBase64; - private static String clientPublicKeyBase64; - - private MockWebServer mockWebServer; - private IWorkIntegrationService integrationService; - private IWorkProperties properties; - - @BeforeAll - static void initKeys() throws Exception { - KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); - generator.initialize(1024); - serverKeyPair = generator.generateKeyPair(); - serverPublicKeyBase64 = Base64.getEncoder().encodeToString(serverKeyPair.getPublic().getEncoded()); - - KeyPair clientKeyPair = generator.generateKeyPair(); - clientPublicKeyBase64 = Base64.getEncoder().encodeToString(clientKeyPair.getPublic().getEncoded()); - } - - @BeforeEach - void setUp() throws Exception { - mockWebServer = new MockWebServer(); - mockWebServer.start(); - - properties = buildProperties(); - WebClient.Builder builder = WebClient.builder(); - ObjectMapper objectMapper = new ObjectMapper(); - integrationService = new IWorkIntegrationServiceImpl(properties, objectMapper, builder); - } - - @AfterEach - void tearDown() throws Exception { - mockWebServer.shutdown(); - } - - @Test - void testWorkflowLifecycle() throws Exception { - enqueueRegisterResponse(); - enqueueApplyTokenResponse(); - enqueueJsonResponse("{\"code\":1,\"userid\":\"1001\",\"msg\":\"OK\"}"); - enqueueJsonResponse("{\"code\":\"1\",\"requestid\":\"REQ-001\",\"msg\":\"created\"}"); - enqueueJsonResponse("{\"code\":\"1\",\"msg\":\"voided\"}"); - - IWorkUserInfoReqVO userReq = new IWorkUserInfoReqVO(); - userReq.setIdentifierKey("loginid"); - userReq.setIdentifierValue("zhangsan"); - - IWorkUserInfoRespVO userResp = integrationService.resolveUserId(userReq); - assertThat(userResp.isSuccess()).isTrue(); - assertThat(userResp.getUserId()).isEqualTo("1001"); - - IWorkWorkflowCreateReqVO createReq = buildCreateRequest(); - IWorkOperationRespVO createResp = integrationService.createWorkflow(createReq); - assertThat(createResp.isSuccess()).isTrue(); - assertThat(createResp.getPayload().get("requestid")).isEqualTo("REQ-001"); - - IWorkWorkflowVoidReqVO voidReq = new IWorkWorkflowVoidReqVO(); - voidReq.setRequestId("REQ-001"); - voidReq.setReason("testing void"); - IWorkOperationRespVO voidResp = integrationService.voidWorkflow(voidReq); - assertThat(voidResp.isSuccess()).isTrue(); - - verifyRegisterRequest(mockWebServer.takeRequest()); - verifyApplyTokenRequest(mockWebServer.takeRequest()); - verifyUserInfoRequest(mockWebServer.takeRequest()); - verifyCreateRequest(mockWebServer.takeRequest()); - verifyVoidRequest(mockWebServer.takeRequest()); - - assertThat(mockWebServer.getRequestCount()).isEqualTo(5); - } - - private IWorkProperties buildProperties() { - IWorkProperties properties = new IWorkProperties(); - properties.setEnabled(true); - properties.setBaseUrl(mockWebServer.url("/").toString()); - properties.setAppId("test-app"); - properties.setClientPublicKey(clientPublicKeyBase64); - properties.setUserId("1"); - properties.setWorkflowId(54L); - properties.getToken().setTtlSeconds(3600L); - properties.getToken().setRefreshAheadSeconds(30L); - properties.getClient().setResponseTimeout(Duration.ofSeconds(5)); - - properties.getPaths().setRegister("/api/ec/dev/auth/regist"); - properties.getPaths().setApplyToken("/api/ec/dev/auth/applytoken"); - properties.getPaths().setUserInfo("/api/workflow/paService/getUserInfo"); - properties.getPaths().setCreateWorkflow("/api/workflow/paService/doCreateRequest"); - properties.getPaths().setVoidWorkflow("/api/workflow/paService/doCancelRequest"); - - properties.getClient().setConnectTimeout(Duration.ofSeconds(5)); - return properties; - } - - private void verifyRegisterRequest(RecordedRequest request) { - assertThat(request.getPath()).isEqualTo("/api/ec/dev/auth/regist"); - assertThat(request.getHeader(properties.getHeaders().getAppId())).isEqualTo("test-app"); - assertThat(request.getHeader(properties.getHeaders().getClientPublicKey())).isEqualTo(clientPublicKeyBase64); - } - - private void verifyApplyTokenRequest(RecordedRequest request) throws Exception { - assertThat(request.getPath()).isEqualTo("/api/ec/dev/auth/applytoken"); - assertThat(request.getHeader(properties.getHeaders().getAppId())).isEqualTo("test-app"); - assertThat(request.getHeader(properties.getHeaders().getTime())).isEqualTo("3600"); - String decryptedSecret = decryptHeader(request.getHeader(properties.getHeaders().getSecret())); - assertThat(decryptedSecret).isEqualTo("plain-secret"); - } - - private void verifyUserInfoRequest(RecordedRequest request) throws Exception { - assertThat(request.getPath()).isEqualTo("/api/workflow/paService/getUserInfo"); - assertThat(request.getHeader(properties.getHeaders().getToken())).isEqualTo("token-123"); - String decryptedUserId = decryptHeader(request.getHeader(properties.getHeaders().getUserId())); - assertThat(decryptedUserId).isEqualTo("1"); - String body = request.getBody().readUtf8(); - assertThat(body).contains("loginid"); - assertThat(body).contains("zhangsan"); - } - - private void verifyCreateRequest(RecordedRequest request) throws Exception { - assertThat(request.getPath()).isEqualTo("/api/workflow/paService/doCreateRequest"); - assertThat(request.getHeader(properties.getHeaders().getToken())).isEqualTo("token-123"); - String decryptedUserId = decryptHeader(request.getHeader(properties.getHeaders().getUserId())); - assertThat(decryptedUserId).isEqualTo("1"); - String body = request.getBody().readUtf8(); - assertThat(body).contains("requestName=测试流程"); - assertThat(body).contains("workflowId=54"); - assertThat(body).contains("mainData=%5B"); - } - - private void verifyVoidRequest(RecordedRequest request) throws Exception { - assertThat(request.getPath()).isEqualTo("/api/workflow/paService/doCancelRequest"); - assertThat(request.getHeader(properties.getHeaders().getToken())).isEqualTo("token-123"); - String decryptedUserId = decryptHeader(request.getHeader(properties.getHeaders().getUserId())); - assertThat(decryptedUserId).isEqualTo("1"); - String body = request.getBody().readUtf8(); - assertThat(body).contains("requestId=REQ-001"); - assertThat(body).contains("remark=testing+void"); - } - - private void enqueueRegisterResponse() { - enqueueJsonResponse("{" + - "\"secret\":\"plain-secret\"," + - "\"spk\":\"" + serverPublicKeyBase64 + "\"}"); - } - - private void enqueueApplyTokenResponse() { - enqueueJsonResponse("{\"token\":\"token-123\",\"expire\":3600}"); - } - - private void enqueueJsonResponse(String body) { - mockWebServer.enqueue(new MockResponse() - .setHeader("Content-Type", "application/json") - .setBody(body)); - } - - private IWorkWorkflowCreateReqVO buildCreateRequest() { - IWorkFormFieldVO field1 = new IWorkFormFieldVO(); - field1.setFieldName("sqr"); - field1.setFieldValue("张三"); - - IWorkFormFieldVO field2 = new IWorkFormFieldVO(); - field2.setFieldName("sqrq"); - field2.setFieldValue("2023-11-02"); - - IWorkDetailRecordVO detailRecord = new IWorkDetailRecordVO(); - detailRecord.setRecordOrder(0); - IWorkFormFieldVO detailField = new IWorkFormFieldVO(); - detailField.setFieldName("ddh"); - detailField.setFieldValue("100010"); - detailRecord.setFields(List.of(detailField)); - - IWorkDetailTableVO detailTable = new IWorkDetailTableVO(); - detailTable.setTableDBName("formtable_main_26_dt1"); - detailTable.setRecords(List.of(detailRecord)); - - IWorkWorkflowCreateReqVO req = new IWorkWorkflowCreateReqVO(); - req.setRequestName("测试流程"); - req.setMainFields(List.of(field1, field2)); - req.setDetailTables(List.of(detailTable)); - req.setOtherParams(Map.of("isnextflow", "0")); - return req; - } - - private String decryptHeader(String headerValue) throws Exception { - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(Cipher.DECRYPT_MODE, serverKeyPair.getPrivate()); - byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(headerValue)); - return new String(decrypted, StandardCharsets.UTF_8); - } -} diff --git a/zt-module-system/zt-module-system-server/src/test/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkOrgRestServiceImplTest.java b/zt-module-system/zt-module-system-server/src/test/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkOrgRestServiceImplTest.java deleted file mode 100644 index f0c96f6d..00000000 --- a/zt-module-system/zt-module-system-server/src/test/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkOrgRestServiceImplTest.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.zt.plat.module.system.service.integration.iwork.impl; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkHrSubcompanyPageRespVO; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkHrSyncRespVO; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkOrgSyncReqVO; -import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkSubcompanyQueryReqVO; -import com.zt.plat.module.system.framework.integration.iwork.config.IWorkProperties; -import com.zt.plat.module.system.service.integration.iwork.IWorkOrgRestService; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.util.DigestUtils; - -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.time.Clock; -import java.time.Duration; -import java.time.Instant; -import java.time.ZoneOffset; -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; - -class IWorkOrgRestServiceImplTest { - - private MockWebServer mockWebServer; - private IWorkOrgRestService service; - private IWorkProperties properties; - private Clock fixedClock; - private ObjectMapper objectMapper; - - @BeforeEach - void setUp() throws Exception { - mockWebServer = new MockWebServer(); - mockWebServer.start(); - - properties = buildProperties(); - fixedClock = Clock.fixed(Instant.ofEpochMilli(1_672_531_200_000L), ZoneOffset.UTC); - objectMapper = new ObjectMapper(); - service = new IWorkOrgRestServiceImpl(properties, objectMapper, fixedClock); - } - - @AfterEach - void tearDown() throws Exception { - mockWebServer.shutdown(); - } - - @Test - void shouldListSubcompanies() throws Exception { - mockWebServer.enqueue(jsonResponse("{\"code\":\"1\",\"data\":{\"totalSize\":1,\"totalPage\":1,\"pageSize\":10,\"pageNumber\":1,\"dataList\":[{\"subcompanyid1\":4,\"subcompanyname\":\"总部\"}]}}")); - - IWorkSubcompanyQueryReqVO reqVO = new IWorkSubcompanyQueryReqVO(); - reqVO.setParams(Map.of("curpage", 1)); - IWorkHrSubcompanyPageRespVO respVO = service.listSubcompanies(reqVO); - - assertThat(respVO.isSuccess()).isTrue(); - assertThat(respVO.getTotalSize()).isEqualTo(1); - assertThat(respVO.getDataList()).hasSize(1); - assertThat(respVO.getDataList().get(0).getSubcompanyname()).isEqualTo("总部"); - - RecordedRequest request = mockWebServer.takeRequest(); - assertThat(request.getPath()).isEqualTo(properties.getOrg().getPaths().getSubcompanyPage()); - String decoded = URLDecoder.decode(request.getBody().readUtf8(), StandardCharsets.UTF_8); - JsonNode bodyNode = objectMapper.readTree(decoded); - assertThat(bodyNode.path("params").path("curpage").asInt()).isEqualTo(1); - JsonNode tokenNode = bodyNode.path("token"); - assertThat(tokenNode.path("ts").asText()).isEqualTo("1672531200000"); - String expectedKey = DigestUtils.md5DigestAsHex("test-seed1672531200000".getBytes(StandardCharsets.UTF_8)).toUpperCase(); - assertThat(tokenNode.path("key").asText()).isEqualTo(expectedKey); - } - - @Test - void shouldSyncDepartments() throws Exception { - mockWebServer.enqueue(jsonResponse("{\"code\":\"1\",\"result\":[{\"@action\":\"add\",\"code\":\"demo\",\"result\":\"success\"}]}")); - - IWorkOrgSyncReqVO reqVO = new IWorkOrgSyncReqVO(); - reqVO.setData(List.of(Map.of("@action", "add", "code", "demo"))); - IWorkHrSyncRespVO respVO = service.syncDepartments(reqVO); - - assertThat(respVO.isSuccess()).isTrue(); - assertThat(respVO.getResult()).hasSize(1); - assertThat(respVO.getResult().get(0).getCode()).isEqualTo("demo"); - - RecordedRequest request = mockWebServer.takeRequest(); - assertThat(request.getPath()).isEqualTo(properties.getOrg().getPaths().getSyncDepartment()); - String decoded = URLDecoder.decode(request.getBody().readUtf8(), StandardCharsets.UTF_8); - JsonNode bodyNode = objectMapper.readTree(decoded); - assertThat(bodyNode.path("data").isArray()).isTrue(); - assertThat(bodyNode.path("data").get(0).path("code").asText()).isEqualTo("demo"); - } - - private MockResponse jsonResponse(String body) { - return new MockResponse() - .setHeader("Content-Type", "application/json") - .setBody(body); - } - - private IWorkProperties buildProperties() { - IWorkProperties properties = new IWorkProperties(); - properties.setBaseUrl(mockWebServer.url("/").toString()); - properties.getClient().setConnectTimeout(Duration.ofSeconds(5)); - properties.getClient().setResponseTimeout(Duration.ofSeconds(5)); - properties.getOrg().setTokenSeed("test-seed"); - IWorkProperties.OrgPaths paths = properties.getOrg().getPaths(); - paths.setSubcompanyPage("/api/hrm/resful/getHrmsubcompanyWithPage"); - paths.setDepartmentPage("/api/hrm/resful/getHrmdepartmentWithPage"); - paths.setJobTitlePage("/api/hrm/resful/getJobtitleInfoWithPage"); - paths.setUserPage("/api/hrm/resful/getHrmUserInfoWithPage"); - paths.setSyncSubcompany("/api/hrm/resful/synSubcompany"); - paths.setSyncDepartment("/api/hrm/resful/synDepartment"); - paths.setSyncJobTitle("/api/hrm/resful/synJobtitle"); - paths.setSyncUser("/api/hrm/resful/synHrmresource"); - return properties; - } -}