1 changed files with 135 additions and 0 deletions
@ -0,0 +1,135 @@ |
|||||
|
# 账户中心套餐卡片与支付二维码弹窗设计 |
||||
|
|
||||
|
日期:2026-09-01 |
||||
|
范围:只改 `laic-frontend` 的 `AccountView`(及必要样式),不改后台、不改代理。 |
||||
|
|
||||
|
## 背景 |
||||
|
|
||||
|
账户中心流量购买与 SIM 充值已接上「选套餐 → 创建业务订单 → POST payments」主链路,但 UI 仍有两处缺口: |
||||
|
|
||||
|
1. 套餐选择仍是默认横排 `t-radio` 文本行,视觉上像未完成;卡片网格此前只定了方向,代码未落地。 |
||||
|
2. `POST /v1/account/payments` 已返回 `providerPayload`(实测为 AgPay 二维码 PNG),前端只 toast「请按返回凭证完成支付」,用户看不到码。 |
||||
|
|
||||
|
## 目标 |
||||
|
|
||||
|
1. 流量页与 SIM 充值弹窗的套餐选择改为**卡片网格**(名称 / 容量 / 价格 / 有效期分区;选中高亮)。 |
||||
|
2. 购买并支付 / 去支付成功后弹出**独立支付弹窗**:金额、业务类型、订单号、二维码、关闭;提供「我已支付,刷新状态」。 |
||||
|
3. 流量与 SIM 共用同一支付弹窗逻辑。 |
||||
|
4. 验收:本地看卡片样式;走通流量下单 → 弹窗出码;刷新状态可读支付/订单结果。 |
||||
|
|
||||
|
## 非目标 |
||||
|
|
||||
|
- 不引入微信支付 JS SDK / 原生扫码 SDK。 |
||||
|
- 不做自动轮询支付结果(仅手动刷新)。 |
||||
|
- 不改后端订单/支付协议、不修 `payment_idempotency_key` 空串唯一索引问题。 |
||||
|
- 不 seed SIM 卡/套餐;SIM 无数据时弹窗与卡片样式仍可用,但充值主路径可缺卡。 |
||||
|
- 不改发票、账号安全、概览其它区块。 |
||||
|
|
||||
|
## 现状 |
||||
|
|
||||
|
- 文件:`src/views/AccountView/AccountView.vue` |
||||
|
- 流量套餐:`t-radio-group` + `t-radio`,文案单行 `名称 · GB · ¥x / 天` |
||||
|
- SIM 套餐:充值弹窗内同样横排 radio |
||||
|
- 支付:`createPayment` → `describePayment` toast;`urls.PAYMENT(id)` 已存在但未用于 UI 刷新 |
||||
|
- 原型参考:`jcWeb 3` 通信卡充值有 `carrier-package-grid` 按钮卡;流量页旧稿是按 GB 快捷量,不是套餐卡 |
||||
|
|
||||
|
## 设计 |
||||
|
|
||||
|
### 1. 套餐卡片网格 |
||||
|
|
||||
|
保留 `t-radio-group` / `t-radio` 的无障碍选择与 `v-model`,只改结构与样式: |
||||
|
|
||||
|
```vue |
||||
|
<t-radio-group class="package-card-grid" v-model="selectedTrafficPackageId" ...> |
||||
|
<t-radio |
||||
|
v-for="pkg in trafficPackages" |
||||
|
:key="pkg.id" |
||||
|
:value="pkg.id" |
||||
|
class="package-card" |
||||
|
> |
||||
|
<strong>{{ pkg.name }}</strong> |
||||
|
<b>{{ amountLabel }}</b> |
||||
|
<em>{{ money(pkg.price) }}</em> |
||||
|
<small v-if="pkg.validityDays">有效期 {{ pkg.validityDays }} 天</small> |
||||
|
</t-radio> |
||||
|
</t-radio-group> |
||||
|
``` |
||||
|
|
||||
|
样式要点: |
||||
|
|
||||
|
- 网格:`repeat(auto-fill, minmax(140px, 1fr))`,间距 8–10px |
||||
|
- 卡片:白底、细边框、圆角;选中态蓝边 + 浅蓝底(对齐现有 `--blue` / `#f3f8fc`) |
||||
|
- 隐藏原生 radio 圆点,整卡可点 |
||||
|
- SIM 充值弹窗复用同一 class;字段映射:`amountGb`、`moneyFromFen(saleFeeFen)`、`validityMonths` |
||||
|
|
||||
|
右侧「订单概要」不变;选中卡片后摘要可显示当前套餐金额(可选增强:有则显示,无则保持现文案)。 |
||||
|
|
||||
|
### 2. 支付二维码弹窗 |
||||
|
|
||||
|
新增状态: |
||||
|
|
||||
|
```js |
||||
|
payDialogOpen |
||||
|
payDialogLoading |
||||
|
payDialogRefreshing |
||||
|
payDialogError |
||||
|
payDialogMeta = { |
||||
|
businessType, // traffic_order | sim_recharge_order |
||||
|
businessOrderId, |
||||
|
transactionId, |
||||
|
amountText, |
||||
|
status, |
||||
|
qrSrc, // data:image/png;base64,... 或可直接用于 <img> |
||||
|
title |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
触发: |
||||
|
|
||||
|
- `createTrafficOrderAndPay` / `payTrafficOrder` |
||||
|
- SIM:`createSimRechargeAndPay` / `payPendingSimOrder` |
||||
|
|
||||
|
成功拿到 payment 后: |
||||
|
|
||||
|
1. 解析 `providerPayload` → `qrSrc` |
||||
|
2. 打开 `t-dialog`(`header=微信支付` / `扫码支付`) |
||||
|
3. toast 可保留一句短提示,或以弹窗为主、toast 降级为失败提示 |
||||
|
|
||||
|
弹窗内容: |
||||
|
|
||||
|
- 金额(大字) |
||||
|
- 业务说明(云媒体流量 / 通信卡充值)+ 订单号 |
||||
|
- 二维码 `<img :src="qrSrc">`;无图时展示错误文案与「重新拉起支付」 |
||||
|
- 底部:`关闭`、`我已支付,刷新状态` |
||||
|
|
||||
|
刷新: |
||||
|
|
||||
|
- `GET urls.PAYMENT(transactionId)` |
||||
|
- 若 `status === 'paid' | 'success'`:toast 成功,关弹窗,刷新订单/余额/SIM |
||||
|
- 若仍 `processing/unpaid`:更新文案「尚未到账,可稍后重试」 |
||||
|
- 同步刷新对应业务列表(`loadOrders` / `loadSim` / balance) |
||||
|
|
||||
|
### 3. providerPayload 解析 |
||||
|
|
||||
|
实测 payload 为 PNG 二进制经 JSON 字符串化后的内容。前端兼容: |
||||
|
|
||||
|
1. 已是 `data:image/...` → 直接用 |
||||
|
2. 已是 `http(s)://` 或 `/...` URL → 直接用 |
||||
|
3. 看起来像 base64(无空白或标准 base64)→ `data:image/png;base64,` + 原文 |
||||
|
4. 其它:标记无图,弹窗提示「支付已创建,但二维码无法展示」 |
||||
|
|
||||
|
不引入第三方 QR 库。 |
||||
|
|
||||
|
## 验收 |
||||
|
|
||||
|
1. 账户 → 云媒体流量:套餐为卡片网格,选中高亮,不再是单行默认 radio。 |
||||
|
2. 点击「购买并支付」:创建订单 + 支付成功后弹出二维码弹窗,图可见。 |
||||
|
3. 「去支付」同样弹窗。 |
||||
|
4. 「我已支付,刷新状态」会请求支付详情并刷新订单列表。 |
||||
|
5. SIM 充值弹窗套餐同为卡片;有支付结果时共用支付弹窗(无卡时不阻塞流量验收)。 |
||||
|
|
||||
|
## 风险 |
||||
|
|
||||
|
- 若后端偶发返回非 PNG/非 base64 的 payload,弹窗需有降级文案,不能白屏。 |
||||
|
- 取消订单后若仍写入空 `payment_idempotency_key`,可能再次误报「存在未付款订单」——属后端问题,本设计不修;测试前可清空串或取消后置 NULL。 |
||||
|
- 真机微信扫码入账依赖外部支付回调,本轮以「出码 + 刷新接口」为前端验收标准。 |
||||
Loading…
Reference in new issue