package handler import ( "errors" "strings" "unicode/utf8" "kefu-cloud/server/internal/storage" ) const ( maxTextMessageLength = 2000 ) // imagePublicBase 由 SetupRoutes 注入,用于校验图片消息 URL 归属 var imagePublicBase string func SetImagePublicBase(base string) { imagePublicBase = storage.NormalizePublicBase(base) } func validateMessageContent(messageType, content string) (string, error) { switch messageType { case "text": content = strings.TrimSpace(content) if content == "" { return "", errors.New("消息内容不能为空") } if utf8.RuneCountInString(content) > maxTextMessageLength { return "", errors.New("单条文本消息不能超过 2000 字") } return content, nil case "image": content = strings.TrimSpace(content) if content == "" { return "", errors.New("图片地址不能为空") } // 开发阶段直接切换为对象存储 URL,不再接受 base64 if strings.HasPrefix(content, "data:") { return "", errors.New("请先上传图片,勿直接发送 base64") } if !strings.HasPrefix(content, "http://") && !strings.HasPrefix(content, "https://") { return "", errors.New("图片地址无效") } if imagePublicBase != "" && !storage.IsAllowedObjectURL(imagePublicBase, content) { return "", errors.New("图片地址不在允许的存储域名下") } if len(content) > 2000 { return "", errors.New("图片地址过长") } return content, nil default: return "", errors.New("不支持的消息类型") } }