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

425 lines
15 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. // 剩余个数和已过期无法领取
  39. if imSendRedPackageOrd.RedPacketBalanceNums == 0 || imSendRedPackageOrd.State == int(pb.RedPacketStatusType_RPS_EXPIRE) {
  40. return nil, "-1", nil
  41. }
  42. //2、判断用户是否已领取
  43. receivedUserIds := strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  44. for k, receivedUserId := range receivedUserIds {
  45. if receivedUserId == utils.Int64ToStr(user.Id) {
  46. redPackageReceivedUserAmounts := strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  47. grabAmount = redPackageReceivedUserAmounts[k]
  48. return nil, grabAmount, err
  49. }
  50. }
  51. //3、判断红包类型
  52. if imSendRedPackageOrd.RedPacketType == int(pb.RedPacketType_RPT_FRIEND) {
  53. //好友红包
  54. grabAmount = imSendRedPackageOrd.Amount
  55. redPacketBalanceAmount = "0"
  56. redPacketReceivedImUserIds = req.UserId
  57. redPacketReceivedUserIds = utils.Int64ToStr(user.Id)
  58. redPackageReceivedUserAmount = imSendRedPackageOrd.Amount
  59. } else {
  60. var receivedImUserIds, receivedUserIds, waitDrawImUserIds, redPackageReceivedUserAmounts []string
  61. if imSendRedPackageOrd.ReceivedImUserIds != "" {
  62. receivedImUserIds = strings.Split(imSendRedPackageOrd.ReceivedImUserIds, ",")
  63. }
  64. if imSendRedPackageOrd.ReceivedUserIds != "" {
  65. receivedUserIds = strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  66. }
  67. if imSendRedPackageOrd.WaitDrawImUserIds != "" {
  68. waitDrawImUserIds = strings.Split(imSendRedPackageOrd.WaitDrawImUserIds, ",")
  69. }
  70. if imSendRedPackageOrd.ReceivedUserAmount != "" {
  71. redPackageReceivedUserAmounts = strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  72. }
  73. //群组红包
  74. switch imSendRedPackageOrd.RedPacketType {
  75. case int(pb.RedPacketType_RPT_GROUP_NORMAL):
  76. amount, _ := decimal.NewFromString(imSendRedPackageOrd.Amount)
  77. tmpGrabAmount := amount.Div(decimal.NewFromInt(int64(imSendRedPackageOrd.RedPacketNums)))
  78. grabAmount = tmpGrabAmount.String()
  79. tempRedPacketBalanceAmount, _ := decimal.NewFromString(imSendRedPackageOrd.RedPacketBalanceAmount)
  80. redPacketBalanceAmount = tempRedPacketBalanceAmount.Sub(tmpGrabAmount).String()
  81. break
  82. case int(pb.RedPacketType_RPT_GROUP_LUCK):
  83. balanceAmount, err := decimal.NewFromString(imSendRedPackageOrd.RedPacketBalanceAmount)
  84. if err != nil {
  85. return nil, grabAmount, err
  86. }
  87. balanceAmountValue, _ := balanceAmount.Float64()
  88. tmpGrabAmount := float64(utils.DoubleAverage(int64(imSendRedPackageOrd.RedPacketBalanceNums), utils.FloatToInt64(balanceAmountValue*100))) / 100
  89. grabAmount = utils.AnyToString(tmpGrabAmount)
  90. redPacketBalanceAmount = balanceAmount.Sub(decimal.NewFromFloat(tmpGrabAmount)).String()
  91. break
  92. case int(pb.RedPacketType_RPT_GROUP_SPECIALLY):
  93. if !utils.ContainerStr(waitDrawImUserIds, req.UserId) {
  94. return nil, grabAmount, errors.New("非专属用户不能领取")
  95. }
  96. grabAmount = imSendRedPackageOrd.Amount
  97. redPacketBalanceAmount = "0"
  98. redPacketReceivedImUserIds = req.UserId
  99. break
  100. case int(pb.RedPacketType_RPT_SYSTEM_FOR):
  101. if !utils.ContainerStr(waitDrawImUserIds, req.UserId) {
  102. return nil, grabAmount, errors.New("非专属用户不能领取")
  103. }
  104. grabAmount = imSendRedPackageOrd.Amount
  105. redPacketBalanceAmount = "0"
  106. redPacketReceivedImUserIds = req.UserId
  107. break
  108. }
  109. receivedImUserIds = append(receivedImUserIds, req.UserId)
  110. redPacketReceivedImUserIds = strings.Join(receivedImUserIds, ",")
  111. receivedUserIds = append(receivedUserIds, utils.AnyToString(user.Id))
  112. redPacketReceivedUserIds = strings.Join(receivedUserIds, ",")
  113. redPackageReceivedUserAmounts = append(redPackageReceivedUserAmounts, grabAmount)
  114. redPackageReceivedUserAmount = strings.Join(redPackageReceivedUserAmounts, ",")
  115. }
  116. session := db.Db.NewSession()
  117. defer session.Close()
  118. //2、改变红包记录状态
  119. if imSendRedPackageOrd.ReceivedTimes != "" {
  120. receivedTimes := strings.Split(imSendRedPackageOrd.ReceivedTimes, ",")
  121. receivedTimes = append(receivedTimes, time.Now().Format("2006-01-02 15:04:05"))
  122. imSendRedPackageOrd.ReceivedTimes = strings.Join(receivedTimes, ",")
  123. } else {
  124. imSendRedPackageOrd.ReceivedTimes = time.Now().Format("2006-01-02 15:04:05")
  125. }
  126. imSendRedPackageOrd.RedPacketBalanceNums = imSendRedPackageOrd.RedPacketBalanceNums - 1
  127. if imSendRedPackageOrd.RedPacketBalanceNums > 0 {
  128. imSendRedPackageOrd.State = int(pb.RedPacketStatusType_RPS_DRAWING)
  129. } else {
  130. imSendRedPackageOrd.State = int(pb.RedPacketStatusType_RPS_DRAW_OVER)
  131. }
  132. imSendRedPackageOrd.ReceivedUserAmount = redPackageReceivedUserAmount
  133. imSendRedPackageOrd.RedPacketBalanceAmount = redPacketBalanceAmount
  134. imSendRedPackageOrd.ReceivedUserIds = redPacketReceivedUserIds
  135. imSendRedPackageOrd.ReceivedImUserIds = redPacketReceivedImUserIds
  136. _, err = redPackageOrdDb.ImSendRedPackageOrdUpdateBySession(session, imSendRedPackageOrd.Id, imSendRedPackageOrd,
  137. "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. session.Commit()
  157. //4、组装消息参数
  158. msg := &pb.RED_PACKAGE{
  159. RedMessageType: pb.RedPacketMessageType_RMT_GRAB,
  160. RedPacketType: pb.RedPacketType(imSendRedPackageOrd.RedPacketType),
  161. RedPacketContent: "",
  162. //RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)),
  163. //RedPacketNums: int32(req.RedPacketNums),
  164. RedPacketBalanceAmount: float32(utils.AnyToFloat64(imSendRedPackageOrd.RedPacketBalanceAmount)),
  165. ReceivedUserId: utils.StrToInt64(req.UserId),
  166. ReceivedUserAmount: utils.StrToFloat32(grabAmount),
  167. ReceivedUserNickname: user.Nickname,
  168. RedPacketStatusType: pb.RedPacketStatusType(imSendRedPackageOrd.State),
  169. RedPacketId: imSendRedPackageOrd.Id,
  170. SendRedPacketUid: int64(imSendRedPackageOrd.ImUid),
  171. SendRedPacketNickname: req.SendRedPackageUserNikeName,
  172. SendRedPacketAvatarUrl: req.SendRedPacketAvatarUrl,
  173. //RedPacketSmallContent: req.RedPacketSmallContent,
  174. RedPacketCover: req.RedPackageCover,
  175. }
  176. utils.FilePutContents("DelGrabRedPackage", utils.SerializeStr(map[string]interface{}{
  177. "args": req,
  178. "msg": msg,
  179. "ord": imSendRedPackageOrd,
  180. }))
  181. resp, err = proto.Marshal(msg)
  182. if err != nil {
  183. return nil, grabAmount, err
  184. }
  185. return resp, grabAmount, nil
  186. }
  187. func DetailGrabRedPackage(redPackageId string) (resp []md.RedPackageDetailUserNode, imSendRedPackageOrd *model.ImSendRedPackageOrd, err error) {
  188. //1、查找红包
  189. redPackageOrdDb := implement.NewImSendRedPackageOrdDb(db.Db)
  190. imSendRedPackageOrd, err = redPackageOrdDb.ImSendRedPackageOrdGetOneByParams(map[string]interface{}{
  191. "key": "id",
  192. "value": redPackageId,
  193. })
  194. if err != nil {
  195. return nil, nil, err
  196. }
  197. if imSendRedPackageOrd == nil {
  198. return resp, imSendRedPackageOrd, errors.New("未查询到对应的红包记录")
  199. }
  200. receivedUserIds := strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",")
  201. userDb := implement.NewUserDb(db.Db)
  202. users, err := userDb.UserFindByParams(map[string]interface{}{
  203. "key": "id",
  204. "value": receivedUserIds,
  205. })
  206. if err != nil {
  207. return resp, imSendRedPackageOrd, err
  208. }
  209. var usersMap = map[string]model.User{}
  210. for _, v := range users {
  211. usersMap[utils.AnyToString(v.Id)] = v
  212. }
  213. receivedImUserIds := strings.Split(imSendRedPackageOrd.ReceivedImUserIds, ",")
  214. receivedTimes := strings.Split(imSendRedPackageOrd.ReceivedTimes, ",")
  215. receivedUserAmount := strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",")
  216. scheme, domain := ImageBucket(db.Db)
  217. for k, v := range receivedUserIds {
  218. resp = append(resp, md.RedPackageDetailUserNode{
  219. ImUserId: receivedImUserIds[k],
  220. UserNickName: usersMap[v].Nickname,
  221. UserAvatarUrl: 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. var imUser model2.User
  249. has, err := db.DbIm.Where("phone_number = ?", user.Phone).Get(&imUser)
  250. if err != nil {
  251. session.Rollback()
  252. return nil, 0, err
  253. }
  254. if has {
  255. imUid = int(imUser.Id)
  256. } else {
  257. if req.UserId != "" {
  258. imUid = utils.StrToInt(req.UserId)
  259. } else {
  260. //TODO::请求rpc接口,同步用户数据
  261. resp, err := utils.GetBusinessExtClient(cfg.ImBusinessRpc.URL, cfg.ImBusinessRpc.PORT).GetUser(utils.GetCtx("", "", ""), &pb.GetUserReq{
  262. UserId: 0,
  263. Phone: user.Phone,
  264. })
  265. if err != nil {
  266. return nil, redPackageId, err
  267. }
  268. imUid = int(resp.User.UserId)
  269. now := time.Now()
  270. tempImUser := model2.User{
  271. Id: int64(imUid),
  272. PhoneNumber: user.Phone,
  273. Nickname: user.Nickname,
  274. Sex: 0,
  275. AvatarUrl: user.Avatar,
  276. Extra: "",
  277. CreateTime: now,
  278. UpdateTime: now,
  279. IsAutoAddedFriends: 0,
  280. }
  281. _, err = db.DbIm.Insert(&tempImUser)
  282. if err != nil {
  283. session.Rollback()
  284. return nil, 0, err
  285. }
  286. }
  287. }
  288. now := time.Now()
  289. ordNo := uuid.New().String()
  290. var waitDrawUserIds string
  291. var waitDrawImUserIds string
  292. if req.RedPacketType == int(pb.RedPacketType_RPT_GROUP_SPECIALLY) {
  293. // 构造 im 用户 id 列表
  294. var toImUserIds []string
  295. for _, v := range req.ToUserIds {
  296. toImUserIds = append(toImUserIds, utils.AnyToString(v))
  297. }
  298. waitDrawImUserIds = strings.Join(toImUserIds, ",")
  299. // 查询 im 用户信息
  300. var imUsers []model2.User
  301. err = db.DbIm.In("id", req.ToUserIds).Find(&imUsers)
  302. if err != nil {
  303. return nil, 0, err
  304. }
  305. // 获取手机号列表
  306. var phones []string
  307. for _, v := range imUsers {
  308. phones = append(phones, v.PhoneNumber)
  309. }
  310. // 查询用户信息
  311. userDb := implement.NewUserDb(db.Db)
  312. waitDrawUsers, err1 := userDb.UserFindByParams(map[string]interface{}{
  313. "key": "phone",
  314. "value": phones,
  315. })
  316. if err1 != nil {
  317. return nil, 0, err1
  318. }
  319. var toUserIDs []string
  320. for _, v := range waitDrawUsers {
  321. toUserIDs = append(toUserIDs, utils.AnyToString(v.Id))
  322. }
  323. waitDrawUserIds = strings.Join(toUserIDs, ",")
  324. }
  325. ordDb := implement.NewImSendRedPackageOrdDb(db.Db)
  326. m := model.ImSendRedPackageOrd{
  327. OrdNo: ordNo,
  328. Uid: int(user.Id),
  329. ImUid: imUid,
  330. Amount: req.Amount,
  331. RedPacketBalanceAmount: req.Amount,
  332. RedPacketType: req.RedPacketType,
  333. RedPacketNums: req.RedPacketNums,
  334. RedPacketBalanceNums: req.RedPacketNums,
  335. State: 0,
  336. WaitDrawUserIds: waitDrawUserIds,
  337. WaitDrawImUserIds: waitDrawImUserIds,
  338. ReceivedUserIds: "",
  339. ReceivedImUserIds: "",
  340. ReceivedUserAmount: "",
  341. CreateTime: now.Format("2006-01-02 15:04:05"),
  342. UpdateTime: now.Format("2006-01-02 15:04:05"),
  343. }
  344. redPackageOrdId, err := ordDb.ImSendRedPackageOrdInsertBySession(session, &m)
  345. if err != nil {
  346. session.Rollback()
  347. return nil, redPackageId, err
  348. }
  349. err = session.Commit()
  350. if err != nil {
  351. return nil, redPackageOrdId, err
  352. }
  353. scheme, domain := ImageBucket(db.Db)
  354. msg := &pb.RED_PACKAGE{
  355. RedMessageType: pb.RedPacketMessageType_RMT_SEND,
  356. RedPacketType: pb.RedPacketType(req.RedPacketType),
  357. RedPacketContent: req.RedPacketContent,
  358. RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)),
  359. RedPacketNums: int32(req.RedPacketNums),
  360. RedPacketBalanceAmount: float32(utils.AnyToFloat64(req.Amount)),
  361. ReceivedUserId: utils.StrToInt64(waitDrawUserIds),
  362. ReceivedUserAmount: 0,
  363. ReceivedUserNickname: "",
  364. RedPacketStatusType: 0,
  365. RedPacketId: redPackageOrdId,
  366. SendRedPacketUid: utils.StrToInt64(req.UserId),
  367. SendRedPacketNickname: user.Nickname,
  368. SendRedPacketAvatarUrl: ImageFormatWithBucket(scheme, domain, user.Avatar),
  369. RedPacketSmallContent: req.RedPacketSmallContent,
  370. }
  371. resp, err = proto.Marshal(msg)
  372. if err != nil {
  373. return nil, redPackageId, err
  374. }
  375. redPackageId = redPackageOrdId
  376. return resp, redPackageId, nil
  377. }
  378. // GetImUser 获取im用户信息
  379. func GetImUser(userId int64, phone string) (user *pb.User, err error) {
  380. resp, err := utils.GetBusinessExtClient(cfg.ImBusinessRpc.URL, cfg.ImBusinessRpc.PORT).GetUser(utils.GetCtx("", "", ""), &pb.GetUserReq{
  381. UserId: userId,
  382. Phone: phone,
  383. })
  384. if err != nil {
  385. return
  386. }
  387. return resp.User, nil
  388. }
  389. func AddSendRedPackageTimesPushToMQ(uid int64) {
  390. ch, err := rabbit.Cfg.Pool.GetChannel()
  391. if err != nil {
  392. return
  393. }
  394. defer ch.Release()
  395. ch.Publish(md3.IMEggEnergyExchange, md3.IMEggEnergyStructForSendRedPackageData{
  396. Uid: uid,
  397. }, md3.IMEggEnergyRoutKeyForSendRedPackage)
  398. }