@@ -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 → 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
|
||||
}
|
||||
Reference in New Issue
Block a user