Files
luo 0d77a7d55b
All checks were successful
构建并部署前端到测试环境 / deploy (push) Successful in 55s
fix: some
2026-10-14 17:08:32 +08:00

126 lines
13 KiB
Markdown
Raw Permalink 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 端;2026-10-14 用户追加代理扫码注册页及同一注册接口的密码校验,其余 C 端接口和页面仍排除。后台本人改密虽然使用 `/api/auth/password`,仍属于本次后台适配。
本设计依据十月第 1 批说明、用户最新确认和当前代码。用户确认不提供最新 OpenAPI;2026-10-14 修正为新密码允许特殊符号,恢复四类至少三类。实施已获批准,结果详见实施记录,没有调用真实后台写接口。
### 代码证据与修改路径
| 依据/代码证据 | 当前差异 | 修改路径 |
| --- | --- | --- |
| 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. 新密码校验专用化
使用新登录密码专用工具,避免影响通用校验与其他密码。按最新修正,长度 8~12,允许英文字母、数字及所有可打印半角 ASCII 符号,四类至少三类;空白、中文、emoji、控制字符和非 ASCII 字符拒绝。不静默 trim。
字符范围为 ASCII `0x21~0x7E`,按大写、小写、数字和标点四类计数,至少三类。`Admin@12345`、`ABC1234!`、`abc1234!`、`Abcdefg!` 均有效;`abcd1234`、`ABCDEF!!` 仅两类无效。
顶栏 `z-index:100`、侧栏 `z-index:101` 导致嵌在顶栏内的改密遮罩被侧栏压住。仅给改密弹窗加 `append-to-body`,不全局提高顶栏层级或修改所有弹窗;由 Element Plus 管理完整遮罩、焦点和关闭行为。
新密码和确认密码统一长度限制、规则说明与一致性校验;本人改密 `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` |
用户明确追加的公开代理注册使用原 `POST /api/c/v1/agent-distribution-registrations` 和 `password` 字段。表单复用 `createNewLoginPasswordRule()`,注册服务发送前复用 `getNewLoginPasswordError()`;保留其他入参和 `withToken: false`。页面将输入上限改为 12,完整规则独立显示在输入框下,并关联 `aria-describedby`,避免移动端 placeholder 截断规则。强度反馈仅按共享校验判定合格/未合格,空格和中文不能被计作有效特殊符号;长错误文案参与正常布局,不覆盖下一个表单项。
用户进一步追加注册失败反馈:仅 `registerAgent` 请求设 `errorMessageMode: 'none'`,页面处理非零业务响应与 HTTP 异常。1050/1001 不暴露企业微信模板配置细节,统一「注册失败, 请联系管理员」,其余错误保留具体业务原因或正常网络降级;不记录密码或完整错误对象。提交进行中阻止再次提交,失败保留表单。公共 HTTP、短信与其他服务的错误提示保持原状。
公共表头 Sortable 报错作为既有列设置功能的生命周期修复:改用 `useDraggable(..., { immediate: false })` 和真实 `HTMLElement` ref,仅在列设置 Popover 已打开且进入后,目标仍连接文档时启动;关闭、卸载及 KeepAlive 停用销毁实例,晚到回调不得重新启动。列排序仍通过原 `columns` model 写回,勾选状态和其他表头功能不变。
错误消息兼容项目既有 `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 端申请。
当前没有待确认的需求问题。用户已批准实施,后台代码已适配;真实后端联调项继续在任务清单保留未完成状态。