93 lines
6.9 KiB
Markdown
93 lines
6.9 KiB
Markdown
## Context
|
||
|
||
AUG26-017 给代理预存款带来两类变化:在线自充的收款方式从「由支付配置自动决定」改为「超管配置允许范围」;线下预存款审批从「金额 + 支付凭证」补齐为「收款方式 + 交易流水号 + 其他凭证」。后端接口边界已经确认:
|
||
|
||
| 用途 | 接口 |
|
||
|---|---|
|
||
| 在线可用方式 | `GET /api/admin/agent-self-recharge-payment-methods`,代理/平台可用,超管 403;旧接口 `GET /api/admin/agent-recharges/payment-methods` 保留但前端不再调用 |
|
||
| 允许范围读取 | `GET /api/admin/system-configs`(`module`、`page`、`page_size`,返回 `list` / `page` / `page_size` / `total`) |
|
||
| 允许范围写入 | `PUT /api/admin/system-configs/{key}`,请求体 `{ key, value }`,`value` 为字符串化配置值 |
|
||
| 交易流水号识别 | `POST /api/admin/agent-recharges/payment-voucher-ocr`,请求 `{ payment_voucher_key }`,响应 `{ external_transaction_no }` |
|
||
| 线下创建 | `POST /api/admin/agent-recharges`,`payment_method=offline` 时新增 `offline_payment_method_id`、`external_transaction_no`、`other_voucher_key` |
|
||
| 列表与详情 | `GET /api/admin/agent-recharges`、`GET /api/admin/agent-recharges/{id}` 新增 5 个响应字段 |
|
||
|
||
## Goals / Non-Goals
|
||
|
||
**Goals**
|
||
|
||
- 在线充值只展示后端返回的实际可用方式,并优雅处理空列表。
|
||
- 超管可在既有系统配置页面维护允许范围,无需新增接口或页面。
|
||
- 线下预存款申请可提交收款方式、交易流水号与其他凭证,并支持 OCR 预填流水号。
|
||
- 列表与详情正确展示两类交易号与收款方式快照。
|
||
|
||
**Non-Goals**
|
||
|
||
- 不新增「代理自充设置」独立页面与专用配置接口。
|
||
- 不实现允许范围的审计查询接口(后端记录操作者、前后值与时间,前端不查询)。
|
||
- 不实现后端接口、商户池交集计算、企微审批回调。
|
||
- 不实现 H5/C 端在线充值,不为企业账号做分支。
|
||
|
||
## Decisions
|
||
|
||
### 允许范围沿用受控系统配置
|
||
|
||
允许范围配置项的读取与写入统一走系统配置:读取 `GET /api/admin/system-configs`,写入 `PUT /api/admin/system-configs/{key}`。系统配置页已是元数据驱动的通用渲染器(`value_type` 决定控件、`enum_values` 决定枚举选项、`readonly` 与 `sensitive` 决定保护策略),因此后端的允许范围配置项注册后即可在页面中展示与编辑。
|
||
|
||
前端 MUST NOT 硬编码该配置项的 `config_key`,也 MUST NOT 新增专用设置写接口。该配置项归属 `c2b.payment` 模块,属于现有 `SystemConfigModule` 取值,无需扩展模块枚举。
|
||
|
||
允许范围的枚举取值为 `wechat_only`(仅微信支付)、`alipay_only`(仅支付宝支付)、`both`(同时支持微信与支付宝);系统配置页展示与选择时使用中文标签,未命中映射时回退展示原值。
|
||
|
||
超管入口使用一个「代理自充设置」菜单项,跳转到系统配置页面并带 `module=c2b.payment` 过滤条件;系统配置页面除了既有的 `config_key` query,还需支持从 `route.query.module` 初始化模块筛选,保证跳转后列表已按模块收敛。
|
||
|
||
### 在线可用方式
|
||
|
||
| 项 | 取值 |
|
||
|---|---|
|
||
| 接口 | `GET /api/admin/agent-self-recharge-payment-methods` |
|
||
| 响应 | `{ methods: (wechat \| alipay)[], min_amount, max_amount }` |
|
||
| 空列表 | 只提示「当前暂无可用的在线支付方式」,禁用提交,不解释被限制还是无可用商户 |
|
||
| 超管 | 该接口对超管返回 403,前端在超管视角不请求它,仅通过系统配置查看允许范围 |
|
||
| 存量单 | 配置变更不影响已创建的待支付单,前端不在配置变更后刷新待支付单 |
|
||
|
||
金额上下限优先使用接口返回的 `min_amount` / `max_amount`(单位分),接口未返回时回退既有常量。
|
||
|
||
### 线下预存款创建字段
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|---|---|---|
|
||
| `offline_payment_method_id` | 是 | 取自 `GET /api/admin/employee-collection-payment-methods` 的启用项(`enabled=true`,`page_size=100`) |
|
||
| `external_transaction_no` | 是 | 交易流水号,OCR 预填后人工确认,可编辑;前端不做重复校验 |
|
||
| `other_voucher_key` | 否 | 其他凭证对象键数组,最多 5 个 |
|
||
| `payment_voucher_key` | 是 | 支付凭证,至少 1 个,与其他凭证分开提交 |
|
||
|
||
历史线下单的收款方式只用 `offline_payment_method_code` / `offline_payment_method_name` 快照展示,不用 `offline_payment_method_id` 反查字典当前值。
|
||
|
||
列表筛选保持后端已有参数集合(`page`、`page_size`、`shop_id`、`status`、`recharge_source`、`start_date`、`end_date`),不新增交易流水号筛选,交易流水号只做展示。
|
||
|
||
### OCR 预填交互
|
||
|
||
- 入口:线下代充弹窗支付凭证区的「识别凭证」按钮,取已上传的第一个 `payment_voucher_key`;未上传凭证时禁用。
|
||
- 请求:`POST /api/admin/agent-recharges/payment-voucher-ocr`;通过 `BaseService.post` 的第三个参数传 `{ timeout: 30000 }`,请求期间按钮与交易流水号字段展示 loading 并防重复点击。
|
||
- 成功:把 `external_transaction_no` 写入交易流水号输入框,字段保持可编辑并提示对照凭证核对。
|
||
- 失败(凭证不是图片、对象不存在、识别服务异常):只提示,不清空已填内容、不阻断手工填写与提交。
|
||
- 只预填交易流水号,金额、付款人、付款时间、备注一律不预填。
|
||
|
||
### 凭证上传类型
|
||
|
||
取上传地址时必须显式声明 `content_type` 为 `image/jpeg`,否则 OCR 会以「不是图片」直接拒绝。`VoucherUpload` 新增可选 `contentType` prop,代理充值的支付凭证与其他凭证固定传 `image/jpeg`,并把它透传给 `StorageService.getUploadUrl` 与 `StorageService.uploadFile`。
|
||
|
||
### 交易流水号展示
|
||
|
||
`payment_transaction_id` 是在线渠道返回的权威交易号,只有在线单有值;`external_transaction_no` 是线下人工申报的交易流水号。两者独立展示、互不覆盖:在线单只展示前者,线下单只展示后者。
|
||
|
||
### 详情页保持只读
|
||
|
||
代理充值详情页只做信息展示,顶部仅保留返回导航;本次新增的交易流水号、收款方式与其他凭证都只读呈现,不引入任何业务操作按钮。创建、确认线下充值、驳回等操作入口仍留在列表页操作列。
|
||
|
||
## Risks / Trade-offs
|
||
|
||
- **配置 Key 由后端注册决定**:前端不硬编码,配置项按 `c2b.payment` 模块渲染;若后端最终调整模块归属,只需同步调整菜单跳转的 `module` 参数。
|
||
- **OCR 端到端约 15 至 16 秒**:必须配置不低于 30 秒的超时并展示 loading,否则用户容易重复点击。
|
||
- **强制声明 `image/jpeg`**:按需求文档要求统一声明为 `image/jpeg`,上传非 JPEG 图片时以声明类型为准。
|
||
- **收款方式字典项被引用后会冻结**:展示历史单依赖快照字段,避免字典改名或停用导致历史数据展示漂移。
|