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" "fmt" "github.com/gin-gonic/gin" "github.com/shopspring/decimal" "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 signPersonalEggEnergy = "0.00" var signTeamEggEnergy = "0.00" var totalEggEnergy float64 //开始时间 以当前时间 往前推多少 var videoRewardSystem *md2.VideoRewardSystemStruct err = json.Unmarshal([]byte(eggEnergyBasicSetting.VideoRewardSystem), &videoRewardSystem) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } var oneRoundDuration = utils.StrToInt(videoRewardSystem.EachRoundHour) startTime := now.Add(-time.Hour * time.Duration(oneRoundDuration)).Format("2006-01-02 15:04:05") signInDb := implement.NewEggSignInDb(db.Db) has, signIn, err := signInDb.EggSignINGetOneByTimeAndUid(startTime, "", user.Id, 0) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } if has && utils.TimeParseStd(signIn.EndTime).After(now) { //3.2.1 获取预估每秒获得蛋蛋能量数 estimatePerSecondPersonEggEnergyValue, err1 := decimal.NewFromString(signIn.EstimatePerSecondPersonEggEnergyValue) if err1 != nil { e.OutErr(c, e.ERR, err1.Error()) return } estimatePerSecondTeamEggEnergyValue, err1 := decimal.NewFromString(signIn.EstimatePerSecondTeamEggEnergyValue) if err1 != nil { e.OutErr(c, e.ERR, err1.Error()) return } signPersonalEggEnergy = estimatePerSecondPersonEggEnergyValue.String() signTeamEggEnergy = estimatePerSecondTeamEggEnergyValue.String() isSign = true signCountdown = signIn.EndTime } // 3.3 查询个人及团队蛋蛋能量 amountDb := implement.NewUserVirtualAmountDb(db.Db) personEggEnergy, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.PersonEggEnergyCoinId) if err != nil { e.OutErr(c, e.ERR_DB_ORM, nil) return } teamEggEnergy, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.TeamEggEnergyCoinId) if err != nil { e.OutErr(c, e.ERR_DB_ORM, nil) return } signEggEnergyValue, _ := decimal.NewFromString(signPersonalEggEnergy) 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(signPersonalEggEnergy) * 60 * 60 //每小时基础速率 NowTeamRate := utils.StrToFloat64(signTeamEggEnergy) * 60 * 60 // 每小时团队速率 userDb := implement.NewUserDb(db.Db) userCount, err := userDb.UserCount() if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } var residueTimes = utils.TimeParseStd(signCountdown).Unix() - time.Now().Unix() 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, "total_active_points": totalActivePoints, "egg_energy_now_price": nowPrice, "initial_price": initialPrice, "is_rises": isRise, "rises": rises, "now_basal_rate": nowBasalRate, "now_team_rate": NowTeamRate, "user_count": userCount, "nickname": user.Nickname, }, })) resp := md.HomePageResp{ LeaveTimer: utils.Int64ToStr(residueTimes), IsSign: isSign, SignEndTime: signCountdown, TotalEggEnergy: utils.Float64ToStr(totalEggEnergy), TotalActivePoints: utils.Float64ToStr(totalActivePoints), InitialPrice: initialPrice, NowBasalRate: utils.Float64ToStr(nowBasalRate), NowTeamRate: utils.Float64ToStr(NowTeamRate), 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) { 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. 查找基础设置 energyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db) basicSetting, err := energyBasicSettingDb.EggEnergyBasicSettingGetOne() if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } // 2. 计算当前还能看几个广告 recordsDb := implement.NewEggEnergyUserWatchRecordsDb(db.Db) records, err := recordsDb.EggEnergyUserWatchRecordsGetOneByParams(map[string]interface{}{ "key": "uid", "value": user.Id, }) if err != nil { return } var videoRewardSystem md2.VideoRewardSystemStruct utils.Unserialize([]byte(basicSetting.VideoRewardSystem), &videoRewardSystem) redisKey := fmt.Sprintf(md2.UserNextWatchAdDate, user.Id) var residueWatchAdNum int if records == nil { residueWatchAdNum = utils.StrToInt(videoRewardSystem.RewardTotalNum) } else { now := time.Now() residueWatchAdNum = records.ResidueWatchAdNum if records.NextWatchAdDate.Before(now) { //TODO::下一轮时间已在当前时间之前 residueWatchAdNum = utils.StrToInt(videoRewardSystem.RewardTotalNum) records.ResidueWatchAdNum = residueWatchAdNum _, err = recordsDb.EggEnergyUserWatchRecordsUpdate(records.Id, records, "residue_watch_ad_num") if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } cache.SetEx(redisKey, "", 60*60*24) } } nextWatchAdDate, _ := cache.GetString(redisKey) nextWatchAdTimes := utils.TimeParseStd(nextWatchAdDate).Unix() - time.Now().Unix() if nextWatchAdTimes < 0 { nextWatchAdTimes = 0 } var roundRemainingSecs int64 now := time.Now() //开始时间 以当前时间 往前推多少 var oneRoundDuration = utils.StrToInt(videoRewardSystem.EachRoundHour) startTime := now.Add(-time.Hour * time.Duration(oneRoundDuration)).Format("2006-01-02 15:04:05") signInDb := implement.NewEggSignInDb(db.Db) has, signIn, err := signInDb.EggSignINGetOneByTimeAndUid(startTime, "", user.Id, 0) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } if has { roundRemainingSecs = utils.TimeParseStd(signIn.EndTime).Unix() - time.Now().Unix() if roundRemainingSecs < 0 { roundRemainingSecs = 0 } } utils.FilePutContents("nextWatchAdDate", utils.SerializeStr(map[string]interface{}{ "nextWatchAdDate": nextWatchAdDate, "next_watch_ad_times": nextWatchAdTimes, "uid": utils.Int64ToStr(user.Id), "time": time.Now().Format("2006-01-02 15:04:05.000"), })) resp := md.HomePageWatchAdRuleResp{ RewardTotalNum: videoRewardSystem.RewardTotalNum, ResidueWatchAdNum: residueWatchAdNum, WatchAdRewardActivePoints: videoRewardSystem.RewardValue, NextWatchAdDate: nextWatchAdDate, NextWatchAdSecs: nextWatchAdTimes, EachRoundHour: videoRewardSystem.EachRoundHour, RoundRemainingSecs: roundRemainingSecs, } 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["egg_energy_now_price"] } isRisesResp, ok := isRises.(bool) if !ok { e.OutErr(c, e.ERR, "断言失败") } resp := md.RealTimePriceResp{ UserCount: utils.AnyToInt64(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) { 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. 红包活动是否开启 redPackageDb := implement.NewNewUserRedPackageDb(db.Db) redPackage, err := redPackageDb.NewUserRedPackageGetOne() if err != nil { e.OutErr(c, e.ERR, err.Error()) return } // 2. 用户已有红包活动记录 userRecordsDb := implement.NewNewUserRedPackageWithUserRecordsDb(db.Db) records, err := userRecordsDb.NewUserRedPackageWithUserRecordsGetLastPendingByParams(map[string]interface{}{ "key": "uid", "value": user.Id, }) if err != nil { e.OutErr(c, e.ERR_DB_ORM, nil) return } isCan := false if redPackage != nil { if redPackage.IsOpen == 1 && records != nil { isCan = true } } resp := md.IsCanGetRedPackageResp{ IsCan: isCan, } e.OutSuc(c, resp, nil) }