|
@@ -122,3 +122,97 @@
|
|
|
`BusinessException` **不带 `@ResponseStatus`**(HTTP 200 + body `code`),顾客页自建实例
|
|
`BusinessException` **不带 `@ResponseStatus`**(HTTP 200 + body `code`),顾客页自建实例
|
|
|
读的是 `res.data.msg`;如果哪天有人把它改成真 4xx/5xx,顾客页会 fallback 成
|
|
读的是 `res.data.msg`;如果哪天有人把它改成真 4xx/5xx,顾客页会 fallback 成
|
|
|
「网络异常,请检查网络后重试」,那句「你所在地区未开通」就再也到不了顾客眼前。
|
|
「网络异常,请检查网络后重试」,那句「你所在地区未开通」就再也到不了顾客眼前。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 六、2026-10-09 追加:开放 API 下单直传地区码(★ 本节产物指纹取代 §二 的,旧件别再用)
|
|
|
|
|
+
|
|
|
|
|
+**需求(用户原文)**:「还有个点做了没?har的下单开放api,我看文档中没有让调用方传用户ip」
|
|
|
|
|
+→ 定案:「要么让调用方传用户地区也可以,省的我们解析了」→ 硬性要求:
|
|
|
|
|
+「那就传地区,但是要在开放文档里写清楚地区的格式,要按照我们接收的格式来,
|
|
|
|
|
+不然找不到门店就麻烦了」。
|
|
|
|
|
+
|
|
|
|
|
+**为什么不能按 IP**:openapi 是服务器对服务器调用,请求 IP 是**调用方机房**的,不是顾客的
|
|
|
|
|
+(只有收款链接那条腿能按 IP —— 顾客浏览器直连)。所以本次让调用方直传 **GB/T 2260 省市码**
|
|
|
|
|
+(不传 IP、平台不解析)。
|
|
|
|
|
+
|
|
|
|
|
+### 行为口径(实现前已与你确认,未改)
|
|
|
|
|
+
|
|
|
|
|
+1. 显式 `shop_code` / `third_shop_code` 优先,两个地区字段被忽略(现状不变);
|
|
|
|
|
+2. 都没给而给了任一地区码 ⇒ 平台按该地区挑一家,填进 `third_shop_code`
|
|
|
|
|
+ (**实体与上游请求两处**),响应回显挑中的那家;
|
|
|
|
|
+3. 市码选填:不给按全省挑;给了但**市内无可用店回退全省**(与收款链接腿同一步梯);
|
|
|
|
|
+4. **全省无可用店 ⇒ 400 拒收**,先于落库与上游(不留单、不打上游、不发订单信号)——
|
|
|
|
|
+ 相对「静默退回不带门店下单」,后者等于调用方明确要求的地区归属悄悄落空;
|
|
|
|
|
+5. 只给 `city_code` 不给 `province_code` ⇒ 400(省码是地区定位的根);
|
|
|
|
|
+6. 同地区多店的稳定散列种子 = **`out_biz_no`**(同一 `out_biz_no` 重复调用挑到同一家)。
|
|
|
|
|
+
|
|
|
|
|
+### 提交(现量:`origin/java` 停在 `f09e9cce`;本地领先 **3** 个 —— 含本批之前的测试夹具刀 `2717f793`)
|
|
|
|
|
+
|
|
|
|
|
+| 提交 | 内容 |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| `cb153add` | 后端:DTO 两个选填字段;`HarShopService#pickForOrder`(校验 + 挑店 + 三种 400,抽出 `requireKnownProvince` 与建店共用同一句文案);`HarOrderService#create` 接线(挑店块 + builder 带 `thirdShopCode`);新契约测试类 `HarOrderCreateJsonContractTest` |
|
|
|
|
|
+| `fcf026c7` | 开放文档 `har-openapi.md` 10.2:字段两行 + 挑店说明块(**格式按接收口径逐字**)+ 响应表 `third_shop_code` 语义订正 + 章首补句 |
|
|
|
|
|
+
|
|
|
|
|
+### 验证读数(本机实测)
|
|
|
|
|
+
|
|
|
|
|
+- **RED**(先写测试,`logs/_tdd-region-red-1.txt`):三个测试文件红于编译错 ——
|
|
|
|
|
+ `pickForOrder` 不存在(8 处)、`setProvinceCode`/`setCityCode` 不存在、
|
|
|
|
|
+ `HarOrderService` 期望 4 参实到 5 参。原因全部是「功能不存在」,无笔误。
|
|
|
|
|
+- **GREEN 聚焦**(`logs/_tdd-region-green-1.txt`):**86/0/0/0** =
|
|
|
|
|
+ 挑店 22(13→22)+ 下单 61(54→61)+ 新契约 3。
|
|
|
|
|
+- **变异两向**(5 个真实变异 + 1 个无害改动,全部先确认变异体生效、还原后逐字节回基线):
|
|
|
|
|
+
|
|
|
|
|
+ | 变异体 | 红集(预测=实测) |
|
|
|
|
|
+ |---|---|
|
|
|
|
|
+ | 城市码整个忽略 | 4 红(cityTier 挑成 SZ + 三条 400 文案/校验),82 对照绿 |
|
|
|
|
|
+ | 显式门店码优先失效 | 2 红(两个 explicit 用例 NPE),84 对照绿 |
|
|
|
|
|
+ | 挑不出来不拒收 | 3 红(三条 400 守卫,none thrown),83 对照绿 |
|
|
|
|
|
+ | 散列种子换成 enterpriseId | 4 红(四条钉了精确种子的 create 用例),82 对照绿 |
|
|
|
|
|
+ | 上游发 dto 的而不是挑中的 | 1 红(「挑中的店必须真的发到上游」NJ→null),85 对照绿 |
|
|
|
|
|
+ | 无害重构(守卫提局部变量) | 全绿 86/86 ✓ |
|
|
|
|
|
+
|
|
|
|
|
+ 还原复核:`HarShopService` `6341E642…`、`HarOrderService` `41745D49…`、
|
|
|
|
|
+ `HarOrderCreateDTO` `40165A56…`(与变异前一致)。
|
|
|
|
|
+- **整包**:**1232 条,0 失败 0 错误 0 跳过,BUILD SUCCESS**,32.298s
|
|
|
|
|
+ (`logs/_mvn-full-region-order.txt`;1232 = 上一批 1213 + 本批 19)。
|
|
|
|
|
+- **产物**(★ 取代 §二 的指纹;旧 jar `b6b64c8a…` / 旧 dist `80038a66…` 作废):
|
|
|
|
|
+ - `java/target/payment-platform-1.0.0.jar`,143,147,907 字节,12:13:28,
|
|
|
|
|
+ sha256 `2F51689B49F8B51D5B890973BEDDF30557A553AD04CA732DA5D5BC2B772133D5`。
|
|
|
|
|
+ 开包回读(`logs/_jar-readback-region-order.py`,只读 jar 里的 .class 常量池):
|
|
|
|
|
+ `pickForOrder`、`requireKnownProvince`、四条 400 文案前缀、
|
|
|
|
|
+ DTO 的 `provinceCode/cityCode/getProvinceCode/setCityCode` 全为 True。
|
|
|
|
|
+ - `frontend/dist.zip`,9,376,009 字节,12:15:03,
|
|
|
|
|
+ sha256 `3cbbdfffae3d6638fc662af1985173b685aafa928caa10c3ea2c4796d0c247b6`。
|
|
|
|
|
+ 281 条目 = 277 文件 + 4 目录条目(与上一版**同形**)、**全正斜杠**、`testzip()` 无坏成员;
|
|
|
|
|
+ 新文档句(「按地区自动挑店」「就必须一并传 province_code」「该地区没有可用门店」)
|
|
|
|
|
+ **只**出现在 `dist/js/index.BRvi1q4X.js` —— 构建产物回读,zip 内也回读到同一文件
|
|
|
|
|
+ (`logs/_dist-zip-region-order.py`)。
|
|
|
|
|
+- **ts:check 没重跑**:本批只动 md(文档经 `?raw` 导入、类型恒为 string),未新增前端代码 ——
|
|
|
|
|
+ 与上批「md 改动不进类型检查」的同一条实测口径。
|
|
|
|
|
+
|
|
|
|
|
+### 开放文档写了什么(你点名要的「格式」)
|
|
|
|
|
+
|
|
|
|
|
+10.2 请求表加 `province_code`/`city_code` 两行,其后一块说明写死:**与 10.1 建店 GB/T 2260
|
|
|
|
|
+同一套码**(省级两位、地级四位);**传代码不是地名**;`city_code` 必须属于 `province_code`;
|
|
|
|
|
+**只在没传任何门店码时生效**;先同市、市无店回退全省;同地区多店按 `out_biz_no` 稳定;
|
|
|
|
|
+挑中回显在响应 `third_shop_code`;三种 400 文案逐字(`省份编码不存在: 99` /
|
|
|
|
|
+`城市编码不属于该省: 3301(省 32)` / `省份编码不能为空: 传了 city_code 就必须一并传 province_code` /
|
|
|
|
|
+`该地区没有可用门店: 省 32`(带市码时 `该地区没有可用门店: 3201(省 32)`))——
|
|
|
|
|
+**这四个字符串与测试里钉的完全同一批**,文档不是手抄的。
|
|
|
|
|
+
|
|
|
|
|
+### 部署(与 §三 同序,换新 jar/dist 即可)
|
|
|
|
|
+
|
|
|
|
|
+1. 先跑 `db/har-shop-region.sql`(若尚未跑;跑过就不必重复);
|
|
|
|
|
+2. 换 `2F51689B…` 的 jar + `3cbbdfff…` 的 dist.zip;
|
|
|
|
|
+3. 无需新菜单 SQL、无需重登。
|
|
|
|
|
+
|
|
|
|
|
+### 悬置/未验(如实)
|
|
|
|
|
+
|
|
|
|
|
+1. **收银台腿(`HarCashierService#createQr`)不带门店码,本批未动** —— 它要不要一并接
|
|
|
|
|
+ 「地区」或「挑店」,待你拍板(现状=不带,不是回归)。
|
|
|
|
|
+2. **「全省无店 ⇒ 400 拒收」按已批准设计执行**(未再单独确认过,若你要改成「允许不带门店
|
|
|
|
|
+ 直接下单」请说)。
|
|
|
|
|
+3. 挑店在**真实调用方**下的表现未端到端跑过(开放 API 需要一条真签名请求);本次只到
|
|
|
|
|
+ 「单元 + 契约 + 产物回读」这一层。
|
|
|
|
|
+4. `pay_url` 真机扫码仍未做过(老账,与 §四.2 相同)。
|