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

svc_im.go 14 KiB

4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
2週間前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  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. "applet/app/utils/cache"
  10. "code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
  11. "code.fnuoos.com/EggPlanet/egg_models.git/src/model"
  12. rule2 "code.fnuoos.com/EggPlanet/egg_system_rules.git"
  13. enum2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/enum"
  14. md2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/md"
  15. "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule"
  16. md3 "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/md"
  17. "code.fnuoos.com/EggPlanet/egg_system_rules.git/svc"
  18. "code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit"
  19. "errors"
  20. "github.com/google/uuid"
  21. "github.com/shopspring/decimal"
  22. "google.golang.org/protobuf/proto"
  23. "strings"
  24. "time"
  25. )
  26. func DelGrabRedPackage(req *md.GrabRedPackageReq, user *model.User) (resp []byte, grabAmount string, err error) {
  27. var redPacketBalanceAmount, redPacketReceivedUserIds, redPacketReceivedImUserIds, redPackageReceivedUserAmount string
  28. //1、查找红包
  29. redPackageOrdDb := implement.NewImSendRedPackageOrdDb(db.Db)
  30. imSendRedPackageOrd, err := redPackageOrdDb.ImSendRedPackageOrdGetOneByParams(map[string]interface{}{
  31. "key": "id",
  32. "value": req.RedPackageId,
  33. })
  34. if err != nil {
  35. return nil, grabAmount, err
  36. }
  37. if imSendRedPackageOrd == nil {
  38. return nil, grabAmount, errors.New("未查询到对应的红包记录")
  39. }
  40. if imSendRedPackageOrd.RedPacketBalanceNums == 0 || imSendRedPackageOrd.State == int(pb.RedPacketStatusType_RPS_EXPIRE) {
  41. return nil, "-1", nil
  42. }
  43. //2、判断用户是否已领取
  44. receivedUserIds := strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  45. for k, receivedUserId := range receivedUserIds {
  46. if receivedUserId == utils.Int64ToStr(user.Id) {
  47. redPackageReceivedUserAmounts := strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  48. grabAmount = redPackageReceivedUserAmounts[k]
  49. return nil, grabAmount, err
  50. }
  51. }
  52. //3、判断红包类型
  53. if imSendRedPackageOrd.RedPacketType == int(pb.RedPacketType_RPT_FRIEND) {
  54. //好友红包
  55. grabAmount = imSendRedPackageOrd.Amount
  56. redPacketBalanceAmount = "0"
  57. redPacketReceivedImUserIds = req.UserId
  58. redPacketReceivedUserIds = utils.Int64ToStr(user.Id)
  59. redPackageReceivedUserAmount = imSendRedPackageOrd.Amount
  60. } else {
  61. var receivedImUserIds, receivedUserIds, waitDrawImUserIds, redPackageReceivedUserAmounts []string
  62. if imSendRedPackageOrd.ReceivedImUserIds != "" {
  63. receivedImUserIds = strings.Split(imSendRedPackageOrd.ReceivedImUserIds, ",")
  64. }
  65. if imSendRedPackageOrd.ReceivedUserIds != "" {
  66. receivedUserIds = strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  67. }
  68. if imSendRedPackageOrd.WaitDrawImUserIds != "" {
  69. waitDrawImUserIds = strings.Split(imSendRedPackageOrd.WaitDrawImUserIds, ",")
  70. }
  71. if imSendRedPackageOrd.ReceivedUserAmount != "" {
  72. redPackageReceivedUserAmounts = strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  73. }
  74. //群组红包
  75. switch imSendRedPackageOrd.RedPacketType {
  76. case int(pb.RedPacketType_RPT_GROUP_NORMAL):
  77. amount, _ := decimal.NewFromString(imSendRedPackageOrd.Amount)
  78. tmpGrabAmount := amount.Div(decimal.NewFromInt(int64(imSendRedPackageOrd.RedPacketNums)))
  79. grabAmount = tmpGrabAmount.String()
  80. tempRedPacketBalanceAmount, _ := decimal.NewFromString(imSendRedPackageOrd.RedPacketBalanceAmount)
  81. redPacketBalanceAmount = tempRedPacketBalanceAmount.Sub(tmpGrabAmount).String()
  82. break
  83. case int(pb.RedPacketType_RPT_GROUP_LUCK):
  84. balanceAmount, err := decimal.NewFromString(imSendRedPackageOrd.RedPacketBalanceAmount)
  85. if err != nil {
  86. return nil, grabAmount, err
  87. }
  88. balanceAmountValue, _ := balanceAmount.Float64()
  89. tmpGrabAmount := float64(utils.DoubleAverage(int64(imSendRedPackageOrd.RedPacketBalanceNums), utils.FloatToInt64(balanceAmountValue*100))) / 100
  90. grabAmount = utils.AnyToString(tmpGrabAmount)
  91. redPacketBalanceAmount = balanceAmount.Sub(decimal.NewFromFloat(tmpGrabAmount)).String()
  92. break
  93. case int(pb.RedPacketType_RPT_GROUP_SPECIALLY):
  94. if !utils.ContainerStr(waitDrawImUserIds, req.UserId) {
  95. return nil, grabAmount, errors.New("非专属用户不能领取")
  96. }
  97. grabAmount = imSendRedPackageOrd.Amount
  98. redPacketBalanceAmount = "0"
  99. redPacketReceivedImUserIds = req.UserId
  100. break
  101. case int(pb.RedPacketType_RPT_SYSTEM_FOR):
  102. if !utils.ContainerStr(waitDrawImUserIds, req.UserId) {
  103. return nil, grabAmount, errors.New("非专属用户不能领取")
  104. }
  105. grabAmount = imSendRedPackageOrd.Amount
  106. redPacketBalanceAmount = "0"
  107. redPacketReceivedImUserIds = req.UserId
  108. break
  109. }
  110. receivedImUserIds = append(receivedImUserIds, req.UserId)
  111. redPacketReceivedImUserIds = strings.Join(receivedImUserIds, ",")
  112. receivedUserIds = append(receivedUserIds, utils.AnyToString(user.Id))
  113. redPacketReceivedUserIds = strings.Join(receivedUserIds, ",")
  114. redPackageReceivedUserAmounts = append(redPackageReceivedUserAmounts, grabAmount)
  115. redPackageReceivedUserAmount = strings.Join(redPackageReceivedUserAmounts, ",")
  116. }
  117. session := db.Db.NewSession()
  118. defer session.Close()
  119. //2、改变红包记录状态
  120. if imSendRedPackageOrd.ReceivedTimes != "" {
  121. receivedTimes := strings.Split(imSendRedPackageOrd.ReceivedTimes, ",")
  122. receivedTimes = append(receivedTimes, time.Now().Format("2006-01-02 15:04:05"))
  123. imSendRedPackageOrd.ReceivedTimes = strings.Join(receivedTimes, ",")
  124. } else {
  125. imSendRedPackageOrd.ReceivedTimes = time.Now().Format("2006-01-02 15:04:05")
  126. }
  127. imSendRedPackageOrd.RedPacketBalanceNums = imSendRedPackageOrd.RedPacketBalanceNums - 1
  128. if imSendRedPackageOrd.RedPacketBalanceNums > 0 {
  129. imSendRedPackageOrd.State = int(pb.RedPacketStatusType_RPS_DRAWING)
  130. } else {
  131. imSendRedPackageOrd.State = int(pb.RedPacketStatusType_RPS_DRAW_OVER)
  132. }
  133. imSendRedPackageOrd.ReceivedUserAmount = redPackageReceivedUserAmount
  134. imSendRedPackageOrd.RedPacketBalanceAmount = redPacketBalanceAmount
  135. imSendRedPackageOrd.ReceivedUserIds = redPacketReceivedUserIds
  136. imSendRedPackageOrd.ReceivedImUserIds = redPacketReceivedImUserIds
  137. _, err = redPackageOrdDb.ImSendRedPackageOrdUpdateBySession(session, imSendRedPackageOrd.Id, imSendRedPackageOrd, "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. //4、组装消息参数
  157. msg := &pb.RED_PACKAGE{
  158. RedMessageType: pb.RedPacketMessageType_RMT_GRAB,
  159. RedPacketType: pb.RedPacketType(imSendRedPackageOrd.RedPacketType),
  160. RedPacketContent: "",
  161. //RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)),
  162. //RedPacketNums: int32(req.RedPacketNums),
  163. RedPacketBalanceAmount: float32(utils.AnyToFloat64(imSendRedPackageOrd.RedPacketBalanceAmount)),
  164. ReceivedUserId: utils.StrToInt64(req.UserId),
  165. ReceivedUserAmount: utils.StrToFloat32(grabAmount),
  166. ReceivedUserNickname: user.Nickname,
  167. RedPacketStatusType: pb.RedPacketStatusType(imSendRedPackageOrd.State),
  168. RedPacketId: imSendRedPackageOrd.Id,
  169. SendRedPacketUid: int64(imSendRedPackageOrd.ImUid),
  170. SendRedPacketNickname: req.SendRedPackageUserNikeName,
  171. SendRedPacketAvatarUrl: req.SendRedPacketAvatarUrl,
  172. //RedPacketSmallContent: req.RedPacketSmallContent,
  173. RedPacketCover: req.RedPackageCover,
  174. }
  175. utils.FilePutContents("DelGrabRedPackage", utils.SerializeStr(map[string]interface{}{
  176. "args": req,
  177. "msg": msg,
  178. "ord": imSendRedPackageOrd,
  179. }))
  180. resp, err = proto.Marshal(msg)
  181. if err != nil {
  182. return nil, grabAmount, err
  183. }
  184. return resp, grabAmount, nil
  185. }
  186. func DetailGrabRedPackage(redPackageId string) (resp []md.RedPackageDetailUserNode, imSendRedPackageOrd *model.ImSendRedPackageOrd, err error) {
  187. //1、查找红包
  188. redPackageOrdDb := implement.NewImSendRedPackageOrdDb(db.Db)
  189. imSendRedPackageOrd, err = redPackageOrdDb.ImSendRedPackageOrdGetOneByParams(map[string]interface{}{
  190. "key": "id",
  191. "value": redPackageId,
  192. })
  193. if err != nil {
  194. return nil, nil, err
  195. }
  196. if imSendRedPackageOrd == nil {
  197. return resp, imSendRedPackageOrd, errors.New("未查询到对应的红包记录")
  198. }
  199. receivedUserIds := strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  200. userDb := implement.NewUserDb(db.Db)
  201. users, err := userDb.UserFindByParams(map[string]interface{}{
  202. "key": "id",
  203. "value": receivedUserIds,
  204. })
  205. if err != nil {
  206. return resp, imSendRedPackageOrd, err
  207. }
  208. var usersMap = map[string]model.User{}
  209. for _, v := range users {
  210. usersMap[utils.AnyToString(v.Id)] = v
  211. }
  212. receivedImUserIds := strings.Split(imSendRedPackageOrd.ReceivedImUserIds, ",")
  213. receivedTimes := strings.Split(imSendRedPackageOrd.ReceivedTimes, ",")
  214. receivedUserAmount := strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  215. redisConn := cache.GetPool().Get()
  216. scheme, domain := svc.ImageBucket(db.Db, redisConn)
  217. for k, v := range receivedUserIds {
  218. resp = append(resp, md.RedPackageDetailUserNode{
  219. ImUserId: receivedImUserIds[k],
  220. UserNickName: usersMap[v].Nickname,
  221. UserAvatarUrl: svc.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. if req.UserId != "" {
  249. imUid = utils.StrToInt(req.UserId)
  250. } else {
  251. //TODO::请求rpc接口,同步用户数据
  252. resp, err := utils.GetBusinessExtClient(cfg.ImBusinessRpc.URL, cfg.ImBusinessRpc.PORT).GetUser(utils.GetCtx("", "", ""), &pb.GetUserReq{
  253. UserId: 0,
  254. Phone: user.Phone,
  255. })
  256. if err != nil {
  257. return nil, redPackageId, err
  258. }
  259. imUid = int(resp.User.UserId)
  260. }
  261. now := time.Now()
  262. ordNo := uuid.New().String()
  263. var waitDrawUserIds string
  264. var waitDrawImUserIds string
  265. if req.RedPacketType == int(pb.RedPacketType_RPT_GROUP_SPECIALLY) {
  266. var toUserIds []string
  267. for _, v := range req.ToUserIds {
  268. toUserIds = append(toUserIds, utils.AnyToString(v))
  269. }
  270. waitDrawUserIds = strings.Join(toUserIds, ",")
  271. userDb := implement.NewUserDb(db.Db)
  272. waitDrawUsers, err1 := userDb.UserFindByParams(map[string]interface{}{
  273. "key": "id",
  274. "value": toUserIds,
  275. })
  276. if err1 != nil {
  277. return nil, 0, err1
  278. }
  279. var waitDrawUserPhones []string
  280. for _, v := range waitDrawUsers {
  281. waitDrawUserPhones = append(waitDrawUserPhones, v.Phone)
  282. }
  283. var waitDrawImUsers []model2.User
  284. err = db.DbIm.Table("user").In("phone_number", waitDrawUserPhones).Find(&waitDrawUsers)
  285. if err != nil {
  286. return nil, 0, err
  287. }
  288. var toUserIMIDs []string
  289. for _, v := range waitDrawImUsers {
  290. toUserIMIDs = append(toUserIMIDs, utils.AnyToString(v.Id))
  291. }
  292. waitDrawImUserIds = strings.Join(toUserIMIDs, ",")
  293. }
  294. ordDb := implement.NewImSendRedPackageOrdDb(db.Db)
  295. m := model.ImSendRedPackageOrd{
  296. OrdNo: ordNo,
  297. Uid: int(user.Id),
  298. ImUid: imUid,
  299. Amount: req.Amount,
  300. RedPacketBalanceAmount: req.Amount,
  301. RedPacketType: req.RedPacketType,
  302. RedPacketNums: req.RedPacketNums,
  303. RedPacketBalanceNums: req.RedPacketNums,
  304. State: 0,
  305. WaitDrawUserIds: waitDrawUserIds,
  306. WaitDrawImUserIds: waitDrawImUserIds,
  307. ReceivedUserIds: "",
  308. ReceivedImUserIds: "",
  309. ReceivedUserAmount: "",
  310. CreateTime: now.Format("2006-01-02 15:04:05"),
  311. UpdateTime: now.Format("2006-01-02 15:04:05"),
  312. }
  313. redPackageOrdId, err := ordDb.ImSendRedPackageOrdInsertBySession(session, &m)
  314. if err != nil {
  315. session.Rollback()
  316. return nil, redPackageId, err
  317. }
  318. err = session.Commit()
  319. if err != nil {
  320. return nil, redPackageOrdId, err
  321. }
  322. redisConn := cache.GetPool().Get()
  323. scheme, domain := svc.ImageBucket(db.Db, redisConn)
  324. msg := &pb.RED_PACKAGE{
  325. RedMessageType: pb.RedPacketMessageType_RMT_SEND,
  326. RedPacketType: pb.RedPacketType(req.RedPacketType),
  327. RedPacketContent: req.RedPacketContent,
  328. RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)),
  329. RedPacketNums: int32(req.RedPacketNums),
  330. RedPacketBalanceAmount: float32(utils.AnyToFloat64(req.Amount)),
  331. ReceivedUserId: utils.StrToInt64(waitDrawUserIds),
  332. ReceivedUserAmount: 0,
  333. ReceivedUserNickname: "",
  334. RedPacketStatusType: 0,
  335. RedPacketId: redPackageOrdId,
  336. SendRedPacketUid: utils.StrToInt64(req.UserId),
  337. SendRedPacketNickname: user.Nickname,
  338. SendRedPacketAvatarUrl: svc.ImageFormatWithBucket(scheme, domain, user.Avatar),
  339. RedPacketSmallContent: req.RedPacketSmallContent,
  340. }
  341. resp, err = proto.Marshal(msg)
  342. if err != nil {
  343. return nil, redPackageId, err
  344. }
  345. redPackageId = redPackageOrdId
  346. return resp, redPackageId, nil
  347. }
  348. // GetImUser 获取im用户信息
  349. func GetImUser(userId int64, phone string) (user *pb.User, err error) {
  350. resp, err := utils.GetBusinessExtClient(cfg.ImBusinessRpc.URL, cfg.ImBusinessRpc.PORT).GetUser(utils.GetCtx("", "", ""), &pb.GetUserReq{
  351. UserId: userId,
  352. Phone: phone,
  353. })
  354. if err != nil {
  355. return
  356. }
  357. return resp.User, nil
  358. }
  359. func AddSendRedPackageTimesPushToMQ(uid int64) {
  360. ch, err := rabbit.Cfg.Pool.GetChannel()
  361. if err != nil {
  362. return
  363. }
  364. defer ch.Release()
  365. ch.Publish(md3.IMEggEnergyExchange, md3.IMEggEnergyStructForSendRedPackageData{
  366. Uid: uid,
  367. }, md3.IMEggEnergyRoutKeyForSendRedPackage)
  368. }