From 961a845b28bbdd7c731764a29792767b4969f2ab Mon Sep 17 00:00:00 2001 From: fengsilin Date: Tue, 24 Mar 2026 10:43:43 +0800 Subject: [PATCH] fix: implement proper upsert in BatchUpsertChannelPricing The previous implementation only did INSERT without handling conflicts. Now uses GORM's OnConflict clause to properly update existing records when (model_name, channel_id) unique constraint is violated. On conflict updates: quota_type, model_ratio, completion_ratio, model_price, tag_ids, updated_time Co-Authored-By: Claude Opus 4.6 --- model/channel_pricing.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/model/channel_pricing.go b/model/channel_pricing.go index 7b2453a..6680de0 100644 --- a/model/channel_pricing.go +++ b/model/channel_pricing.go @@ -3,6 +3,7 @@ package model import ( "github.com/QuantumNous/new-api/common" "gorm.io/gorm" + "gorm.io/gorm/clause" ) // QuotaType 计费类型 @@ -85,9 +86,26 @@ func BatchUpsertChannelPricing(pricings []*ChannelPricing) error { } now := common.GetTimestamp() for _, cp := range pricings { - cp.CreatedTime = now cp.UpdatedTime = now + // 仅在 CreatedTime 为空时设置(新记录) + if cp.CreatedTime == 0 { + cp.CreatedTime = now + } } - // GORM 的 GORM:OnConflict 会自动处理唯一键冲突 - return DB.Create(&pricings).Error + // 使用 GORM 的 OnConflict 实现 upsert + // 唯一索引为 idx_model_channel (model_name, channel_id) + return DB.Clauses(clause.OnConflict{ + Columns: []clause.Column{ + {Name: "model_name"}, + {Name: "channel_id"}, + }, + DoUpdates: clause.AssignmentColumns([]string{ + "quota_type", + "model_ratio", + "completion_ratio", + "model_price", + "tag_ids", + "updated_time", + }), + }).Create(&pricings).Error }