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

395 行
14 KiB

  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. }