fix: 购买时检查载体实名状态,已实名跳过 pending 直接激活
- iot_card 载体:扩展查询字段同时读取 real_name_status,已实名则保持 Active 不切换 pending - device 载体:通过 GORM 子查询统计绑定卡中已实名数量,count>0 则直接激活 - 查询出错时保守默认 false,不阻断购买流程 - 修复「先实名后购买」场景下套餐永久 pending 及购买后不自动复机的双重缺陷 Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -1776,16 +1776,32 @@ func (s *Service) activateMainPackage(ctx context.Context, tx *gorm.DB, order *m
|
|||||||
nextResetAt = packagepkg.CalculateNextResetTime(pkg.DataResetCycle, pkg.CalendarType, now, activatedAt)
|
nextResetAt = packagepkg.CalculateNextResetTime(pkg.DataResetCycle, pkg.CalendarType, now, activatedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// REALNAME-02: 后台囤货场景三维决策(卡类型 + 购买路径 + expiry_base)
|
// REALNAME-02: 后台囤货场景三维决策(卡类型 + 购买路径 + expiry_base + 实名状态)
|
||||||
// 注意:仅在 else 分支(立即激活)时才需要判断是否切换为等实名
|
// 注意:仅在 else 分支(立即激活)时才需要判断是否切换为等实名
|
||||||
if !hasActiveMain {
|
if !hasActiveMain {
|
||||||
// 查询卡类型(行业卡永远直接激活,不等实名)
|
// 查询卡类型(行业卡永远直接激活,不等实名)
|
||||||
|
// 同时查询载体当前实名状态:已实名则跳过 pending,直接激活
|
||||||
var cardCategory string
|
var cardCategory string
|
||||||
|
var currentlyRealnamed bool
|
||||||
if carrierType == "iot_card" {
|
if carrierType == "iot_card" {
|
||||||
var card model.IotCard
|
var card model.IotCard
|
||||||
if err := tx.Select("card_category").First(&card, carrierID).Error; err == nil {
|
if err := tx.Select("card_category", "real_name_status").First(&card, carrierID).Error; err == nil {
|
||||||
cardCategory = card.CardCategory
|
cardCategory = card.CardCategory
|
||||||
|
currentlyRealnamed = card.RealNameStatus == constants.RealNameStatusVerified
|
||||||
}
|
}
|
||||||
|
// err != nil 时 currentlyRealnamed 保守默认 false,不阻断购买流程
|
||||||
|
} else if carrierType == "device" {
|
||||||
|
// 子查询:统计该设备绑定的已实名卡数量(GORM 自动注入 deleted_at IS NULL)
|
||||||
|
var count int64
|
||||||
|
subQuery := tx.Model(&model.DeviceSimBinding{}).
|
||||||
|
Select("iot_card_id").
|
||||||
|
Where("device_id = ? AND bind_status = 1", carrierID)
|
||||||
|
if err := tx.Model(&model.IotCard{}).
|
||||||
|
Where("id IN (?) AND real_name_status = 1", subQuery).
|
||||||
|
Count(&count).Error; err == nil {
|
||||||
|
currentlyRealnamed = count > 0
|
||||||
|
}
|
||||||
|
// err != nil 时保守默认 false,不阻断购买流程
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断是否 C 端购买(C 端购买前已做实名前置检查,直接激活)
|
// 判断是否 C 端购买(C 端购买前已做实名前置检查,直接激活)
|
||||||
@@ -1794,12 +1810,18 @@ func (s *Service) activateMainPackage(ctx context.Context, tx *gorm.DB, order *m
|
|||||||
if cardCategory != "industry" && !isCEndPurchase {
|
if cardCategory != "industry" && !isCEndPurchase {
|
||||||
// 后台囤货路径:按 expiry_base 决定是否等实名
|
// 后台囤货路径:按 expiry_base 决定是否等实名
|
||||||
if pkg.ExpiryBase != "from_purchase" {
|
if pkg.ExpiryBase != "from_purchase" {
|
||||||
// from_activation(默认):等实名后激活
|
if currentlyRealnamed {
|
||||||
status = constants.PackageUsageStatusPending
|
s.logger.Info("购买时载体已实名,直接激活套餐",
|
||||||
pendingRealnameActivation = true
|
zap.String("carrier_type", carrierType),
|
||||||
activatedAt = time.Time{}
|
zap.Uint("carrier_id", carrierID))
|
||||||
expiresAt = time.Time{}
|
} else {
|
||||||
nextResetAt = nil
|
// from_activation(默认):未实名,等实名后激活
|
||||||
|
status = constants.PackageUsageStatusPending
|
||||||
|
pendingRealnameActivation = true
|
||||||
|
activatedAt = time.Time{}
|
||||||
|
expiresAt = time.Time{}
|
||||||
|
nextResetAt = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// from_purchase:立即激活,status 已为 Active,保持不变
|
// from_purchase:立即激活,status 已为 Active,保持不变
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user