Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+861
View File
@@ -0,0 +1,861 @@
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 → imUserIdimusermod 为准)
//循环获取组装用户信息
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
}