feat(framework): 全局 Long 字符串化,ID 一律以字符串下发

用户裁定方案 (a):雪花 id 精度问题全局修,统一契约。

- 新增 JacksonLongToStringConfig(fruitshorts-framework):Long/Long.TYPE → ToStringSerializer,
  经 Jackson2ObjectMapperBuilderCustomizer 挂进 Spring Boot 的 ObjectMapper;admin-api 与
  app-api 都是 scanBasePackages=com.fruitshorts,一处生效两端一致
- 例外:PageResult.total 是计数不是 id,用 mixin 显式保持数字(前端分页组件要数字);
  Integer/int(pageIndex/pageSize/Result.code 等)不受影响
- 反序列化方向不变:请求体 'id:123'、路径变量、查询参数都接受字符串
- 契约 api-phase1.md §0 新增「ID 字段一律以字符串下发」总口径,§2.11/§2.12 改为引用 §0;
  I1 里逐字段加的 @JsonSerialize 与 Result<String> 回退成自然写法,避免多套口径
- 测试:新增 LongToStringSerializationTest(普通/嵌套/List/Map/分页 + 反序列化 + 19 位路径变量),
  契约测试的 standalone mapper 也挂上模块(否则测试假绿);C 端 4 条 id 断言改成 isString
- mvn test:commerce 33 / admin-api 21 / app-api 49 / worker 12 = 115 条全过
This commit is contained in:
jianghaifeng committed 2026-10-16 16:44:13 +08:00
1 parent c503629bf9
commit f35db2cd3b
16 files changed
+355 -33

No files matched your search

@@ -53,13 +53,12 @@ public class NoticeAdminController {
return Result.ok(opsNoticeService.detail(id));
}
@Operation(summary = "新建公告(默认发布,C 端立即可见;返回新公告 id,字符串)")
@Operation(summary = "新建公告(默认发布,C 端立即可见;返回新公告 id,按 §0 以字符串下发)")
@PostMapping
@PreAuthorize("@ss.hasPermission('notice:update')")
@OperationLog(module = "系统公告", action = "新建公告")
public Result<String> create(@Valid @RequestBody NoticeSaveReqVO req) {
// 雪花 id 用字符串回,避免前端拿到被四舍五入的 id
return Result.ok(String.valueOf(opsNoticeService.create(req)));
public Result<Long> create(@Valid @RequestBody NoticeSaveReqVO req) {
return Result.ok(opsNoticeService.create(req));
}
@Operation(summary = "编辑公告")
@@ -53,13 +53,12 @@ public class ProductAdminController {
return Result.ok(productService.detail(id));
}
@Operation(summary = "新建商品(默认下架,需显式上架;返回新商品 id,字符串)")
@Operation(summary = "新建商品(默认下架,需显式上架;返回新商品 id,按 §0 以字符串下发)")
@PostMapping
@PreAuthorize("@ss.hasPermission('product:update')")
@OperationLog(module = "商品配置", action = "新建商品")
public Result<String> create(@Valid @RequestBody ProductSaveReqVO req) {
// 雪花 id 用字符串回,避免前端拿到被四舍五入的 id
return Result.ok(String.valueOf(productService.create(req)));
public Result<Long> create(@Valid @RequestBody ProductSaveReqVO req) {
return Result.ok(productService.create(req));
}
@Operation(summary = "编辑商品")