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

svc_im.go 14 KiB

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