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

367 lines
13 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. md2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/md"
  14. "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule"
  15. "code.fnuoos.com/EggPlanet/egg_system_rules.git/svc"
  16. "errors"
  17. "github.com/google/uuid"
  18. "github.com/shopspring/decimal"
  19. "google.golang.org/protobuf/proto"
  20. "strings"
  21. "time"
  22. )
  23. func DelGrabRedPackage(req *md.GrabRedPackageReq, user *model.User) (resp []byte, grabAmount string, err error) {
  24. var redPacketBalanceAmount, redPacketReceivedUserIds, redPacketReceivedImUserIds, redPackageReceivedUserAmount string
  25. //1、查找红包
  26. redPackageOrdDb := implement.NewImSendRedPackageOrdDb(db.Db)
  27. imSendRedPackageOrd, err := redPackageOrdDb.ImSendRedPackageOrdGetOneByParams(map[string]interface{}{
  28. "key": "id",
  29. "value": req.RedPackageId,
  30. })
  31. if err != nil {
  32. return nil, grabAmount, err
  33. }
  34. if imSendRedPackageOrd == nil {
  35. return nil, grabAmount, errors.New("未查询到对应的红包记录")
  36. }
  37. if imSendRedPackageOrd.RedPacketBalanceNums == 0 || imSendRedPackageOrd.State == int(pb.RedPacketStatusType_RPS_EXPIRE) {
  38. return nil, "-1", nil
  39. }
  40. //2、判断用户是否已领取
  41. receivedUserIds := strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  42. for k, receivedUserId := range receivedUserIds {
  43. if receivedUserId == utils.Int64ToStr(user.Id) {
  44. redPackageReceivedUserAmounts := strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  45. grabAmount = redPackageReceivedUserAmounts[k]
  46. return nil, grabAmount, err
  47. }
  48. }
  49. //3、判断红包类型
  50. if imSendRedPackageOrd.RedPacketType == int(pb.RedPacketType_RPT_FRIEND) {
  51. //好友红包
  52. grabAmount = imSendRedPackageOrd.Amount
  53. redPacketBalanceAmount = "0"
  54. redPacketReceivedImUserIds = req.UserId
  55. redPacketReceivedUserIds = utils.Int64ToStr(user.Id)
  56. redPackageReceivedUserAmount = imSendRedPackageOrd.Amount
  57. } else {
  58. var receivedImUserIds, receivedUserIds, waitDrawImUserIds, redPackageReceivedUserAmounts []string
  59. if imSendRedPackageOrd.ReceivedImUserIds != "" {
  60. receivedImUserIds = strings.Split(imSendRedPackageOrd.ReceivedImUserIds, ",")
  61. }
  62. if imSendRedPackageOrd.ReceivedUserIds != "" {
  63. receivedUserIds = strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  64. }
  65. if imSendRedPackageOrd.WaitDrawImUserIds != "" {
  66. waitDrawImUserIds = strings.Split(imSendRedPackageOrd.WaitDrawImUserIds, ",")
  67. }
  68. if imSendRedPackageOrd.ReceivedUserAmount != "" {
  69. redPackageReceivedUserAmounts = strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  70. }
  71. //群组红包
  72. switch imSendRedPackageOrd.RedPacketType {
  73. case int(pb.RedPacketType_RPT_GROUP_NORMAL):
  74. amount, _ := decimal.NewFromString(imSendRedPackageOrd.Amount)
  75. tmpGrabAmount := amount.Div(decimal.NewFromInt(int64(imSendRedPackageOrd.RedPacketNums)))
  76. grabAmount = tmpGrabAmount.String()
  77. tempRedPacketBalanceAmount, _ := decimal.NewFromString(imSendRedPackageOrd.RedPacketBalanceAmount)
  78. redPacketBalanceAmount = tempRedPacketBalanceAmount.Sub(tmpGrabAmount).String()
  79. break
  80. case int(pb.RedPacketType_RPT_GROUP_LUCK):
  81. balanceAmount, err := decimal.NewFromString(imSendRedPackageOrd.RedPacketBalanceAmount)
  82. if err != nil {
  83. return nil, grabAmount, err
  84. }
  85. balanceAmountValue, _ := balanceAmount.Float64()
  86. tmpGrabAmount := float64(utils.DoubleAverage(int64(imSendRedPackageOrd.RedPacketBalanceNums), utils.FloatToInt64(balanceAmountValue*100))) / 100
  87. grabAmount = utils.AnyToString(tmpGrabAmount)
  88. redPacketBalanceAmount = balanceAmount.Sub(decimal.NewFromFloat(tmpGrabAmount)).String()
  89. break
  90. case int(pb.RedPacketType_RPT_GROUP_SPECIALLY):
  91. if !utils.ContainerStr(waitDrawImUserIds, req.UserId) {
  92. return nil, grabAmount, errors.New("非专属用户不能领取")
  93. }
  94. grabAmount = imSendRedPackageOrd.Amount
  95. redPacketBalanceAmount = "0"
  96. redPacketReceivedImUserIds = req.UserId
  97. break
  98. case int(pb.RedPacketType_RPT_SYSTEM_FOR):
  99. if !utils.ContainerStr(waitDrawImUserIds, req.UserId) {
  100. return nil, grabAmount, errors.New("非专属用户不能领取")
  101. }
  102. grabAmount = imSendRedPackageOrd.Amount
  103. redPacketBalanceAmount = "0"
  104. redPacketReceivedImUserIds = req.UserId
  105. break
  106. }
  107. receivedImUserIds = append(receivedImUserIds, req.UserId)
  108. redPacketReceivedImUserIds = strings.Join(receivedImUserIds, ",")
  109. receivedUserIds = append(receivedUserIds, utils.AnyToString(user.Id))
  110. redPacketReceivedUserIds = strings.Join(receivedUserIds, ",")
  111. redPackageReceivedUserAmounts = append(redPackageReceivedUserAmounts, grabAmount)
  112. redPackageReceivedUserAmount = strings.Join(redPackageReceivedUserAmounts, ",")
  113. }
  114. session := db.Db.NewSession()
  115. defer session.Close()
  116. //2、改变红包记录状态
  117. if imSendRedPackageOrd.ReceivedTimes != "" {
  118. receivedTimes := strings.Split(imSendRedPackageOrd.ReceivedTimes, ",")
  119. receivedTimes = append(receivedTimes, time.Now().Format("2006-01-02 15:04:05"))
  120. imSendRedPackageOrd.ReceivedTimes = strings.Join(receivedTimes, ",")
  121. } else {
  122. imSendRedPackageOrd.ReceivedTimes = time.Now().Format("2006-01-02 15:04:05")
  123. }
  124. imSendRedPackageOrd.RedPacketBalanceNums = imSendRedPackageOrd.RedPacketBalanceNums - 1
  125. if imSendRedPackageOrd.RedPacketBalanceNums > 0 {
  126. imSendRedPackageOrd.State = int(pb.RedPacketStatusType_RPS_DRAWING)
  127. } else {
  128. imSendRedPackageOrd.State = int(pb.RedPacketStatusType_RPS_DRAW_OVER)
  129. }
  130. imSendRedPackageOrd.ReceivedUserAmount = redPackageReceivedUserAmount
  131. imSendRedPackageOrd.RedPacketBalanceAmount = redPacketBalanceAmount
  132. imSendRedPackageOrd.ReceivedUserIds = redPacketReceivedUserIds
  133. imSendRedPackageOrd.ReceivedImUserIds = redPacketReceivedImUserIds
  134. _, err = redPackageOrdDb.ImSendRedPackageOrdUpdateBySession(session, imSendRedPackageOrd.Id, imSendRedPackageOrd, "red_packet_balance_nums", "state", "received_user_ids", "received_im_user_ids", "received_times",
  135. "received_user_amount", "create_time", "update_time", "red_packet_balance_amount")
  136. if err != nil {
  137. session.Rollback()
  138. return nil, grabAmount, err
  139. }
  140. //3、加上给用户加上余额
  141. dealUserWalletReq := md2.DealUserWalletReq{
  142. Direction: "add",
  143. Kind: 5,
  144. Title: "领取红包收益",
  145. Uid: user.Id,
  146. Amount: utils.StrToFloat64(grabAmount),
  147. }
  148. err = rule.DealUserWallet(session, dealUserWalletReq)
  149. if err != nil {
  150. session.Rollback()
  151. return nil, grabAmount, err
  152. }
  153. //4、组装消息参数
  154. msg := &pb.RED_PACKAGE{
  155. RedMessageType: pb.RedPacketMessageType_RMT_GRAB,
  156. RedPacketType: pb.RedPacketType(imSendRedPackageOrd.RedPacketType),
  157. RedPacketContent: "",
  158. //RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)),
  159. //RedPacketNums: int32(req.RedPacketNums),
  160. RedPacketBalanceAmount: float32(utils.AnyToFloat64(imSendRedPackageOrd.RedPacketBalanceAmount)),
  161. ReceivedUserId: utils.StrToInt64(req.UserId),
  162. ReceivedUserAmount: utils.StrToFloat32(grabAmount),
  163. ReceivedUserNickname: user.Nickname,
  164. RedPacketStatusType: pb.RedPacketStatusType(imSendRedPackageOrd.State),
  165. RedPacketId: imSendRedPackageOrd.Id,
  166. SendRedPacketUid: int64(imSendRedPackageOrd.ImUid),
  167. SendRedPacketNickname: req.SendRedPackageUserNikeName,
  168. SendRedPacketAvatarUrl: req.SendRedPacketAvatarUrl,
  169. //RedPacketSmallContent: req.RedPacketSmallContent,
  170. RedPacketCover: req.RedPackageCover,
  171. }
  172. utils.FilePutContents("DelGrabRedPackage", utils.SerializeStr(map[string]interface{}{
  173. "args": req,
  174. "msg": msg,
  175. "ord": imSendRedPackageOrd,
  176. }))
  177. resp, err = proto.Marshal(msg)
  178. if err != nil {
  179. return nil, grabAmount, err
  180. }
  181. return resp, grabAmount, nil
  182. }
  183. func DetailGrabRedPackage(redPackageId string) (resp []md.RedPackageDetailUserNode, imSendRedPackageOrd *model.ImSendRedPackageOrd, err error) {
  184. //1、查找红包
  185. redPackageOrdDb := implement.NewImSendRedPackageOrdDb(db.Db)
  186. imSendRedPackageOrd, err = redPackageOrdDb.ImSendRedPackageOrdGetOneByParams(map[string]interface{}{
  187. "key": "id",
  188. "value": redPackageId,
  189. })
  190. if err != nil {
  191. return nil, nil, err
  192. }
  193. if imSendRedPackageOrd == nil {
  194. return resp, imSendRedPackageOrd, errors.New("未查询到对应的红包记录")
  195. }
  196. receivedUserIds := strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  197. userDb := implement.NewUserDb(db.Db)
  198. users, err := userDb.UserFindByParams(map[string]interface{}{
  199. "key": "id",
  200. "value": receivedUserIds,
  201. })
  202. if err != nil {
  203. return resp, imSendRedPackageOrd, err
  204. }
  205. var usersMap = map[string]model.User{}
  206. for _, v := range users {
  207. usersMap[utils.AnyToString(v.Id)] = v
  208. }
  209. receivedImUserIds := strings.Split(imSendRedPackageOrd.ReceivedImUserIds, ",")
  210. receivedTimes := strings.Split(imSendRedPackageOrd.ReceivedTimes, ",")
  211. receivedUserAmount := strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  212. redisConn := cache.GetPool().Get()
  213. scheme, domain := svc.ImageBucket(db.Db, redisConn)
  214. for k, v := range receivedUserIds {
  215. resp = append(resp, md.RedPackageDetailUserNode{
  216. ImUserId: receivedImUserIds[k],
  217. UserNickName: usersMap[v].Nickname,
  218. UserAvatarUrl: svc.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: 6,
  233. Title: "领取红包收益",
  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. redisConn := cache.GetPool().Get()
  320. scheme, domain := svc.ImageBucket(db.Db, redisConn)
  321. msg := &pb.RED_PACKAGE{
  322. RedMessageType: pb.RedPacketMessageType_RMT_SEND,
  323. RedPacketType: pb.RedPacketType(req.RedPacketType),
  324. RedPacketContent: req.RedPacketContent,
  325. RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)),
  326. RedPacketNums: int32(req.RedPacketNums),
  327. RedPacketBalanceAmount: float32(utils.AnyToFloat64(req.Amount)),
  328. ReceivedUserId: utils.StrToInt64(waitDrawUserIds),
  329. ReceivedUserAmount: 0,
  330. ReceivedUserNickname: "",
  331. RedPacketStatusType: 0,
  332. RedPacketId: redPackageOrdId,
  333. SendRedPacketUid: utils.StrToInt64(req.UserId),
  334. SendRedPacketNickname: user.Nickname,
  335. SendRedPacketAvatarUrl: svc.ImageFormatWithBucket(scheme, domain, user.Avatar),
  336. RedPacketSmallContent: req.RedPacketSmallContent,
  337. }
  338. resp, err = proto.Marshal(msg)
  339. if err != nil {
  340. return nil, redPackageId, err
  341. }
  342. redPackageId = redPackageOrdId
  343. return resp, redPackageId, nil
  344. }