Files
jx-callback/business/partner/purchase/im/im.go
richboo111 d72d5dc75d 1
2023-05-15 09:18:08 +08:00

484 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package im
import (
"encoding/json"
"errors"
"fmt"
"git.rosy.net.cn/jx-callback/business/jxutils"
"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"
"git.rosy.net.cn/jx-callback/globals/api"
"github.com/gorilla/websocket"
)
// SendToVendor 向平台发消息
func SendToVendor(msg []byte) {
var (
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)
if sendData.Data.(map[string]interface{})["app_id"] == nil {
globals.SugarLogger.Debug("SendToVendor appId=null")
return
}
Send(temp, sendData.Data.(map[string]interface{})["app_id"])
return
}
if sendData.VendorID == VendorIDELM {
param := sendData.Data.(ebaiapi.BusinessSendMsgReq)
if err := api.EbaiAPI.BusinessSendMsg(&param); err != nil {
globals.SugarLogger.Debugf("elm发送信息错误%v", err)
return
}
}
return
}
func Send(data []byte, appID interface{}) {
//根据appID生成完整url
fullUrl := GenFullUrl(appID.(float64)) //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()
temp := string(msg)
res := JsonCommon(HeartSuccessWord)
fmt.Printf("Send %s receive: %s\n", conn.RemoteAddr(), string(msg))
if err != nil {
break
} else if temp == res {
continue
} else {
ReadMsgFromVendor(VendorIDMT, "", msg)
}
}
}
// MtInit 发送心跳
func MtInit() {
data := []byte(HeartCheckMsg)
//生成完整url
url := GenFullUrl2()
//主连接
jxutils.CallMsgHandlerAsync(func() {
conn, resp, err := websocket.DefaultDialer.Dial(url.UrlMain, 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)
//client连接事件
client := NewClient(url.ClientIDMain, conn, ClientTypeMt)
Manager.Connect <- client
err = conn.WriteMessage(websocket.TextMessage, data)
if err != nil {
fmt.Println(err)
}
for {
_, msg, err := conn.ReadMessage()
temp := string(msg)
res := JsonCommon(HeartCheckSuccess)
fmt.Printf("MtInit %s receive: %s\n", conn.RemoteAddr(), string(msg))
if err != nil {
break
} else if temp == res {
continue
} else {
ReadMsgFromVendor(VendorIDMT, "", msg)
}
}
}, url.ClientIDMain)
//副连接
if url.UrlSub != "" {
jxutils.CallMsgHandlerAsync(func() {
connSub, respSub, errSub := websocket.DefaultDialer.Dial(url.UrlSub, nil)
if errSub != nil || respSub.StatusCode != 101 {
fmt.Printf("连接失败:%v http响应不成功", errSub)
}
//关闭
defer func(conn *websocket.Conn) {
err := conn.Close()
if err != nil {
return
}
}(connSub)
//client连接事件
client := NewClient(url.ClientIDSub, connSub, ClientTypeMt)
Manager.Connect <- client
errSub = connSub.WriteMessage(websocket.TextMessage, data)
if errSub != nil {
fmt.Println(errSub)
}
for {
_, msg, err := connSub.ReadMessage()
temp := string(msg)
res := JsonCommon(HeartCheckSuccess)
if err != nil || temp == res {
break
} else {
ReadMsgFromVendor(VendorIDMT, "", msg)
}
fmt.Printf("MtInit %s connSub:receive: %s\n", connSub.RemoteAddr(), string(msg))
}
}, url.ClientIDSub)
}
}
// 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: VendorIDELM,
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: VendorIDELM,
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 长链接通知给客户端
if err != nil {
ToClientChan <- clientInfo{Code: SuccessCode, Msg: fmt.Sprintf("%v", err), Data: jxMsg}
} else {
ToClientChan <- clientInfo{Code: SuccessCode, Msg: SuccessMsg, 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 + ":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.SingleChat)
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 {
retVal[j] = append(retVal[j], v)
//暂时写死
//retVal["userList"] = append(retVal["userList"], v)
}
}
return retVal, nil
}
// 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
}