merge: integrate PR #430 channel model batch operations

This commit is contained in:
ddCat committed 2026-09-07 15:31:43 +08:00
commit ad5b2d5a14
9 files changed
+361 -39

No files matched your search

+36 -6
View File
@@ -231,11 +231,39 @@ func (r *Repository) PopulateChannelModelPriceTier(item *model.ChannelModel) err
}
func (r *Repository) DeleteChannelModel(channelID string, id string, modelsJSON string, now time.Time) error {
return r.db.Transaction(func(tx *gorm.DB) error {
deleted, err := r.DeleteChannelModels(channelID, []string{id}, modelsJSON, now)
if err != nil {
return err
}
if deleted != 1 {
return gorm.ErrRecordNotFound
}
return nil
}
// DeleteChannelModels atomically removes a selection and refreshes the channel's
// compatibility model list. Any active route or task reference aborts the whole
// transaction so a bulk action cannot leave the administrator with a partial result.
func (r *Repository) DeleteChannelModels(channelID string, ids []string, modelsJSON string, now time.Time) (int64, error) {
ids = uniqueStrings(ids)
if len(ids) == 0 {
return 0, gorm.ErrRecordNotFound
}
var deleted int64
err := r.db.Transaction(func(tx *gorm.DB) error {
var existing int64
if err := tx.Model(&model.ChannelModel{}).
Where("channel_id = ? AND id IN ?", channelID, ids).
Count(&existing).Error; err != nil {
return err
}
if existing != int64(len(ids)) {
return gorm.ErrRecordNotFound
}
var activeReferences int64
if err := tx.Table("logical_model_routes AS route").
Joins("JOIN logical_models AS logical_model ON logical_model.active_revision_id = route.logical_model_revision_id").
Where("route.channel_model_id = ?", id).
Where("route.channel_model_id IN ?", ids).
Count(&activeReferences).Error; err != nil {
return err
}
@@ -243,7 +271,7 @@ func (r *Repository) DeleteChannelModel(channelID string, id string, modelsJSON
return ErrChannelModelInUse
}
if err := tx.Model(&model.Task{}).
Where("channel_model_id = ? AND status IN ?", id, []model.TaskStatus{model.TaskStatusQueued, model.TaskStatusRunning}).
Where("channel_model_id IN ? AND status IN ?", ids, []model.TaskStatus{model.TaskStatusQueued, model.TaskStatusRunning}).
Count(&activeReferences).Error; err != nil {
return err
}
@@ -251,15 +279,15 @@ func (r *Repository) DeleteChannelModel(channelID string, id string, modelsJSON
return ErrChannelModelInUse
}
result := tx.Model(&model.ChannelModel{}).
Where("id = ? AND channel_id = ?", id, channelID).
Where("id IN ? AND channel_id = ?", ids, channelID).
Updates(map[string]any{"enabled": false, "price_version": gorm.Expr("price_version + 1"), "updated_at": now})
if result.Error != nil {
return result.Error
}
if result.RowsAffected != 1 {
if result.RowsAffected != int64(len(ids)) {
return gorm.ErrRecordNotFound
}
if err := tx.Where("id = ? AND channel_id = ?", id, channelID).Delete(&model.ChannelModel{}).Error; err != nil {
if err := tx.Where("id IN ? AND channel_id = ?", ids, channelID).Delete(&model.ChannelModel{}).Error; err != nil {
return err
}
channelResult := tx.Model(&model.ModelChannel{}).
@@ -271,8 +299,10 @@ func (r *Repository) DeleteChannelModel(channelID string, id string, modelsJSON
if channelResult.RowsAffected != 1 {
return gorm.ErrRecordNotFound
}
deleted = result.RowsAffected
return nil
})
return deleted, err
}
func (r *Repository) CreateMissingChannelModels(items []model.ChannelModel) (int64, error) {