package im import ( "encoding/json" "errors" "fmt" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/baseapi/platformapi/ebaiapi" "git.rosy.net.cn/baseapi/platformapi/mtwmapi" "git.rosy.net.cn/baseapi/utils" push "git.rosy.net.cn/jx-callback/business/jxutils/unipush" "git.rosy.net.cn/jx-callback/globals/api" "github.com/gorilla/websocket" ) // SendToVendor 向平台发消息 func SendToVendor(msg []byte) { var ( //w http.ResponseWriter sendData SendData err error elmAppID = api.EbaiAPI.GetSource() ) //解析数据 if err = json.Unmarshal(msg, &sendData); err != nil { return } //存储数据 ReadMsgFromClient(sendData.VendorID, elmAppID, sendData.Data) //发送信息 if sendData.VendorID == VendorIDMT { temp, _ := json.Marshal(sendData.Data) Send(temp) } if sendData.VendorID == VendorIDELM { param := sendData.Data.(ebaiapi.BusinessSendMsgReq) if err := api.EbaiAPI.BusinessSendMsg(¶m); err != nil { globals.SugarLogger.Debugf("elm发送信息错误:%v", err) return } } if err != nil { ClientRender(Fail, FailMsg, map[string]string{ "errMsg": fmt.Sprintf("%v", err), }) return } else { ClientRender(SuccessCode, SuccessMsg, map[string]interface{}{ "vendorID": sendData.VendorID, "msg": "ok", }) return } } func Send(data []byte) { //生成完整url fullUrl := GenFullUrl() //clientID暂时不用 conn, resp, err := websocket.DefaultDialer.Dial(fullUrl, nil) if err != nil || resp.StatusCode != 101 { fmt.Printf("连接失败:%v http响应不成功", err) } //关闭 defer func(conn *websocket.Conn) { err := conn.Close() if err != nil { return } }(conn) err = conn.WriteMessage(websocket.TextMessage, data) if err != nil { fmt.Println(err) } for { _, msg, err := conn.ReadMessage() if err != nil { break } else { temp := string(msg) if temp != HeartCheckSuccess { ReadMsgFromVendor(VendorIDMT, "", msg) } } fmt.Printf("%s receive: %s\n", conn.RemoteAddr(), string(msg)) } return } // ReadMsgFromClient 存储客户端发送的消息 func ReadMsgFromClient(vendorID int, elmAppID string, msg interface{}) { var ( err error jxMsg = &JXMsg{} userList = &UserMessageList{} ) data, err := json.Marshal(msg) if err != nil { return } if vendorID == VendorIDMT { var MtSingleChat = mtwmapi.SingleChat{} err = json.Unmarshal(data, &MtSingleChat) jxMsg = &JXMsg{ SendType: SendTypeJx, MsgContent: MtSingleChat, } userList = &UserMessageList{ VendorID: VendorIDMT, UserID: utils.Int2Str(MtSingleChat.OpenUserID), LatestMsg: MtSingleChat.MsgContent, LatestTime: MtSingleChat.Cts, } } if vendorID == VendorIDELM { var ElmData = ebaiapi.ImMessageSend{} err = json.Unmarshal(data, &ElmData) jxMsg = &JXMsg{ SendType: SendTypeJx, MsgContent: ElmData, } userList = &UserMessageList{ VendorID: VendorIDMT, UserID: ElmData.PayLoad.GroupID, LatestMsg: ElmData.PayLoad.Content, LatestTime: int(ElmData.PayLoad.CreateTime), } } //1 存储详细聊天记录list if err = SetMessageDetail(jxMsg, vendorID, elmAppID); err != nil { globals.SugarLogger.Debugf("ReadMsgFromClient SetMessageDetail err:=%v\n", err) //return } //2 存储展示列表时单条数据 if err = SetUserList(jxMsg, userList, vendorID, elmAppID); err != nil { globals.SugarLogger.Debugf("ReadMsgFromClient SetUserList err:=%v\n", err) //return } } // ReadMsgFromVendor 读取数据并存储到redis func ReadMsgFromVendor(vendorID int, elmAppID string, msg []byte) { if string(msg) == "" { return } var ( err error vendorStoreID string jxMsg = &JXMsg{} userList = &UserMessageList{} ) if vendorID == VendorIDMT { var MtSingleChat = mtwmapi.SingleChat{} err = json.Unmarshal(msg, &MtSingleChat) jxMsg = &JXMsg{ SendType: SendTypeMt, MsgContent: MtSingleChat, } userList = &UserMessageList{ VendorID: VendorIDMT, UserID: utils.Int2Str(MtSingleChat.OpenUserID), LatestMsg: MtSingleChat.MsgContent, LatestTime: MtSingleChat.Cts, } vendorStoreID = MtSingleChat.AppPoiCode } if vendorID == VendorIDELM { var ElmData = ebaiapi.ImMessageSend{} err = json.Unmarshal(msg, &ElmData) jxMsg = &JXMsg{ SendType: SendTypeElm, MsgContent: ElmData, } userList = &UserMessageList{ VendorID: VendorIDMT, UserID: ElmData.PayLoad.GroupID, LatestMsg: ElmData.PayLoad.Content, LatestTime: int(ElmData.PayLoad.CreateTime), } } //1 存储详细聊天记录list if err = SetMessageDetail(jxMsg, vendorID, elmAppID); err != nil { globals.SugarLogger.Debugf("ReadMsgFromVendor SetMessageDetail err:=%v\n", err) //return } //2 存储展示列表时单条数据 if err = SetUserList(jxMsg, userList, vendorID, elmAppID); err != nil { globals.SugarLogger.Debugf("ReadMsgFromVendor SetUserList err:=%v\n", err) //return } //3 cid推送新消息 err = PushMsgByCid(vendorStoreID, vendorID) //4 长链接通知给客户端 ToClientChan <- clientInfo{Code: SuccessCode, Msg: fmt.Sprintf("%v", err), Data: jxMsg} return } // PushMsgByCid 通过cid push用户 func PushMsgByCid(vendorStoreID string, vendorID int) error { if err := push.NotifyImNewMessage(vendorStoreID, vendorID); err != nil { return err } return nil } // SetMessageDetail 赋值 //格式 AppID:AppPoiCode:10:OpenUserID func SetMessageDetail(req *JXMsg, vendorID int, elmAppID string) error { //生成京西消息ID detail msgID := GenMsgDetailID(req, vendorID, elmAppID) data, _ := json.Marshal(req) err := rdb.RPush(msgID, string(data)) ok, err := rdb.ExpireResult(msgID, ExpireTimeDay) if err != nil || !ok { return err } return nil } // SetUserList 赋值 //AppPoiCode:10 [userid1:{SingleChat},userid2:{}] func SetUserList(jxMsg *JXMsg, userList *UserMessageList, vendorID int, elmAppID string) error { //生成msgID msgID := GenMsgListID(jxMsg, vendorID, elmAppID) //获取未读消息条数并删除旧数据 cnt, err := GetNewAndTrim(msgID, userList.UserID) if cnt > 0 { userList.NewMessageNum = cnt } else { userList.NewMessageNum = 1 } //存储当前数据 data, _ := json.Marshal(userList) err = rdb.RPush(msgID, string(data)) ok, err := rdb.ExpireResult(msgID, ExpireTimeDay) if err != nil || !ok { return err } return nil } // GetNewAndTrim 获取未读条数并清除旧数据 func GetNewAndTrim(key string, flag string) (cnt int, err error) { cnt = 0 if n, err := rdb.Exists(key); n > 0 && err == nil { s2 := rdb.LRange(key) for i := 0; i < len(s2); i++ { v := UserMessageList{} _ = json.Unmarshal([]byte(s2[i]), &v) if v.UserID == flag { err = rdb.LSet(key, i, "del") err = rdb.LRem(key, 0, "del") s2 = append(s2[:i], s2[i+1:]...) i-- if v.NewMessageNum == 0 { //目前为首条 cnt++ //赋值1 } else { cnt = v.NewMessageNum } } } } else { return 0, nil } return cnt, err } // GenMsgDetailID 生成查询详细聊天记录ID func GenMsgDetailID(jxMsg *JXMsg, vendorID int, elmAppID string) (msgID string) { if vendorID == VendorIDMT { var d1 = jxMsg.MsgContent.(mtwmapi.SingleChat) msgID = utils.Int2Str(d1.AppID) + ":" + d1.AppPoiCode + ":10:" + utils.Int2Str(d1.OpenUserID) } if vendorID == VendorIDELM { var d2 = jxMsg.MsgContent.(ebaiapi.ImMessageSend) msgID = elmAppID + ":" + d2.PlatformShopID + ":11:" + d2.PayLoad.GroupID } return msgID } // GenMsgListID 生成展示列表时单条数据ID(部分) func GenMsgListID(jxMsg *JXMsg, vendorID int, elmAppID string) (msgID string) { if vendorID == VendorIDMT { var d1 = jxMsg.MsgContent.(mtwmapi.SingleChat) msgID = utils.Int2Str(d1.AppID) + ":" + d1.AppPoiCode + ":10" } if vendorID == VendorIDELM { var d2 = jxMsg.MsgContent.(ebaiapi.ImMessageSend) msgID = elmAppID + ":" + d2.PlatformShopID + ":11" } return msgID } // GetImUserList 获取门店用户聊天列表 func GetImUserList(req []RelInfo) (retVal []interface{}, err error) { if len(req) == 0 { return nil, errors.New("msgID不允许为空") } var keys []string for _, i := range req { key := i.AppID + ":" + i.VendorStoreID + ":" + i.VendorID keys = append(keys, key) } for _, j := range keys { temp := rdb.Get(j) retVal = append(retVal, temp) } return retVal, err } // GetImChatDetail 获取门店用户聊天详情 func GetImChatDetail(req []UserRelInfo) (retVal []interface{}, err error) { if len(req) == 0 { return nil, errors.New("msgID不允许为空") } var keys []string for _, i := range req { key := i.AppID + ":" + i.VendorStoreID + ":" + i.VendorID + ":" + i.UserID keys = append(keys, key) } for _, j := range keys { temp := rdb.Get(j) retVal = append(retVal, temp) } return retVal, err } // SetJxMsgRead 设置jx消息已读 userID(美团:openUserID;饿了么:groupID) func SetJxMsgRead(appID, vendorStoreID, vendorID, userID string) error { key := appID + ":" + vendorStoreID + ":" + vendorID if n, err := rdb.Exists(key); n > 0 && err == nil { s2 := rdb.LRange(key) for i := 0; i < len(s2); i++ { v := UserMessageList{} _ = json.Unmarshal([]byte(s2[i]), &v) if v.UserID == userID { err = rdb.LSet(key, i, "del") err = rdb.LRem(key, 0, "del") s2 = append(s2[:i], s2[i+1:]...) i-- } } } return nil }