51 lines
2.4 KiB
Markdown
51 lines
2.4 KiB
Markdown
Status: done
|
||
|
||
# CustomerBinding 模块骨架 + 有虚拟号路径替换(纯重构)
|
||
|
||
## What to build
|
||
|
||
建立 `internal/service/customer_binding` 包,对外暴露 `Bind()` 和 `OwnsAsset()` 两个接口,将现有有虚拟号路径的逻辑迁入。同时将代码库中 6 处归属验证调用点统一替换为新接口。
|
||
|
||
**本切片是纯重构,不改变任何现有行为。**
|
||
|
||
### Bind(ctx, tx, customerID, assetType, assetID)
|
||
|
||
封装创建客户与资产绑定记录的逻辑,当前只实现有虚拟号路径:
|
||
- IoT 卡有虚拟号 → 写 `tb_personal_customer_device`(与现在 `bindAsset` 行为一致)
|
||
- 设备 → 写 `tb_personal_customer_device`(设备必然有虚拟号)
|
||
- 首次绑定时触发 `markAssetAsSold()`(firstEverBind 逻辑保持不变)
|
||
|
||
### OwnsAsset(ctx, customerID, assetType, assetID) bool
|
||
|
||
封装归属验证逻辑,当前只实现有虚拟号路径:
|
||
- 查 `tb_personal_customer_device WHERE virtual_no = ? AND status = 1`
|
||
- 内部统一强制 `status = 1` 过滤(修复现有部分实现缺少此过滤的安全缺口)
|
||
|
||
### 替换 6 处调用点
|
||
|
||
以下调用点替换为 `CustomerBinding` 的方法:
|
||
|
||
| 调用点 | 替换目标 |
|
||
|--------|---------|
|
||
| `client_auth/service.go: bindAsset()` | `CustomerBinding.Bind()` |
|
||
| `handler/app/client_realname.go:92` | `CustomerBinding.OwnsAsset()` |
|
||
| `handler/app/client_device.go:82` | `CustomerBinding.OwnsAsset()` |
|
||
| `handler/app/client_wallet.go: isCustomerOwnAsset()` | `CustomerBinding.OwnsAsset()` |
|
||
| `handler/app/client_asset.go: isCustomerOwnAsset()` | `CustomerBinding.OwnsAsset()` |
|
||
| `service/client_order/service.go: checkAssetOwnership()` | `CustomerBinding.OwnsAsset()` |
|
||
|
||
exchange service 的 `customerOwnsAsset()` 在切片 3 中处理。
|
||
|
||
## Acceptance criteria
|
||
|
||
- [ ] `internal/service/customer_binding` 包存在,对外暴露 `Bind` 和 `OwnsAsset`
|
||
- [ ] 有虚拟号的 IoT 卡登录后,`tb_personal_customer_device` 正常写入绑定记录(与现在一致)
|
||
- [ ] 设备登录后,`tb_personal_customer_device` 正常写入绑定记录(与现在一致)
|
||
- [ ] 被禁用(status=0)的绑定记录不能通过 `OwnsAsset` 验证(修复安全缺口)
|
||
- [ ] 6 处调用点全部替换完毕,原有私有方法(resolveAssetBindingKey、isCustomerOwnAsset 等)可删除
|
||
- [ ] 有虚拟号卡的实名认证、购买套餐、设备操作全链路与现在行为一致
|
||
|
||
## Blocked by
|
||
|
||
None - 可立即开始
|