Files
one-pipe-system/openspec/changes/update-october-batch-one-admin-integration/design.md
luo 16effb69f3
All checks were successful
构建并部署前端到测试环境 / deploy (push) Successful in 55s
fix: some
2026-10-13 17:43:38 +08:00

118 lines
12 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.
# 十月第 1 批后台适配设计
## Context
本仓库为 Vue 3/TypeScript 后台,HTTP 服务使用 `BaseService` 与 Axios,页面已有业务权限、状态映射、详情组件、异步导入导出任务。用户明确排除所有 C 端接口和页面。后台本人改密虽然使用 `/api/auth/password`,仍属于本次后台适配。
本设计依据十月第 1 批说明、用户最新确认和当前代码。用户确认不提供最新 OpenAPI,不以该文件作为实施前置条件;新密码禁止特殊符号的确认优先于原说明。实施已获批准,代码与本地模拟页面验证详见实施记录;没有调用真实后台写接口或验证后端运行行为。
### 代码证据与修改路径
| 依据/代码证据 | 当前差异 | 修改路径 |
| --- | --- | --- |
| M3;`src/types/api/order.ts`、`src/api/modules/order.ts` | 详情与列表共用 `Order`,缺三项支付信息与支付记录 | `Order` 补公共字段,另建 `OrderDetail` 与支付记录类型,详情服务改用详情类型 |
| M8;`employeeCollectionDisplay.ts`、核销申请列表/详情 | 状态仅 0~3,可重提仅状态 2;提交状态只读名称 | 补终态 4、状态值映射与恢复/重提判断,覆盖账单关联申请 |
| M14;退款/充值/提现类型与状态映射 | 缺退款 7、充值 7、提现 5;旧重提及补发条件不认识终态 | 各业务独立扩展类型、筛选、标签和可执行操作 |
| M14;后台代理注册查询类型/详情 | 筛选仅 0~2,恢复操作仅看 `recoverable` | 补状态 3,并在业务终态下优先隐藏恢复 |
| M1;账号、客户账号、店铺、企业表单及本人改密弹窗 | 仍使用 8~32 或 6~20;旧密码也有长度规则 | 新密码使用专用校验,旧密码只保留必要输入校验 |
| M1;`AccountService.updateAccountPassword` | 独立改密发送 `{ password }`,说明要求 `{ new_password }` | 按第 1 批说明修正独立改密请求,不误改其他接口字段 |
| M12;换货创建/确认完成、`apiError.ts` | 无 1202 定制反馈;错误归一化不暴露业务 data,换货 catch 可能输出错误对象 | 在换货操作定向提取 code/msg/message/data.phone,只在提示中展示号码,不记录完整错误对象 |
| M16;预警规则与记录类型/页面 | 规则依赖已删除的 `real_data_mb`;记录未定义三项 MB 字段 | 只移除规则响应引用,补记录快照并明确 MB 单位 |
| M2;业务员导入页 | 仍写「业务员登录账号」且未注明只填手机号 | 同步说明及已有前端模板,保留逐行失败明细 |
| M23;设备导入任务页 | IMEI 被列为可选,已支持 `failed_items` | 改说明,复用失败明细,不改 Excel 模板结构 |
## Goals / Non-goals
- Goals:让后台显示、筛选、请求字段和可执行操作符合本批次说明;保留既有权限、表单内容、财务快照和导入导出流程。
- Non-goals:C 端适配、后台接口实现、新审批机制、新页面架构、自动解绑手机号、前端重算预警或余额、替换设备导入模板、引入测试框架。
## Decisions
### 1. 订单详情类型与支付状态隔离
公共 `Order` 接收三项字符串字段,列表与创建响应仍使用公共类型;详情增加独立 `payments` 数组。支付记录状态 0~3 与订单 `PaymentStatus` 的 1~4 含义不同,使用独立枚举/映射,不能复用。
支付记录使用后端顺序,不自行筛掉失败或待支付记录;金额用已有分转元格式化,`paid_at`、`expire_at` 空值显示 `-`。渠道码映射 `wechat` 为微信直连 v3、`wechat_v2` 为微信直连 v2、`fuiou` 为富友;支付方式微信/支付宝与技术渠道分开展示,未知非空渠道保留原值。公共字段为空串显示 `-`,不能据此虚构支付信息。
### 2. 业务终态优先于恢复标志
六个业务各自定义终态,禁止跨业务共用数值。恢复入口使用「不是本业务审批提交失败终态 + 后端允许恢复 + 原权限允许」共同判断;即使陈旧响应仍返回 `recoverable=true`,终态也不得显示恢复按钮。
「提交结果未知」不能只凭提交状态转换成业务失败,保留原后端恢复资格判断,不扩大恢复权限。终态下隐藏恢复/补发和不适用的审批操作,查看详情、凭证等只读操作保留。
重新发起复用既有表单和文档规定的接口:核销/退款/提现使用原业务重提接口,线下充值创建新单,提现资料提交新版本。代理注册仅提示申请人重新扫码,后台不调用 `/api/c/v1`、不补建后台代注册接口。涉及预占/冻结金额时重新加载账单或佣金概览,前端不乐观加减财务数据。
核销审批提交状态使用 `approval_submission_status` 的 0 待提交、1 提交中、2 已提交、3 提交失败、4 结果未知。名称字段存在时可使用后端名称,但字段为空时需按真实数值回退,0 不能因 falsy 判断显示成缺失。
### 3. 新密码校验专用化
新增/复用新登录密码专用工具,避免直接改通用 `validatePassword` 或 `validateStrongPassword` 影响非登录密码。按用户最新确认,长度 8~12,仅允许 ASCII 英文字母和数字,并必须同时包含大写字母、小写字母和数字;所有特殊符号、空白、中文、emoji 和其他非英文字母数字字符均拒绝。不对输入静默 `trim` 后放行。
实现判定为 `^[A-Za-z0-9]{8,12}$` 且同时满足 `[A-Z]`、`[a-z]`、`[0-9]` 三个包含条件。例如 `Abc12345` 可接受,`abcd1234` 因缺少大写拒绝,`Abc1234!` 即使包含大写、小写和数字也因特殊符号拒绝。
新密码和确认密码统一长度限制、规则说明与一致性校验;本人改密 `old_password` 不设新规则的 `maxlength` 或类别限制,旧登录表单不收紧。账号编辑目前没有密码输入则不新增;若既有调用传递可选 `password`,仅非空新值需要校验,未修改密码时不发送空串。
后台七个契约:
| 场景 | 接口 | 新密码字段 |
| --- | --- | --- |
| 本人修改 | `PUT /api/auth/password` | `new_password` |
| 创建账号(含店铺/企业下的客户账号) | `POST /api/admin/accounts` | `password` |
| 修改账号 | `PUT /api/admin/accounts/{id}` | 可选 `password` |
| 独立修改账号密码 | `PUT /api/admin/accounts/{id}/password` | `new_password` |
| 创建店铺初始账号 | `POST /api/admin/shops` | `init_password` |
| 创建企业 | `POST /api/admin/enterprises` | `password` |
| 修改企业密码 | `PUT /api/admin/enterprises/{id}/password` | `password` |
错误消息兼容项目既有 `msg` 与说明中的 `message`,优先展示后端提供的可读字段级原因;不改变 401 等既有统一处理,不重复弹错、不输出密码值。
### 4. 换货 1202 定向错误处理
创建换货和确认完成同时覆盖 HTTP 200 的非零业务码与 Axios HTTP 错误响应,不假定只有一种承载形式。在受影响的两个服务调用范围关闭重复默认提示,局部共享处理器处理 1202,其余错误仍按既有统一错误分类/文案展示。
1202 弹窗原样使用业务 `msg`,不拼接号码或固定替换文案。只有响应明确带有效字符串 `data.phone` 时才允许带参跳转;`data=null` 的已换货等拒绝仅显示后端文案和「知道了」。只以文本渲染,不拼成 HTML。
手机号冲突且具备原关联页面查看权限时提供跳转;无权限或新资产标识缺失时仅提示,不扩大权限。禁止自动解绑。完整号码不额外写日志或本地存储;用户主动跳转的 query 参数是已明确授权的例外。
创建失败保留资产/原因等字段;完成失败重新加载换货单,保持后端「已发货待确认」事实,不乐观标记完成。解除后由用户再次提交。取消只关闭提示,不当作解绑或换货成功。
用户追加快捷定位:创建换货冻结当前新资产上下文,确认完成使用原单新资产标识;手机号只能取当前错误响应 `data.phone`,不得根据历史数组推断其他 1202 是手机号冲突。主动跳转通过 `asset_identifier` 和 `phone` query 传递目标。关联页按 1 页/20 条加载,仅选中精确匹配有效行,继续原原因和二次确认。
通过 ArtTable 透传清空/勾选方法,数据更新后 nextTick 完成实际选择。缓存重入和路由参数变更重置查询,请求序号防止过期响应覆盖;手工筛选/翻页、解绑后刷新清除旧选择。批量结果保持后端布尔契约,仅展示中文「解绑成功/解绑失败」。原查看与批量解绑权限不变。
### 5. 预警只展示快照,不重算阈值
删除 `PackageTrafficAlertRuleItem.real_data_mb` 与规则行/详情/列设置依赖。来自 `/api/admin/packages` 的套餐选项 `real_data_mb` 保留,套餐选择与规则参数校验不变。
记录列表/详情接收后端 `threshold_mb`、`used_mb`、`limit_mb`,用 MB 显示两位小数;0 显示 `0.00`,缺失/null 显示 `-`。标签分别为阈值流量、已用流量(含加油包)、总流量(含加油包)。不使用当前套餐额度重新计算历史 `threshold_mb`,不把新字段作为新的请求入参或筛选项。
### 6. 导入说明与后端结果保持一致
CSV 只同步新表头和手机号说明,不为旧表头做客户端转换、不将用户名转为手机号。发现内置模板时同步,否则仅改当前说明,任务明细保留原后端原因。
设备导入保持原下载文件与列序,将说明中的 IMEI 移到必填列;只把空值规则交给后端逐行处理,不为单行缺失拦截整个文件,不添加格式或去重限制。
## Risks / Trade-offs
- 无最新 OpenAPI:按用户确认,以第 1 批说明实施,不要求补文件;联调发现真实接口与说明不符时先反馈,不自行猜测或声称已通过联调。
- 密码口径覆盖原说明:用户明确禁止特殊符号,前端不得按原「四类至少三类」放行含符号的新密码;如后端实际校验与该确认冲突,先反馈用户。
- 恢复旧规范与新业务终态冲突:文档注明差异,实施时优先按本批次终态处理,结果未知继续守原恢复规则。
- 改错密码/流量范围:专用新密码工具和独立规则/套餐类型限制修改范围,回归旧密码、操作密码、WiFi 密码、套餐额度。
- 换货错误提示重复或泄漏号码:两个请求定向接管提示,共享处理器保留其他错误行为,删除受影响分支的完整错误输出。
- 财务状态不同步:重提和失败后重新拉取后端数据,不修改本地冻结金额来模拟后端效果。
- 仓库未配置可直接运行的单测脚本:先检查现有测试方式,以针对性逻辑检查、类型检查、编码检查和人工联调为验收,不自动引入新框架。
## Migration plan
提案获批后,依据第 1 批说明和用户最新确认,依任务清单按公共类型/规则、各页面、联调顺序实施;前端与对应测试后端一起验收。无数据库迁移、权限迁移、历史导出重生成或自动数据修复。
回退只回退本次业务代码,不触及原有提案和用户改动;后端若仍保留新校验及终态,旧前端将重新出现展示与提交问题,因此上线/回退需确认前后端契约匹配。
## 已确认事项
1. 没有最新 `admin-openapi.yaml`,不要求提供,以第 1 批说明实施。
2. 新密码 8~12 位,仅允许英文字母和数字,且大写、小写和数字均必需,不允许特殊符号。
3. 所有 `/api/c/v1` 和 C 端页面排除;后台代理注册失败仅展示重新扫码申请指引,不代发 C 端申请。
当前没有待确认的需求问题。用户已批准实施,后台代码已适配;真实后端联调项继续在任务清单保留未完成状态。