fix(设备实名): 无当前卡时按绑定卡实名回退并初始化单槽当前卡
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 14m42s

- 设备资产解析外层 real_name_status:存在当前使用卡时沿用该卡状态,无任何当前卡时任一有效绑定卡已实名即视为已实名
- 手工绑定与设备导入:设备最大槽位为 1 且有效绑定唯一时,在同一事务内将该绑定初始化为当前使用卡;多卡设备不推断
- 同步 asset-device、personal-customer 主 Spec;归档变更并附存量核对清单(75 条单槽唯一待修复绑定,其中 16 条已实名)
This commit is contained in:
2026-09-18 17:48:17 +08:00
parent d24e777a4c
commit 54c4ec7ba4
12 changed files with 465 additions and 4 deletions

View File

@@ -247,13 +247,23 @@ func (s *Service) buildDeviceResolveResponse(ctx context.Context, device *model.
})
}
// RealNameStatus 以当前使用卡为准;无当前卡视为实名
// RealNameStatus 以当前使用卡为准;无当前卡时,任一有效绑定卡已实名即视为实名
hasCurrentCard := false
for _, c := range cards {
if isCurrentMap[c.ID] {
resp.RealNameStatus = c.RealNameStatus
hasCurrentCard = true
break
}
}
if !hasCurrentCard {
for _, c := range cards {
if c.RealNameStatus == constants.RealNameStatusVerified {
resp.RealNameStatus = constants.RealNameStatusVerified
break
}
}
}
// RealNameAt 取所有绑定卡中最早的实名时间
for _, c := range cards {
if c.FirstRealnameAt == nil {

View File

@@ -146,12 +146,27 @@ func (s *Service) BindCard(ctx context.Context, deviceID uint, req *dto.BindCard
}
err = s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := postgres.NewDeviceSimBindingStore(tx, nil).Create(ctx, binding); err != nil {
txBindingStore := postgres.NewDeviceSimBindingStore(tx, nil)
if err := txBindingStore.Create(ctx, binding); err != nil {
return err
}
// 单槽设备绑定后有效绑定唯一,当前使用卡不可能是其他卡,直接初始化为当前卡
if device.MaxSimSlots == 1 {
activeCount, err := txBindingStore.CountByDeviceID(ctx, device.ID)
if err != nil {
return err
}
if activeCount == 1 {
if err := tx.WithContext(ctx).Model(&model.DeviceSimBinding{}).
Where("id = ?", binding.ID).Update("is_current", true).Error; err != nil {
return err
}
binding.IsCurrent = true
}
}
item.Binding = binding
item.BindingRole = constants.AuditResourceRoleDeviceCreatedBinding
item.BindingAfter = bindingStateData(binding, constants.BindStatusBound, false)
item.BindingAfter = bindingStateData(binding, constants.BindStatusBound, binding.IsCurrent)
return s.appendDeviceBindingAudit(ctx, tx, constants.AuditActionDeviceCardBound, "设备绑定 IoT 卡", constants.AuditResultSuccess,
device,
map[string]any{"slot_position": req.SlotPosition, "iot_card_id": nil},