package messageser import ( "91porn-server/app/appg" "91porn-server/app/middleware/authuser" "91porn-server/app/service/imser" "91porn-server/common" "91porn-server/common/db" "91porn-server/common/log" "91porn-server/common/services/message" "91porn-server/common/stderr" "91porn-server/models/cache/sysconfdata" "91porn-server/models/v/imusermod" "91porn-server/models/v/messagemod" "91porn-server/models/v/sessionmod" "91porn-server/models/v/sysconfmod" "91porn-server/models/v/txnmod" "91porn-server/models/v/usermod" "91porn-server/models/v/vidmod" "91porn-server/models/v/walletmod" "encoding/json" "fmt" "strconv" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) // QueryDynamics 查询动态列表 func QueryDynamics(uid uint64, req *messagemod.QueryCond) ([]messagemod.MsgDynamicsApp, bool, stderr.Code) { //now := time.Now() // 处理用户消息提示状态 _ = message.CancelTip(uid) //动态类型消息 var msgType []string if req.MsgType == 1 { msgType = []string{"like_msg", "like_comment_msg"} } else { msgType = []string{"comment_msg", "reply_comment_msg"} } cond := bson.M{"msgType": bson.M{"$in": msgType}, "takeUid": uid} mData, hasNext, err := messagemod.QueryDynamics(cond, int(req.PageSize), int(req.PageNumber)) if err != nil { return nil, false, stderr.ErrDbQueryError } if len(mData) > 0 { //用户查看自己的动态列表, 则消息接受者是查看用户 uids := []uint64{} vid := []primitive.ObjectID{} for _, m := range mData { uids = append(uids, m.SendUid) vid = append(vid, m.ObjId) } //查询帖子信息 vidMap, _ := vidmod.VideoMap(vid) if len(uids) > 0 { //查询用户信息 uData, err := usermod.FindUsersMapByUID(uids) if err != nil { return mData, false, stderr.ErrDbQueryError } //循环获取组装用户信息 for i, m := range mData { if uData[m.SendUid] != nil { mData[i].SendName = uData[m.SendUid].Name mData[i].SendAvatar = uData[m.SendUid].Portrait mData[i].SendGender = uData[m.SendUid].Gender //mData[i].SuperUser = uData[m.SendUid].GetSuperUser(now) mData[i].SuperUser = 0 mData[i].Awards = uData[m.SendUid].Awards mData[i].VipExpireDate = uData[m.SendUid].VipExpireDate mData[i].VipLevel = uData[m.SendUid].VipLevel } if m.MsgType == messagemod.LikeCommentMsg { mData[i].LikeCount = m.UserCount } else if m.MsgType == messagemod.LikeMsg { if video, ok := vidMap[m.ObjId]; ok { mData[i].LikeCount = video.LikeCount mData[i].ImgUrl = video.Cover } } } } //获取成功后, 将当前动态全部变为已读 common.Go(func() { //更新状态 messagemod.UpdDynamicsIsReadByUid(nil, uid) //清除redis appg.Redis.Del(messagemod.NoRedDynamicNumRedisKey + strconv.FormatUint(uid, 10)) }) } return mData, hasNext, stderr.Success } // 查询未读动态数 func QueryNoRedDynamicNum(uid uint64) (messagemod.NoReadMsgDynamicsCountApp, stderr.Code) { var ret = messagemod.NoReadMsgDynamicsCountApp{ DtCount: 0, MsgCount: 0, } //redis限制, 一分钟一次 key := messagemod.NoRedDynamicNumRedisKey + strconv.FormatUint(uid, 10) result, err := appg.Redis.Get(key) if err != nil || result == nil { mt := messagemod.GetDynamics() //包含私信 mt = append(mt, messagemod.PrivateLetterMsg) //动态类型消息 cond := bson.M{"msgType": bson.M{"$in": mt}, "takeUid": uid, "isRead": false} data, err := messagemod.FindByFilter(cond) if err != nil { log.Warn(fmt.Sprintf("messageser QueryNoRedDynamicNum messagemod.FindByFilter error:%+v:", err), log.Any("uid", uid)) return ret, stderr.ErrDbQueryError } if len(data) > 0 { for _, d := range data { if d.MsgType == messagemod.PrivateLetterMsg { ret.MsgCount += 1 } else { ret.DtCount += 1 } } } } else { err := json.Unmarshal([]byte(*result), &ret) if err != nil { log.Warn(fmt.Sprintf("messageser QueryNoRedDynamicNum json.Unmarshal error:%+v:", err), log.Any("uid", uid)) return ret, stderr.Failure } return ret, stderr.Success } //将对象转为字符串 jsonstr, err := json.Marshal(ret) if err != nil { log.Warn(fmt.Sprintf("messageser QueryNoRedDynamicNum json.Marshal error:%+v:", err), log.Any("uid", uid)) return ret, stderr.Success } //设置redis缓存 _ = appg.Redis.Set(key, string(jsonstr), time.Minute*1) return ret, stderr.Success } // QueryPrivateLetterSession 查询私信会话列表 func QueryPrivateLetterSession(uid uint64, req *sessionmod.QueryCond) ([]sessionmod.SessionApp, bool, stderr.Code) { // 处理用户消息提示状态 _ = message.CancelTip(uid) //查询当前用户的会话 cond := bson.M{"$or": []bson.M{{"sendUid": uid}, {"takeUid": uid}}} sData, hasNext, err := sessionmod.Query(cond, req) if err != nil { log.Warn(fmt.Sprintf("messageser Add sessionmod.Query error:%+v:", err), log.Any("uid", uid)) return nil, false, stderr.ErrDbQueryError } if len(sData) > 0 { var uids []uint64 for i, m := range sData { //查询未读条数 count, err := messagemod.Count(bson.M{"sessionId": m.SessionId, "takeUid": uid, "isRead": false}) if err != nil { log.Error(fmt.Sprintf("messageser Add messagemod.Count error:%+v:", err), log.Any("sessionId", m.ID.Hex()), log.Any("uid", uid)) continue } sData[i].NoReadNum = count //sendId是当前用户,则会话是有当前用户主动发起的,反之,对方用户主动发起 //注意, 会话列表用来展示对方用户头像姓名, 所有这里取对方用户信息 if uid == m.SendUid { uids = append(uids, m.TakeUid) continue } if uid == m.TakeUid { uids = append(uids, m.SendUid) } } if len(uids) > 0 { //查询用户信息 uData, err := usermod.FindUsersMapByUID(uids) if err != nil { log.Warn(fmt.Sprintf("messageser Add usermod.FindUsersMapByUID error:%+v:", err), log.Any("uids", uids), log.Any("uid", uid)) return sData, false, stderr.ErrDbQueryError } imByUID, _ := imusermod.IMUserIDMapByUIDs(uids) // uid → imUserId(imusermod 为准) //循环获取组装用户信息 for i, m := range sData { if uid == m.SendUid && uData[m.TakeUid] != nil { peer := uData[m.TakeUid] sData[i].UserId = peer.UID sData[i].PeerImUserID = imByUID[peer.UID] sData[i].UserName = peer.Name sData[i].UserAvatar = peer.Portrait continue } if uid == m.TakeUid && uData[m.SendUid] != nil { peer := uData[m.SendUid] sData[i].UserId = peer.UID sData[i].PeerImUserID = imByUID[peer.UID] sData[i].UserName = peer.Name sData[i].UserAvatar = peer.Portrait } } } } return sData, hasNext, stderr.Success } // DelSession 删除私信会话 func DelSession(uid uint64, sessionId string) stderr.Code { //查询会话是否存在 session, err := sessionmod.FindOneByFilter(bson.M{"sessionId": sessionId}) if err != nil { log.Warn(fmt.Sprintf("messageser DelSession sessionmod.FindOneByFilter error:%+v:", err), log.Any("uid", uid), log.Any("sessionId", sessionId)) return stderr.ErrDbQueryError } if session.ID.IsZero() { log.Warn("messageser DelSession session is null", log.Any("uid", uid), log.Any("sessionId", sessionId)) return stderr.Failure } if session.SendUid != uid && session.TakeUid != uid { log.Warn("messageser DelSession session.SendUid != uid && session.TakeUid != uid", log.Any("uid", uid), log.Any("sessionId", sessionId)) return stderr.Failure } //删除 err = sessionmod.Delete(bson.M{"sessionId": sessionId}) if err != nil { log.Warn(fmt.Sprintf("messageser DelSession sessionmod.Delete error:%+v:", err), log.Any("uid", uid), log.Any("sessionId", sessionId)) return stderr.ErrDbDeleteError } //删除会话对应的消息 _, err = messagemod.DeleteMsgBySessionId(sessionId) if err != nil { log.Warn(fmt.Sprintf("messageser DelSession messagemod.DeleteMsgBySessionId error:%+v:", err), log.Any("uid", uid), log.Any("sessionId", sessionId)) return stderr.ErrDbDeleteError } return stderr.Success } // GetSessionId 获取sessionId func GetSessionId(uid, takeUid uint64) string { //会话id sessionId := "" if uid == takeUid { log.Warn(fmt.Sprintf("messageser GetSessionId uid == takeUid"), log.Any("uid", uid), log.Any("takeUid", takeUid)) return sessionId } //先查询是否有会话信息 cond := bson.M{"$or": []bson.M{bson.M{"sendUid": uid, "takeUid": takeUid}, bson.M{"sendUid": takeUid, "takeUid": uid}}} session, err := sessionmod.FindOneByFilter(cond) if err != nil { log.Warn(fmt.Sprintf("messageser GetSessionId sessionmod.FindOneByFilter error:%+v:", err), log.Any("uid", uid)) return sessionId } if session.ID.IsZero() { sessionId = common.UUID() //新增session s := &sessionmod.Session{ SendUid: uid, TakeUid: takeUid, SessionId: sessionId, CreatedAt: time.Now(), } err := sessionmod.InsertOne(nil, s) if err != nil { log.Warn(fmt.Sprintf("messageser GetSessionId sessionmod.InsertOne error:%+v:", err), log.Any("session", s), log.Any("uid", uid), log.Any("takeUid", takeUid)) return "" } } else { sessionId = session.SessionId } return sessionId } // QueryPrivateLetterMsg 查询私信聊天列表 func QueryPrivateLetterMsg(uid uint64, req *messagemod.QueryMsgCond) ([]messagemod.MessageApp, bool, stderr.Code) { //私信类型消息 msgTypes := [...]string{string(messagemod.PrivateLetterMsg), string(messagemod.OfficialPrivateLetterMsg)} cond := bson.M{"msgType": bson.M{"$in": msgTypes}, "sessionId": req.SessionId} mData, hasNext, err := messagemod.Query(cond, int(req.PageSize), int(req.PageNumber)) if err != nil { return nil, false, stderr.ErrDbQueryError } if len(mData) > 0 { uids := []uint64{} for _, m := range mData { uids = append(uids, m.SendUid) uids = append(uids, m.TakeUid) } if len(uids) > 0 { //查询用户信息 uData, err := usermod.FindUsersMapByUID(uids) if err != nil { return mData, false, stderr.ErrDbQueryError } //循环获取组装用户信息 for i, m := range mData { if sendUser := uData[m.SendUid]; sendUser != nil { mData[i].SendName = sendUser.Name mData[i].SendAvatar = sendUser.Portrait } if takeUser := uData[m.TakeUid]; takeUser != nil { mData[i].TakeName = takeUser.Name mData[i].TakeAvatar = takeUser.Portrait } peerUID := m.SendUid if uid == m.SendUid { peerUID = m.TakeUid } if peer := uData[peerUID]; peer != nil { mData[i].PeerImUserID = imusermod.IMUserIDByUID(peer.UID) } } } } //请求列表时,将当前用户当前会话所有未读消息更新为已读 common.Go(func() { messagemod.UpdIsReadBySessionIdAndUid(nil, uid, req.SessionId) }) return mData, hasNext, stderr.Success } // AddPrivateLetter 新增私信消息 func AddPrivateLetter(uid uint64, req messagemod.AddMsgReqInfo) stderr.Code { data, err := usermod.FindUserByUID(uid) if err != nil || data == nil { log.Warn(fmt.Sprintf("messageser Add send user is null"), log.Any("uid", uid), log.Any("takeUid", req.TakeUid)) return stderr.CommentUserInfoErr } if data.HasBanned { return stderr.CommentUserHasBanned } if uid == req.TakeUid { log.Warn(fmt.Sprintf("messageser Add user cant self add msg"), log.Any("uid", uid), log.Any("takeUid", req.TakeUid)) return stderr.NoSelfAddMsg } //校验私信用户是否vip //if !data.IsVIP(time.Now()) { // return stderr.Success //} ////校验vip是否是充值过的,没有充值则不允许私信 //if uid > 150000 && !walletmod.IsRechargeUser(nil, uid) { // log.Warn(fmt.Sprintf("messageser Add user no recharge"), log.Any("uid", uid), log.Any("takeUid", req.TakeUid), log.Any("content", req.Content)) // return stderr.Success //} price := CheckChatPrice(data) wallet, err := walletmod.GetWallet(uid) if err != nil { return stderr.ErrParamError } if price > 0 && (wallet == nil || wallet.ID.IsZero()) { return stderr.InsufficientBalance } checkUserBalance, deAmt, deIncome := CheckUserBalance(wallet, price) if !checkUserBalance { return stderr.InsufficientBalance } //if wallet.Amount+wallet.Income<=0 || wallet.Amount+wallet.Income fengjin := false //查询被私信的用户是否存在 takeUser, err := usermod.FindUserByUID(req.TakeUid) if err != nil || takeUser == nil { fengjin = true } //校验用户请求频率,5秒内超过5次,则封禁 //key := "add-private-letter-" + strconv.FormatUint(uid, 10) //ret, err := appg.Redis.Get(key) //if !fengjin && err == nil { // var i int = 0 // if ret != nil { // i, _ = strconv.Atoi(*ret) // } // if i > 5 { // //封禁 // fengjin = true // } else { // i += 1 // appg.Redis.Set(key, strconv.Itoa(i), time.Second*5) // } //} //检测私信内容是否包含网址 //if truthutil.CheckStrIsUrl(req.Content) { // fengjin = true // //这里直接返回成功,让广告用户误以为成功了,免得一直来麻烦 // log.Warn("messageser Add checkStrIsUrl true", log.Any("uid", uid), log.Any("takeUid", req.TakeUid), log.Any("content", req.Content)) // return stderr.Success //} if fengjin { common.Go(func() { log.Warn("messageser Add takeUser == nil", log.Any("uid", uid), log.Any("takeUid", req.TakeUid), log.Any("content", req.Content)) //如果用户不存在, 则证明是脚本在刷私信, 封禁该用户 hasLocked := true lockReason := "脚本打广告的用户" doc := usermod.UserSelector{ HasLocked: &hasLocked, LockReason: &lockReason, } usermod.Update(uid, doc) //删除token authuser.RevokeTokenCache(uid) }) return stderr.CommentUserHasBanned } //会话id sessionId := "" //新增私聊信息之前, 先查询是否有会话信息 cond := bson.M{"$or": []bson.M{bson.M{"sendUid": uid, "takeUid": req.TakeUid}, bson.M{"sendUid": req.TakeUid, "takeUid": uid}}} session, err := sessionmod.FindOneByFilter(cond) if err != nil { log.Warn(fmt.Sprintf("messageser Add sessionmod.FindOneByFilter error:%+v:", err), log.Any("uid", uid)) return stderr.ErrDbQueryError } t := time.Now() if session.ID.IsZero() { sessionId = common.UUID() //新增session s := &sessionmod.Session{ SendUid: uid, TakeUid: req.TakeUid, SessionId: sessionId, CreatedAt: t, UpdatedAt: t, } err := sessionmod.InsertOne(nil, s) if err != nil { log.Warn(fmt.Sprintf("messageser Add sessionmod.InsertOne error:%+v:", err), log.Any("session", s), log.Any("uid", uid), log.Any("takeUid", req.TakeUid)) return stderr.ErrDbInsertError } } else { sessionId = session.SessionId } if deAmt > 0 || deIncome > 0 { // 扣除用户余额 plan := &walletmod.DebitPlan{ Amount: deAmt, Income: deIncome, } if err = appg.VideoDB.Trans(func(t *db.MongoTool) error { wallet, err := walletmod.Debit(t, plan, uid) if err != nil { //扣钱 return err } var txnLogs []txnmod.TransactionLog if deAmt > 0 { txnLogs = append(txnLogs, txnmod.TransactionLog{ UID: uid, Amount: -deAmt, ActualAmount: float64(-deAmt), TranType: txnmod.SendMsgDebitAmountGold.Key(), TranTypeInt: int64(txnmod.SendMsgDebitAmountGoldReturn), Desc: fmt.Sprintf("用户私信扣除%v个金币", deAmt), SysType: data.SysType, RealAmount: walletmod.GetRealAmount(wallet), }) } if deIncome > 0 { if err = txnmod.InsertTransactionLog(t, &txnmod.TransactionLog{ UID: uid, Amount: -deIncome, ActualAmount: float64(-deIncome), TranType: txnmod.SendMsgDebitIncomeGold.Key(), TranTypeInt: int64(txnmod.SendMsgDebitIncomeGold), Desc: fmt.Sprintf("用户私信扣除收益%v个金币", deIncome), SysType: data.SysType, RealAmount: walletmod.GetRealAmount(wallet), }); err != nil { return stderr.ErrDbQueryError } } if len(txnLogs) > 0 { if err = txnmod.InsertManyTransactionLog(t, txnLogs); err != nil { log.Warn(fmt.Sprintf("productser BuyVIP Transaction err %s", err.Error())) return err } } return nil }); err != nil { log.Warn(fmt.Sprintf("send meaasge Transaction err %s", err.Error())) return stderr.ErrDbUpdateError //通知消息 } } if err = imser.SendPrivateMessage(uid, req.TakeUid, req.Content, req.ImgUrl); err != nil { imser.LogSDKSendError(uid, req.TakeUid, err) return stderr.Failure } code := PublicAddMsg(messagemod.PublicAddMsg{ SendUid: uid, TakeUid: req.TakeUid, SessionId: sessionId, Content: req.Content, ImgUrl: req.ImgUrl, MsgType: messagemod.PrivateLetterMsg, }) if code != stderr.Success { return code } common.Go(func() { //更新会话预览消息 content := req.Content if len(req.ImgUrl) > 0 && content == "" { content = "发送了一张图片" } err := sessionmod.UpdOneByFilter(nil, bson.M{"sessionId": sessionId}, bson.M{"$set": bson.M{"preContent": content, "updatedAt": t}}) if err != nil { log.Warn(fmt.Sprintf("messageser Add messagemod.UpdOneByFilter error:%+v:", err), log.Any("sessionId", sessionId), log.Any("preContent", req.Content), log.Any("uid", uid)) } }) return stderr.Success } // SendIMPrivateLetter 走第三方 IM 通道发送私信: // 校验发送/接收方 → 校验余额 → 扣费(含 txn log)→ 调用 imser.SendPrivateMessage 走 IM SDK 投递。 func SendIMPrivateLetter(uid uint64, req messagemod.AddMsgReqInfo) stderr.Code { sender, err := usermod.FindUserByUID(uid) if err != nil || sender == nil { log.Warn("messageser SendIMPrivateLetter sender not found", log.Any("uid", uid), log.Any("takeUid", req.TakeUid)) return stderr.CommentUserInfoErr } if sender.HasBanned { return stderr.CommentUserHasBanned } if uid == req.TakeUid { return stderr.NoSelfAddMsg } takeUser, err := usermod.FindUserByUID(req.TakeUid) if err != nil || takeUser == nil { log.Warn("messageser SendIMPrivateLetter take user not found", log.Any("uid", uid), log.Any("takeUid", req.TakeUid)) return stderr.UserIsNotExists } price := CheckChatPrice(sender) if uid != 100001 && price > 0 { wallet, err := walletmod.GetWallet(uid) if err != nil { return stderr.ErrParamError } if wallet == nil || wallet.ID.IsZero() { return stderr.InsufficientBalance } ok, deAmt, deIncome := CheckUserBalance(wallet, price) if !ok { return stderr.InsufficientBalance } if err = appg.VideoDB.Trans(func(t *db.MongoTool) error { w, err := walletmod.Debit(t, &walletmod.DebitPlan{Amount: deAmt, Income: deIncome}, uid) if err != nil { return err } var logs []txnmod.TransactionLog if deAmt > 0 { logs = append(logs, txnmod.TransactionLog{ UID: uid, Amount: -deAmt, ActualAmount: float64(-deAmt), TranType: txnmod.SendMsgDebitAmountGold.Key(), TranTypeInt: int64(txnmod.SendMsgDebitAmountGoldReturn), Desc: fmt.Sprintf("用户私信(IM)扣除%v个金币", deAmt), SysType: sender.SysType, RealAmount: w.RealAmount(), }) } if deIncome > 0 { logs = append(logs, txnmod.TransactionLog{ UID: uid, Amount: -deIncome, ActualAmount: float64(-deIncome), TranType: txnmod.SendMsgDebitIncomeGold.Key(), TranTypeInt: int64(txnmod.SendMsgDebitIncomeGold), Desc: fmt.Sprintf("用户私信(IM)扣除收益%v个金币", deIncome), SysType: sender.SysType, RealAmount: w.RealAmount(), }) } if len(logs) > 0 { if err = txnmod.InsertManyTransactionLog(t, logs); err != nil { return err } } return nil }); err != nil { log.Warn("messageser SendIMPrivateLetter charge tx fail", log.Any("uid", uid), log.Any("takeUid", req.TakeUid), log.E(err)) return stderr.ErrDbUpdateError } } if err := imser.SendPrivateMessage(uid, req.TakeUid, req.Content, req.ImgUrl); err != nil { log.Error("messageser SendIMPrivateLetter imser.SendPrivateMessage fail", log.Any("uid", uid), log.Any("takeUid", req.TakeUid), log.E(err)) return stderr.Failure } return stderr.Success } func CheckChatPrice(u *usermod.User) int64 { configure, _ := sysconfdata.GetAllFromCache() if u == nil { return configure.GetInt(sysconfmod.SendMsgPrice) } var price int64 // 校验私信用户是否vip isVip := u.IsPaidVIP() if isVip && u.ChatPrice > 0 { price = u.ChatPrice } else if isVip && u.ChatPrice < 0 { // vip私信价格设置为负数的时候,则说明不需要钱(因为旧的用户数据这个字段都是0,所以都得读默认配置) price = 0 } else { // 非vip用户或者是旧的vip用户的u.ChatPrice字段为0的时候,都是默认读配置 price = configure.GetInt(sysconfmod.SendMsgPrice) } return price } func CheckUserBalance(w *walletmod.Wallet, price int64) (checkStatus bool, deAmt, deIncome int64) { totalAmt := w.Amount + w.Income var dAmt, dIncome int64 if totalAmt < price { return false, dAmt, dIncome } if totalAmt >= price && w.Amount >= price { dAmt = price } if totalAmt >= price && w.Amount < price { dAmt = w.Amount dIncome = price - w.Amount } return true, dAmt, dIncome } // ReadMsg 阅读消息 func ReadMsg(uid uint64, req messagemod.ReadMsgReqInfo) stderr.Code { if len(req.MsgIds) < 0 { log.Error(fmt.Sprintf("messageser readMsg req.MsgIds <= 0"), log.Any("uid", uid)) return stderr.Success } var ids []primitive.ObjectID for _, v := range req.MsgIds { id, _ := primitive.ObjectIDFromHex(v) ids = append(ids, id) } if len(ids) < 0 { log.Error(fmt.Sprintf("messageser readMsg ids <= 0"), log.Any("uid", uid)) return stderr.Success } //更新消息已读状态 err := messagemod.UpdIsRead(nil, uid, ids) if err != nil { log.Error(fmt.Sprintf("messageser messagemod.UpdIsRead error:%+v:", err), log.Any("ids", ids), log.Any("uid", uid)) return stderr.ErrDbUpdateError } return stderr.Success } // DynamicMsgUserGroup 同一obj下的相同操作归类相同用户 func DynamicMsgUserGroup(params messagemod.PublicAddMsg) stderr.Code { //查询用户信息 user, err := usermod.FindUserByUID(params.SendUid) if err != nil { return stderr.ErrDbQueryError } if user == nil || user.HasLocked { return stderr.UserIsNotExists } filter := bson.M{"takeUid": params.TakeUid, "msgType": params.MsgType, "objId": params.ObjId} msg, err := messagemod.FindOneByFilter(filter) if err != nil || msg.ID.IsZero() { params.UserCount = 1 params.UserGroup = []messagemod.UserInfo{ { Uid: user.UID, Name: user.Name, Avatar: user.Portrait, }, } // 发布消息并返回 return PublicAddMsg(params) } ug := msg.UserGroup for _, v := range ug { // 已经有记录直接返回 if v.Uid == params.SendUid { return stderr.Success } } // 取前9个用户 + 当前用户 if len(ug) >= 10 { ug = ug[:9] } ug = append([]messagemod.UserInfo{{ Uid: user.UID, Name: user.Name, Avatar: user.Portrait, }}, ug...) set := bson.M{"userCount": msg.UserCount + 1, "updatedAt": time.Now(), "userGroup": ug} err = messagemod.UpdOneByFilter(nil, bson.M{"_id": msg.ID}, bson.M{"$set": set}) if err != nil { log.Error(fmt.Sprintf("PublicMsgUserGroup error:%+v:", err), log.Any("set", set), log.Any("msgID", msg.ID)) return stderr.ErrDbQueryError } return stderr.Success } // PublicAddMsg 添加消息公共方法 func PublicAddMsg(prams messagemod.PublicAddMsg) stderr.Code { //查询用户信息 user, err := usermod.FindUserByUID(prams.SendUid) if err != nil { return stderr.ErrDbQueryError } if user == nil || user.HasLocked { return stderr.UserIsNotExists } now := time.Now() //新增消息 msg := &messagemod.Message{ SendUid: prams.SendUid, TakeUid: prams.TakeUid, MsgType: prams.MsgType, Content: prams.Content, ImgUrl: prams.ImgUrl, UserCount: prams.UserCount, UserGroup: prams.UserGroup, IsRead: false, CreatedAt: now, UpdatedAt: now, } // 是否加入未读提醒 needTip := false switch prams.MsgType { case messagemod.PrivateLetterMsg: //私信 msg.SessionId = prams.SessionId needTip = true case messagemod.OfficialPrivateLetterMsg: //官方私信 msg.SessionId = prams.SessionId msg.ContentType = prams.ContentType needTip = true case messagemod.FollowMsg: //关注 msg.Content = "关注了你" //needTip = true case messagemod.LikeMsg: //点赞 msg.Content = "点赞了你的帖子" msg.ObjId = prams.ObjId msg.ObjName = prams.ObjName msg.ObjType = prams.ObjType needTip = true case messagemod.ForwardMsg: //转发 msg.Content = "转发了你的帖子" msg.ObjId = prams.ObjId msg.ObjName = prams.ObjName case messagemod.CommentMsg: //评论 //msg.Content = "评论了你的帖子" msg.ObjId = prams.ObjId msg.ObjName = prams.ObjName msg.ObjCover = prams.ObjCover msg.ObjType = prams.ObjType needTip = true case messagemod.DesireMsg: msg.Content = "回复了你的工单" msg.ObjId = prams.ObjId msg.ObjName = prams.ObjName //needTip = true case messagemod.LikeCommentMsg: // 点赞评论 msg.Content = "点赞了你的评论" msg.ObjId = prams.ObjId msg.ObjName = prams.ObjName msg.ObjType = prams.ObjType needTip = true case messagemod.ReplyCommentMsg: // 回复评论 msg.Content = "回复了你的评论" msg.ObjId = prams.ObjId msg.ObjName = prams.ObjName msg.ObjType = prams.ObjType //needTip = true } _, err = messagemod.InsertOne(nil, msg) if err != nil { log.Warn(fmt.Sprintf("messageser Add messagemod.InsertOne error:%+v:", err), log.Any("message", msg)) return stderr.ErrDbQueryError } go func() { err = usermod.IncDynamic(prams.TakeUid) }() // 更新提示状态 if needTip { _ = message.SetTip(prams.TakeUid) } return stderr.Success } func HandleOfficialMsg(receiveUId uint64, content string, contentType int) stderr.Code { var ( uid uint64 = 100000 // 官方ID sessionId = "" // 会话ID ) //新增私聊信息之前, 先查询是否有会话信息 cond := bson.M{"$or": []bson.M{bson.M{"sendUid": uid, "takeUid": receiveUId}, bson.M{"sendUid": receiveUId, "takeUid": uid}}} session, err := sessionmod.FindOneByFilter(cond) if err != nil { log.Warn(fmt.Sprintf("messageser Add sessionmod.FindOneByFilter error:%+v:", err), log.Any("uid", uid)) return stderr.ErrDbQueryError } t := time.Now() if session.ID.IsZero() { sessionId = common.UUID() //新增session s := &sessionmod.Session{ SendUid: uid, TakeUid: receiveUId, SessionId: sessionId, CreatedAt: t, UpdatedAt: t, } err := sessionmod.InsertOne(nil, s) if err != nil { log.Warn(fmt.Sprintf("messageser Add sessionmod.InsertOne error:%+v:", err), log.Any("session", s), log.Any("uid", uid), log.Any("takeUid", receiveUId)) return stderr.ErrDbInsertError } } else { sessionId = session.SessionId } code := PublicAddMsg(messagemod.PublicAddMsg{ SendUid: uid, TakeUid: receiveUId, SessionId: sessionId, Content: content, ContentType: contentType, MsgType: messagemod.OfficialPrivateLetterMsg, }) if code != stderr.Success { return code } common.Go(func() { //更新会话预览消息 err := sessionmod.UpdOneByFilter(nil, bson.M{"sessionId": sessionId}, bson.M{"$set": bson.M{"preContent": content, "updatedAt": t}}) if err != nil { log.Warn(fmt.Sprintf("messageser Add messagemod.UpdOneByFilter error:%+v:", err), log.Any("sessionId", sessionId), log.Any("preContent", content), log.Any("uid", uid)) } }) return stderr.Success }