feat(03-02): DeviceSimBindingStore 新增 UpdateIsCurrentByDeviceID 方法
- 事务两步原子更新:先全部清空 is_current=false,再按 ICCID 设 true - 通过子查询定位 iot_card_id,避免跨表 JOIN 更新 - currentIccid 为空时仅清空,不做第二步设置
This commit is contained in:
@@ -200,3 +200,37 @@ func (s *DeviceSimBindingStore) GetBoundICCIDs(ctx context.Context, iccids []str
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UpdateIsCurrentByDeviceID 原子更新设备当前使用的卡标识
|
||||
// 使用事务两步操作:先全部设为 false,再将 currentIccid 对应行设为 true
|
||||
// currentIccid 为空字符串时,仅执行全部清空(无当前卡的情况)
|
||||
func (s *DeviceSimBindingStore) UpdateIsCurrentByDeviceID(ctx context.Context, deviceID uint, currentIccid string) error {
|
||||
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// 第一步:将该设备所有活跃绑定的 is_current 设为 false
|
||||
if err := tx.Model(&model.DeviceSimBinding{}).
|
||||
Where("device_id = ? AND bind_status = 1", deviceID).
|
||||
Update("is_current", false).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 第二步:将当前 ICCID 对应的绑定记录设为 is_current = true
|
||||
if currentIccid == "" {
|
||||
return nil
|
||||
}
|
||||
// 通过子查询找到对应的 iot_card_id(避免跨表 JOIN 更新)
|
||||
var iotCardID uint
|
||||
if err := tx.Table("tb_iot_card").
|
||||
Select("id").
|
||||
Where("iccid = ? AND deleted_at IS NULL", currentIccid).
|
||||
Scan(&iotCardID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if iotCardID == 0 {
|
||||
// 未找到对应卡记录,不更新(可能卡尚未入库)
|
||||
return nil
|
||||
}
|
||||
return tx.Model(&model.DeviceSimBinding{}).
|
||||
Where("device_id = ? AND iot_card_id = ? AND bind_status = 1", deviceID, iotCardID).
|
||||
Update("is_current", true).Error
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user