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

hdl_home_page.go 22 KiB

1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
3週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
3週間前
3週間前
3週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
3週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
3週間前
3週間前
1ヶ月前
1ヶ月前
3週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
3週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
3週間前
3週間前
3週間前
3週間前
3週間前
3週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
2週間前
2週間前
2週間前
2週間前
2週間前
2週間前
2週間前
2週間前
2週間前
2週間前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. package hdl
  2. import (
  3. "applet/app/db"
  4. "applet/app/e"
  5. "applet/app/md"
  6. "applet/app/svc"
  7. "applet/app/utils"
  8. "applet/app/utils/cache"
  9. "code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
  10. "code.fnuoos.com/EggPlanet/egg_models.git/src/model"
  11. md2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/md"
  12. "encoding/json"
  13. "fmt"
  14. "github.com/gin-gonic/gin"
  15. "github.com/shopspring/decimal"
  16. "time"
  17. )
  18. // HomePage
  19. // @Summary 蛋蛋星球-主页-基础信息(获取)
  20. // @Tags 主页
  21. // @Description 基础信息(获取)
  22. // @Accept json
  23. // @Produce json
  24. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  25. // @Success 200 {object} md.HomePageResp "具体数据"
  26. // @Failure 400 {object} md.Response "具体错误"
  27. // @Router /api/v1/homePage/index [get]
  28. func HomePage(c *gin.Context) {
  29. now := time.Now()
  30. val, exists := c.Get("user")
  31. if !exists {
  32. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  33. return
  34. }
  35. user, ok := val.(*model.User)
  36. if !ok {
  37. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  38. return
  39. }
  40. //1、查找 `egg_energy_basic_setting` 基础设置
  41. eggEnergyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db)
  42. eggEnergyBasicSetting, err := eggEnergyBasicSettingDb.EggEnergyBasicSettingGetOneByParams(map[string]interface{}{
  43. "key": "is_open",
  44. "value": 1,
  45. })
  46. if err != nil {
  47. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  48. return
  49. }
  50. //2、计算今日涨幅
  51. err, rises, isRise, nowPrice, initialPrice := svc.CalcTodayEggEnergyPriceRises(db.Db, now)
  52. if err != nil {
  53. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  54. return
  55. }
  56. //3、获取当前用户 蛋蛋能量(可用+结算+今日签到预估蛋蛋能量)
  57. var isSign bool
  58. var signCountdown string
  59. var signPersonalEggEnergy = "0.00"
  60. var signTeamEggEnergy = "0.00"
  61. var totalEggEnergy float64
  62. var estimatePersonEggEnergyValue decimal.Decimal
  63. var estimateTeamEggEnergyValue decimal.Decimal
  64. signInDb := implement.NewEggSignInDb(db.Db)
  65. nowStr := now.Format("2006-01-02 15:04:05")
  66. has, signIn, err := signInDb.EggSignINGetOneByTimeAndUid("", nowStr, user.Id, 0)
  67. if err != nil {
  68. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  69. return
  70. }
  71. if has && utils.TimeParseStd(signIn.EndTime).After(now) {
  72. //3.2.1 获取预估每秒获得蛋蛋能量数
  73. estimatePerSecondPersonEggEnergyValue, err1 := decimal.NewFromString(signIn.EstimatePerSecondPersonEggEnergyValue)
  74. if err1 != nil {
  75. e.OutErr(c, e.ERR, err1.Error())
  76. return
  77. }
  78. estimatePerSecondTeamEggEnergyValue, err1 := decimal.NewFromString(signIn.EstimatePerSecondTeamEggEnergyValue)
  79. if err1 != nil {
  80. e.OutErr(c, e.ERR, err1.Error())
  81. return
  82. }
  83. signPersonalEggEnergy = estimatePerSecondPersonEggEnergyValue.String()
  84. signTeamEggEnergy = estimatePerSecondTeamEggEnergyValue.String()
  85. isSign = true
  86. signCountdown = signIn.EndTime
  87. //3.2.2 计算预估获得的蛋蛋能量数
  88. estimateTimeSec := now.Unix() - utils.TimeParseStd(signIn.StartTime).Unix()
  89. estimatePersonEggEnergyValue = decimal.NewFromInt(estimateTimeSec).Mul(estimatePerSecondPersonEggEnergyValue)
  90. estimateTeamEggEnergyValue = decimal.NewFromInt(estimateTimeSec).Mul(estimatePerSecondTeamEggEnergyValue)
  91. }
  92. // 3.3 查询个人及团队蛋蛋能量
  93. amountDb := implement.NewUserVirtualAmountDb(db.Db)
  94. personEggEnergy, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.PersonEggEnergyCoinId)
  95. if err != nil {
  96. e.OutErr(c, e.ERR_DB_ORM, nil)
  97. return
  98. }
  99. teamEggEnergy, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.TeamEggEnergyCoinId)
  100. if err != nil {
  101. e.OutErr(c, e.ERR_DB_ORM, nil)
  102. return
  103. }
  104. personEggEnergyValue, _ := decimal.NewFromString(personEggEnergy.Amount)
  105. teamEggEnergyValue, _ := decimal.NewFromString(teamEggEnergy.Amount)
  106. totalEggEnergy, _ = personEggEnergyValue.Add(teamEggEnergyValue).Float64()
  107. //4、活跃积分(个人+团队)
  108. var totalActivePoints float64
  109. personActivePoints, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.PersonEggPointsCoinId)
  110. if err != nil {
  111. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  112. return
  113. }
  114. teamActivePoints, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.TeamEggPointsCoinId)
  115. if err != nil {
  116. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  117. return
  118. }
  119. totalActivePoints = utils.StrToFloat64(personActivePoints.Amount) + utils.StrToFloat64(teamActivePoints.Amount)
  120. //5、计算当前基础速率、团队速率
  121. nowBasalRate := utils.StrToFloat64(signPersonalEggEnergy) * 60 * 60 //每小时基础速率
  122. NowTeamRate := utils.StrToFloat64(signTeamEggEnergy) * 60 * 60 // 每小时团队速率
  123. userDb := implement.NewUserDb(db.Db)
  124. userCount, err := userDb.UserCount()
  125. if err != nil {
  126. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  127. return
  128. }
  129. var residueTimes = utils.TimeParseStd(signCountdown).Unix() - time.Now().Unix()
  130. // 6、预估能量 + 原有能量
  131. totalEggEnergyDecimal := decimal.NewFromFloat(totalEggEnergy).Add(estimatePersonEggEnergyValue).Add(estimateTeamEggEnergyValue)
  132. // 7、总能量预估价值
  133. coreDataDb := implement.NewEggEnergyCoreDataDb(db.Db)
  134. coreData, err := coreDataDb.EggEnergyCoreDataGet()
  135. if err != nil {
  136. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  137. return
  138. }
  139. nowPriceDecimal, err := decimal.NewFromString(coreData.NowPrice)
  140. if err != nil {
  141. e.OutErr(c, e.ERR, err.Error())
  142. return
  143. }
  144. totalEggEnergyValueDecimal := totalEggEnergyDecimal.Mul(nowPriceDecimal)
  145. utils.FilePutContents("HomePage", utils.SerializeStr(map[string]interface{}{
  146. "user_phone": user.Phone,
  147. "user_uid": user.Id,
  148. "data": map[string]interface{}{
  149. "is_sign": isSign,
  150. "sign_end_date": signCountdown,
  151. "sign_end_timestamp": utils.TimeParseStd(signCountdown).Unix(),
  152. "residue_times": residueTimes,
  153. "total_egg_energy": totalEggEnergyDecimal.String(),
  154. "total_active_points": totalActivePoints,
  155. "egg_energy_now_price": nowPrice,
  156. "initial_price": initialPrice,
  157. "is_rises": isRise,
  158. "rises": rises,
  159. "now_basal_rate": nowBasalRate,
  160. "now_team_rate": NowTeamRate,
  161. "user_count": userCount,
  162. "nickname": user.Nickname,
  163. },
  164. }))
  165. resp := md.HomePageResp{
  166. LeaveTimer: utils.Int64ToStr(residueTimes),
  167. IsSign: isSign,
  168. SignEndTime: signCountdown,
  169. TotalEggEnergy: totalEggEnergyDecimal.String(),
  170. TotalEggEnergyValue: totalEggEnergyValueDecimal.String(),
  171. TotalActivePoints: utils.Float64ToStr(totalActivePoints),
  172. InitialPrice: initialPrice,
  173. NowBasalRate: utils.Float64ToStr(nowBasalRate),
  174. NowTeamRate: utils.Float64ToStr(NowTeamRate),
  175. NickName: user.Nickname,
  176. }
  177. e.OutSuc(c, resp, nil)
  178. return
  179. }
  180. // HomePageWatchAdRule
  181. // @Summary 蛋蛋星球-主页-视频奖励规则(获取)
  182. // @Tags 主页
  183. // @Description 视频奖励规则(获取)
  184. // @Accept json
  185. // @Produce json
  186. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  187. // @Success 200 {object} md.HomePageWatchAdRuleResp "具体数据"
  188. // @Failure 400 {object} md.Response "具体错误"
  189. // @Router /api/v1/homePage/adRule [get]
  190. func HomePageWatchAdRule(c *gin.Context) {
  191. val, exists := c.Get("user")
  192. if !exists {
  193. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  194. return
  195. }
  196. user, ok := val.(*model.User)
  197. if !ok {
  198. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  199. return
  200. }
  201. // 1. 查找基础设置
  202. energyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db)
  203. basicSetting, err := energyBasicSettingDb.EggEnergyBasicSettingGetOne()
  204. if err != nil {
  205. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  206. return
  207. }
  208. // 2. 计算当前还能看几个广告
  209. recordsDb := implement.NewEggEnergyUserWatchRecordsDb(db.Db)
  210. records, err := recordsDb.EggEnergyUserWatchRecordsGetOneByParams(map[string]interface{}{
  211. "key": "uid",
  212. "value": user.Id,
  213. })
  214. if err != nil {
  215. return
  216. }
  217. var videoRewardSystem md2.VideoRewardSystemStruct
  218. utils.Unserialize([]byte(basicSetting.VideoRewardSystem), &videoRewardSystem)
  219. redisKey := fmt.Sprintf(md2.UserNextWatchAdDate, user.Id)
  220. var residueWatchAdNum int
  221. if records == nil {
  222. residueWatchAdNum = utils.StrToInt(videoRewardSystem.RewardTotalNum)
  223. } else {
  224. now := time.Now()
  225. residueWatchAdNum = records.ResidueWatchAdNum
  226. if records.NextWatchAdDate.Before(now) {
  227. //TODO::下一轮时间已在当前时间之前
  228. residueWatchAdNum = utils.StrToInt(videoRewardSystem.RewardTotalNum)
  229. records.ResidueWatchAdNum = residueWatchAdNum
  230. _, err = recordsDb.EggEnergyUserWatchRecordsUpdate(records.Id, records, "residue_watch_ad_num")
  231. if err != nil {
  232. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  233. return
  234. }
  235. cache.SetEx(redisKey, "", 60*60*24)
  236. }
  237. }
  238. nextWatchAdDate, _ := cache.GetString(redisKey)
  239. nextWatchAdTimes := utils.TimeParseStd(nextWatchAdDate).Unix() - time.Now().Unix()
  240. if nextWatchAdTimes < 0 {
  241. nextWatchAdTimes = 0
  242. }
  243. var roundRemainingSecs int64
  244. now := time.Now()
  245. //开始时间 以当前时间 往前推多少
  246. signInDb := implement.NewEggSignInDb(db.Db)
  247. nowStr := now.Format("2006-01-02 15:04:05")
  248. has, signIn, err := signInDb.EggSignINGetOneByTimeAndUid("", nowStr, user.Id, 0)
  249. if err != nil {
  250. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  251. return
  252. }
  253. if has {
  254. roundRemainingSecs = utils.TimeParseStd(signIn.EndTime).Unix() - time.Now().Unix()
  255. if roundRemainingSecs < 0 {
  256. roundRemainingSecs = 0
  257. }
  258. }
  259. utils.FilePutContents("nextWatchAdDate", utils.SerializeStr(map[string]interface{}{
  260. "nextWatchAdDate": nextWatchAdDate,
  261. "next_watch_ad_times": nextWatchAdTimes,
  262. "uid": utils.Int64ToStr(user.Id),
  263. "roundRemainingSecs": roundRemainingSecs,
  264. "time": time.Now().Format("2006-01-02 15:04:05.000"),
  265. }))
  266. resp := md.HomePageWatchAdRuleResp{
  267. RewardTotalNum: videoRewardSystem.RewardTotalNum,
  268. ResidueWatchAdNum: residueWatchAdNum,
  269. WatchAdRewardActivePoints: videoRewardSystem.RewardValue,
  270. NextWatchAdDate: nextWatchAdDate,
  271. NextWatchAdSecs: nextWatchAdTimes,
  272. EachRoundHour: videoRewardSystem.EachRoundHour,
  273. RoundRemainingSecs: roundRemainingSecs,
  274. }
  275. e.OutSuc(c, resp, nil)
  276. }
  277. const HomePageRealTimeRedisKey = "Home_Page_Real_Time_Cache_Key"
  278. // RealTimePrice
  279. // @Summary 蛋蛋星球-主页-实时数据(获取)
  280. // @Tags 主页
  281. // @Description 实时数据(获取)
  282. // @Accept json
  283. // @Produce json
  284. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  285. // @Success 200 {object} md.RealTimePriceResp "具体数据"
  286. // @Failure 400 {object} md.Response "具体错误"
  287. // @Router /api/v1/homePage/realTimePrice [get]
  288. func RealTimePrice(c *gin.Context) {
  289. var isRises, userCount, risesValue, nowPrice interface{}
  290. var rises float64
  291. redisKey := HomePageRealTimeRedisKey
  292. redisValue, err := cache.GetString(redisKey)
  293. if err != nil {
  294. if err.Error() == "redigo: nil returned" {
  295. now := time.Now()
  296. err, rises, isRises, nowPrice, _ = svc.CalcTodayEggEnergyPriceRises(db.Db, now)
  297. if err != nil {
  298. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  299. return
  300. }
  301. userDb := implement.NewUserDb(db.Db)
  302. userCount, err = userDb.UserCount()
  303. if err != nil {
  304. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  305. return
  306. }
  307. decimalRate := decimal.NewFromInt(100) //百分比
  308. risesValue = decimal.NewFromFloat(rises).Mul(decimalRate).StringFixed(16)
  309. // 缓存 5 s
  310. cache.SetEx(redisKey, utils.SerializeStr(map[string]interface{}{
  311. "user_count": userCount,
  312. "is_rises": isRises,
  313. "rises": risesValue,
  314. "egg_energy_now_price": nowPrice,
  315. }), 5)
  316. } else {
  317. e.OutErr(c, e.ERR, err.Error())
  318. return
  319. }
  320. } else {
  321. var result map[string]interface{}
  322. err1 := json.Unmarshal([]byte(redisValue), &result)
  323. if err1 != nil {
  324. e.OutErr(c, e.ERR, err1.Error())
  325. return
  326. }
  327. userCount = result["user_count"]
  328. isRises = result["is_rises"]
  329. risesValue = result["rises"]
  330. nowPrice = result["egg_energy_now_price"]
  331. }
  332. isRisesResp, ok := isRises.(bool)
  333. if !ok {
  334. e.OutErr(c, e.ERR, "断言失败")
  335. }
  336. resp := md.RealTimePriceResp{
  337. UserCount: utils.AnyToInt64(userCount),
  338. NowPrice: utils.AnyToString(nowPrice),
  339. IsRises: isRisesResp,
  340. Rises: utils.AnyToString(risesValue),
  341. }
  342. e.OutSuc(c, resp, nil)
  343. }
  344. // IsCanSignIn
  345. // @Summary 蛋蛋星球-主页-是否能签到(获取)
  346. // @Tags 主页
  347. // @Description 是否可以签到(获取)
  348. // @Accept json
  349. // @Produce json
  350. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  351. // @Success 200 {object} md.IsCanSignInResp "具体数据"
  352. // @Failure 400 {object} md.Response "具体错误"
  353. // @Router /api/v1/homePage/isCanSignIn [get]
  354. func IsCanSignIn(c *gin.Context) {
  355. val, exists := c.Get("user")
  356. if !exists {
  357. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  358. return
  359. }
  360. user, ok := val.(*model.User)
  361. if !ok {
  362. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  363. return
  364. }
  365. now := time.Now()
  366. var isCan = false
  367. signInDb := implement.NewEggSignInDb(db.Db)
  368. nowStr := now.Format("2006-01-02 15:04:05")
  369. has, _, err := signInDb.EggSignINGetOneByTimeAndUid("", nowStr, user.Id, 0)
  370. if err != nil {
  371. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  372. return
  373. }
  374. if has {
  375. isCan = false
  376. } else {
  377. //1、查找 `OneCirclesPublicPlatoonBasicSetting` 基础设置
  378. energyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db)
  379. eggEnergyBasicSetting, err := energyBasicSettingDb.EggEnergyBasicSettingGetOneByParams(map[string]interface{}{
  380. "key": "is_open",
  381. "value": 1,
  382. })
  383. if err != nil {
  384. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  385. return
  386. }
  387. var videoRewardSystem *md2.VideoRewardSystemStruct
  388. err = json.Unmarshal([]byte(eggEnergyBasicSetting.VideoRewardSystem), &videoRewardSystem)
  389. if err != nil {
  390. e.OutErr(c, e.ERR, err.Error())
  391. return
  392. }
  393. rewardTotalNum := utils.StrToInt(videoRewardSystem.RewardTotalNum)
  394. //2、查询当前用户观看视屏记录
  395. watchRecordsDb := implement.NewEggEnergyUserWatchRecordsDb(db.Db)
  396. userWatchRecords, err := watchRecordsDb.EggEnergyUserWatchRecordsGetOneByParams(map[string]interface{}{
  397. "key": "uid",
  398. "value": user.Id,
  399. })
  400. if err != nil {
  401. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  402. return
  403. }
  404. if userWatchRecords != nil && userWatchRecords.ResidueWatchAdNum == rewardTotalNum && userWatchRecords.NextWatchAdDate.After(now) {
  405. isCan = true
  406. }
  407. }
  408. utils.FilePutContents("HomePageIsCanSignIn", utils.SerializeStr(map[string]interface{}{
  409. "user_phone": user.Phone,
  410. "user_uid": user.Id,
  411. "is_can": isCan,
  412. "time": now.Format("2006-01-02 15:04:05"),
  413. }))
  414. resp := md.IsCanSignInResp{
  415. IsCan: isCan,
  416. }
  417. e.OutSuc(c, resp, nil)
  418. return
  419. }
  420. // IsCanGetRedPackage
  421. // @Summary 蛋蛋星球-主页-是否领取红包(获取)
  422. // @Tags 主页
  423. // @Description 是否可以领取红包(获取)
  424. // @Accept json
  425. // @Produce json
  426. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  427. // @Success 200 {object} md.IsCanGetRedPackageResp "具体数据"
  428. // @Failure 400 {object} md.Response "具体错误"
  429. // @Router /api/v1/homePage/isCanGetRedPackage [get]
  430. func IsCanGetRedPackage(c *gin.Context) {
  431. val, exists := c.Get("user")
  432. if !exists {
  433. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  434. return
  435. }
  436. user, ok := val.(*model.User)
  437. if !ok {
  438. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  439. return
  440. }
  441. // 1. 红包活动是否开启
  442. redPackageDb := implement.NewNewUserRedPackageDb(db.Db)
  443. redPackage, err := redPackageDb.NewUserRedPackageGetOne()
  444. if err != nil {
  445. e.OutErr(c, e.ERR, err.Error())
  446. return
  447. }
  448. // 2. 用户已有红包活动记录
  449. userRecordsDb := implement.NewNewUserRedPackageWithUserRecordsDb(db.Db)
  450. records, err := userRecordsDb.NewUserRedPackageWithUserRecordsGetLastPendingByParams(map[string]interface{}{
  451. "key": "uid",
  452. "value": user.Id,
  453. })
  454. if err != nil {
  455. e.OutErr(c, e.ERR_DB_ORM, nil)
  456. return
  457. }
  458. isCan := false
  459. if redPackage != nil {
  460. if redPackage.IsOpen == 1 && records != nil {
  461. isCan = true
  462. }
  463. }
  464. resp := md.IsCanGetRedPackageResp{
  465. IsCan: isCan,
  466. }
  467. e.OutSuc(c, resp, nil)
  468. }
  469. const HeroListRedisRankKey = "EggEnergy:HomePage:HeroList:Rank:%d" // 1.kind
  470. // HeroList
  471. // @Summary 蛋蛋星球-主页-英雄榜(获取)
  472. // @Tags 主页
  473. // @Description 英雄榜(获取)
  474. // @Accept json
  475. // @Produce json
  476. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  477. // @Param kind query string true "时间类型:1.天 2.周 3.月"
  478. // @Param page query string true "页数"
  479. // @Success 200 {object} md.IsCanGetRedPackageResp "具体数据"
  480. // @Failure 400 {object} md.Response "具体错误"
  481. // @Router /api/v1/homePage/heroList [get]
  482. func HeroList(c *gin.Context) {
  483. kind := utils.StrToInt(c.DefaultQuery("kind", "1"))
  484. page := utils.StrToInt(c.DefaultQuery("page", "1"))
  485. limit := 10
  486. start := (page - 1) * limit
  487. end := start + limit - 1
  488. rankCacheKey := fmt.Sprintf(HeroListRedisRankKey, kind)
  489. // 1. 获取指定范围的排行
  490. results, err := cache.ZRevRange(rankCacheKey, start, end, true)
  491. if err != nil {
  492. e.OutErr(c, e.ERR, err.Error())
  493. return
  494. }
  495. // 2. 查询排行内用户头像和昵称
  496. total := len(results)
  497. list := make([]md.HeroListNode, total/2)
  498. userIds := make([]string, total/2)
  499. for i, result := range results {
  500. if i%2 == 1 {
  501. // 奇数数据是分数
  502. list[(i-1)/2].SumValue = string(result.([]uint8))
  503. } else {
  504. // 偶数数据是 uid
  505. list[i/2] = md.HeroListNode{
  506. AvatarUrl: "",
  507. SumValue: "",
  508. Uid: string(result.([]uint8)),
  509. Nickname: "",
  510. }
  511. userIds = append(userIds, string(result.([]uint8)))
  512. }
  513. }
  514. userDb := implement.NewUserDb(db.Db)
  515. users, err := userDb.UserFindByParams(map[string]interface{}{
  516. "key": "id",
  517. "value": userIds,
  518. })
  519. if err != nil {
  520. e.OutErr(c, e.ERR, err.Error())
  521. return
  522. }
  523. userMap := make(map[int64]model.User, len(users))
  524. for _, user := range users {
  525. userMap[user.Id] = user
  526. }
  527. for i, node := range list {
  528. val, ok := userMap[utils.StrToInt64(node.Uid)]
  529. if ok {
  530. list[i].Nickname = val.Nickname
  531. list[i].AvatarUrl = svc.GetOssUrl(val.Avatar)
  532. }
  533. }
  534. // 3. 查询当前用户排名信息
  535. var rank int64
  536. var score string
  537. var err1 error
  538. user := svc.GetUser(c)
  539. rank, err1 = cache.ZRevRangeByMember(rankCacheKey, utils.Int64ToStr(user.Id))
  540. if err1 != nil {
  541. if err1.Error() != "redigo: nil returned" {
  542. e.OutErr(c, e.ERR, err1.Error())
  543. return
  544. } else {
  545. // 3.1 当前用户不在排行榜上
  546. aggregationDb := implement.NewUserVirtualCoinFlowAggregationDb(db.Db)
  547. flowAggregation, err := aggregationDb.UserVirtualCoinFlowAggregationGetOneByParams(map[string]interface{}{
  548. "key": "uid",
  549. "value": user.Id,
  550. })
  551. if err != nil {
  552. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  553. return
  554. }
  555. if flowAggregation != nil {
  556. switch kind {
  557. case 1:
  558. score = flowAggregation.TodayData
  559. case 2:
  560. score = flowAggregation.ThisWeekData
  561. case 3:
  562. score = flowAggregation.ThisMonthData
  563. }
  564. } else {
  565. score = "0"
  566. }
  567. }
  568. } else {
  569. // 3.2 该用户在排行榜上
  570. scoreNum, err2 := cache.ZScoreByMember(rankCacheKey, utils.Int64ToStr(user.Id))
  571. if err2 != nil {
  572. if err2.Error() != "redigo: nil returned" {
  573. e.OutErr(c, e.ERR, err2.Error())
  574. return
  575. }
  576. }
  577. // redis 排名从 0 开始
  578. rank++
  579. score = utils.Float64ToStr(scoreNum)
  580. }
  581. selfRank := md.SelfHeroListNode{
  582. AvatarUrl: svc.GetOssUrl(user.Avatar),
  583. SumValue: score,
  584. Uid: user.Id,
  585. Nickname: user.Nickname,
  586. Rank: rank,
  587. }
  588. resp := md.HeroListResp{
  589. Total: 100,
  590. Page: page,
  591. Limit: 10,
  592. SelfRank: selfRank,
  593. List: list,
  594. }
  595. e.OutSuc(c, resp, nil)
  596. }
  597. // StarRoadProgress
  598. // @Summary 蛋蛋星球-主页-星球之路升级条件(获取)
  599. // @Tags 主页
  600. // @Description 星球之路升级条件(获取)
  601. // @Accept json
  602. // @Produce json
  603. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  604. // @Success 200 {object} md.StarRoadProgressResp "具体数据"
  605. // @Failure 400 {object} md.Response "具体错误"
  606. // @Router /api/v1/homePage/starRoad [get]
  607. func StarRoadProgress(c *gin.Context) {
  608. user := svc.GetUser(c)
  609. // 1. 获取等级列表
  610. levelDb := implement.NewUserLevelDb(db.Db)
  611. levels, err := levelDb.UserLevelAllByAsc()
  612. if err != nil {
  613. e.OutErr(c, e.ERR, err.Error())
  614. return
  615. }
  616. // 2. 获取下一等级信息
  617. var nextLevel *model.UserLevel
  618. var currentLevelName string
  619. for i, level := range levels {
  620. if level.Id == user.Level {
  621. if i < len(levels)-1 {
  622. nextLevel = levels[i+1]
  623. }
  624. currentLevelName = level.LevelName
  625. }
  626. }
  627. var list []md.LevelTaskNode
  628. // 3. 判断是否已达到最高等级
  629. if nextLevel != nil {
  630. // 4. 获取下一等级任务信息
  631. taskDb := implement.NewUserLevelTaskDb(db.Db)
  632. levelTasks, err := taskDb.UserLevelTaskFindByParams(map[string]interface{}{
  633. "key": "level_id",
  634. "value": nextLevel.Id,
  635. })
  636. if err != nil {
  637. e.OutErr(c, e.ERR, err.Error())
  638. return
  639. }
  640. now := time.Now()
  641. // 5. 统计完成任务数
  642. for _, levelTask := range levelTasks {
  643. var count int64
  644. var err1 error
  645. // 5.1 判断任务是否完成
  646. switch levelTask.TaskType {
  647. case 1:
  648. _, count, err1 = svc.IsFinishDirectPush(user.Id, levelTask.FinishCount)
  649. case 2:
  650. _, count, err1 = svc.IsFinishDirectPushOfActiveDays(user.Id, levelTask.FinishCount, levelTask.ActiveDays, now, levelTask.WithinDays)
  651. case 3:
  652. _, count, err1 = svc.IsFinishDirectPushLevel(user.Id, levelTask.LevelId, levelTask.FinishCount)
  653. }
  654. if err1 != nil {
  655. e.OutErr(c, e.ERR_DB_ORM, err1.Error())
  656. return
  657. }
  658. task := md.LevelTaskNode{
  659. LevelId: levelTask.LevelId,
  660. IsMustTask: levelTask.IsMustTask,
  661. TaskType: levelTask.TaskType,
  662. WithinDays: levelTask.WithinDays,
  663. FinishCount: levelTask.FinishCount,
  664. ActiveDays: levelTask.ActiveDays,
  665. TaskTypeLevelId: levelTask.TaskType,
  666. FinishNum: count,
  667. }
  668. list = append(list, task)
  669. }
  670. }
  671. resp := md.StarRoadProgressResp{
  672. LevelName: currentLevelName,
  673. LevelId: user.Level,
  674. List: list,
  675. }
  676. e.OutSuc(c, resp, nil)
  677. }