package hdl import ( "applet/app/db" "applet/app/e" "applet/app/md" "applet/app/svc" "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" md2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/md" "encoding/json" "github.com/gin-gonic/gin" "github.com/shopspring/decimal" "math" "time" ) // HomePage // @Summary 蛋蛋星球-主页-基础信息(获取) // @Tags 主页 // @Description 基础信息(获取) // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Success 200 {object} md.HomePageResp "具体数据" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/homePage/index [get] func HomePage(c *gin.Context) { now := time.Now() val, exists := c.Get("user") if !exists { e.OutErr(c, e.ERR_USER_CHECK_ERR, nil) return } user, ok := val.(*model.User) if !ok { e.OutErr(c, e.ERR_USER_CHECK_ERR, nil) return } //1、查找 `egg_energy_basic_setting` 基础设置 eggEnergyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db) eggEnergyBasicSetting, err := eggEnergyBasicSettingDb.EggEnergyBasicSettingGetOneByParams(map[string]interface{}{ "key": "is_open", "value": 1, }) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } //2、计算今日涨幅 err, rises, isRise, nowPrice, initialPrice := svc.CalcTodayEggEnergyPriceRises(db.Db, now) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } //3、获取当前用户 蛋蛋能量(可用+结算+今日签到预估蛋蛋能量) var isSign bool var signCountdown string var signEggEnergy = "0.00" var totalEggEnergy float64 var teamRewardSetting *md2.TeamRewardSettingStruct // 3.1 获取团队收益设置 一轮持续时间 err = json.Unmarshal([]byte(eggEnergyBasicSetting.DirectPushReward), &teamRewardSetting) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } //3.2 计算用户是否在团队收益时间段内签到 var oneRoundDuration = utils.StrToInt(teamRewardSetting.OneRoundDuration) startTime := now.Add(-time.Hour * time.Duration(oneRoundDuration)).Format("2006-01-02 15:04:05") signInDb := implement.NewEggSignInDb(db.Db) has, signIn, err := signInDb.EggSignInGetOne(startTime, now.Format("2006-01-02 15:04:05"), user.Id) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } if has && utils.TimeParseStd(signIn.EndTime).After(now) { //3.2.1 获取预估每秒获得蛋蛋能量数 estimatePerSecondEggEnergyValue, err1 := decimal.NewFromString(signIn.EstimatePerSecondEggEnergyValue) if err1 != nil { e.OutErr(c, e.ERR, err1.Error()) return } signEggEnergy = estimatePerSecondEggEnergyValue.String() isSign = true signCountdown = signIn.EndTime } // 3.3 查询个人及团队蛋蛋能量 amountDb := implement.NewUserVirtualAmountDb(db.Db) personEggEnergy, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.PersonEggEnergyCoinId) if err != nil { return } teamEggEnergy, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.TeamEggEnergyCoinId) if err != nil { return } signEggEnergyValue, _ := decimal.NewFromString(signEggEnergy) personEggEnergyValue, _ := decimal.NewFromString(personEggEnergy.Amount) teamEggEnergyValue, _ := decimal.NewFromString(teamEggEnergy.Amount) totalEggEnergy, _ = signEggEnergyValue.Add(personEggEnergyValue).Add(teamEggEnergyValue).Float64() //4、活跃积分(个人+团队) var totalActivePoints float64 personActivePoints, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.PersonEggPointsCoinId) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } teamActivePoints, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.TeamEggPointsCoinId) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } totalActivePoints = utils.StrToFloat64(personActivePoints.Amount) + utils.StrToFloat64(teamActivePoints.Amount) //5、计算当前基础速率、团队速率 nowBasalRate := utils.StrToFloat64(signEggEnergy) * 60 * 60 //每小时基础速率 var estimateLevel int nowBasalRateValue := decimal.NewFromFloat(nowBasalRate) for { estimateLevel++ rewardDecrementValue := utils.StrToFloat64(teamRewardSetting.RewardDecrementValue) / 100 tmpRewardBase := decimal.NewFromFloat(math.Pow(rewardDecrementValue, float64(estimateLevel))) tmpReward := nowBasalRateValue.Mul(tmpRewardBase) rewardEndValue, _ := decimal.NewFromString(teamRewardSetting.RewardEndValue) if !tmpReward.GreaterThanOrEqual(rewardEndValue) { estimateLevel-- break } if estimateLevel == 99 { e.OutErr(c, e.ERR, "奖励结束值设置有误") return } } relateDb := implement.NewUserRelateDb(db.Db) userRelates, err := relateDb.FindUserRelateByParentUid(user.Id, estimateLevel) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } var userRelatesUids []string var userRelatesMap = map[int64]model.UserRelate{} if userRelates != nil { for _, userRelate := range *userRelates { userRelatesUids = append(userRelatesUids, utils.Int64ToStr(userRelate.Uid)) userRelatesMap[userRelate.Uid] = userRelate } } var eggSignIns []*model.EggSignIn if len(userRelatesUids) > 0 { eggSignIns, err = signInDb.EggSignInFindByParams(map[string]interface{}{ "key": "uid", "value": userRelatesUids, }) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } } var nowTeamRate float64 //每小时基础速率 for _, vv := range eggSignIns { rewardDecrementValue := utils.StrToFloat64(teamRewardSetting.RewardDecrementValue) / 100 tmpRewardBase := decimal.NewFromFloat(math.Pow(rewardDecrementValue, float64(userRelatesMap[vv.Uid].Level))) tmpReward := nowBasalRateValue.Mul(tmpRewardBase) rewardEndValue, _ := decimal.NewFromString(teamRewardSetting.RewardEndValue) if tmpReward.GreaterThanOrEqual(rewardEndValue) { tmpRewardValue, _ := tmpReward.Float64() nowTeamRate += tmpRewardValue } } decimalRate := decimal.NewFromInt(100) //百分比 risesValue, _ := decimal.NewFromFloat(rises).Mul(decimalRate).Float64() var residueTimes = utils.TimeParseStd(signCountdown).Unix() - time.Now().Unix() userDb := implement.NewUserDb(db.Db) userCount, err := userDb.UserCount() if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } utils.FilePutContents("HomePage", utils.SerializeStr(map[string]interface{}{ "user_phone": user.Phone, "user_uid": user.Id, "data": map[string]interface{}{ "is_sign": isSign, "sign_end_date": signCountdown, "sign_end_timestamp": utils.TimeParseStd(signCountdown).Unix(), "residue_times": residueTimes, "total_egg_energy": totalEggEnergy, "sign_reward_egg_energy": utils.StrToFloat64(signIn.EstimatePerSecondEggEnergyValue), "total_active_points": totalActivePoints, "egg_energy_now_price": nowPrice, "initial_price": initialPrice, "is_rises": isRise, "rises": risesValue, "now_basal_rate": nowBasalRate, "now_team_rate": nowTeamRate, "user_count": userCount, "nickname": user.Nickname, }, })) resp := md.HomePageResp{ IsSign: isSign, SignEndTime: signCountdown, TotalEggEnergy: utils.Float64ToStr(totalEggEnergy), SignRewardEggEnergy: signIn.EstimatePerSecondEggEnergyValue, TotalActivePoints: utils.Float64ToStr(totalActivePoints), EggEnergyNowPrice: nowPrice, InitialPrice: initialPrice, IsRises: isRise, Rises: utils.Float64ToStr(risesValue), NowBasalRate: utils.Float64ToStr(nowBasalRate), NowTeamRate: utils.Float64ToStr(nowTeamRate), UserCount: userCount, NickName: user.Nickname, } e.OutSuc(c, resp, nil) return } // HomePageWatchAdRule // @Summary 蛋蛋星球-主页-视频奖励规则(获取) // @Tags 主页 // @Description 视频奖励规则(获取) // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Success 200 {object} md.HomePageWatchAdRuleResp "具体数据" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/homePage/adRule [get] func HomePageWatchAdRule(c *gin.Context) { energyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db) basicSetting, err := energyBasicSettingDb.EggEnergyBasicSettingGetOne() if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } var videoRewardSystem md2.VideoRewardSystemStruct utils.Unserialize([]byte(basicSetting.VideoRewardSystem), &videoRewardSystem) resp := md.HomePageWatchAdRuleResp{ RewardValue: videoRewardSystem.RewardValue, RewardTotalNum: videoRewardSystem.RewardTotalNum, IntervalMinutes: videoRewardSystem.IntervalMinutes, EachRoundHour: videoRewardSystem.EachRoundHour, } e.OutSuc(c, resp, nil) } const HomePageRealTimeRedisKey = "Home_Page_Real_Time_Cache_Key" // RealTimePrice // @Summary 蛋蛋星球-主页-实时数据(获取) // @Tags 主页 // @Description 实时数据(获取) // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Success 200 {object} md.RealTimePriceResp "具体数据" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/homePage/realTimePrice [get] func RealTimePrice(c *gin.Context) { var isRises, userCount, risesValue, nowPrice interface{} var rises float64 redisKey := HomePageRealTimeRedisKey redisValue, err := cache.GetString(redisKey) if err != nil { if err.Error() == "redigo: nil returned" { now := time.Now() err, rises, isRises, nowPrice, _ = svc.CalcTodayEggEnergyPriceRises(db.Db, now) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } userDb := implement.NewUserDb(db.Db) userCount, err = userDb.UserCount() if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } decimalRate := decimal.NewFromInt(100) //百分比 risesValue, _ = decimal.NewFromFloat(rises).Mul(decimalRate).Float64() // 缓存 5 s cache.SetEx(redisKey, utils.SerializeStr(map[string]interface{}{ "user_count": userCount, "is_rises": isRises, "rises": risesValue, "egg_energy_now_price": nowPrice, }), 5) } else { e.OutErr(c, e.ERR, err.Error()) return } } else { var result map[string]interface{} err1 := json.Unmarshal([]byte(redisValue), &result) if err1 != nil { e.OutErr(c, e.ERR, err1.Error()) return } userCount = result["user_count"] isRises = result["is_rises"] risesValue = result["rises"] nowPrice = result["green_energy_now_price"] } isRisesResp, ok := isRises.(bool) if !ok { e.OutErr(c, e.ERR, "断言失败") } resp := md.RealTimePriceResp{ UserCount: utils.AnyToString(userCount), NowPrice: utils.AnyToString(nowPrice), IsRises: isRisesResp, Rises: utils.AnyToString(risesValue), } e.OutSuc(c, resp, nil) } // IsCanSignIn // @Summary 蛋蛋星球-主页-是否能签到(获取) // @Tags 主页 // @Description 是否可以签到(获取) // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Success 200 {object} md.IsCanSignInResp "具体数据" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/homePage/isCanSignIn [get] func IsCanSignIn(c *gin.Context) { val, exists := c.Get("user") if !exists { e.OutErr(c, e.ERR_USER_CHECK_ERR, nil) return } user, ok := val.(*model.User) if !ok { e.OutErr(c, e.ERR_USER_CHECK_ERR, nil) return } //1、查找 `OneCirclesPublicPlatoonBasicSetting` 基础设置 energyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db) eggEnergyBasicSetting, err := energyBasicSettingDb.EggEnergyBasicSettingGetOneByParams(map[string]interface{}{ "key": "is_open", "value": 1, }) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } var videoRewardSystem *md2.VideoRewardSystemStruct err = json.Unmarshal([]byte(eggEnergyBasicSetting.VideoRewardSystem), &videoRewardSystem) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } rewardTotalNum := utils.StrToInt(videoRewardSystem.RewardTotalNum) //2、查询当前用户观看视屏记录 watchRecordsDb := implement.NewEggEnergyUserWatchRecordsDb(db.Db) userWatchRecords, err := watchRecordsDb.EggEnergyUserWatchRecordsGetOneByParams(map[string]interface{}{ "key": "uid", "value": user.Id, }) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } var isCan bool now := time.Now() if userWatchRecords != nil && userWatchRecords.ResidueWatchAdNum == rewardTotalNum && userWatchRecords.NextWatchAdDate.After(now) { isCan = true } utils.FilePutContents("HomePageIsCanSignIn", utils.SerializeStr(map[string]interface{}{ "user_phone": user.Phone, "user_uid": user.Id, "is_can": isCan, "time": now.Format("2006-01-02 15:04:05"), })) resp := md.IsCanSignInResp{ IsCan: isCan, } e.OutSuc(c, resp, nil) return } // IsCanGetRedPackage // @Summary 蛋蛋星球-主页-是否领取红包(获取) // @Tags 主页 // @Description 是否可以领取红包(获取) // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Success 200 {object} md.IsCanGetRedPackageResp "具体数据" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/homePage/isCanGetRedPackage [get] func IsCanGetRedPackage(c *gin.Context) { redPackageDb := implement.NewNewUserRedPackageDb(db.Db) redPackage, err := redPackageDb.NewUserRedPackageGetOne() if err != nil { e.OutErr(c, e.ERR, err.Error()) return } isCan := false if redPackage != nil { if redPackage.IsOpen == 1 { isCan = true } } resp := md.IsCanGetRedPackageResp{ IsCan: isCan, } e.OutSuc(c, resp, nil) }