All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 4m39s
46 lines
3.4 KiB
Markdown
46 lines
3.4 KiB
Markdown
## Why
|
||
|
||
当前系统存在两个关联缺陷,且缺陷 A 的影响远不止套餐激活本身:
|
||
|
||
**缺陷 A**:代理商**先给设备/卡实名,再购买 `expiry_base=from_activation` 的套餐**,系统未检查当前实名状态,无条件将套餐标记为 `pending_realname_activation=true`(待生效,status=0)。这不仅导致套餐永久无法激活,还**连带阻断了购买后的自动复机链路**:`tryResumeAfterPayment` 在检查到 `activatedCount=0` 时直接跳过,即使卡此前因无套餐而停机,购买成功后也不会自动开机。
|
||
|
||
**缺陷 B**:卡首次实名(0→1)时,实名轮询处理器只触发卡级套餐激活,不处理该卡所属设备的设备级套餐,导致设备级套餐在"购买后某张卡实名"场景下永不激活,同样无法触发设备下绑定卡的复机。
|
||
|
||
修复后的规则:**`from_activation` 套餐在购买时检查实名状态,已实名则直接激活(同时保障复机链路正常触发);卡首次实名时同时触发其所属设备的设备级套餐激活与复机**。
|
||
|
||
## What Changes
|
||
|
||
- **购买时实名状态检查**:在 `activateMainPackage` 中,当判断 `expiry_base != "from_purchase"` 时,额外检查载体当前实名状态:
|
||
- `iot_card`:查询该卡的 `real_name_status`
|
||
- `device`:通过 `tb_device_sim_binding` 查询是否存在任意已实名的绑定卡
|
||
- 已实名 → 直接激活(`status=Active`),`tryResumeAfterPayment` 检查到 `activatedCount>0` 后正常触发复机链路
|
||
- 未实名 → 保持原有逻辑等待实名触发
|
||
- **实名轮询触发设备级激活与复机**:在 `PollingRealnameHandler` 的卡首次实名(0→1)路径中,额外查询该卡所属设备,若设备存在则同时提交 `carrier_type=device` 的 `TaskTypePackageFirstActivation` 任务;任务执行后 `ActivateByRealname` 内部会调用 `ResumeCardIfStopped("device", deviceID)` 触发设备下符合条件卡的复机
|
||
- `NewPollingRealnameHandler` 构造函数新增 `*postgres.DeviceSimBindingStore` 参数
|
||
|
||
**复机行为说明**:自动复机仅针对由轮询系统引起的停机(`stop_reason` 为 `no_package`、`traffic_exhausted`、`not_realname`),手动停机(`manual`)不受影响,设备下每张卡独立判断实名状态后再决定是否复机。
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
|
||
无新能力,均为现有逻辑的修正。
|
||
|
||
### Modified Capabilities
|
||
|
||
- `package-realname-activation`:补充"购买时载体已实名则直接激活"的决策分支,以及"设备下卡实名时触发设备级套餐激活"的联动规则
|
||
- `polling-task-handlers`:`PollingRealnameHandler` 新增 `DeviceSimBindingStore` 依赖,新增 `triggerDeviceRealnameActivation` 函数
|
||
|
||
## Impact
|
||
|
||
**涉及文件**:
|
||
- `internal/service/order/service.go`(`activateMainPackage` 函数,~1782-1807 行)
|
||
- `internal/task/polling_realname_handler.go`(结构体、构造函数、新增函数)
|
||
- `pkg/queue/handler.go`(`registerPollingHandlers` 中的构造调用)
|
||
|
||
**数据库**:无 schema 变更,无迁移
|
||
|
||
**API**:无接口变更,对外透明
|
||
|
||
**当前问题设备的直接影响**:设备 `862639076038233` 的套餐(`tb_package_usage.id=1`)需要手动修复(修改 `pending_realname_activation=false`、激活套餐),代码修复仅防止新订单再次陷入同样问题。手动修复套餐后,还需手动触发设备复机(或等待轮询系统下次评估),因为历史停机事件不会被追溯重放。
|