feat(admin): 添加模型算力点配置和扣费功能
- 在管理后台设置页面添加模型算力点配置表格 - 实现后端AI接口调用时按模型扣除用户算力点 - 添加算力点余额检查和不足时的错误处理 - 在credit_logs中记录AI调用消费流水 - 更新前端远程调用后刷新用户信息显示 - 文档中补充模型算力点配置说明
This commit is contained in:
+27
-3
@@ -54,7 +54,7 @@ func proxyAIGetRequest(w http.ResponseWriter, r *http.Request, path string) {
|
||||
return
|
||||
}
|
||||
request.Header.Set("Authorization", "Bearer "+channel.APIKey)
|
||||
copyAIResponse(w, request)
|
||||
copyAIResponse(w, request, nil)
|
||||
}
|
||||
|
||||
func proxyAIRequest(w http.ResponseWriter, r *http.Request, path string) {
|
||||
@@ -64,6 +64,21 @@ func proxyAIRequest(w http.ResponseWriter, r *http.Request, path string) {
|
||||
Fail(w, "AI 接口请求失败")
|
||||
return
|
||||
}
|
||||
user, ok := service.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
Fail(w, "未登录或权限不足")
|
||||
return
|
||||
}
|
||||
credits, err := service.ModelCost(modelName)
|
||||
if err != nil {
|
||||
log.Printf("AI proxy read model cost failed: model=%s err=%v", modelName, err)
|
||||
Fail(w, "AI 接口请求失败")
|
||||
return
|
||||
}
|
||||
if err := service.EnsureUserCredits(user.ID, credits); err != nil {
|
||||
FailError(w, err)
|
||||
return
|
||||
}
|
||||
channel, err := service.SelectModelChannel(modelName)
|
||||
if err != nil {
|
||||
log.Printf("AI proxy select channel failed: model=%s err=%v", modelName, err)
|
||||
@@ -80,10 +95,12 @@ func proxyAIRequest(w http.ResponseWriter, r *http.Request, path string) {
|
||||
if contentType != "" {
|
||||
request.Header.Set("Content-Type", contentType)
|
||||
}
|
||||
copyAIResponse(w, request)
|
||||
copyAIResponse(w, request, func() error {
|
||||
return service.ConsumeUserCredits(user.ID, modelName, credits, path)
|
||||
})
|
||||
}
|
||||
|
||||
func copyAIResponse(w http.ResponseWriter, request *http.Request) {
|
||||
func copyAIResponse(w http.ResponseWriter, request *http.Request, beforeWrite func() error) {
|
||||
response, err := http.DefaultClient.Do(request)
|
||||
if err != nil {
|
||||
log.Printf("AI proxy request failed: url=%s err=%v", request.URL.String(), err)
|
||||
@@ -98,6 +115,13 @@ func copyAIResponse(w http.ResponseWriter, request *http.Request) {
|
||||
Fail(w, "AI 接口请求失败")
|
||||
return
|
||||
}
|
||||
if beforeWrite != nil {
|
||||
if err := beforeWrite(); err != nil {
|
||||
log.Printf("AI proxy before write failed: url=%s err=%v", request.URL.String(), err)
|
||||
FailError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for key, values := range response.Header {
|
||||
if strings.EqualFold(key, "Content-Length") {
|
||||
|
||||
Reference in New Issue
Block a user