Files
one-pipe-system/openspec/changes/add-traffic-records-and-refund-post-processing/design.md

142 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Context
- **后端(8-11,不改)**:接口和字段见 `junhong_cmp_fiber/docs/2026-11-06-测试环境8-11新功能前端对接与权限现状.md` 第 2.9、2.11、2.12 节,以 8-11 生成的 `admin-openapi.yaml` 为准。
- **账号类型限制**(后端只按账号类型校验,没有对应权限码):
- 记录查询接口不传资产标识时查全部,仅平台账号可用。
- 资产详情的采集记录、冲正查询与提交,企业账号无权调用。
- 退款后处理人工重试、尝试记录查询,仅平台账号(含超级管理员)可用。
- 人工重试只接受 `asset_post_status = 3`(需人工处理)且资产后处理未完成的退款单。
- **管理后台现状(`iteration/8-11`)**:
- 菜单为静态路由(`src/router/routes/asyncRoutes.ts`),用 `meta.permissions` 过滤;按钮用 `useAuth().hasAuth()`;超级管理员不受限。
- 列表页通用组件:`ArtSearchBar`、`ArtTableHeader`、`ArtTableFullScreen`。
- 可复用的模式是 `components/business/gateway/StopResumeRecords.vue`:同一个组件既作为独立页(`views/polling-management/stop-resume-records`),也嵌在资产详情里(传入卡 ID)。
- 资产详情:
- `views/asset-management/asset-information` 用 `BasicInfoCard` 触发停复机记录、`PackageListCard` 触发日流量详单(`DailyRecordsDialog`)。
- 同步按钮走 `useAssetInfo.refreshAsset`,目前忽略响应体。
- 退款:`views/finance/refund/index.vue`、`detail.vue`,接口在 `api/modules/refund.ts`,类型在 `types/api/refund.ts`。
- **约束**:基于 `iteration/8-11`,只部署测试环境;不改停复机逻辑;网关只读开关保持开启。
## Goals / Non-Goals
**Goals:**
- 运营能在后台查清楚"一张卡的流量读数从采集到入账"的全过程,并能人工冲正。
- 退款后处理卡住时,运营能看到原因并人工重试。
- 新页面和按钮有明确的权限码,可以分配给非超级管理员角色。
**Non-Goals:**
- 后端接口或权限校验改动。
- 采集记录导出、归档文件下载(后端未提供)。
- 生产发布与生产权限数据。
## Decisions
### D1 记录列表做成可复用组件,页面只是壳
参照 `StopResumeRecords.vue`,在 `src/components/business/traffic-records/` 下新建组件:
- `TrafficCollectionRecords.vue`:成功记录;传 `failures` 时切到失败记录。
- `CardDailyUsages.vue`
- `PackageUsageDailyRecords.vue`
- `PackageTrafficAdjustments.vue`
- `RefundPostProcessAttempts.vue`
每个组件接受可选的固定筛选项,例如 `identifier`、`packageUsageId`、`refundId`。独立页面不传,资产详情和退款详情传入,复用同一套列表与原始数据展开。
**备选**:页面与弹窗各写一套。**拒绝原因**:字段多(约 30 个),两套容易不一致。
### D2 菜单位置
| 页面 | 菜单位置 |
|---|---|
| 流量采集成功记录、流量采集失败记录、卡日流量、套餐日流量详单、套餐流量冲正流水 | 资产管理 → 记录管理(与"资产分配""授权记录"并列) |
| 退款后处理尝试记录 | 财务管理(紧跟"退款管理") |
路由别名在 `routesAlias.ts` 注册,页面目录分别为 `views/asset-management/record-management/<name>/index.vue` 与 `views/finance/refund-post-attempts/index.vue`。
### D3 权限码
后端没有这些权限码,前端新增常量文件 `src/config/constants/trafficRecords.ts`:
| 用途 | 权限码 |
|---|---|
| 采集成功记录页 | `traffic_collection_record:page` |
| 采集失败记录页 | `traffic_collection_failure:page` |
| 卡日流量页 | `card_daily_usage:page` |
| 套餐日流量详单页 | `package_usage_daily_record:page` |
| 冲正流水页 | `package_traffic_adjustment:page` |
| 退款后处理尝试记录页 | `refund_post_process_attempt:page` |
| 资产详情 · 采集记录(卡 / 设备绑定卡) | `iot_info:traffic_collections`、`device_info:traffic_collections` |
| 资产详情 · 冲正记录 | `package_usage:traffic_adjustments` |
| 资产详情 · 人工冲正 | `package_usage:traffic_adjust` |
| 退款 · 人工重试 | `refund:asset_post_retry` |
- 菜单用 `meta.permissions`,按钮用 `hasAuth`。
- 前端还要按账号类型隐藏后端会拒绝的入口:企业账号不显示资产详情的采集记录和冲正;非平台账号不显示人工重试和尝试记录页。
- 清单交后端写入测试库 `tb_permission` 并挂到对应菜单。权限码命名最终以写入测试库的数据为准。
### D4 时间范围与默认值
- 所有列表默认最近 1 天(日期类默认最近 7 天)。
- 选择器限制跨度 ≤ 31 天,提交前再校验一次。
- 时间参数按上海时间 `YYYY-MM-DD HH:mm:ss` 传,后端同时接受 RFC3339。
- 结束时间按"不含"处理,日期类按"含首尾"处理,筛选栏旁用文字说明。
### D5 枚举中文名
在 `src/config/constants/trafficRecords.ts` 统一维护以下中文名,未知值原样显示:
| 枚举 | 中文名 |
|---|---|
| `decision` | written 已写入、baseline 建立基线、queue_not_full 采集队列未满、slope_negative 读数回落、out_of_order 采集乱序、settled_existing 已结算 |
| `result` | ok 正常、failed 失败、rate_limited 限流、invalid_payload 响应无效、no_reading 无读数、invalid_reading 读数无效 |
| `source` | polling 轮询、manual_sync 人工同步、business_event 业务事件 |
| 退款后处理 `step` | load 加载、invalidate 失效套餐、activate 激活、check_main 检查主套餐、stop 停机、mark 标记完成、done 完成 |
| 退款后处理 `trigger` | outbox 自动、manual 人工 |
| `asset_post_status` | 0 未开始、1 待重试、2 已完成、3 需人工处理 |
### D6 原始数据展示
- 表格行展开后,用只读 JSON 块(`<pre>` 格式化)展示 `queue_points`、`raw_request`、`raw_response`。
- `raw_response` 为空、`raw_response_text` 有值时,显示文本并标注"已截断"。
- 每块提供"复制"按钮,方便贴给网关方排查。
### D7 人工冲正交互
- 表单只让运营填正整数加方向,由前端换算 `delta_mb` 的正负,避免运营手输负号出错。
- 确认框展示当前已用量(取套餐行的已用量)、调整量与预计结果。
- 退回不能使结果小于 0。
- 成功后刷新套餐列表,并展示返回的 `before_usage_mb → after_usage_mb`。
- 提示文案说明"提交后系统会按规则重新判断停复机",前端不调用任何停复机接口。
### D8 人工重试交互
- 按钮只在"需人工处理 + 平台账号 + 有权限"时出现。
- 成功时接口返回最新退款详情,直接替换当前行或详情数据。
- 失败时显示后端 `msg`,并重新拉取该退款单,更新尝试次数和最后错误。
### D9 同步结果(可选)
- `AssetService.refreshAsset` 的响应类型增加 `traffic_refresh`。
- `useAssetInfo.refreshAsset` 在成功提示里附加一行入账结果,或用 `ElNotification` 展示。
- 不改同步按钮的限流和刷新逻辑。
## Risks / Trade-offs
- **[权限码未入库,非超级管理员看不到新功能]** → 测试先用超级管理员验证。按 D3 清单补测试库后,再用普通运营账号验证。
- **[人工冲正、人工重试会触发后端停复机判断]** → 测试环境资产已全部在网关只读表,停复机调用会被拦截,不会改上游卡状态。验证只看停复机指令和拦截日志,不看上游卡状态。
- **[采集记录字段多,表格过宽]** → 默认只显示关键列,其余列通过 `ArtTableHeader` 列设置打开;原始数据放展开行。
- **[采集记录只保留当月加最近 2 个整月,资产详情采集记录保留 90 天]** → 筛选栏说明保留期,超出保留期查询为空属正常。
## Migration Plan
1. 在 `iteration/8-11` 实现。本地 `build:development`(接测试后端)通过类型检查与构建。
2. 后端在测试库补 D3 权限码,并分配给测试角色。
3. 推送 `iteration/8-11` 部署测试环境。管理后台 CI 要求推送前在本机构建镜像并推送到 `registry.boss160.cn`,需先 `docker login`;部署时间由你安排。
4. 用超级管理员和普通运营账号分别验证。
5. 回退:回滚对应提交重新部署;新增页面不影响现有页面。
## Open Questions
- 权限码命名(D3)是否沿用此清单,还是由后端统一定名后回填前端常量?默认先用此清单。
- 记录查询菜单是否放在"资产管理 → 记录管理",还是放到"轮询管理"下与停复机记录并列?默认放"记录管理"。