蛋蛋星球-客户端
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.
 
 
 
 
 

391 lines
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. "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. }