package model import ( "fmt" "net/url" "regexp" "strconv" ) // @某个QQ用户的结构体 type AtMessage struct { Type string `json:"type"` Data AtData `json:"data"` } // @消息数据结构体 type AtData struct { QQ string `json:"qq"` } // 回复消息结构体 type ReplyMessage struct { Type string `json:"type"` Data ReplyData `json:"data"` } // 回复消息数据结构体 type ReplyData struct { ID string `json:"id"` } type CQImageMessage struct { File string SubType string FileID string URL string FileSize int FileUnique string } func (msg *CQImageMessage) ToCQString() (string, error) { // URL 转义 escapedURL := url.QueryEscape(msg.URL) // 构造 CQ:image 字符串 cqString := fmt.Sprintf("[CQ:image,file=%s,sub_type=%s,file_id=%s,url=%s,file_size=%d,file_unique=%s]", msg.File, msg.SubType, msg.FileID, escapedURL, msg.FileSize, msg.FileUnique) return cqString, nil } func ParseCQImageMessage(data string) (*CQImageMessage, error) { // 使用正则表达式提取各个字段 re := regexp.MustCompile(`CQ:image,file=(.*?),sub_type=(.*?),file_id=(.*?),url=(.*?),file_size=(\d+),file_unique=(.*?)\]`) matches := re.FindStringSubmatch(data) if len(matches) < 7 { return nil, fmt.Errorf("数据格式不正确") } // 转换file_size为整数 fileSize, err := strconv.Atoi(matches[5]) if err != nil { return nil, fmt.Errorf("解析 file_size 出错: %v", err) } // 处理URL转义 decodedURL, err := url.QueryUnescape(matches[4]) if err != nil { return nil, fmt.Errorf("URL 转义失败: %v", err) } // 返回解析后的结构体 return &CQImageMessage{ File: matches[1], SubType: matches[2], FileID: matches[3], URL: decodedURL, FileSize: fileSize, FileUnique: matches[6], }, nil }