## 0. 实施前确认与审批门禁

- [ ] 0.1 确认 `xyw_data_test.as_phone_asset` 已由已完成建表动作提供，且本变更不包含 DDL、数据迁移、配置密钥或其他资产表写入。
- [ ] 0.2 审批本提案中的接口路径、三组下拉选项、手机号规范化、只读关联快照和关联阻止删除策略；未审批不得开始第 1 节代码修改。
- [ ] 0.3 开始每一组文件修改前检查工作区未提交改动，保护不属于本变更的用户修改。

## 1. 后端分页、DTO 与错误协议

- [ ] 1.1 新增 `MybatisPlusConfig` 并注册分页拦截器，确认 `Page` 查询以 MySQL 方言执行；为 `paginationInterceptor()` 添加新手注释：代码作用（白话）是启用分页 SQL，关联文件是 `PhoneAssetService`，关联逻辑是 Controller 列表请求 → Service Page → Mapper。
- [ ] 1.2 新增 `PhoneAssetPageQuery`、`PhoneAssetSaveRequest`、`PhoneAssetResponse` 与 `PhoneAssetPageResponse`，对页码、页大小、手机号、ICCID、文本长度和设备 ID 设置校验，并确保写入 DTO 不包含关联快照字段。
- [ ] 1.3 新增“未找到”和“手机号冲突”业务异常及统一异常处理；为 `handleValidation()`、`handleNotFound()`、`handleConflict()` 添加新手注释，分别说明校验/Service 异常 → `ApiResponse.error` → 前端错误提示的调用链。
- [ ] 1.4 为 DTO 校验、分页默认值和 400/404/409 响应编写后端测试，验证失败请求不写入 `as_phone_asset`。

## 2. 后端手机号资产服务与接口

- [ ] 2.1 新增 `PhoneAssetService`，实现 `page()`、`getActiveById()`、`create()`、`update()`、`softDelete()`；每个方法添加新手注释，至少说明各自的白话作用、关联 Controller/Mapper/DTO 和“HTTP 请求 → Service → `PhoneAssetMapper` → `as_phone_asset`”数据流。
- [ ] 2.2 在 `PhoneAssetService` 中实现 `buildActiveQuery()`、`ensurePhoneNumberAvailable()`、`applyEditableFields()`、`toResponse()` 与 `parseRelationIds()`；每个方法添加新手注释，说明有效记录过滤、唯一性保护、可写字段边界、Entity→Response 转换和 JSON 快照解析各自的关联文件与数据流。
- [ ] 2.3 让创建显式写入五个关联快照 JSON `[]`、通用审计时间和 `delete_time=0`；让更新保留快照和 `relation_synced_at`；让删除写 Unix 毫秒 `delete_time` 与 `update_time`。
- [ ] 2.4 新增 `PhoneAssetController` 的 `page()`、`getById()`、`create()`、`update()`、`delete()`；每个方法添加新手注释，说明 HTTP 路径、关联 Service/DTO、以及请求 → `ApiResponse` → 浏览器客户端的数据流。
- [ ] 2.5 为服务与 Controller 编写测试：默认分页、组合筛选、精确手机号、创建、重复手机号、编辑冲突、软删除后不可读、软删除后可重建、关联字段不可由请求覆盖。

## 3. 前端手机号资产工作页

- [ ] 3.1 新增 `phone-api-client.js` 的 `request()`、`listPhoneAssets()`、`getPhoneAsset()`、`createPhoneAsset()`、`updatePhoneAsset()`、`deletePhoneAsset()`；每个方法添加新手注释，说明浏览器请求、关联 `PhoneAssetController`、以及统一响应解析/异常消息的数据流。
- [ ] 3.2 新增 `PhoneAssetView.js` 的 `setup()`、`loadPage()`、`submitSearch()`、`resetSearch()`、`openCreate()`、`openEdit()`、`submitForm()`、`confirmDelete()`、`openDetails()`；每个方法或含业务逻辑回调添加新手注释，说明页面事件、关联 API 客户端/Element Plus、以及“用户操作 → API → 列表或弹窗状态”的消息链。
- [ ] 3.3 实现筛选栏、分页表格、新增/编辑共用表单、删除二次确认和只读关联快照详情；保存失败时保留弹窗与表单数据，成功后仅刷新当前筛选列表。
- [ ] 3.4 修改 `frontend/src/router/index.js` 注册 `/phone-assets` 并保留 `/reference/phone`；为 `createPlaceholderView()` 重新核对并补充其新手注释，说明占位页面与新路由的边界，避免旧入口误接新 API。
- [ ] 3.5 修改 `frontend/src/App.js` 的导航模板，将“手机号卡（参考）”改为“手机号资产”并指向 `/phone-assets`；补充组件模板相关注释，说明 RouterLink → RouterView 的导航链。
- [ ] 3.6 修改 `frontend/src/styles/app.css`，为筛选、表格、抽屉、弹窗和窄屏布局增加与现有后台一致的样式；不改变其他参考页面的可读性。

## 4. 验证与交付

- [ ] 4.1 新增 Playwright 用例，mock `/api/phone-assets`，覆盖页面初始加载、筛选重置、创建成功、服务端重复错误、删除确认和只读关系详情；所有测试辅助回调添加“代码作用（白话）/关联文件/关联逻辑”注释。
- [ ] 4.2 执行后端 `mvn test` 和前端 `npm run build`；若环境具备本地后端与数据库，再执行 Playwright 用例。任何失败先记录原因，再作最小范围修复。
- [ ] 4.3 使用本地 smoke 验证：创建一条测试手机号、按手机号查到、编辑、软删除、确认列表不再显示并可用同手机号重建；仅使用明确标识的测试记录。
- [ ] 4.4 交付时说明修改/新增文件、是否影响接口 DTO 数据库或配置、实际验证结果及未执行项原因；确认本期未修改数据库结构与旧参考路由。

## 5. 已确认规则的实现补充

- [ ] 5.1 在后端和前端实现手机号“去空格、去一个 `+86`、最终 11 位数字”的同一规则；`deviceId` 可为空且不查询设备表。
- [ ] 5.2 实现卡类型、管理类型和处置状态的固定下拉选项；管理类型空值显示为空并保存为 `null`，处置状态必填且创建默认“正常使用”。
- [ ] 5.3 在软删除前检查有效企微、微信、抖音、域名账号、商户关联；任一关联存在则返回关联类型并由前端提示不可删除。
- [ ] 5.4 为上述号码规范化、下拉值、空设备 ID、关联阻止删除编写后端与前端回归测试。