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

svc_im.go 14 KiB

4週間前
3週間前
4週間前
3週間前
4週間前
4週間前
4週間前
3週間前
3週間前
4週間前
4週間前
4週間前
4週間前
4週間前
3週間前
4週間前
4週間前
4週間前
3週間前
4週間前
4週間前
4週間前
3週間前
4週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
3週間前
4週間前
2週間前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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. }