From 5753cb6fa828f92744f5b45e99fbf0ccbec6e215 Mon Sep 17 00:00:00 2001 From: chenyuan Date: Tue, 4 Aug 2026 14:20:39 +0800 Subject: [PATCH] docs: plan Chinese API message updates --- .../plans/2026-08-04-api-messages-encoding.md | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 docs/superpowers/plans/2026-08-04-api-messages-encoding.md diff --git a/docs/superpowers/plans/2026-08-04-api-messages-encoding.md b/docs/superpowers/plans/2026-08-04-api-messages-encoding.md new file mode 100644 index 0000000..a227885 --- /dev/null +++ b/docs/superpowers/plans/2026-08-04-api-messages-encoding.md @@ -0,0 +1,175 @@ +# 后端中文提示与 UTF-8 响应实施计划 + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 所有 API 对外提示使用中文,并以 UTF-8 JSON 返回,避免 Swagger 和前端出现乱码。 + +**Architecture:** 通过 `ApiResponse` 统一成功提示,通过 Spring Security 的异常写入器统一鉴权提示,通过业务服务中文化可回传的校验信息。应用配置与响应写入器共同确保 UTF-8;错误码保持不变。 + +**Tech Stack:** Java 8、Spring Boot 2.7、Spring Security、Springdoc OpenAPI、JUnit 5、MockMvc。 + +## Global Constraints + +- 保持现有 `ErrorCode` 枚举值不变。 +- 所有面向前端的 `message` 必须为中文。 +- JSON 响应必须使用 UTF-8。 +- 保留业务校验的具体中文原因;框架参数校验使用统一中文提示。 + +--- + +### Task 1: 统一响应和安全异常提示 + +**Files:** +- Modify: `src/main/java/com/yau/digitalrmb/shared/api/ApiResponse.java` +- Modify: `src/main/java/com/yau/digitalrmb/security/config/SecurityConfig.java` +- Modify: `src/main/resources/application.yml` +- Test: `src/test/java/com/yau/digitalrmb/security/SecurityConfigTest.java` + +**Interfaces:** +- Produces: 成功响应的 `message` 为“操作成功”;401、403 响应分别为“未登录或登录已失效”“无访问权限”。 +- Produces: 安全异常响应头为 `application/json;charset=UTF-8`。 + +- [ ] **Step 1: 写失败测试** + +```java +mockMvc.perform(get("/api/v1/commercial-banks/issuance/inventory")) + .andExpect(status().isUnauthorized()) + .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect(content().encoding(StandardCharsets.UTF_8)) + .andExpect(jsonPath("$.message").value("未登录或登录已失效")); +``` + +- [ ] **Step 2: 运行失败测试** + +Run: `mvn -B -Dtest=SecurityConfigTest test` + +Expected: FAIL,当前消息为 `UNAUTHORIZED` 或响应编码不是 UTF-8。 + +- [ ] **Step 3: 最小实现** + +```java +response.setContentType(MediaType.APPLICATION_JSON_VALUE); +response.setCharacterEncoding(StandardCharsets.UTF_8.name()); +response.getWriter().write(... "未登录或登录已失效" ...); +``` + +并将 `ApiResponse.success` 的消息改为“操作成功”,在 `application.yml` 添加: + +```yaml +server: + servlet: + encoding: + charset: UTF-8 + enabled: true + force: true +``` + +- [ ] **Step 4: 运行测试验证通过** + +Run: `mvn -B -Dtest=SecurityConfigTest test` + +Expected: PASS。 + +- [ ] **Step 5: 提交** + +```bash +git add src/main/java/com/yau/digitalrmb/shared/api/ApiResponse.java src/main/java/com/yau/digitalrmb/security/config/SecurityConfig.java src/main/resources/application.yml src/test/java/com/yau/digitalrmb/security/SecurityConfigTest.java +git commit -m "fix: return Chinese security messages in UTF-8" +``` + +### Task 2: 中文化发行模块对外业务提示 + +**Files:** +- Modify: `src/main/java/com/yau/digitalrmb/issuance/application/service/DenominationPlanService.java` +- Modify: `src/main/java/com/yau/digitalrmb/issuance/application/service/CommercialBankIssuanceApplicationService.java` +- Modify: `src/main/java/com/yau/digitalrmb/issuance/application/service/CentralBankIssuanceQueryService.java` +- Modify: `src/main/java/com/yau/digitalrmb/issuance/interfaces/rest/CommercialBankIssuanceController.java` +- Modify: `src/main/java/com/yau/digitalrmb/security/interfaces/AuthController.java` +- Test: `src/test/java/com/yau/digitalrmb/issuance/interfaces/rest/IssuanceControllerTest.java` + +**Interfaces:** +- Produces: 面额总额不一致时 `VALIDATION_ERROR` 消息为“各面额小计之和必须等于申请总金额”。 +- Produces: 当前用户审计声明缺失或非法时返回中文未授权提示。 + +- [ ] **Step 1: 写失败测试** + +```java +mockMvc.perform(post("/api/v1/commercial-banks/issuance/denomination-plan/validate") + .with(issuanceJwt()).contentType(MediaType.APPLICATION_JSON) + .content(invalidPlanJson)) + .andExpect(jsonPath("$.code").value("VALIDATION_ERROR")) + .andExpect(jsonPath("$.message").value("各面额小计之和必须等于申请总金额")); +``` + +- [ ] **Step 2: 运行失败测试** + +Run: `mvn -B -Dtest=IssuanceControllerTest test` + +Expected: FAIL,当前消息为 `denomination total must equal totalAmount`。 + +- [ ] **Step 3: 最小实现** + +将所有会经 `BusinessException` 或校验转换返回前端的英文文本替换为对应中文,包括申请不存在、申请 ID 为空、库存配置不存在、JWT 缺失 `userId` 或 `preferred_username`、金额和面额规则。 + +- [ ] **Step 4: 运行测试验证通过** + +Run: `mvn -B -Dtest=IssuanceControllerTest test` + +Expected: PASS。 + +- [ ] **Step 5: 提交** + +```bash +git add src/main/java/com/yau/digitalrmb/issuance src/main/java/com/yau/digitalrmb/security/interfaces/AuthController.java src/test/java/com/yau/digitalrmb/issuance/interfaces/rest/IssuanceControllerTest.java +git commit -m "fix: translate issuance API messages to Chinese" +``` + +### Task 3: 统一全局校验和验证 + +**Files:** +- Modify: `src/main/java/com/yau/digitalrmb/shared/web/GlobalExceptionHandler.java` +- Modify: `src/main/java/com/yau/digitalrmb/platformintegration/application/PlatformTokenVerifier.java` +- Test: `src/test/java/com/yau/digitalrmb/shared/GlobalExceptionHandlerTest.java` + +**Interfaces:** +- Produces: 框架参数校验统一返回“请求参数校验失败”。 +- Produces: 无效平台令牌返回“平台登录凭据无效”。 + +- [ ] **Step 1: 写失败测试** + +```java +mockMvc.perform(post("/api/v1/auth/login").contentType(MediaType.APPLICATION_JSON).content("{}")) + .andExpect(jsonPath("$.code").value("VALIDATION_ERROR")) + .andExpect(jsonPath("$.message").value("请求参数校验失败")); +``` + +- [ ] **Step 2: 运行失败测试** + +Run: `mvn -B -Dtest=GlobalExceptionHandlerTest test` + +Expected: FAIL,当前返回框架英文校验文本。 + +- [ ] **Step 3: 最小实现** + +```java +return ApiResponse.failure(ErrorCode.VALIDATION_ERROR, "请求参数校验失败", traceId()); +``` + +并把平台令牌异常内部消息改为中文,避免任何异常链的英文文本进入 API 响应。 + +- [ ] **Step 4: 执行完整验证** + +Run: `mvn -B test` + +Expected: 全部测试通过;新增中文/UTF-8 断言通过。 + +- [ ] **Step 5: 重启与人工验证** + +Run: `mvn -B package -DskipTests`,重启本地 `8081` 后端;在 Swagger 调用面额校验接口,确认响应体中文且响应头为 UTF-8。 + +- [ ] **Step 6: 提交** + +```bash +git add src/main/java/com/yau/digitalrmb/shared/web/GlobalExceptionHandler.java src/main/java/com/yau/digitalrmb/platformintegration/application/PlatformTokenVerifier.java src/test/java/com/yau/digitalrmb/shared/GlobalExceptionHandlerTest.java +git commit -m "fix: standardize Chinese validation messages" +```