Files
junhong_cmp_fiber/openspec/changes/asset-realname-policy/proposal.md
huang 505b30aa8f
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m44s
feat: 实现资产实名认证策略功能 (asset-realname-policy)
- 新增 realname_policy 字段到 tb_iot_card、tb_device、tb_iot_card_import_task、tb_device_import_task 四张表
- 策略枚举:none(无需实名)、before_order(先实名后充值/购买)、after_order(先充值/购买后实名)
- C端充值拦截:before_order 策略下未实名用户禁止充值
- C端订单拦截:before_order 策略下未实名用户禁止购买套餐
- C端实名链接拦截:after_order 策略下无充值/订单用户禁止实名认证
- Admin API:PATCH /api/admin/assets/:identifier/realname-mode
- 新增错误码 CodeRealnameNotAvailable=1189
2026-04-17 17:03:41 +08:00

49 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Why
现有系统对实名认证的要求硬编码在卡业务类型(`card_category`)上,且当前拦截逻辑已被注释(`REALNAME-03`),由网关侧临时托管。业务侧实际存在两种截然不同的场景:**先实名后充值/购买**(实名是充值的前置条件)与**先充值/购买后实名**(充值不受限,实名在事后完成),且行业卡在特定业务下也需要实名。需要在资产(卡和设备)层面引入可配置的实名策略字段,彻底替代原有的硬编码逻辑,支持灵活的运营策略配置。
## What Changes
- **新增 `realname_policy` 字段**`IotCard``Device` 模型),枚举值:
- `none`:无需实名
- `before_order`:先实名后充值/购买(充值/购买前拦截未实名资产)
- `after_order`:先充值/购买后实名(充值/购买放行,实名链接在有订单前拦截)
- **生效优先级**:卡绑定设备时(设备卡)使用 `Device.realname_policy`,单卡使用 `IotCard.realname_policy`
- **C 端拦截**充值C3/C4、购买套餐/订单D1/D4按策略决定是否拦截实名链接E1`after_order` 模式下要求先有充值/订单记录才能获取链接
- **IoT 卡导入** 支持在导入时批量设置 `realname_policy`,并写入每张卡
- **设备导入** 支持在导入时设置 `realname_policy`,并写入每台设备
- **后台管理** 新增接口 `PATCH /api/admin/assets/:identifier/realname-mode` 支持逐资产修改策略
- **所有涉及卡/设备/资产的查询接口**(后台管理端 + C 端)返回 `realname_policy` 字段,便于前端展示和逻辑判断
- **废弃** `REALNAME-03` 注释代码,由新的策略逻辑替代
## Capabilities
### New Capabilities
- `asset-realname-policy`:资产实名认证策略——定义策略枚举、生效规则(单卡 vs 设备卡优先级、C 端三接口拦截逻辑、后台管理更新接口、以及所有查询接口返回该字段的规范
### Modified Capabilities
- `iot-card-import-task`IoT 卡导入请求新增 `realname_policy` 参数,导入任务模型记录该字段,批量初始化卡的策略值
- `device-import`:设备导入请求新增 `realname_policy` 参数,导入任务模型记录该字段,批量初始化设备的策略值
- `client-realname-link`E1 接口在 `after_order` 模式下新增"是否有有效充值/订单"的前置检查;`none` 模式正常返回链接
- `client-order-purchase`D1/D4 接口启用实名策略拦截(替代 REALNAME-03 注释逻辑),`before_order` + 未实名 → 返回 `CodeNeedRealname`
- `client-wallet-recharge`C3/C4 接口新增实名策略拦截,`before_order` + 未实名 → 返回 `CodeNeedRealname`
## Impact
**数据库**`tb_iot_card``tb_device``tb_iot_card_import_task``tb_device_import_task` 各新增 `realname_policy` 字段,迁移默认值 `none`(存量数据不影响现有行为)
**Model 层**`internal/model/iot_card.go``internal/model/device.go``internal/model/iot_card_import_task.go``internal/model/device_import_task.go`
**DTO 层**(新增 `realname_policy` 字段):
- 后台管理:`StandaloneIotCardResponse``DeviceResponse``AssetResolveResponse``AssetRealtimeStatusResponse``DeviceCardBindingResponse``BoundCardInfo``ImportTaskResponse`iot`DeviceImportTaskResponse`
- C 端:`AssetInfoResponse``BoundCardInfo`C端`DeviceCardItem`
- 导入请求:`ImportIotCardRequest``ImportDeviceRequest`
**Service 层**`client_order``client_wallet``client_realname` 新增策略检查逻辑;`iot_card``device` 新增 `UpdateRealnamePolicy` 方法;`iot_card_import``device_import` 传播策略字段至各资产记录
**常量**`pkg/constants/iot.go`(或新文件)新增 `RealnamePolicy*` 枚举常量
**路由 + 文档生成器**:新增 1 个后台管理接口,需同步更新 `cmd/api/docs.go``cmd/gendocs/main.go`