feat(admin): 添加模型算力点配置和扣费功能
- 在管理后台设置页面添加模型算力点配置表格 - 实现后端AI接口调用时按模型扣除用户算力点 - 添加算力点余额检查和不足时的错误处理 - 在credit_logs中记录AI调用消费流水 - 更新前端远程调用后刷新用户信息显示 - 文档中补充模型算力点配置说明
This commit is contained in:
@@ -318,6 +318,45 @@ func AdjustUserCredits(id string, credits int) (model.User, error) {
|
||||
return user, err
|
||||
}
|
||||
|
||||
func EnsureUserCredits(userID string, credits int) error {
|
||||
if credits <= 0 {
|
||||
return nil
|
||||
}
|
||||
ok, err := repository.HasUserCredits(userID, credits)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return safeMessageError{message: "算力点不足"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ConsumeUserCredits(userID string, modelName string, credits int, path string) error {
|
||||
if credits <= 0 {
|
||||
return nil
|
||||
}
|
||||
user, ok, err := repository.ConsumeUserCredits(userID, credits, now())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return safeMessageError{message: "算力点不足"}
|
||||
}
|
||||
extra, _ := json.Marshal(map[string]string{"model": modelName, "path": path})
|
||||
_, err = repository.SaveCreditLog(model.CreditLog{
|
||||
ID: newID("credit"),
|
||||
UserID: userID,
|
||||
Type: model.CreditLogTypeAIConsume,
|
||||
Amount: -credits,
|
||||
Balance: user.Credits,
|
||||
Remark: "调用模型 " + modelName,
|
||||
Extra: string(extra),
|
||||
CreatedAt: now(),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func ListCreditLogs(q model.Query) (model.CreditLogList, error) {
|
||||
logs, total, err := repository.ListCreditLogs(q)
|
||||
if err != nil {
|
||||
|
||||
@@ -65,6 +65,15 @@ func normalizePublicSetting(setting model.PublicSetting) model.PublicSetting {
|
||||
if setting.ModelChannel.AvailableModels == nil {
|
||||
setting.ModelChannel.AvailableModels = []string{}
|
||||
}
|
||||
if setting.ModelChannel.ModelCosts == nil {
|
||||
setting.ModelChannel.ModelCosts = []model.ModelCost{}
|
||||
}
|
||||
for i := range setting.ModelChannel.ModelCosts {
|
||||
setting.ModelChannel.ModelCosts[i].Model = strings.TrimSpace(setting.ModelChannel.ModelCosts[i].Model)
|
||||
if setting.ModelChannel.ModelCosts[i].Credits < 0 {
|
||||
setting.ModelChannel.ModelCosts[i].Credits = 0
|
||||
}
|
||||
}
|
||||
if setting.ModelChannel.AllowCustomChannel == nil {
|
||||
enabled := true
|
||||
setting.ModelChannel.AllowCustomChannel = &enabled
|
||||
@@ -72,6 +81,20 @@ func normalizePublicSetting(setting model.PublicSetting) model.PublicSetting {
|
||||
return setting
|
||||
}
|
||||
|
||||
func ModelCost(modelName string) (int, error) {
|
||||
settings, err := repository.GetSettings()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
modelName = strings.TrimSpace(modelName)
|
||||
for _, item := range normalizePublicSetting(settings.Public).ModelChannel.ModelCosts {
|
||||
if item.Model == modelName {
|
||||
return item.Credits, nil
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func normalizePrivateSetting(setting model.PrivateSetting) model.PrivateSetting {
|
||||
if setting.Channels == nil {
|
||||
setting.Channels = []model.ModelChannel{}
|
||||
|
||||
Reference in New Issue
Block a user