package svc import ( "applet/app/cfg" "applet/app/db" model2 "applet/app/db/im/model" "applet/app/md" "applet/app/pkg/pb" "applet/app/utils" "applet/app/utils/cache" "code.fnuoos.com/EggPlanet/egg_models.git/src/implement" "code.fnuoos.com/EggPlanet/egg_models.git/src/model" rule2 "code.fnuoos.com/EggPlanet/egg_system_rules.git" enum2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/enum" md2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/md" "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule" md3 "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/md" "code.fnuoos.com/EggPlanet/egg_system_rules.git/svc" "code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit" "errors" "github.com/google/uuid" "github.com/shopspring/decimal" "google.golang.org/protobuf/proto" "strings" "time" ) func DelGrabRedPackage(req *md.GrabRedPackageReq, user *model.User) (resp []byte, grabAmount string, err error) { var redPacketBalanceAmount, redPacketReceivedUserIds, redPacketReceivedImUserIds, redPackageReceivedUserAmount string //1、查找红包 redPackageOrdDb := implement.NewImSendRedPackageOrdDb(db.Db) imSendRedPackageOrd, err := redPackageOrdDb.ImSendRedPackageOrdGetOneByParams(map[string]interface{}{ "key": "id", "value": req.RedPackageId, }) if err != nil { return nil, grabAmount, err } if imSendRedPackageOrd == nil { return nil, grabAmount, errors.New("未查询到对应的红包记录") } if imSendRedPackageOrd.RedPacketBalanceNums == 0 || imSendRedPackageOrd.State == int(pb.RedPacketStatusType_RPS_EXPIRE) { return nil, "-1", nil } //2、判断用户是否已领取 receivedUserIds := strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",") for k, receivedUserId := range receivedUserIds { if receivedUserId == utils.Int64ToStr(user.Id) { redPackageReceivedUserAmounts := strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",") grabAmount = redPackageReceivedUserAmounts[k] return nil, grabAmount, err } } //3、判断红包类型 if imSendRedPackageOrd.RedPacketType == int(pb.RedPacketType_RPT_FRIEND) { //好友红包 grabAmount = imSendRedPackageOrd.Amount redPacketBalanceAmount = "0" redPacketReceivedImUserIds = req.UserId redPacketReceivedUserIds = utils.Int64ToStr(user.Id) redPackageReceivedUserAmount = imSendRedPackageOrd.Amount } else { var receivedImUserIds, receivedUserIds, waitDrawImUserIds, redPackageReceivedUserAmounts []string if imSendRedPackageOrd.ReceivedImUserIds != "" { receivedImUserIds = strings.Split(imSendRedPackageOrd.ReceivedImUserIds, ",") } if imSendRedPackageOrd.ReceivedUserIds != "" { receivedUserIds = strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",") } if imSendRedPackageOrd.WaitDrawImUserIds != "" { waitDrawImUserIds = strings.Split(imSendRedPackageOrd.WaitDrawImUserIds, ",") } if imSendRedPackageOrd.ReceivedUserAmount != "" { redPackageReceivedUserAmounts = strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",") } //群组红包 switch imSendRedPackageOrd.RedPacketType { case int(pb.RedPacketType_RPT_GROUP_NORMAL): amount, _ := decimal.NewFromString(imSendRedPackageOrd.Amount) tmpGrabAmount := amount.Div(decimal.NewFromInt(int64(imSendRedPackageOrd.RedPacketNums))) grabAmount = tmpGrabAmount.String() tempRedPacketBalanceAmount, _ := decimal.NewFromString(imSendRedPackageOrd.RedPacketBalanceAmount) redPacketBalanceAmount = tempRedPacketBalanceAmount.Sub(tmpGrabAmount).String() break case int(pb.RedPacketType_RPT_GROUP_LUCK): balanceAmount, err := decimal.NewFromString(imSendRedPackageOrd.RedPacketBalanceAmount) if err != nil { return nil, grabAmount, err } balanceAmountValue, _ := balanceAmount.Float64() tmpGrabAmount := float64(utils.DoubleAverage(int64(imSendRedPackageOrd.RedPacketBalanceNums), utils.FloatToInt64(balanceAmountValue*100))) / 100 grabAmount = utils.AnyToString(tmpGrabAmount) redPacketBalanceAmount = balanceAmount.Sub(decimal.NewFromFloat(tmpGrabAmount)).String() break case int(pb.RedPacketType_RPT_GROUP_SPECIALLY): if !utils.ContainerStr(waitDrawImUserIds, req.UserId) { return nil, grabAmount, errors.New("非专属用户不能领取") } grabAmount = imSendRedPackageOrd.Amount redPacketBalanceAmount = "0" redPacketReceivedImUserIds = req.UserId break case int(pb.RedPacketType_RPT_SYSTEM_FOR): if !utils.ContainerStr(waitDrawImUserIds, req.UserId) { return nil, grabAmount, errors.New("非专属用户不能领取") } grabAmount = imSendRedPackageOrd.Amount redPacketBalanceAmount = "0" redPacketReceivedImUserIds = req.UserId break } receivedImUserIds = append(receivedImUserIds, req.UserId) redPacketReceivedImUserIds = strings.Join(receivedImUserIds, ",") receivedUserIds = append(receivedUserIds, utils.AnyToString(user.Id)) redPacketReceivedUserIds = strings.Join(receivedUserIds, ",") redPackageReceivedUserAmounts = append(redPackageReceivedUserAmounts, grabAmount) redPackageReceivedUserAmount = strings.Join(redPackageReceivedUserAmounts, ",") } session := db.Db.NewSession() defer session.Close() //2、改变红包记录状态 if imSendRedPackageOrd.ReceivedTimes != "" { receivedTimes := strings.Split(imSendRedPackageOrd.ReceivedTimes, ",") receivedTimes = append(receivedTimes, time.Now().Format("2006-01-02 15:04:05")) imSendRedPackageOrd.ReceivedTimes = strings.Join(receivedTimes, ",") } else { imSendRedPackageOrd.ReceivedTimes = time.Now().Format("2006-01-02 15:04:05") } imSendRedPackageOrd.RedPacketBalanceNums = imSendRedPackageOrd.RedPacketBalanceNums - 1 if imSendRedPackageOrd.RedPacketBalanceNums > 0 { imSendRedPackageOrd.State = int(pb.RedPacketStatusType_RPS_DRAWING) } else { imSendRedPackageOrd.State = int(pb.RedPacketStatusType_RPS_DRAW_OVER) } imSendRedPackageOrd.ReceivedUserAmount = redPackageReceivedUserAmount imSendRedPackageOrd.RedPacketBalanceAmount = redPacketBalanceAmount imSendRedPackageOrd.ReceivedUserIds = redPacketReceivedUserIds imSendRedPackageOrd.ReceivedImUserIds = redPacketReceivedImUserIds _, err = redPackageOrdDb.ImSendRedPackageOrdUpdateBySession(session, imSendRedPackageOrd.Id, imSendRedPackageOrd, "red_packet_balance_nums", "state", "received_user_ids", "received_im_user_ids", "received_times", "received_user_amount", "create_time", "update_time", "red_packet_balance_amount") if err != nil { session.Rollback() return nil, grabAmount, err } //3、加上给用户加上余额 dealUserWalletReq := md2.DealUserWalletReq{ Direction: "add", Kind: int(enum2.UserReceiveRedPackage), Title: enum2.UserReceiveRedPackage.String(), Uid: user.Id, Amount: utils.StrToFloat64(grabAmount), } err = rule.DealUserWallet(session, dealUserWalletReq) if err != nil { session.Rollback() return nil, grabAmount, err } //4、组装消息参数 msg := &pb.RED_PACKAGE{ RedMessageType: pb.RedPacketMessageType_RMT_GRAB, RedPacketType: pb.RedPacketType(imSendRedPackageOrd.RedPacketType), RedPacketContent: "", //RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)), //RedPacketNums: int32(req.RedPacketNums), RedPacketBalanceAmount: float32(utils.AnyToFloat64(imSendRedPackageOrd.RedPacketBalanceAmount)), ReceivedUserId: utils.StrToInt64(req.UserId), ReceivedUserAmount: utils.StrToFloat32(grabAmount), ReceivedUserNickname: user.Nickname, RedPacketStatusType: pb.RedPacketStatusType(imSendRedPackageOrd.State), RedPacketId: imSendRedPackageOrd.Id, SendRedPacketUid: int64(imSendRedPackageOrd.ImUid), SendRedPacketNickname: req.SendRedPackageUserNikeName, SendRedPacketAvatarUrl: req.SendRedPacketAvatarUrl, //RedPacketSmallContent: req.RedPacketSmallContent, RedPacketCover: req.RedPackageCover, } utils.FilePutContents("DelGrabRedPackage", utils.SerializeStr(map[string]interface{}{ "args": req, "msg": msg, "ord": imSendRedPackageOrd, })) resp, err = proto.Marshal(msg) if err != nil { return nil, grabAmount, err } return resp, grabAmount, nil } func DetailGrabRedPackage(redPackageId string) (resp []md.RedPackageDetailUserNode, imSendRedPackageOrd *model.ImSendRedPackageOrd, err error) { //1、查找红包 redPackageOrdDb := implement.NewImSendRedPackageOrdDb(db.Db) imSendRedPackageOrd, err = redPackageOrdDb.ImSendRedPackageOrdGetOneByParams(map[string]interface{}{ "key": "id", "value": redPackageId, }) if err != nil { return nil, nil, err } if imSendRedPackageOrd == nil { return resp, imSendRedPackageOrd, errors.New("未查询到对应的红包记录") } receivedUserIds := strings.Split(imSendRedPackageOrd.ReceivedUserIds, ",") userDb := implement.NewUserDb(db.Db) users, err := userDb.UserFindByParams(map[string]interface{}{ "key": "id", "value": receivedUserIds, }) if err != nil { return resp, imSendRedPackageOrd, err } var usersMap = map[string]model.User{} for _, v := range users { usersMap[utils.AnyToString(v.Id)] = v } receivedImUserIds := strings.Split(imSendRedPackageOrd.ReceivedImUserIds, ",") receivedTimes := strings.Split(imSendRedPackageOrd.ReceivedTimes, ",") receivedUserAmount := strings.Split(imSendRedPackageOrd.ReceivedUserAmount, ",") redisConn := cache.GetPool().Get() scheme, domain := svc.ImageBucket(db.Db, redisConn) for k, v := range receivedUserIds { resp = append(resp, md.RedPackageDetailUserNode{ ImUserId: receivedImUserIds[k], UserNickName: usersMap[v].Nickname, UserAvatarUrl: svc.ImageFormatWithBucket(scheme, domain, usersMap[v].Avatar), Amount: receivedUserAmount[k], ReceiveAt: receivedTimes[k], }) } return resp, imSendRedPackageOrd, nil } // BalancePayForRedPackage 红包余额支付 func BalancePayForRedPackage(user *model.User, money string, req md.SendRedPackageReq) (resp []byte, redPackageId int64, err error) { session := db.Db.NewSession() defer session.Close() //扣除用户余额 dealUserWalletReq := md2.DealUserWalletReq{ Direction: "sub", Kind: int(enum2.UserSendRedPackage), Title: enum2.UserSendRedPackage.String(), Uid: user.Id, Amount: utils.StrToFloat64(money), } rule2.Init(cfg.RedisAddr) err = rule.DealUserWallet(session, dealUserWalletReq) if err != nil { session.Rollback() return nil, 0, err } // 新增红包记录 var imUid int if req.UserId != "" { imUid = utils.StrToInt(req.UserId) } else { //TODO::请求rpc接口,同步用户数据 resp, err := utils.GetBusinessExtClient(cfg.ImBusinessRpc.URL, cfg.ImBusinessRpc.PORT).GetUser(utils.GetCtx("", "", ""), &pb.GetUserReq{ UserId: 0, Phone: user.Phone, }) if err != nil { return nil, redPackageId, err } imUid = int(resp.User.UserId) } now := time.Now() ordNo := uuid.New().String() var waitDrawUserIds string var waitDrawImUserIds string if req.RedPacketType == int(pb.RedPacketType_RPT_GROUP_SPECIALLY) { var toUserIds []string for _, v := range req.ToUserIds { toUserIds = append(toUserIds, utils.AnyToString(v)) } waitDrawUserIds = strings.Join(toUserIds, ",") userDb := implement.NewUserDb(db.Db) waitDrawUsers, err1 := userDb.UserFindByParams(map[string]interface{}{ "key": "id", "value": toUserIds, }) if err1 != nil { return nil, 0, err1 } var waitDrawUserPhones []string for _, v := range waitDrawUsers { waitDrawUserPhones = append(waitDrawUserPhones, v.Phone) } var waitDrawImUsers []model2.User err = db.DbIm.Table("user").In("phone_number", waitDrawUserPhones).Find(&waitDrawUsers) if err != nil { return nil, 0, err } var toUserIMIDs []string for _, v := range waitDrawImUsers { toUserIMIDs = append(toUserIMIDs, utils.AnyToString(v.Id)) } waitDrawImUserIds = strings.Join(toUserIMIDs, ",") } ordDb := implement.NewImSendRedPackageOrdDb(db.Db) m := model.ImSendRedPackageOrd{ OrdNo: ordNo, Uid: int(user.Id), ImUid: imUid, Amount: req.Amount, RedPacketBalanceAmount: req.Amount, RedPacketType: req.RedPacketType, RedPacketNums: req.RedPacketNums, RedPacketBalanceNums: req.RedPacketNums, State: 0, WaitDrawUserIds: waitDrawUserIds, WaitDrawImUserIds: waitDrawImUserIds, ReceivedUserIds: "", ReceivedImUserIds: "", ReceivedUserAmount: "", CreateTime: now.Format("2006-01-02 15:04:05"), UpdateTime: now.Format("2006-01-02 15:04:05"), } redPackageOrdId, err := ordDb.ImSendRedPackageOrdInsertBySession(session, &m) if err != nil { session.Rollback() return nil, redPackageId, err } err = session.Commit() if err != nil { return nil, redPackageOrdId, err } redisConn := cache.GetPool().Get() scheme, domain := svc.ImageBucket(db.Db, redisConn) msg := &pb.RED_PACKAGE{ RedMessageType: pb.RedPacketMessageType_RMT_SEND, RedPacketType: pb.RedPacketType(req.RedPacketType), RedPacketContent: req.RedPacketContent, RedPacketAmount: float32(utils.AnyToFloat64(req.Amount)), RedPacketNums: int32(req.RedPacketNums), RedPacketBalanceAmount: float32(utils.AnyToFloat64(req.Amount)), ReceivedUserId: utils.StrToInt64(waitDrawUserIds), ReceivedUserAmount: 0, ReceivedUserNickname: "", RedPacketStatusType: 0, RedPacketId: redPackageOrdId, SendRedPacketUid: utils.StrToInt64(req.UserId), SendRedPacketNickname: user.Nickname, SendRedPacketAvatarUrl: svc.ImageFormatWithBucket(scheme, domain, user.Avatar), RedPacketSmallContent: req.RedPacketSmallContent, } resp, err = proto.Marshal(msg) if err != nil { return nil, redPackageId, err } redPackageId = redPackageOrdId return resp, redPackageId, nil } // GetImUser 获取im用户信息 func GetImUser(userId int64, phone string) (user *pb.User, err error) { resp, err := utils.GetBusinessExtClient(cfg.ImBusinessRpc.URL, cfg.ImBusinessRpc.PORT).GetUser(utils.GetCtx("", "", ""), &pb.GetUserReq{ UserId: userId, Phone: phone, }) if err != nil { return } return resp.User, nil } func AddSendRedPackageTimesPushToMQ(uid int64) { ch, err := rabbit.Cfg.Pool.GetChannel() if err != nil { return } defer ch.Release() ch.Publish(md3.IMEggEnergyExchange, md3.IMEggEnergyStructForSendRedPackageData{ Uid: uid, }, md3.IMEggEnergyRoutKeyForSendRedPackage) }