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
|
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