# Implementation Plan: 用户发票抬头管理 **Date**: 2026-07-24 ## 定位与决策 - **镜像 `InfoAddress`**(收货地址)用户级 CRUD 模式:实体即 DTO/VO、JWT userId 隔离、App 端接口风格(`@Anonymous @Auth` + token header)、无默认 / 无上限 / 硬删除。 - **仅 App 端 CRUD**:不建后台端接口、不建 sys_menu、不建 Vue 页面、无 i18n(按需求决策,YAGNI)。 - **与 010 解耦**:不改 010 `applyInvoice` / `getInvoice`;抬头是纯输入辅助,开票时客户端选用预填。 - **校验在 service 层**(`validateInvoiceProfile`),中校验力度:必填 + 统编 8 位 + 载具正则。 - **捐赠(DONATION)不存为抬头**;B2C 必须有载具(对齐 010 当前规则)。 ## 文件落点 | 层 | 路径 | |---|---| | 实体 | `ruoyi-system/src/main/java/com/ruoyi/system/domain/InfoInvoice.java` | | Mapper 接口 | `ruoyi-system/src/main/java/com/ruoyi/system/mapper/InfoInvoiceMapper.java` | | Mapper XML | `ruoyi-system/src/main/resources/mapper/system/InfoInvoiceMapper.xml` | | Service 接口 | `ruoyi-system/src/main/java/com/ruoyi/system/service/IInfoInvoiceService.java` | | Service 实现 | `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/InfoInvoiceServiceImpl.java` | | Controller | `ruoyi-admin/src/main/java/com/ruoyi/app/order/InfoInvoiceController.java` | | SQL | `updatesql/sql.md`(追加 2026-07-24 段) | > Mapper XML 放 `mapper/system/`(与 `InfoAddressMapper.xml` 同位),非 `mapper/chanting/`(那是 pos_ 业务表)。 ## 分阶段 1. **Setup**:DDL 写 `updatesql/sql.md`(开发者手动执行)。 2. **Foundational**:实体 + Mapper(+XML) + Service(+校验)。 3. **Controller**:App 端 4 接口。 4. **Polish**:curl 手测(B2C / B2B / 校验 / 越权)+ 更新记忆索引。 ## 测试策略 轻量。无单测强制;按 `contracts/api.md` 用 curl/Postman 手测 4 条接口 + 校验矩阵各分支 + 越权拒绝。 ## 风险与注意 - `InfoAddressServiceImpl` 的 `ServiceImpl` 泛型用的是 `BaseMapper`(历史遗留);新建 `InfoInvoiceServiceImpl` 时用具体 `ServiceImpl`。 - `@Auth` 来源 `com.ruoyi.system.utils.Auth`、`@Anonymous` 来源 `com.ruoyi.common.annotation.Anonymous`、`JwtUtil` 来源 `com.ruoyi.system.utils.JwtUtil`(均照搬 InfoAddressController)。 - 后端文件亦为 CRLF(见 memory `project-build-env`);新建文件用项目默认换行即可,编辑既有文件注意 CRLF。