package im import ( "encoding/base64" "encoding/json" "errors" "fmt" "strings" "time" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/baseapi/utils/errlist" "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" ) func SendVendorV2(data SendData, vendorOrgCode string) (err error) { if data.VendorID == model.VendorIDMTWM { dataStr, _ := json.Marshal(data.Data) temp := string(dataStr) globals.SugarLogger.Debugf("SendVendorV2 temp=%s", temp) //if _, err = api.MtwmAPI.MsgSend(string(dataStr)); err != nil { if _, err = partner.CurAPIManager.GetAPI(model.VendorIDMTWM, vendorOrgCode).(*mtwmapi.API).MsgSend(string(dataStr)); err != nil { return err } } //if data.VendorID == model.VendorIDEBAI { //todo 后续添加 // err = nil //} err = ReadMsgFromClient(data.VendorID, "", data.Data) if err != nil { globals.SugarLogger.Debugf("SendVendorV2:%v", err) } return nil } // ReadMsgFromClient 存储客户端发送的消息 func ReadMsgFromClient(vendorID int, elmAppID string, msg interface{}) error { var ( err error jxMsg = &JXMsg{} errList errlist.ErrList userList = &UserMessageList{} ) data, err := json.Marshal(msg) if err != nil { errList.AddErr(fmt.Errorf("json处理数据错误:%v", err)) } if vendorID == VendorIDMT { var pushContent = mtwmapi.PushContentReq{} err = json.Unmarshal(data, &pushContent) jxMsg = &JXMsg{ SendType: SendTypeJx, MsgContent: pushContent, } userList = &UserMessageList{ VendorID: VendorIDMT, UserID: utils.Int2Str(pushContent.OpenUserID), LatestMsg: pushContent.MsgContent, LatestTime: pushContent.Cts, OrderID: "", } globals.SugarLogger.Debugf("ReadMsgFromClient pushContent.OrderID=%d", pushContent.OrderID) if pushContent.OrderID != 0 { userList.OrderID = utils.Int2Str(pushContent.OrderID) } globals.SugarLogger.Debugf("ReadMsgFromClient userList=%s", utils.Format4Output(userList, false)) } if vendorID == VendorIDELM { var ElmData = ebaiapi.ImMessageSend{} err = json.Unmarshal(data, &ElmData) jxMsg = &JXMsg{ SendType: SendTypeJx, MsgContent: ElmData, } userList = &UserMessageList{ VendorID: VendorIDELM, UserID: ElmData.PayLoad.GroupID, LatestMsg: ElmData.PayLoad.Content, LatestTime: int(ElmData.PayLoad.CreateTime), } } //1 存储详细聊天记录list if err = SetMessageDetail(jxMsg, vendorID, elmAppID); err != nil { errList.AddErr(fmt.Errorf("存储详细聊天记录错误:%v", err)) } //2 存储展示列表时单条数据 if err = SetUserList(jxMsg, userList, vendorID, elmAppID); err != nil { errList.AddErr(fmt.Errorf("存储STU聊天记录错误:%v", err)) } if errList.GetErrListAsOne() != nil { return fmt.Errorf("ReadMsgFromClient:%v", errList.GetErrListAsOne()) } return nil } // ReadMsgFromVendor 读取数据并存储到redis func ReadMsgFromVendor(vendorID int, elmAppID string, msg []byte) error { var ( err error jxMsg = &JXMsg{} vendorStoreID string errList errlist.ErrList userList = &UserMessageList{} ) if len(string(msg)) == 0 { errList.AddErr(fmt.Errorf("读取平台数据为空,请检查")) } if vendorID == VendorIDMT { var PushContentReq = mtwmapi.PushContentReq{} err = json.Unmarshal(msg, &PushContentReq) if FilterIm(PushContentReq.AppID, PushContentReq.MsgContent) { //自动回复消息过滤 return nil } jxMsg = &JXMsg{ SendType: SendTypeMt, MsgContent: PushContentReq, } userList = &UserMessageList{ VendorID: VendorIDMT, UserID: utils.Int2Str(PushContentReq.OpenUserID), LatestMsg: PushContentReq.MsgContent, LatestTime: PushContentReq.Cts, OrderID: "", } vendorStoreID = PushContentReq.AppPoiCode if PushContentReq.OrderID != 0 { userList.OrderID = utils.Int2Str(PushContentReq.OrderID) } } if vendorID == VendorIDELM { var ElmData = ebaiapi.ImMessageSend{} err = json.Unmarshal(msg, &ElmData) jxMsg = &JXMsg{ SendType: SendTypeElm, MsgContent: ElmData, } userList = &UserMessageList{ VendorID: VendorIDELM, UserID: ElmData.PayLoad.GroupID, LatestMsg: ElmData.PayLoad.Content, LatestTime: int(ElmData.PayLoad.CreateTime), } } //1 存储详细聊天记录list if err = SetMessageDetail(jxMsg, vendorID, elmAppID); err != nil { errList.AddErr(fmt.Errorf("存储详细聊天记录错误:%v", err)) } //2 存储展示列表时单条数据 if err = SetUserList(jxMsg, userList, vendorID, elmAppID); err != nil { errList.AddErr(fmt.Errorf("存储STU聊天记录错误:%v", err)) } //3 cid推送新消息 if err = PushMsgByCid(vendorStoreID, vendorID, string(msg)); err != nil { errList.AddErr(fmt.Errorf("向商家cid推送新消息错误:%v", err)) } if errList.GetErrListAsOne() != nil { return fmt.Errorf("ReadMsgFromVendor:%v", errList.GetErrListAsOne()) } return nil } // PushMsgByCid 通过cid push用户 func PushMsgByCid(vendorStoreID string, vendorID int, msg string) error { if err := push.NotifyImNewMessage(vendorStoreID, vendorID, msg); err != nil { return err } return nil } // SetMessageDetail 赋值 //格式 AppID:AppPoiCode:1:OpenUserID func SetMessageDetail(req *JXMsg, vendorID int, elmAppID string) error { //生成京西消息ID detail msgID := GenMsgDetailID(req, vendorID, elmAppID) data, _ := json.Marshal(req) globals.SugarLogger.Debugf("SetMessageDetail data=%s", string(data)) 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) globals.SugarLogger.Debugf("SetUserList data=%s", string(data)) 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.PushContentReq) msgID = utils.Int2Str(d1.AppID) + ":" + d1.AppPoiCode + ":1:" + utils.Int2Str(d1.OpenUserID) } if vendorID == VendorIDELM { var d2 = jxMsg.MsgContent.(ebaiapi.ImMessageSend) msgID = elmAppID + ":" + d2.PlatformShopID + ":3:" + 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.PushContentReq) msgID = utils.Int2Str(d1.AppID) + ":" + d1.AppPoiCode + ":1" } if vendorID == VendorIDELM { var d2 = jxMsg.MsgContent.(ebaiapi.ImMessageSend) msgID = elmAppID + ":" + d2.PlatformShopID + ":3" } return msgID } // GetImUserList 获取门店用户聊天列表 func GetImUserList(req []RelInfo) (map[string][]interface{}, error) { retVal := make(map[string][]interface{}, 0) 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.LRange(j) for _, v := range temp { //过滤过期信息 if FilterUserList(v) { retVal[j] = append(retVal[j], v) } } } return retVal, nil } func FilterUserList(val string) bool { retVal := UserMessageList{} err := json.Unmarshal([]byte(val), &retVal) if err != nil || time.Now().Unix()-int64(retVal.LatestTime) >= 3600*6 { return false } return true } // GetImChatDetail 获取门店用户聊天详情 func GetImChatDetail(req []UserRelInfo) (map[string][]interface{}, error) { retVal := make(map[string][]interface{}, 0) 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.LRange(j) for _, v := range temp { retVal[j] = append(retVal[j], v) //retVal["chatDetail"] = append(retVal["chatDetail"], v) } } return retVal, nil } // SetJxMsgRead 设置jx消息已读 userID(美团:openUserID;饿了么:groupID) func SetJxMsgRead(appID, vendorStoreID, vendorID, userID string) error { var ( temp = UserMessageList{} 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-- //cnt=0 重新赋值 temp = UserMessageList{ VendorID: v.VendorID, UserID: v.UserID, NewMessageNum: 0, LatestMsg: v.LatestMsg, LatestTime: v.LatestTime, } } } str, _ := json.Marshal(temp) err = rdb.RPush(key, str) } return nil } // DelRedisByKey 清除redis数据 func DelRedisByKey(keys []string) { var errList errlist.ErrList for _, key := range keys { err := rdb.Del(key) if err != nil { errList.AddErr(err) } } if errList.GetErrListAsOne() != nil { globals.SugarLogger.Debugf("DelRedisByKey err=%v", errList.GetErrListAsOne()) } return } var rel = map[int]string{ 589: "a81eb3df418d83d6a1a4b7c572156d2f", 5873: "41c479790a76f86326f89e8048964739", 4123: "df2c88338b85f830cebce2a9eab56628", } // DecryptIm 解密操作 func DecryptIm(appID int, msg string) (string, error) { data, _ := base64.StdEncoding.DecodeString(msg) key := utils.LimitUTF8StringLen2(rel[appID], 16) res, err := utils.AESCBCDecpryt(data, []byte(key), []byte(key)) if len(string(res)) > 0 && err == nil { return string(res), nil } return "", err } // FilterIm 过滤操作 func FilterIm(appID int, msg string) bool { var check = "[自动回复]" data, _ := DecryptIm(appID, msg) if len(data) > 0 && strings.Contains(data, check) { return true } return false }