53 lines
2.2 KiB
Markdown
53 lines
2.2 KiB
Markdown
Status: done
|
||
|
||
# 无虚拟号单卡 C 端完整链路
|
||
|
||
## Parent
|
||
|
||
`.scratch/customer-binding-architecture/PRD.md`
|
||
|
||
## What to build
|
||
|
||
扩展 `CustomerBinding` 模块,使无虚拟号的独立 IoT 卡(单卡)能够完整走通 C 端业务流程:登录绑定、实名认证、购买套餐。
|
||
|
||
**仅影响 IoT 卡(单卡)。设备资产必然有虚拟号,不在本切片处理范围内。**
|
||
|
||
### 扩展 Bind()
|
||
|
||
当资产为 IoT 卡且 `virtual_no` 为空时:
|
||
- 写 `tb_personal_customer_iccid`(按 ICCID 绑定),而非 `tb_personal_customer_device`
|
||
- `PersonalCustomerICCIDStore` 已有完整实现,直接注入使用
|
||
|
||
当资产为 IoT 卡且 `virtual_no` 不为空时:行为与切片 1 一致,不变。
|
||
|
||
### 修复 firstEverBind + markAssetAsSold
|
||
|
||
当前 `firstEverBind` 通过查 `tb_personal_customer_device WHERE virtual_no = ""` 来判断是否首次绑定,对无虚拟号的卡完全失效(所有无虚拟号的卡共用同一个空 key)。
|
||
|
||
修复方式:在 `Bind()` 内,按路径分别判断首绑:
|
||
- 有虚拟号路径:查 `tb_personal_customer_device WHERE virtual_no = ?`
|
||
- 无虚拟号路径:查 `tb_personal_customer_iccid WHERE iccid = ?`
|
||
|
||
首次绑定后正常触发 `markAssetAsSold()`,将卡的 `asset_status` 从在库(1)更新为已销售(2)。
|
||
|
||
### 扩展 OwnsAsset()
|
||
|
||
当资产为 IoT 卡时:
|
||
- 若卡有 `virtual_no`:查 `tb_personal_customer_device`(与切片 1 一致)
|
||
- 若卡无 `virtual_no`:查 `tb_personal_customer_iccid WHERE iccid = ? AND status = 1`
|
||
|
||
当资产为设备时:行为不变,只查 `tb_personal_customer_device`。
|
||
|
||
## Acceptance criteria
|
||
|
||
- [ ] 无虚拟号的单卡 C 端登录后,`tb_personal_customer_iccid` 中出现对应的绑定记录
|
||
- [ ] 无虚拟号单卡首次登录后,`tb_iot_card.asset_status` 变为 2(已销售)
|
||
- [ ] 无虚拟号单卡登录后,实名认证接口返回成功(不报"无权限")
|
||
- [ ] 无虚拟号单卡登录后,购买套餐接口归属验证通过
|
||
- [ ] 有虚拟号卡的全部行为与切片 1 完成后保持一致(无回归)
|
||
- [ ] 设备资产的全部行为不受影响
|
||
|
||
## Blocked by
|
||
|
||
`.scratch/customer-binding-architecture/issues/01-customer-binding-module-refactor.md`
|