蛋蛋星球-客户端
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

svc_im.go 15 KiB

1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
3週間前
1ヶ月前
1ヶ月前
1ヶ月前
3週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
3週間前
1ヶ月前
3週間前
1ヶ月前
1ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. package svc
  2. import (
  3. "applet/app/cfg"
  4. "applet/app/db"
  5. model2 "applet/app/db/im/model"
  6. "applet/app/md"
  7. "applet/app/pkg/pb"
  8. "applet/app/utils"
  9. "code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
  10. "code.fnuoos.com/EggPlanet/egg_models.git/src/model"
  11. rule2 "code.fnuoos.com/EggPlanet/egg_system_rules.git"
  12. enum2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/enum"
  13. md2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/md"
  14. "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule"
  15. md3 "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/md"
  16. "code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit"
  17. "errors"
  18. "github.com/google/uuid"
  19. "github.com/shopspring/decimal"
  20. "google.golang.org/protobuf/proto"
  21. "strings"
  22. "time"
  23. )
  24. func DelGrabRedPackage(req *md.GrabRedPackageReq, user *model.User) (resp []byte, grabAmount string, err error) {
  25. var redPacketBalanceAmount, redPacketReceivedUserIds, redPacketReceivedImUserIds, redPackageReceivedUserAmount string
  26. //1、查找红包
  27. redPackageOrdDb := implement.NewImSendRedPackageOrdDb(db.Db)
  28. imSendRedPackageOrd, err := redPackageOrdDb.ImSendRedPackageOrdGetOneByParams(map[string]interface{}{
  29. "key": "id",
  30. "value": req.RedPackageId,
  31. })
  32. if err != nil {
  33. return nil, grabAmount, err
  34. }
  35. if imSendRedPackageOrd == nil {
  36. return nil, grabAmount, errors.New("未查询到对应的红包记录")
  37. }
  38. // 剩余个数和已过期无法领取
  39. if imSendRedPackageOrd.RedPacketBalanceNums == 0 || imSendRedPackageOrd.State == int(pb.RedPacketStatusType_RPS_EXPIRE) {
  40. return nil, "-1", nil
  41. }
  42. //2、判断用户是否已领取
  43. receivedUserIds := strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  44. for k, receivedUserId := range receivedUserIds {
  45. if receivedUserId == utils.Int64ToStr(user.Id) {
  46. redPackageReceivedUserAmounts := strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  47. grabAmount = redPackageReceivedUserAmounts[k]
  48. return nil, grabAmount, err
  49. }
  50. }
  51. //3、判断红包类型
  52. if imSendRedPackageOrd.RedPacketType == int(pb.RedPacketType_RPT_FRIEND) {
  53. //好友红包
  54. grabAmount = imSendRedPackageOrd.Amount
  55. redPacketBalanceAmount = "0"
  56. redPacketReceivedImUserIds = req.UserId
  57. redPacketReceivedUserIds = utils.Int64ToStr(user.Id)
  58. redPackageReceivedUserAmount = imSendRedPackageOrd.Amount
  59. } else {
  60. var receivedImUserIds, receivedUserIds, waitDrawImUserIds, redPackageReceivedUserAmounts []string
  61. if imSendRedPackageOrd.ReceivedImUserIds != "" {
  62. receivedImUserIds = strings.Split(imSendRedPackageOrd.ReceivedImUserIds, ",")
  63. }
  64. if imSendRedPackageOrd.ReceivedUserIds != "" {
  65. receivedUserIds = strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  66. }
  67. if imSendRedPackageOrd.WaitDrawImUserIds != "" {
  68. waitDrawImUserIds = strings.Split(imSendRedPackageOrd.WaitDrawImUserIds, ",")
  69. }
  70. if imSendRedPackageOrd.ReceivedUserAmount != "" {
  71. redPackageReceivedUserAmounts = strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  72. }
  73. //群组红包
  74. switch imSendRedPackageOrd.RedPacketType {
  75. case int(pb.RedPacketType_RPT_GROUP_NORMAL):
  76. amount, _ := decimal.NewFromString(imSendRedPackageOrd.Amount)
  77. tmpGrabAmount := amount.Div(decimal.NewFromInt(int64(imSendRedPackageOrd.RedPacketNums)))
  78. grabAmount = tmpGrabAmount.String()
  79. tempRedPacketBalanceAmount, _ := decimal.NewFromString(imSendRedPackageOrd.RedPacketBalanceAmount)
  80. redPacketBalanceAmount = tempRedPacketBalanceAmount.Sub(tmpGrabAmount).String()
  81. break
  82. case int(pb.RedPacketType_RPT_GROUP_LUCK):
  83. balanceAmount, err := decimal.NewFromString(imSendRedPackageOrd.RedPacketBalanceAmount)
  84. if err != nil {
  85. return nil, grabAmount, err
  86. }
  87. balanceAmountValue, _ := balanceAmount.Float64()
  88. tmpGrabAmount := float64(utils.DoubleAverage(int64(imSendRedPackageOrd.RedPacketBalanceNums), utils.FloatToInt64(balanceAmountValue*100))) / 100
  89. grabAmount = utils.AnyToString(tmpGrabAmount)
  90. redPacketBalanceAmount = balanceAmount.Sub(decimal.NewFromFloat(tmpGrabAmount)).String()
  91. break
  92. case int(pb.RedPacketType_RPT_GROUP_SPECIALLY):
  93. if !utils.ContainerStr(waitDrawImUserIds, req.UserId) {
  94. return nil, grabAmount, errors.New("非专属用户不能领取")
  95. }
  96. grabAmount = imSendRedPackageOrd.Amount
  97. redPacketBalanceAmount = "0"
  98. redPacketReceivedImUserIds = req.UserId
  99. break
  100. case int(pb.RedPacketType_RPT_SYSTEM_FOR):
  101. if !utils.ContainerStr(waitDrawImUserIds, req.UserId) {
  102. return nil, grabAmount, errors.New("非专属用户不能领取")
  103. }
  104. grabAmount = imSendRedPackageOrd.Amount
  105. redPacketBalanceAmount = "0"
  106. redPacketReceivedImUserIds = req.UserId
  107. break
  108. }
  109. receivedImUserIds = append(receivedImUserIds, req.UserId)
  110. redPacketReceivedImUserIds = strings.Join(receivedImUserIds, ",")
  111. receivedUserIds = append(receivedUserIds, utils.AnyToString(user.Id))
  112. redPacketReceivedUserIds = strings.Join(receivedUserIds, ",")
  113. redPackageReceivedUserAmounts = append(redPackageReceivedUserAmounts, grabAmount)
  114. redPackageReceivedUserAmount = strings.Join(redPackageReceivedUserAmounts, ",")
  115. }
  116. session := db.Db.NewSession()
  117. defer session.Close()
  118. //2、改变红包记录状态
  119. if imSendRedPackageOrd.ReceivedTimes != "" {
  120. receivedTimes := strings.Split(imSendRedPackageOrd.ReceivedTimes, ",")
  121. receivedTimes = append(receivedTimes, time.Now().Format("2006-01-02 15:04:05"))
  122. imSendRedPackageOrd.ReceivedTimes = strings.Join(receivedTimes, ",")
  123. } else {
  124. imSendRedPackageOrd.ReceivedTimes = time.Now().Format("2006-01-02 15:04:05")
  125. }
  126. imSendRedPackageOrd.RedPacketBalanceNums = imSendRedPackageOrd.RedPacketBalanceNums - 1
  127. if imSendRedPackageOrd.RedPacketBalanceNums > 0 {
  128. imSendRedPackageOrd.State = int(pb.RedPacketStatusType_RPS_DRAWING)
  129. } else {
  130. imSendRedPackageOrd.State = int(pb.RedPacketStatusType_RPS_DRAW_OVER)
  131. }
  132. imSendRedPackageOrd.ReceivedUserAmount = redPackageReceivedUserAmount
  133. imSendRedPackageOrd.RedPacketBalanceAmount = redPacketBalanceAmount
  134. imSendRedPackageOrd.ReceivedUserIds = redPacketReceivedUserIds
  135. imSendRedPackageOrd.ReceivedImUserIds = redPacketReceivedImUserIds
  136. _, err = redPackageOrdDb.ImSendRedPackageOrdUpdateBySession(session, imSendRedPackageOrd.Id, imSendRedPackageOrd,
  137. "red_packet_balance_nums", "state", "received_user_ids", "received_im_user_ids", "received_times",
  138. "received_user_amount", "create_time", "update_time", "red_packet_balance_amount")
  139. if err != nil {
  140. session.Rollback()
  141. return nil, grabAmount, err
  142. }
  143. //3、加上给用户加上余额
  144. dealUserWalletReq := md2.DealUserWalletReq{
  145. Direction: "add",
  146. Kind: int(enum2.UserReceiveRedPackage),
  147. Title: enum2.UserReceiveRedPackage.String(),
  148. Uid: user.Id,
  149. Amount: utils.StrToFloat64(grabAmount),
  150. }
  151. err = rule.DealUserWallet(session, dealUserWalletReq)
  152. if err != nil {
  153. session.Rollback()
  154. return nil, grabAmount, err
  155. }
  156. session.Commit()
  157. //4、组装消息参数
  158. msg := &pb.RED_PACKAGE{
  159. RedMessageType: pb.RedPacketMessageType_RMT_GRAB,
  160. RedPacketType: pb.RedPacketType(imSendRedPackageOrd.RedPacketType),
  161. RedPacketContent: "",
  162. //RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)),
  163. //RedPacketNums: int32(req.RedPacketNums),
  164. RedPacketBalanceAmount: float32(utils.AnyToFloat64(imSendRedPackageOrd.RedPacketBalanceAmount)),
  165. ReceivedUserId: utils.StrToInt64(req.UserId),
  166. ReceivedUserAmount: utils.StrToFloat32(grabAmount),
  167. ReceivedUserNickname: user.Nickname,
  168. RedPacketStatusType: pb.RedPacketStatusType(imSendRedPackageOrd.State),
  169. RedPacketId: imSendRedPackageOrd.Id,
  170. SendRedPacketUid: int64(imSendRedPackageOrd.ImUid),
  171. SendRedPacketNickname: req.SendRedPackageUserNikeName,
  172. SendRedPacketAvatarUrl: req.SendRedPacketAvatarUrl,
  173. //RedPacketSmallContent: req.RedPacketSmallContent,
  174. RedPacketCover: req.RedPackageCover,
  175. }
  176. utils.FilePutContents("DelGrabRedPackage", utils.SerializeStr(map[string]interface{}{
  177. "args": req,
  178. "msg": msg,
  179. "ord": imSendRedPackageOrd,
  180. }))
  181. resp, err = proto.Marshal(msg)
  182. if err != nil {
  183. return nil, grabAmount, err
  184. }
  185. return resp, grabAmount, nil
  186. }
  187. func DetailGrabRedPackage(redPackageId string) (resp []md.RedPackageDetailUserNode, imSendRedPackageOrd *model.ImSendRedPackageOrd, err error) {
  188. //1、查找红包
  189. redPackageOrdDb := implement.NewImSendRedPackageOrdDb(db.Db)
  190. imSendRedPackageOrd, err = redPackageOrdDb.ImSendRedPackageOrdGetOneByParams(map[string]interface{}{
  191. "key": "id",
  192. "value": redPackageId,
  193. })
  194. if err != nil {
  195. return nil, nil, err
  196. }
  197. if imSendRedPackageOrd == nil {
  198. return resp, imSendRedPackageOrd, errors.New("未查询到对应的红包记录")
  199. }
  200. receivedUserIds := strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  201. userDb := implement.NewUserDb(db.Db)
  202. users, err := userDb.UserFindByParams(map[string]interface{}{
  203. "key": "id",
  204. "value": receivedUserIds,
  205. })
  206. if err != nil {
  207. return resp, imSendRedPackageOrd, err
  208. }
  209. var usersMap = map[string]model.User{}
  210. for _, v := range users {
  211. usersMap[utils.AnyToString(v.Id)] = v
  212. }
  213. receivedImUserIds := strings.Split(imSendRedPackageOrd.ReceivedImUserIds, ",")
  214. receivedTimes := strings.Split(imSendRedPackageOrd.ReceivedTimes, ",")
  215. receivedUserAmount := strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  216. scheme, domain := ImageBucket(db.Db)
  217. for k, v := range receivedUserIds {
  218. resp = append(resp, md.RedPackageDetailUserNode{
  219. ImUserId: receivedImUserIds[k],
  220. UserNickName: usersMap[v].Nickname,
  221. UserAvatarUrl: ImageFormatWithBucket(scheme, domain, usersMap[v].Avatar),
  222. Amount: receivedUserAmount[k],
  223. ReceiveAt: receivedTimes[k],
  224. })
  225. }
  226. return resp, imSendRedPackageOrd, nil
  227. }
  228. // BalancePayForRedPackage 红包余额支付
  229. func BalancePayForRedPackage(user *model.User, money string, req md.SendRedPackageReq) (resp []byte, redPackageId int64, err error) {
  230. session := db.Db.NewSession()
  231. defer session.Close()
  232. //扣除用户余额
  233. dealUserWalletReq := md2.DealUserWalletReq{
  234. Direction: "sub",
  235. Kind: int(enum2.UserSendRedPackage),
  236. Title: enum2.UserSendRedPackage.String(),
  237. Uid: user.Id,
  238. Amount: utils.StrToFloat64(money),
  239. }
  240. rule2.Init(cfg.RedisAddr)
  241. err = rule.DealUserWallet(session, dealUserWalletReq)
  242. if err != nil {
  243. session.Rollback()
  244. return nil, 0, err
  245. }
  246. // 新增红包记录
  247. var imUid int
  248. var imUser model2.User
  249. has, err := db.DbIm.Where("phone_number = ?", user.Phone).Get(&imUser)
  250. if err != nil {
  251. session.Rollback()
  252. return nil, 0, err
  253. }
  254. if has {
  255. imUid = int(imUser.Id)
  256. } else {
  257. if req.UserId != "" {
  258. imUid = utils.StrToInt(req.UserId)
  259. } else {
  260. //TODO::请求rpc接口,同步用户数据
  261. resp, err := utils.GetBusinessExtClient(cfg.ImBusinessRpc.URL, cfg.ImBusinessRpc.PORT).GetUser(utils.GetCtx("", "", ""), &pb.GetUserReq{
  262. UserId: 0,
  263. Phone: user.Phone,
  264. })
  265. if err != nil {
  266. return nil, redPackageId, err
  267. }
  268. imUid = int(resp.User.UserId)
  269. now := time.Now()
  270. tempImUser := model2.User{
  271. Id: int64(imUid),
  272. PhoneNumber: user.Phone,
  273. Nickname: user.Nickname,
  274. Sex: 0,
  275. AvatarUrl: user.Avatar,
  276. Extra: "",
  277. CreateTime: now,
  278. UpdateTime: now,
  279. IsAutoAddedFriends: 0,
  280. }
  281. _, err = db.DbIm.Insert(&tempImUser)
  282. if err != nil {
  283. session.Rollback()
  284. return nil, 0, err
  285. }
  286. }
  287. }
  288. now := time.Now()
  289. ordNo := uuid.New().String()
  290. var waitDrawUserIds string
  291. var waitDrawImUserIds string
  292. if req.RedPacketType == int(pb.RedPacketType_RPT_GROUP_SPECIALLY) {
  293. // 构造 im 用户 id 列表
  294. var toImUserIds []string
  295. for _, v := range req.ToUserIds {
  296. toImUserIds = append(toImUserIds, utils.AnyToString(v))
  297. }
  298. waitDrawImUserIds = strings.Join(toImUserIds, ",")
  299. // 查询 im 用户信息
  300. var imUsers []model2.User
  301. err = db.DbIm.In("id", req.ToUserIds).Find(&imUsers)
  302. if err != nil {
  303. return nil, 0, err
  304. }
  305. // 获取手机号列表
  306. var phones []string
  307. for _, v := range imUsers {
  308. phones = append(phones, v.PhoneNumber)
  309. }
  310. // 查询用户信息
  311. userDb := implement.NewUserDb(db.Db)
  312. waitDrawUsers, err1 := userDb.UserFindByParams(map[string]interface{}{
  313. "key": "phone",
  314. "value": phones,
  315. })
  316. if err1 != nil {
  317. return nil, 0, err1
  318. }
  319. var toUserIDs []string
  320. for _, v := range waitDrawUsers {
  321. toUserIDs = append(toUserIDs, utils.AnyToString(v.Id))
  322. }
  323. waitDrawUserIds = strings.Join(toUserIDs, ",")
  324. }
  325. ordDb := implement.NewImSendRedPackageOrdDb(db.Db)
  326. m := model.ImSendRedPackageOrd{
  327. OrdNo: ordNo,
  328. Uid: int(user.Id),
  329. ImUid: imUid,
  330. Amount: req.Amount,
  331. RedPacketBalanceAmount: req.Amount,
  332. RedPacketType: req.RedPacketType,
  333. RedPacketNums: req.RedPacketNums,
  334. RedPacketBalanceNums: req.RedPacketNums,
  335. State: 0,
  336. WaitDrawUserIds: waitDrawUserIds,
  337. WaitDrawImUserIds: waitDrawImUserIds,
  338. ReceivedUserIds: "",
  339. ReceivedImUserIds: "",
  340. ReceivedUserAmount: "",
  341. CreateTime: now.Format("2006-01-02 15:04:05"),
  342. UpdateTime: now.Format("2006-01-02 15:04:05"),
  343. }
  344. redPackageOrdId, err := ordDb.ImSendRedPackageOrdInsertBySession(session, &m)
  345. if err != nil {
  346. session.Rollback()
  347. return nil, redPackageId, err
  348. }
  349. err = session.Commit()
  350. if err != nil {
  351. return nil, redPackageOrdId, err
  352. }
  353. scheme, domain := ImageBucket(db.Db)
  354. msg := &pb.RED_PACKAGE{
  355. RedMessageType: pb.RedPacketMessageType_RMT_SEND,
  356. RedPacketType: pb.RedPacketType(req.RedPacketType),
  357. RedPacketContent: req.RedPacketContent,
  358. RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)),
  359. RedPacketNums: int32(req.RedPacketNums),
  360. RedPacketBalanceAmount: float32(utils.AnyToFloat64(req.Amount)),
  361. ReceivedUserId: utils.StrToInt64(waitDrawUserIds),
  362. ReceivedUserAmount: 0,
  363. ReceivedUserNickname: "",
  364. RedPacketStatusType: 0,
  365. RedPacketId: redPackageOrdId,
  366. SendRedPacketUid: utils.StrToInt64(req.UserId),
  367. SendRedPacketNickname: user.Nickname,
  368. SendRedPacketAvatarUrl: ImageFormatWithBucket(scheme, domain, user.Avatar),
  369. RedPacketSmallContent: req.RedPacketSmallContent,
  370. }
  371. resp, err = proto.Marshal(msg)
  372. if err != nil {
  373. return nil, redPackageId, err
  374. }
  375. redPackageId = redPackageOrdId
  376. return resp, redPackageId, nil
  377. }
  378. // GetImUser 获取im用户信息
  379. func GetImUser(userId int64, phone string) (user *pb.User, err error) {
  380. resp, err := utils.GetBusinessExtClient(cfg.ImBusinessRpc.URL, cfg.ImBusinessRpc.PORT).GetUser(utils.GetCtx("", "", ""), &pb.GetUserReq{
  381. UserId: userId,
  382. Phone: phone,
  383. })
  384. if err != nil {
  385. return
  386. }
  387. return resp.User, nil
  388. }
  389. func AddSendRedPackageTimesPushToMQ(uid int64) {
  390. ch, err := rabbit.Cfg.Pool.GetChannel()
  391. if err != nil {
  392. return
  393. }
  394. defer ch.Release()
  395. ch.Publish(md3.IMEggEnergyExchange, md3.IMEggEnergyStructForSendRedPackageData{
  396. Uid: uid,
  397. }, md3.IMEggEnergyRoutKeyForSendRedPackage)
  398. }