diff --git a/pkg/common/qwen/qwen_vl.go b/pkg/common/qwen/qwen_vl.go index c503468..4ce8688 100644 --- a/pkg/common/qwen/qwen_vl.go +++ b/pkg/common/qwen/qwen_vl.go @@ -68,8 +68,8 @@ func VL(videoURLs []string, imageURLs []string, text string, model string) (resp return nil, errors.New("序列化请求失败") } - // 发送请求 - body, err := utils.PostBytes(modelQwen.DashscopeVLURL, map[string]interface{}{ + // 发送请求,使用PostBytesHeader获取状态码和响应体 + statusCode, body, err := utils.PostBytesHeader(modelQwen.DashscopeVLURL, map[string]interface{}{ "Authorization": "Bearer " + modelQwen.DashscopeAPIKey, "Content-Type": "application/json", }, jsonData) @@ -78,6 +78,25 @@ func VL(videoURLs []string, imageURLs []string, text string, model string) (resp return nil, errors.New("请求视觉AI失败") } + // 检查状态码,如果不是200,尝试解析错误响应 + if statusCode != 200 { + // 尝试解析错误响应 + var errorResp struct { + Error struct { + Message string `json:"message"` + Type string `json:"type"` + Code string `json:"code"` + } `json:"error"` + } + if err := json.Unmarshal(body, &errorResp); err == nil && errorResp.Error.Message != "" { + zap.L().Error("VL API error", zap.Int("status", statusCode), zap.String("message", errorResp.Error.Message)) + return nil, fmt.Errorf("%s", errorResp.Error.Message) + } + // 如果无法解析错误响应,返回通用错误 + zap.L().Error("VL API error", zap.Int("status", statusCode), zap.String("body", string(body))) + return nil, fmt.Errorf("接口返回错误") + } + // 解析响应 var result modelQwen.VLResponse if err = json.Unmarshal(body, &result); err != nil { diff --git a/pkg/service/ai/video_vl.go b/pkg/service/ai/video_vl.go index 77afc6d..bbe5707 100644 --- a/pkg/service/ai/video_vl.go +++ b/pkg/service/ai/video_vl.go @@ -4,7 +4,7 @@ import ( "errors" "fonchain-fiee/pkg/common/qwen" "fonchain-fiee/pkg/service" - "fonchain-fiee/pkg/utils" + "strings" "github.com/gin-gonic/gin" ) @@ -31,32 +31,31 @@ func AIVideoVL(ctx *gin.Context) { return } - // 检查视频大小,每个视频不能超过55MB - const maxVideoSizeMB = 55 - for _, videoURL := range req.Videos { - if videoURL == "" { - continue - } - // 获取视频文件大小(单位:MB) - sizeMB, err := utils.GetRemoteFileSize(videoURL) - if err != nil { - service.Error(ctx, errors.New("获取视频大小失败: "+err.Error())) - return - } - // 检查是否超过55MB - if sizeMB > maxVideoSizeMB { - service.Error(ctx, errors.New("作品视频数不能超过55MB")) - return - } + if len(req.Videos) > 1 { + service.Error(ctx, errors.New("当前只能选一个视频")) + return } + Prompt := "请你详细描述视频和图片中的内容分别是什么" + // 调用VL函数进行AI理解 - result, err := qwen.VL(req.Videos, req.Images, req.Text, req.Model) + result, err := qwen.VL(req.Videos, req.Images, Prompt, req.Model) if err != nil { - service.Error(ctx, err) + // 检查是否是文件下载超时错误(内容过大) + errMsg := err.Error() + if contains(errMsg, "Download multimodal file timed out") || contains(errMsg, "timed out") { + service.Error(ctx, errors.New("报错内容过大,请重新选择")) + } else { + service.Error(ctx, errors.New("ai分析帖子内容失败")) + } return } // 返回AI返回的数据 service.Success(ctx, result) } + +// contains 检查字符串是否包含子字符串(不区分大小写) +func contains(s, substr string) bool { + return strings.Contains(strings.ToLower(s), strings.ToLower(substr)) +}