## 1. M1 登录密码规则与修改密码提示 - [x] 1.1 `pkg/validator` 新增登录密码规则函数(8~12 位 → `1001`;仅 ASCII 可见字符、四类至少三类 → `1016`),消息不含密码;在本人改密码、后台账号创建/修改/改密码、建店铺初始密码、企业新增/改密码、代理注册(替换 `distribution.go:67` 的 6~64 判断)共七处哈希前调用;对应 DTO 标签改为 `min=8,max=12` 并更新字段说明。不改登录校验与 `CreateSystemAccount`。 - [x] 1.2 为 `ChangePasswordRequest` 的旧密码、新密码字段补中文描述,统一修改密码 Handler 用 `validation.Message` 返回“修改密码参数不合法:”加字段级提示;结构校验通过后在 Handler 内做强度判断(同样带该前缀),先于旧密码比对;不回显密码。 - [x] 1.3 核对短于 8 位、超过 12 位、强度不足、必填缺失四种消息符合 delta spec;JSON 解析失败与旧密码错误行为不变。 ## 2. M4 订单导出操作人 - [x] 2.1 订单导出查询带出 `operator_name`,新任务在最后一列输出“操作人”;`orderCardGroupCountFromHeaders` 先识别末列是否为“操作人”再反推卡列组数;按 `ResolvedHeaders` 判定是否输出,历史任务保持旧列序与行宽。 ## 3. M5 IoT 卡导出套餐到期时间 - [x] 3.1 IoT 卡导出新任务在最后一列增加“套餐到期时间”;每个分页调用一次 `packageexpiry.Query.ResolveBatch`,只有 `exact` 输出时间,其余留空;历史任务不加列。 ## 4. M6 设备导出流量单位 - [x] 4.1 设备导出新任务表头改为 `ICCIDn使用的流量(MB)`、“设备合计(MB)”,在最后一列增加“设备合计(GB)”(MB 合计 ÷ 1024,两位小数),`cardGroupCountFromHeaders` 增加对新尾部列数(7)的识别;无绑定卡设备 MB、GB 合计输出格式化零值;历史任务按冻结表头输出。 - [x] 4.2 核对三类导出新旧表头与每行列数严格一致,空操作人、到期不可精确推算、无绑定卡设备均不丢行。 ## 5. 文档与测试环境验证 - [x] 5.1 `gofmt`、`go build ./cmd/api ./cmd/worker`、`go run cmd/gendocs/main.go`。 - [x] 5.2 按 ENG-TEST-001(测试库 `junhong_cmp_test`、Redis DB 6):修改密码接口验证四种提示且失败不改密码;七个入口各用 `Abc12345` 成功、`abcd1234` 返回 `1016`、7 位与 13 位返回 `1001`、含空格返回 `1016`;用规则上线前的 6 位旧密码账号登录照常成功。只使用本 Change 自建的测试账号、企业与店铺,验证后清理。 - [ ] 5.3 通知测试环境前端同步七个入口的密码提示与前端校验(8~12 位、四类至少三类)。 - [x] 5.4 测试环境为订单、IoT 卡、设备各建一个导出任务,下载核对新表头、值来源、MB/GB 换算与列数;再用变更前创建的任务验证旧表头与行宽不变;只清理本 Change 自建的任务与对象。 - [ ] 5.5 运行 `openspec validate --all` 与 `./scripts/context-health.sh`。