时间:2026-10-17 进度:151 个接口已全部实现,剩余 0(
tools/check_progress.py复核:PHP 151 / Java 151 / 待实现 0) 验证:读接口 26/26 零差异、写接口 21/21 断言全通过;订单 10/10、设置 13/13、营销 6/6 回归全 PASS
| 分组 | 接口 | 方法 | 说明 |
|---|---|---|---|
| 客户端设置 | /store/client.h5.setting/detail |
GET/POST | resetOptions 合并默认,未知 key 返回 [] |
/store/client.h5.setting/update |
POST | 先 update 后 insert(有则改、无则插) | |
/store/client.wxapp.setting/detail |
GET/POST | 额外返回 domain(去端口) |
|
/store/client.wxapp.setting/update |
POST | 仅落库 4 个白名单字段 | |
| 商品评论 | /store/goods.comment/list |
GET/POST | join 商品/订单子查询,page 15 |
/store/goods.comment/detail |
GET/POST | 含 images / imageIds / imageList | |
/store/goods.comment/edit |
POST | 先删后插 comment_image,同步 is_picture | |
/store/goods.comment/delete |
POST | 软删除 | |
| 订单导出 | /store/order.export/list |
GET/POST | 导出记录分页 |
/store/order.export/exportOrder |
GET/POST | 生成 xlsx + 落导出记录(兼容 export_order) |
|
| 统计 | /store/statistics.data/data |
GET/POST | overview + tradeTrend + goodsRanking + userExpendRanking |
/store/statistics.data/survey |
GET/POST | 6 项指标,支持起止时间 | |
/store/statistics.data/initialize |
GET/POST | 空响应体(void) | |
| 其他 | /store/controller/initialize |
GET/POST | 空响应体(void) |
/store/order.event/printer |
POST | 小票打印(飞鹅 / 365 两种驱动) |
实体:CommentImage(新增);Comment 补 user/orderGoods/imageIds/imageList/images;
H5Setting、WxappSetting、OrderExport(新增,主键与保留字列均加反引号映射)。
Mapper:CommentImageMapper、H5SettingMapper、WxappSettingMapper、OrderExportMapper(新增);
OrderGoodsMapper 新增 goodsRanking()(销量 Top10,@Select 手写 SQL)。
服务:CommentService、ClientSettingService、StatisticsService、OrderExportService、PrinterService(新增)。
控制器:GoodsCommentController、ClientH5SettingController、ClientWxappSettingController、
StatisticsController、StoreBaseController、OrderExportController(新增);OrderEventController 增 printer。
改造:OrderService 抽出 buildQuery,新增 listAll(导出不分页)与 findAssembled(打印);
BizException 增 silent 工厂 + GlobalExceptionHandler 对应分支;
WebMvcConfig 加 /downloads/** 静态映射与 yoshop.export-path;pom.xml 加 poi-ooxml 5.4.1。
工具脚本:seed_comment_golden.py(评论种子,支持 --cleanup)、
compare_final_batch.py(26 读用例)、test_final_writes.py(21 写断言,含 Excel 逐格对比)。
读接口 compare_final_batch.py:26/26 PASS
| 分组 | 用例数 | 覆盖 |
|---|---|---|
| 评论列表 | 11 | 无参 / 分页 / goodsId / orderNo / userId / status / score / 组合 / 空结果 |
| 评论详情 | 4 | 正常 / 含图 / 软删除记录 / 不存在报错 |
| H5 设置 | 2 | 默认合并 / 未知 key |
| 小程序设置 | 2 | 含 domain / 默认值 |
| 导出列表 | 1 | 分页结构 |
| 统计 | 4 | data / survey 无参 / 带区间 / 反向区间 |
| initialize | 2 | 两个接口空响应体 |
写接口 test_final_writes.py:21/21 PASS(PHP 跑 → 采样 → 复位 → Java 跑 → 采样 → 对照)
is_picture 由 1 → 0;is_delete=1,列表与详情同步消失;Call to a member function edit() on null / setDelete() on null;start_time/end_time 落库一致、文件名时间戳归一化后一致;回归(本地 PHP 源):订单 10/10、设置 13/13、营销 6/6,全部 PASS。
renderError 与 throwError 的 data 结构不同:打印失败走 renderError,PHP 返回
{"status":500,"message":"...","data":[]};而多数业务异常走 throwError,data 是 {"isPrompt":true}。
Java 侧新增 BizException.silent()(不置 prompt 标志)+ 全局处理器分支返回 new Object[0],
否则前端 data.isPrompt 判断会走错分支。consumeUsers 的 PHP 是 group('user_id')->count()——分组行数,
不是 count(*) 也不是 count(user_id),等价 SQL 是 count(distinct user_id);
计数类走 number_format(千分位字符串),金额类走 helper::number2(两位小数),
两者都是字符串出参,不是数字。Export::dictionary() 用 LinkedHashMap 语义,
Excel 列顺序必须与字典顺序一致(28 列),不能按实体字段顺序生成。
单元格值一律 \t值\t 包裹,金额加「元」,商品明细是「1.商品名称:…\n 商品规格:g: v; \n…」的多行模板,
是全角空格——这些细节逐字节影响 Excel 对比。json_encode 字节:PHP 默认转义 / 与非 ASCII(\uXXXX)。
通用 Jackson 配置产出的 JSON 字节不同,虽然语义一样但会导致「落库不一致」。
已建专用 PHP_JSON(ESCAPE_NON_ASCII)+ .replace("/", "\\/"),实测字节完全一致。domain 去端口:PHP $request->host(true) 第二参为 true 时不带端口;
Java getServerName() 也不带端口,但为兼容反向代理场景仍统一 replaceAll(":\\d+$", "")。detail 传未知 key 时 PHP 走 resetOptions 后返回空数组 [](不报错);
而 update 里取 describe[$key] 会抛 Undefined array key。两处分支不能合并。$result['msg'] ?: '操作失败',业务失败也返回 200 之外的 status=500,
但 message 用驱动原文。Java 侧 BizException.silent(error != null ? error : "操作失败") 复刻。| 指标 | 数值 |
|---|---|
| PHP 接口总数(store 模块) | 151 |
| Java 已实现 | 151(100%) |
| 控制器 | 43 个 |
| 服务 | 30 个 |
| 读接口双跑对比 | 累计 26 + 60 + 13 + 10 + 7 + 6 ≈ 122 项,0 差异 |
| 写接口断言 | 累计 21 + 118 + 66 + 77 + 42 + 62 + 38 + 24 ≈ 448 项,全通过 |
自动化脚本(tools/):check_progress.py 盘点进度、compare_*.py 双跑对比、
test_*_writes.py 写接口对照、seed_*_golden.py 造数、backup_*.py 测试前备份。
checkPrivilege 角色权限校验——当前所有 store 接口只校验登录态(token),未按
yoshop_store_role_menu 做接口级鉴权,这是切流前的第一优先级;OrderDeliveryService 内留空);yoshop_order 10099(TESTORDER10099)、yoshop_printer 10001、
yoshop_comment 10001–10004 及 yoshop_comment_image 3 条、yoshop_order_export 3 条;
复核:订单表回到原始 2 条(10001/10002),其余 4 张表归零。F:/shop/shop/public/downloads/10001/*.xlsx、yoshop-java/runtime/downloads/10001/*.xlsx。F:/shop/shop/.env 已按原字节还原(备份 /tmp/yoshop_env_backup.txt,即 localhost/test)。C:/Users/Administrator/AppData/Local/Temp/php82/,需要再跑双端对比时可直接复用。mvn -q -o -DskipTests spring-boot:run -Dspring-boot.run.arguments="--server.port=18080 --yoshop.auth.mode=file --yoshop.auth.runtime-cache-path=<...>/runtime/cache"。