Bläddra i källkod

docs(交付): 收款链接 + 自助收银台 交付说明 —— 用户侧四步动作与八条未验项

alphaH 2 veckor sedan
förälder
incheckning
377008d104
1 ändrade filer med 78 tillägg och 0 borttagningar
  1. 78 0
      .claude/plan/2026-09-30-lsy-checkout-link-交付说明.md

+ 78 - 0
.claude/plan/2026-09-30-lsy-checkout-link-交付说明.md

@@ -0,0 +1,78 @@
+# 乐收赢「收款链接 + 自助收银台」交付说明(2026-09-30)
+
+计划:`.claude/plan/2026-09-30-lsy-checkout-link.md`(同批入库)
+
+需求原文(用户 2026-09-30,两句话定的范围):
+①「lsy渠道的主扫是一码一收,做不了静态码,我们自己要做一个checkout,主扫api提供的将是一个https链接,
+ 这个链接就与该商户绑定,链接可以无限次使用,这个链接打开的就是我们的checkout,用户自己在checkout
+ 输入金额然后拉起实际支付」
+②「checkout链接获取的按钮可以做到系统页面上,顺便封装成二维码,链接和二维码都可以拿走直接用」
+
+## 一、提交清单(5 个,均**未 push**)
+
+| 提交 | 内容 |
+|---|---|
+| `87536f0c` | 后端:建表 SQL(只写不执行)、`LsyCheckoutLinkService`、免登录两个端点、管理端与开放 API 两条发链接的腿 |
+| `6c663b97` | 前端顾客页 `/#/checkout/:token` + 免登录判据(`permission.ts`)+ 静态路由 |
+| `e6035c06` | 商户页操作列「收款链接」按钮 + 二维码 + 复制 / 下载 PNG |
+| `3c47de8c` | 接入文档 §5.8 + 侧边栏条目(含 §1 接口计数 10→11、§3.5 信封清单两处顺带订正) |
+| `1e925a21` | 实现计划(含**计划与落地的两处偏差**:axios 实例没单独成文件、弹窗没单独成组件) |
+
+## 二、验证读数(都是本机实测,不是推断)
+
+- `mvn test` 全量 **1007 条,0 失败 0 错误 0 跳过**(14:08)
+- 前端执行级验证台(真 SFC 编译 + 真 vue + 驱动真函数;本仓无测试框架、`ts:check` 有历史非零基线):
+  **65 条断言全绿**
+- 文档切片:**8 条断言全绿** —— 11 条侧边栏定义 == 11 条产出(一条都没静默消失)
+- `vue-tsc` 总量 **289 条**(与 09-28 基线同数);**本次碰过的 6 个前端文件在其中 0 命中**
+- 构建:`java/target/payment-platform-1.0.0.jar` 重打于 **14:08:42**(sha256 `1d0fca8d5b5f2815…`,
+  内含 9 个 checkout class 与 `db/lsy-checkout-link.sql`);`frontend/dist` 已重建
+  (§5.8 在 `js/index.CGO9EMvq.js`,顾客页在 `js/index.D8IdXt0n.js`)
+
+两向变异(每条都先验「变异体确实生效」,还原后逐文件 sha256 复核回基线):
+
+| 变异体 | 结果 |
+|---|---|
+| M1 元→分改回浮点乘法 | 红 6(**拒绝类**向量与安全整数守卫;≤2 位小数的合法输入两种写法同值 —— 不能说成「浮点会算错钱」) |
+| M2 下限改 1 分 | 红 3 |
+| M3 免登录判定挪进已登录分支 | 红 1(未登录那条) |
+| M3b 免登录判定挪到 try 末尾 | 红 3,读数 `next` 被调**两次**:先 `/login?redirect=%2Fcheckout%2F%3Atoken` |
+| M4 无害改名(两个文件) | **仍绿 65/65** |
+| M5 二维码只编码 token 而非整条 url | 红 1 |
+| M6 路由 `name` 改名 | 红 6 |
+
+## 三、部署要求(按顺序,第 1 步不做就没有后面)
+
+1. **先执行建表 SQL**:`java/src/main/resources/db/lsy-checkout-link.sql`。
+   本工程未接 Flyway,脚本由人工执行;**只能由你执行**。
+   ★ 这张表**原先不存在** ⇒ 不建表就部署,管理端按钮、开放 API 那条腿、顾客页开屏
+   三处**全部** 500/404。
+2. **重新部署**:`java/target/payment-platform-1.0.0.jar` + `frontend/dist`(两者都已就绪)。
+3. **重新登录**(权限串复用商户 `:list`,**没有菜单 SQL 要跑**,菜单也不变)。
+4. 验收路径:乐收赢商户页 → 操作列「收款链接」→ 弹窗里「复制链接」/「下载二维码」
+   → 手机打开那条链接 → 输金额(≥1 元)→ 确认 → 应跳到支付宝收银台。
+
+**不需要改 `application.yml`。** `leshouying.checkout-base-url` 有代码默认值(留空 ⇒
+按请求头推导:`X-Forwarded-Proto` / `X-Forwarded-Host` / `Host`)。
+★ 但**基址取自调用方访问的域名**:如果后台是用 `IP:端口` 打开的,取到的链接就是那个地址、
+顾客打不开 —— 那种情况下要么把 `checkout-base-url` 配成公网域名,要么用公网域名访问后台。
+同一个商户,从管理端取到的链接与从开放 API 取到的链接,基址可能**不同**(同因)。
+
+## 四、未验证 / 未做(逐条,都是交付时的实测状态)
+
+1. **这条路一笔真钱都没收过。** 建表 SQL 未执行、未部署 ⇒ 顾客页开屏、下单、跳转
+   三个环节都**没有线上读数**。上面全部读数来自单测与执行级验证台。
+2. **真机浏览器未验。** 顾客页是手机优先设计,但只在验证台里驱动过函数,没有在手机上打开过。
+3. **二维码的实际可读性未验。** 下载机制(文件名、href、click、位图尺寸)验了,
+   把 PNG 印出来**用手机扫**没验。
+4. **链接没有撤销入口。** 表里有 `status` 列,服务层也认它(`DISABLED` ⇒ 按不存在处理,
+   同一条 404),但**没有任何接口能把它改成 DISABLED**。一条链接流出去了,目前**只能改库**。
+   本批有意不做(用户只要求「能拿走直接用」),验收时请知情。
+5. **同一商户换一条新链接也不行。** `uk_lsy_checkout_tenant_mch` 让一商户恒等于一条链接,
+   `issue` 又对同一条幂等 ⇒ 想让旧链接作废**没有接口**(同第 4 条,同一个根因)。
+6. **商户改名不会自动刷新链接行上的名字快照。** 快照在「重新取一次链接」时才刷新
+   (顾客页显示的是快照)。已写进文档与类注释。
+7. **开放 API 那条腿的 `merchant_code` 留空 + 租户登记了多个商户号 ⇒ 400**(不替调用方挑),
+   与三个下单端点同一条分流;这条**没有**联调过真请求。
+8. **计划与落地有两处偏差**(axios 实例没单独成文件、弹窗没单独成组件),已写进 `1e925a21`
+   的提交消息,计划文件本身**没有改**。