蛋蛋星球-客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

728 lines
22 KiB

  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. }