golang-im聊天
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

308 lines
7.9 KiB

  1. package friend
  2. import (
  3. "context"
  4. svc "gim/internal/business/comm/service"
  5. "gim/internal/business/comm/utils"
  6. "gim/internal/logic/domain/message/repo"
  7. "gim/internal/logic/proxy"
  8. "gim/pkg/db"
  9. "gim/pkg/gerrors"
  10. "gim/pkg/grpclib"
  11. "gim/pkg/pb"
  12. "gim/pkg/rpc"
  13. "google.golang.org/protobuf/proto"
  14. "time"
  15. )
  16. type friendService struct{}
  17. var FriendService = new(friendService)
  18. // List 获取好友列表
  19. func (s *friendService) List(ctx context.Context, userId int64) ([]*pb.Friend, error) {
  20. friends, err := FriendRepo.List(userId, FriendStatusAgree)
  21. if err != nil {
  22. return nil, err
  23. }
  24. userIds := make(map[int64]int32, len(friends))
  25. for i := range friends {
  26. userIds[friends[i].FriendId] = 0
  27. }
  28. resp, err := rpc.GetBusinessIntClient().GetUsers(ctx, &pb.GetUsersReq{UserIds: userIds})
  29. if err != nil {
  30. return nil, err
  31. }
  32. var infos = make([]*pb.Friend, len(friends))
  33. for i := range friends {
  34. friend := pb.Friend{
  35. UserId: friends[i].FriendId,
  36. Remarks: friends[i].Remarks,
  37. Extra: friends[i].Extra,
  38. }
  39. user, ok := resp.Users[friends[i].FriendId]
  40. if ok {
  41. friend.Nickname = user.Nickname
  42. friend.Sex = user.Sex
  43. friend.AvatarUrl = user.AvatarUrl
  44. friend.UserExtra = user.Extra
  45. }
  46. infos[i] = &friend
  47. }
  48. return infos, nil
  49. }
  50. // DeleteFriend 删除好友
  51. func (*friendService) DeleteFriend(ctx context.Context, userId, friendId int64) error {
  52. err := FriendRepo.Delete(userId, friendId)
  53. if err != nil {
  54. return err
  55. }
  56. return nil
  57. }
  58. // AddFriend 添加好友
  59. func (*friendService) AddFriend(ctx context.Context, userId, friendId int64, remarks, description string) error {
  60. masterId, _ := grpclib.GetCtxMasterId(ctx)
  61. isAutoAddFriends := svc.SysCfgGet(masterId, "is_auto_add_friends")
  62. friend, err := FriendRepo.Get(userId, friendId)
  63. if err != nil {
  64. return err
  65. }
  66. if friend != nil {
  67. if friend.Status == FriendStatusApply {
  68. if isAutoAddFriends != "1" {
  69. return nil
  70. }
  71. //TODO::防止第一次加好友失败
  72. db.DB.Where("user_id = ? and friend_id = ?", userId, friendId).Delete(&friend)
  73. }
  74. if friend.Status == FriendStatusAgree {
  75. return gerrors.ErrAlreadyIsFriend
  76. }
  77. }
  78. now := time.Now()
  79. err = FriendRepo.Save(&Friend{
  80. UserId: userId,
  81. FriendId: friendId,
  82. Remarks: remarks,
  83. Status: FriendStatusApply,
  84. CreateTime: now,
  85. UpdateTime: now,
  86. })
  87. if err != nil {
  88. return err
  89. }
  90. resp, err := rpc.GetBusinessIntClient().GetUser(ctx, &pb.GetUserReq{UserId: userId})
  91. if err != nil {
  92. return err
  93. }
  94. err = proxy.MessageProxy.PushToUser(ctx, friendId, pb.PushCode_PC_ADD_FRIEND, &pb.AddFriendPush{
  95. FriendId: userId,
  96. Nickname: resp.User.Nickname,
  97. AvatarUrl: resp.User.AvatarUrl,
  98. Description: description,
  99. }, true)
  100. if err != nil {
  101. return err
  102. }
  103. //TODO::判断是否需要`自动添加好友`
  104. //if isAutoAddFriends == "1" && resp.User.IsAutoAddedFriends == 1 {
  105. if isAutoAddFriends == "1" {
  106. respFriend, err := rpc.GetBusinessIntClient().GetUser(ctx, &pb.GetUserReq{UserId: friendId})
  107. if err != nil {
  108. return err
  109. }
  110. utils.FilePutContents("addFriend", utils.SerializeStr(map[string]interface{}{
  111. "is_auto_add_friends": isAutoAddFriends,
  112. "user": resp.User,
  113. }))
  114. if description == "社交人脉圈添加好友" {
  115. return FriendService.AgreeAddFriend(ctx, friendId, userId, description)
  116. } else if description == "客服自动添加" {
  117. return FriendService.AgreeAddFriend(ctx, friendId, userId, "客服")
  118. } else {
  119. if respFriend.User.IsAutoAddedFriends == 1 {
  120. return FriendService.AgreeAddFriend(ctx, friendId, userId, "系统自动添加")
  121. }
  122. }
  123. }
  124. return nil
  125. }
  126. // AgreeAddFriend 同意添加好友
  127. func (*friendService) AgreeAddFriend(ctx context.Context, userId, friendId int64, remarks string) error {
  128. friend, err := FriendRepo.Get(friendId, userId)
  129. if err != nil {
  130. return err
  131. }
  132. if friend == nil {
  133. utils.FilePutContents("AgreeAddFriend", utils.SerializeStr(map[string]interface{}{
  134. "userId": userId,
  135. "friendId": friendId,
  136. }))
  137. return gerrors.ErrBadRequest
  138. }
  139. if friend.Status == FriendStatusAgree {
  140. return nil
  141. }
  142. friend.Status = FriendStatusAgree
  143. err = FriendRepo.Save(friend)
  144. if err != nil {
  145. return err
  146. }
  147. newFriend, err := FriendRepo.Get(userId, friendId)
  148. if newFriend != nil && newFriend.Status != FriendStatusAgree {
  149. newFriend.Status = FriendStatusAgree
  150. err = FriendRepo.Save(newFriend)
  151. } else {
  152. now := time.Now()
  153. err = FriendRepo.Save(&Friend{
  154. UserId: userId,
  155. FriendId: friendId,
  156. Remarks: remarks,
  157. Status: FriendStatusAgree,
  158. CreateTime: now,
  159. UpdateTime: now,
  160. })
  161. }
  162. if err != nil {
  163. return err
  164. }
  165. resp, err := rpc.GetBusinessIntClient().GetUser(ctx, &pb.GetUserReq{UserId: userId})
  166. if err != nil {
  167. return err
  168. }
  169. err = proxy.MessageProxy.PushToUser(ctx, friendId, pb.PushCode_PC_AGREE_ADD_FRIEND, &pb.AgreeAddFriendPush{
  170. FriendId: userId,
  171. Nickname: resp.User.Nickname,
  172. AvatarUrl: resp.User.AvatarUrl,
  173. }, true)
  174. utils.FilePutContents("push_AgreeAddFriend", utils.SerializeStr(map[string]interface{}{
  175. "friend_id": userId,
  176. "friend_nick_name": resp.User.Nickname,
  177. "friend_avatar_url": resp.User.AvatarUrl,
  178. "err": err,
  179. }))
  180. if err != nil {
  181. return err
  182. }
  183. return nil
  184. }
  185. // SendToFriend 消息发送至好友
  186. func (*friendService) SendToFriend(ctx context.Context, sender *pb.Sender, req *pb.SendMessageReq) (int64, error) {
  187. //TODO::判断是否为好友
  188. friend, err := FriendRepo.Get(sender.SenderId, req.ReceiverId)
  189. if err != nil {
  190. return 0, err
  191. }
  192. if friend == nil || friend.Status != FriendStatusAgree {
  193. return 0, gerrors.ErrNotIsFriend
  194. }
  195. //utils.FilePutContents("sendToFriend", utils.SerializeStr(map[string]interface{}{
  196. // "send": sender,
  197. // "req": req,
  198. //}))
  199. // 发给发送者
  200. seq, err := proxy.MessageProxy.SendToUser(ctx, sender, sender.SenderId, req)
  201. if err != nil {
  202. return 0, err
  203. }
  204. // 发给接收者
  205. _, err = proxy.MessageProxy.SendToUser(ctx, sender, req.ReceiverId, req)
  206. if err != nil {
  207. return 0, err
  208. }
  209. return seq, nil
  210. }
  211. // RecallMessageSendToFriend 撤回消息发送至好友
  212. func (*friendService) RecallMessageSendToFriend(ctx context.Context, sender *pb.Sender, req *pb.RecallMessageReq) (int64, error) {
  213. //TODO::判断是否为好友
  214. friend, err := FriendRepo.Get(sender.SenderId, req.ReceiverId)
  215. if err != nil {
  216. return 0, err
  217. }
  218. if friend == nil || friend.Status != FriendStatusAgree {
  219. return 0, gerrors.ErrNotIsFriend
  220. }
  221. utils.FilePutContents("RecallMessageSendToFriend", utils.SerializeStr(map[string]interface{}{
  222. "send": sender,
  223. "req": req,
  224. }))
  225. //查询到对应seq的消息
  226. msg := &pb.RECALL{}
  227. err = proto.Unmarshal(req.MessageContent, msg)
  228. if err != nil {
  229. return 0, err
  230. }
  231. message, err := repo.MessageRepo.GetMessage(sender.SenderId, msg.RecallSeq)
  232. if err != nil {
  233. return 0, err
  234. }
  235. // 发给发送者
  236. seq, err := proxy.MessageProxy.RecallMessageSendToUser(ctx, sender, sender.SenderId, req, message.SendTime)
  237. if err != nil {
  238. return 0, err
  239. }
  240. // 发给接收者
  241. _, err = proxy.MessageProxy.RecallMessageSendToUser(ctx, sender, req.ReceiverId, req, message.SendTime)
  242. if err != nil {
  243. return 0, err
  244. }
  245. return seq, nil
  246. }
  247. // RedPackageMessageSendToFriend 红包发送至好友
  248. func (*friendService) RedPackageMessageSendToFriend(ctx context.Context, sender *pb.Sender, req *pb.SendRedPacketReq) (int64, error) {
  249. //TODO::判断是否为好友
  250. friend, err := FriendRepo.Get(sender.SenderId, req.ReceiverId)
  251. if err != nil {
  252. return 0, err
  253. }
  254. if friend == nil || friend.Status != FriendStatusAgree {
  255. return 0, gerrors.ErrNotIsFriend
  256. }
  257. utils.FilePutContents("RedPackageMessageSendToFriend", utils.SerializeStr(map[string]interface{}{
  258. "send": sender,
  259. "req": req,
  260. }))
  261. // 发给发送者
  262. seq, err := proxy.MessageProxy.SendRedPackageToUser(ctx, sender, sender.SenderId, req)
  263. if err != nil {
  264. return 0, err
  265. }
  266. // 发给接收者
  267. _, err = proxy.MessageProxy.SendRedPackageToUser(ctx, sender, req.ReceiverId, req)
  268. if err != nil {
  269. return 0, err
  270. }
  271. return seq, nil
  272. }