# 十月第 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 端申请。 当前没有待确认的需求问题。用户已批准实施,后台代码已适配;真实后端联调项继续在任务清单保留未完成状态。