showliuzp 2025-10-27 18:17 采纳率: 83.8%
浏览 4
已结题

golang im消息类型转换

定义的消息类型

//文本
{
    "chat_text": "testing",
    "translate_chat_text": "testing"
}

//语音
{
    "duration": "4",
    "translate_chat_text": "",
    "voice_path ": "/image/20251022/706907294512944878.m4a"
}

//表情符号
{
    "chat_text": "[/1f600]",
    "translate_chat_text": "[1f600]"
}

//图片
{
    "height": "1920",
    "img_path": "/image/20251022/706969135126867853.jpg",
    "translate_chat_text": "",
    "width": "1080"
}

//礼物
{
    "chat_text": {
        "type": "gift",
        "gift_id": 4,
        "gift_title": "Cheers beer",
        "gift_gold": 30,
        "gift_icon": "/gift/cheers_beer.png",
        "gift_count": 1,
        "gift_url": "/gift/cheers_beer.svga"
    },
    "translate_chat_text": {
        "type": "quà tặng",
        "gift_id": 4,
        "gift_title": "Bia Cheers",
        "gift_gold": 30,
        "gift_icon": "/gift/cheers_beer.png",
        "gift_count": 1,
        "gift_url": "/gift/cheers_beer.svga"
    }
}

//im上报的文本类型聊天结构
        "data": {
            "id": "ac703410-da60-4c2f-ac0e-ed8a6c6fbfbd",
            "request_id": "chat_person",
            "status": 1,
            "content": {
                "chat_text": "可以的",
                "translate_chat_text": "Có thể."
            },
            "uid": 10,
            "to_uid": 4,
            "ip": "192.168.1.4",
            "ua": "ss",
            "nick_name": "xiaoxin",
            "avatar": ["/image/20251013/178851099961921089.jpg"]
        }

//im上报的礼物类型聊天结构
        "data": {
            "id": "ac703410-da60-4c2f-ac0e-ed8a6c6fbfbd",
            "request_id": "chat_person",
            "status": 1,
            "content": {
    "chat_text": {
        "type": "gift",
        "gift_id": 4,
        "gift_title": "Cheers beer",
        "gift_gold": 30,
        "gift_icon": "/gift/cheers_beer.png",
        "gift_count": 1,
        "gift_url": "/gift/cheers_beer.svga"
    },
    "translate_chat_text": {
        "type": "quà tặng",
        "gift_id": 4,
        "gift_title": "Bia Cheers",
        "gift_gold": 30,
        "gift_icon": "/gift/cheers_beer.png",
        "gift_count": 1,
        "gift_url": "/gift/cheers_beer.svga"
    }
}
,
            "uid": 10,
            "to_uid": 4,
            "ip": "192.168.1.4",
            "ua": "ss",
            "nick_name": "xiaoxin",
            "avatar": ["/image/20251013/178851099961921089.jpg"]
        }

data.content有可能是文本结构,也有可能是图片结构,还有可能是礼物结构,我在上面定义了文本、图片的结构,这是定义的解析content的结构

定义的解析客户端结构:
type ChatType struct{
    ChatText                    string `json:"chat_text"`  
TranslateChatText     string `json:"translate_chat_text"`
    Duration                    string `json:"duration"`
    VoicePath                 string `json:"voice_path"`
    Height                      string `json:"height"`
    ImgPath                   string `json:"img_path"`
    Width                       string `json:"width"`  
}

type ChatGift struct{
    Type        string  `json:"type"`
    GiftId      string  `json:"gift_id"`
    GiftTitle   string  `json:"gift_title"`
    GiftGold    int     `json:"gift_gold"`
    GiftIcon    string  `json:"gift_icon"`
    GiftCount   int     `json:"gift_count"`
    GiftUrl     string  `json:"gift_url"`
}

现在需要json解析到一个变量里,特别是礼物的,ChatTex怎么既能表示文本、又能表示礼物
  • 写回答

3条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-10-27 22:00
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案让您满意,请采纳、点赞、关注,非常感谢!
    .
    每日一句正能量,让它带给您好心情:每天给自己一个希望,试着不为明天烦恼,不为昨天叹息。
    .

    根据你提供的消息结构,我理解你需要一个统一的类型来处理不同类型的消息内容,特别是要解决chat_text字段既能是字符串又能是对象的问题。以下是解决方案:

    解决方案:使用自定义类型和灵活的结构设计

    1. 定义统一的消息结构

    type ChatMessage struct {
        ID        string      `json:"id"`
        RequestID string      `json:"request_id"`
        Status    int         `json:"status"`
        Content   ChatContent `json:"content"`
        UID       int64       `json:"uid"`
        ToUID     int64       `json:"to_uid"`
        IP        string      `json:"ip"`
        UA        string      `json:"ua"`
        NickName  string      `json:"nick_name"`
        Avatar    []string    `json:"avatar"`
    }
    
    
    // 使用灵活的类型处理chat_text字段
    type FlexibleText struct {
        StringValue string
        ObjectValue *ChatGift
        IsObject    bool
    }
    
    
    // 实现json.Unmarshaler接口
    func (f *FlexibleText) UnmarshalJSON(data []byte) error {
        // 尝试解析为字符串
        var str string
        if err := json.Unmarshal(data, &str); err == nil {
            f.StringValue = str
            f.IsObject = false
            return nil
        }
        
        // 尝试解析为ChatGift对象
        var gift ChatGift
        if err := json.Unmarshal(data, &gift); err == nil {
            f.ObjectValue = &gift
            f.IsObject = true
            return nil
        }
        
        return fmt.Errorf("无法解析为字符串或礼物对象")
    }
    
    
    // 统一的内容结构
    type ChatContent struct {
        ChatText           FlexibleText `json:"chat_text"`
        TranslateChatText  FlexibleText `json:"translate_chat_text"`
        Duration           string       `json:"duration"`
        VoicePath          string       `json:"voice_path"`
        Height             string       `json:"height"`
        ImgPath            string       `json:"img_path"`
        Width              string       `json:"width"`
    }
    

    2. 使用方法示例

    func main() {
        jsonData := `{
            "id": "ac703410-da60-4c2f-ac0e-ed8a6c6fbfbd",
            "request_id": "chat_person", 
            "status": 1,
            "content": {
                "chat_text": {
                    "type": "gift",
                    "gift_id": 4,
                    "gift_title": "Cheers beer",
                    "gift_gold": 30,
                    "gift_icon": "/gift/cheers_beer.png",
                    "gift_count": 1,
                    "gift_url": "/gift/cheers_beer.svga"
                },
                "translate_chat_text": {
                    "type": "quà tặng", 
                    "gift_id": 4,
                    "gift_title": "Bia Cheers",
                    "gift_gold": 30,
                    "gift_icon": "/gift/cheers_beer.png",
                    "gift_count": 1,
                    "gift_url": "/gift/cheers_beer.svga"
                }
            },
            "uid": 10,
            "to_uid": 4,
            "ip": "192.168.1.4",
            "ua": "ss",
            "nick_name": "xiaoxin",
            "avatar": ["/image/20251013/178851099961921089.jpg"]
        }`
        
        var msg ChatMessage
        if err := json.Unmarshal([]byte(jsonData), &msg); err != nil {
            panic(err)
        }
        
        // 判断消息类型并处理
        if msg.Content.ChatText.IsObject {
            fmt.Printf("收到礼物消息: %s\n", msg.Content.ChatText.ObjectValue.GiftTitle)
        } else {
            fmt.Printf("收到文本消息: %s\n", msg.Content.ChatText.StringValue)
        }
    }
    

    3. 辅助方法

    // 获取消息文本内容
    func (f *FlexibleText) GetText() string {
        if f.IsObject {
            return f.ObjectValue.GiftTitle
        }
        return f.StringValue
    }
    
    
    // 判断是否为礼物消息
    func (f *FlexibleText) IsGift() bool {
        return f.IsObject && f.ObjectValue != nil && f.ObjectValue.Type == "gift"
    }
    
    
    // 获取礼物信息
    func (f *FlexibleText) GetGift() *ChatGift {
        if f.IsGift() {
            return f.ObjectValue
        }
        return nil
    }
    

    4. 完整的使用示例

    func processMessage(data []byte) error {
        var msg ChatMessage
        if err := json.Unmarshal(data, &msg); err != nil {
            return err
        }
        
        content := msg.Content
        
        // 根据消息类型处理
        switch {
        case content.ChatText.IsGift():
            gift := content.ChatText.GetGift()
            fmt.Printf("处理礼物: %s, 价值: %d金币\n", gift.GiftTitle, gift.GiftGold)
            
        case content.ImgPath != "":
            fmt.Printf("处理图片: %s, 尺寸: %sx%s\n", content.ImgPath, content.Width, content.Height)
            
        case content.VoicePath != "":
            fmt.Printf("处理语音: %s, 时长: %s秒\n", content.VoicePath, content.Duration)
            
        default:
            fmt.Printf("处理文本: %s\n", content.ChatText.GetText())
        }
        
        return nil
    }
    

    关键点说明

    1. FlexibleText类型:通过自定义JSON解析来处理chat_text字段的两种可能类型
    2. 类型判断:使用IsObject字段区分字符串和对象类型
    3. 统一处理:所有消息类型都可以解析到同一个结构中
    4. 向后兼容:新增消息类型时只需扩展ChatContent结构

    这种设计能够很好地处理你提到的各种消息类型,特别是礼物消息中chat_text字段的双重身份问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 11月5日
  • 已采纳回答 10月28日
  • 创建了问题 10月27日