fix(ai): 修复AI代理请求和图片生成功能

- 添加详细的错误日志记录,包括请求读取、渠道选择、请求构建和响应处理的失败情况
- 统一AI接口请求失败返回消息为"AI 接口请求失败"
- 添加对上游响应状态码>=400的检查和错误处理
- 在JWT解析中验证签名方法有效性,防止无效登录状态
- 移除JWT密钥警告日志,改为运行时生成随机密钥
- 调整应用配置模态框中云端和本地选项的显示顺序
- 添加图片生成元数据记录生成类型、模型、尺寸、质量和参考图等信息
- 实现空图片节点直接生成图片而不保留空框的功能
- 完善图片重试逻辑,优先使用保存的元数据进行重试
- 添加参考图片丢失时的错误提示
- 修复图片节点样式圆角显示问题
- 更新AI代理路径为/api/v1/*保持OpenAI风格
- 添加系统设置页面的安全警告提示
This commit is contained in:
HouYunFei
2026-05-21 17:50:14 +08:00
parent f9b2759499
commit d40b9b53c2
14 changed files with 214 additions and 51 deletions
+16 -4
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"io"
"log"
"mime"
"mime/multipart"
"net/http"
@@ -27,17 +28,20 @@ func AIChatCompletions(w http.ResponseWriter, r *http.Request) {
func proxyAIRequest(w http.ResponseWriter, r *http.Request, path string) {
body, contentType, modelName, err := readAIRequest(r)
if err != nil {
Fail(w, err.Error())
log.Printf("AI proxy request read failed: %v", err)
Fail(w, "AI 接口请求失败")
return
}
channel, err := service.SelectModelChannel(modelName)
if err != nil {
Fail(w, err.Error())
log.Printf("AI proxy select channel failed: model=%s err=%v", modelName, err)
Fail(w, "AI 接口请求失败")
return
}
request, err := http.NewRequest(http.MethodPost, service.BuildModelChannelURL(channel, path), bytes.NewReader(body))
if err != nil {
Fail(w, err.Error())
log.Printf("AI proxy build request failed: url=%s err=%v", service.BuildModelChannelURL(channel, path), err)
Fail(w, "AI 接口请求失败")
return
}
request.Header.Set("Authorization", "Bearer "+channel.APIKey)
@@ -46,11 +50,19 @@ func proxyAIRequest(w http.ResponseWriter, r *http.Request, path string) {
}
response, err := http.DefaultClient.Do(request)
if err != nil {
Fail(w, err.Error())
log.Printf("AI proxy request failed: url=%s err=%v", request.URL.String(), err)
Fail(w, "AI 接口请求失败")
return
}
defer response.Body.Close()
if response.StatusCode >= http.StatusBadRequest {
payload, _ := io.ReadAll(io.LimitReader(response.Body, 4096))
log.Printf("AI upstream error: url=%s status=%d body=%s", request.URL.String(), response.StatusCode, strings.TrimSpace(string(payload)))
Fail(w, "AI 接口请求失败")
return
}
for key, values := range response.Header {
if strings.EqualFold(key, "Content-Length") {
continue