接口实现进度-第8批.md 8.9 KB

第 8 批接口实现进度:客户端设置、评论、导出、统计与打印(15 个,收官)

时间: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

一、本批 15 个接口

分组 接口 方法 说明
客户端设置 /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 跑 → 采样 → 对照)

  • 评论编辑:改分数/内容/状态/排序 + 换图(先删后插,comment_image 行 id 递增但内容一致);
  • 评论清空图片:is_picture 由 1 → 0;
  • 评论软删除:is_delete=1,列表与详情同步消失;
  • 缺失记录报错文案:Call to a member function edit() on null / setDelete() on null;
  • H5 设置:首次新增 + 二次覆盖,库内 JSON 字节完全一致;
  • 小程序设置:4 字段白名单落库一致(多余字段被丢弃);
  • 订单导出:Excel 单元格逐格完全一致(28 列 × N 行,含商品明细多行文本与「元」后缀);
  • 导出 betweenTime:start_time/end_time 落库一致、文件名时间戳归一化后一致;
  • 打印:打印机不存在、驱动调用失败(真实请求飞鹅接口返回「参数错误 : 该帐号未注册.」)两端一致。

回归(本地 PHP 源):订单 10/10、设置 13/13、营销 6/6,全部 PASS。

四、七个关键对齐点

  1. renderError 与 throwError 的 data 结构不同:打印失败走 renderError,PHP 返回 {"status":500,"message":"...","data":[]};而多数业务异常走 throwError,data 是 {"isPrompt":true}。 Java 侧新增 BizException.silent()(不置 prompt 标志)+ 全局处理器分支返回 new Object[0], 否则前端 data.isPrompt 判断会走错分支。
  2. 统计口径三处易错:consumeUsers 的 PHP 是 group('user_id')->count()——分组行数, 不是 count(*) 也不是 count(user_id),等价 SQL 是 count(distinct user_id); 计数类走 number_format(千分位字符串),金额类走 helper::number2(两位小数), 两者都是字符串出参,不是数字。
  3. 导出字典即列序:PHP Export::dictionary() 用 LinkedHashMap 语义, Excel 列顺序必须与字典顺序一致(28 列),不能按实体字段顺序生成。 单元格值一律 \t值\t 包裹,金额加「元」,商品明细是「1.商品名称:…\n 商品规格:g: v; \n…」的多行模板,   是全角空格——这些细节逐字节影响 Excel 对比。
  4. H5/小程序设置落库要复刻 PHP json_encode 字节:PHP 默认转义 / 与非 ASCII(\uXXXX)。 通用 Jackson 配置产出的 JSON 字节不同,虽然语义一样但会导致「落库不一致」。 已建专用 PHP_JSON(ESCAPE_NON_ASCII)+ .replace("/", "\\/"),实测字节完全一致。
  5. 小程序 domain 去端口:PHP $request->host(true) 第二参为 true 时不带端口; Java getServerName() 也不带端口,但为兼容反向代理场景仍统一 replaceAll(":\\d+$", "")。
  6. 未知 setting key 的两种行为:detail 传未知 key 时 PHP 走 resetOptions 后返回空数组 [](不报错); 而 update 里取 describe[$key] 会抛 Undefined array key。两处分支不能合并。
  7. 打印驱动的错误透传:PHP 是 $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 测试前备份。

六、仍未接入的能力(切流前必须补)

  1. checkPrivilege 角色权限校验——当前所有 store 接口只校验登录态(token),未按 yoshop_store_role_menu 做接口级鉴权,这是切流前的第一优先级;
  2. 微信小程序发货信息上报(OrderDeliveryService 内留空);
  3. 第三方支付(微信/支付宝)退款接口调用;
  4. 阿里云物流轨迹驱动(当前只落库物流单号,不拉轨迹);
  5. 微信支付 V3 平台证书自动下载(现依赖手工放置证书)。

七、测试数据清理与环境还原

  • 删除 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)。
  • 本地 PHP 站点(127.0.0.1:8899,PHP 8.2 便携包)已关闭;PHP 8.2 目录保留在 C:/Users/Administrator/AppData/Local/Temp/php82/,需要再跑双端对比时可直接复用。
  • Java 服务(18080)启动命令保持不变: 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"。