# Data Model: 用户发票抬头管理 **Date**: 2026-07-24 ## 新增表:info_invoice(用户发票抬头,用户级,镜像 info_address) > DDL 写入 `updatesql/sql.md`,由开发者手动执行(项目规范)。用户级数据用 `info_` 前缀(与 `info_address` / `info_user` 一致),区别于订单级 `pos_order_invoice`。 | 字段 | 类型 | 说明 | |------|------|------| | id | BIGINT PK AUTO | 主键 | | user_id | BIGINT NOT NULL | 用户id(JWT 隔离;写库前强制以 token 解析值覆盖) | | title_name | VARCHAR(50) NOT NULL | 抬头备注名(如「公司-美食達」「个人-手机条码」),客户端列表展示用 | | category | VARCHAR(8) NOT NULL | 类型:`B2C`=个人 / `B2B`=公司 | | buyer_name | VARCHAR(100) NOT NULL | 买方名称:B2C=个人姓名 / B2B=公司全名 | | buyer_ubn | VARCHAR(16) | 统一编号(统编,8 位数字,含前导零须字符串);**仅 B2B** | | buyer_email | VARCHAR(200) | 接收邮箱;B2B 必填 / B2C 仅 ezPay 会员载具(2) 时必填 | | carrier_type | VARCHAR(8) | 载具类型 `0`手机条码 / `1`自然人凭证 / `2`ezPay 会员;**仅 B2C** | | carrier_num | VARCHAR(64) | 载具号码(随 carrier_type) | | create_time | DATETIME DEFAULT CURRENT_TIMESTAMP | 创建时间(DB 自动) | | update_time | DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 更新时间(DB 自动) | > 不设 `create_by` / `update_by`:App 端走 JWT(非 ruoyi 登录用户名),无意义字段,从简。`create_time` / `update_time` 由 DB `DEFAULT` / `ON UPDATE` 自动维护,代码不手动赋值。 **索引**:`KEY idx_user (user_id)`(用户隔离查询)。 **约束约定**(应用层校验,非 DB 约束): - 无默认抬头列、无数量上限、硬删除(与 `info_address` 一致)。 - B2B ↔ 载具字段互斥:B2B 时 `carrier_type` / `carrier_num` 必空;B2C 时 `buyer_ubn` 必空。 - 完整保存校验矩阵见 `contracts/api.md`。 ## 复用实体(不改) - **InfoUser**(`info_user`):提供 userId(JWT claim `id` → `JwtUtil.getusid`)。 - **010 `ApplyInvoiceDto` / `PosOrderInvoice`**:不改。开票时客户端从选中抬头取字段填入 `ApplyInvoiceDto`,开票链路完全不动。