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

380 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. "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. "code.fnuoos.com/EggPlanet/egg_system_rules.git/svc"
  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. redisConn := cache.GetPool().Get()
  214. scheme, domain := svc.ImageBucket(db.Db, redisConn)
  215. for k, v := range receivedUserIds {
  216. resp = append(resp, md.RedPackageDetailUserNode{
  217. ImUserId: receivedImUserIds[k],
  218. UserNickName: usersMap[v].Nickname,
  219. UserAvatarUrl: svc.ImageFormatWithBucket(scheme, domain, usersMap[v].Avatar),
  220. Amount: receivedUserAmount[k],
  221. ReceiveAt: receivedTimes[k],
  222. })
  223. }
  224. return resp, imSendRedPackageOrd, nil
  225. }
  226. // BalancePayForRedPackage 红包余额支付
  227. func BalancePayForRedPackage(user *model.User, money string, req md.SendRedPackageReq) (resp []byte, redPackageId int64, err error) {
  228. session := db.Db.NewSession()
  229. defer session.Close()
  230. //扣除用户余额
  231. dealUserWalletReq := md2.DealUserWalletReq{
  232. Direction: "sub",
  233. Kind: int(enum2.UserSendRedPackage),
  234. Title: enum2.UserSendRedPackage.String(),
  235. Uid: user.Id,
  236. Amount: utils.StrToFloat64(money),
  237. }
  238. rule2.Init(cfg.RedisAddr)
  239. err = rule.DealUserWallet(session, dealUserWalletReq)
  240. if err != nil {
  241. session.Rollback()
  242. return nil, 0, err
  243. }
  244. // 新增红包记录
  245. var imUid int
  246. if req.UserId != "" {
  247. imUid = utils.StrToInt(req.UserId)
  248. } else {
  249. //TODO::请求rpc接口,同步用户数据
  250. resp, err := utils.GetBusinessExtClient(cfg.ImBusinessRpc.URL, cfg.ImBusinessRpc.PORT).GetUser(utils.GetCtx("", "", ""), &pb.GetUserReq{
  251. UserId: 0,
  252. Phone: user.Phone,
  253. })
  254. if err != nil {
  255. return nil, redPackageId, err
  256. }
  257. imUid = int(resp.User.UserId)
  258. }
  259. now := time.Now()
  260. ordNo := uuid.New().String()
  261. var waitDrawUserIds string
  262. var waitDrawImUserIds string
  263. if req.RedPacketType == int(pb.RedPacketType_RPT_GROUP_SPECIALLY) {
  264. var toUserIds []string
  265. for _, v := range req.ToUserIds {
  266. toUserIds = append(toUserIds, utils.AnyToString(v))
  267. }
  268. waitDrawUserIds = strings.Join(toUserIds, ",")
  269. userDb := implement.NewUserDb(db.Db)
  270. waitDrawUsers, err1 := userDb.UserFindByParams(map[string]interface{}{
  271. "key": "id",
  272. "value": toUserIds,
  273. })
  274. if err1 != nil {
  275. return nil, 0, err1
  276. }
  277. var waitDrawUserPhones []string
  278. for _, v := range waitDrawUsers {
  279. waitDrawUserPhones = append(waitDrawUserPhones, v.Phone)
  280. }
  281. var waitDrawImUsers []model2.User
  282. err = db.DbIm.Table("user").In("phone_number", waitDrawUserPhones).Find(&waitDrawUsers)
  283. if err != nil {
  284. return nil, 0, err
  285. }
  286. var toUserIMIDs []string
  287. for _, v := range waitDrawImUsers {
  288. toUserIMIDs = append(toUserIMIDs, utils.AnyToString(v.Id))
  289. }
  290. waitDrawImUserIds = strings.Join(toUserIMIDs, ",")
  291. }
  292. ordDb := implement.NewImSendRedPackageOrdDb(db.Db)
  293. m := model.ImSendRedPackageOrd{
  294. OrdNo: ordNo,
  295. Uid: int(user.Id),
  296. ImUid: imUid,
  297. Amount: req.Amount,
  298. RedPacketBalanceAmount: req.Amount,
  299. RedPacketType: req.RedPacketType,
  300. RedPacketNums: req.RedPacketNums,
  301. RedPacketBalanceNums: req.RedPacketNums,
  302. State: 0,
  303. WaitDrawUserIds: waitDrawUserIds,
  304. WaitDrawImUserIds: waitDrawImUserIds,
  305. ReceivedUserIds: "",
  306. ReceivedImUserIds: "",
  307. ReceivedUserAmount: "",
  308. CreateTime: now.Format("2006-01-02 15:04:05"),
  309. UpdateTime: now.Format("2006-01-02 15:04:05"),
  310. }
  311. redPackageOrdId, err := ordDb.ImSendRedPackageOrdInsertBySession(session, &m)
  312. if err != nil {
  313. session.Rollback()
  314. return nil, redPackageId, err
  315. }
  316. err = session.Commit()
  317. if err != nil {
  318. return nil, redPackageOrdId, err
  319. }
  320. redisConn := cache.GetPool().Get()
  321. scheme, domain := svc.ImageBucket(db.Db, redisConn)
  322. msg := &pb.RED_PACKAGE{
  323. RedMessageType: pb.RedPacketMessageType_RMT_SEND,
  324. RedPacketType: pb.RedPacketType(req.RedPacketType),
  325. RedPacketContent: req.RedPacketContent,
  326. RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)),
  327. RedPacketNums: int32(req.RedPacketNums),
  328. RedPacketBalanceAmount: float32(utils.AnyToFloat64(req.Amount)),
  329. ReceivedUserId: utils.StrToInt64(waitDrawUserIds),
  330. ReceivedUserAmount: 0,
  331. ReceivedUserNickname: "",
  332. RedPacketStatusType: 0,
  333. RedPacketId: redPackageOrdId,
  334. SendRedPacketUid: utils.StrToInt64(req.UserId),
  335. SendRedPacketNickname: user.Nickname,
  336. SendRedPacketAvatarUrl: svc.ImageFormatWithBucket(scheme, domain, user.Avatar),
  337. RedPacketSmallContent: req.RedPacketSmallContent,
  338. }
  339. resp, err = proto.Marshal(msg)
  340. if err != nil {
  341. return nil, redPackageId, err
  342. }
  343. redPackageId = redPackageOrdId
  344. return resp, redPackageId, nil
  345. }
  346. // GetImUser 获取im用户信息
  347. func GetImUser(userId int64, phone string) (user *pb.User, err error) {
  348. resp, err := utils.GetBusinessExtClient(cfg.ImBusinessRpc.URL, cfg.ImBusinessRpc.PORT).GetUser(utils.GetCtx("", "", ""), &pb.GetUserReq{
  349. UserId: userId,
  350. Phone: phone,
  351. })
  352. if err != nil {
  353. return
  354. }
  355. return resp.User, nil
  356. }