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

hdl_home_page.go 14 KiB

1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  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. nowStr := now.Format("2006-01-02 15:04:05")
  63. signInDb := implement.NewEggSignInDb(db.Db)
  64. has, signIn, err := signInDb.EggSignInGetOne(nowStr, nowStr, user.Id)
  65. if err != nil {
  66. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  67. return
  68. }
  69. if has && utils.TimeParseStd(signIn.EndTime).After(now) {
  70. //3.2.1 获取预估每秒获得蛋蛋能量数
  71. estimatePerSecondPersonEggEnergyValue, err1 := decimal.NewFromString(signIn.EstimatePerSecondPersonEggEnergyValue)
  72. if err1 != nil {
  73. e.OutErr(c, e.ERR, err1.Error())
  74. return
  75. }
  76. estimatePerSecondTeamEggEnergyValue, err1 := decimal.NewFromString(signIn.EstimatePerSecondTeamEggEnergyValue)
  77. if err1 != nil {
  78. e.OutErr(c, e.ERR, err1.Error())
  79. return
  80. }
  81. signPersonalEggEnergy = estimatePerSecondPersonEggEnergyValue.String()
  82. signTeamEggEnergy = estimatePerSecondTeamEggEnergyValue.String()
  83. isSign = true
  84. signCountdown = signIn.EndTime
  85. }
  86. // 3.3 查询个人及团队蛋蛋能量
  87. amountDb := implement.NewUserVirtualAmountDb(db.Db)
  88. personEggEnergy, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.PersonEggEnergyCoinId)
  89. if err != nil {
  90. e.OutErr(c, e.ERR_DB_ORM, nil)
  91. return
  92. }
  93. teamEggEnergy, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.TeamEggEnergyCoinId)
  94. if err != nil {
  95. e.OutErr(c, e.ERR_DB_ORM, nil)
  96. return
  97. }
  98. signEggEnergyValue, _ := decimal.NewFromString(signPersonalEggEnergy)
  99. personEggEnergyValue, _ := decimal.NewFromString(personEggEnergy.Amount)
  100. teamEggEnergyValue, _ := decimal.NewFromString(teamEggEnergy.Amount)
  101. totalEggEnergy, _ = signEggEnergyValue.Add(personEggEnergyValue).Add(teamEggEnergyValue).Float64()
  102. //4、活跃积分(个人+团队)
  103. var totalActivePoints float64
  104. personActivePoints, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.PersonEggPointsCoinId)
  105. if err != nil {
  106. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  107. return
  108. }
  109. teamActivePoints, err := amountDb.GetUserVirtualWalletBySession(user.Id, eggEnergyBasicSetting.TeamEggPointsCoinId)
  110. if err != nil {
  111. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  112. return
  113. }
  114. totalActivePoints = utils.StrToFloat64(personActivePoints.Amount) + utils.StrToFloat64(teamActivePoints.Amount)
  115. //5、计算当前基础速率、团队速率
  116. nowBasalRate := utils.StrToFloat64(signPersonalEggEnergy) * 60 * 60 //每小时基础速率
  117. NowTeamRate := utils.StrToFloat64(signTeamEggEnergy) * 60 * 60 // 每小时团队速率
  118. userDb := implement.NewUserDb(db.Db)
  119. userCount, err := userDb.UserCount()
  120. if err != nil {
  121. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  122. return
  123. }
  124. var residueTimes = utils.TimeParseStd(signCountdown).Unix() - time.Now().Unix()
  125. utils.FilePutContents("HomePage", utils.SerializeStr(map[string]interface{}{
  126. "user_phone": user.Phone,
  127. "user_uid": user.Id,
  128. "data": map[string]interface{}{
  129. "is_sign": isSign,
  130. "sign_end_date": signCountdown,
  131. "sign_end_timestamp": utils.TimeParseStd(signCountdown).Unix(),
  132. "residue_times": residueTimes,
  133. "total_egg_energy": totalEggEnergy,
  134. "total_active_points": totalActivePoints,
  135. "egg_energy_now_price": nowPrice,
  136. "initial_price": initialPrice,
  137. "is_rises": isRise,
  138. "rises": rises,
  139. "now_basal_rate": nowBasalRate,
  140. "now_team_rate": NowTeamRate,
  141. "user_count": userCount,
  142. "nickname": user.Nickname,
  143. },
  144. }))
  145. resp := md.HomePageResp{
  146. IsSign: isSign,
  147. SignEndTime: signCountdown,
  148. TotalEggEnergy: utils.Float64ToStr(totalEggEnergy),
  149. TotalActivePoints: utils.Float64ToStr(totalActivePoints),
  150. InitialPrice: initialPrice,
  151. NowBasalRate: utils.Float64ToStr(nowBasalRate),
  152. NowTeamRate: utils.Float64ToStr(NowTeamRate),
  153. NickName: user.Nickname,
  154. }
  155. e.OutSuc(c, resp, nil)
  156. return
  157. }
  158. // HomePageWatchAdRule
  159. // @Summary 蛋蛋星球-主页-视频奖励规则(获取)
  160. // @Tags 主页
  161. // @Description 视频奖励规则(获取)
  162. // @Accept json
  163. // @Produce json
  164. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  165. // @Success 200 {object} md.HomePageWatchAdRuleResp "具体数据"
  166. // @Failure 400 {object} md.Response "具体错误"
  167. // @Router /api/v1/homePage/adRule [get]
  168. func HomePageWatchAdRule(c *gin.Context) {
  169. val, exists := c.Get("user")
  170. if !exists {
  171. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  172. return
  173. }
  174. user, ok := val.(*model.User)
  175. if !ok {
  176. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  177. return
  178. }
  179. // 1. 查找基础设置
  180. energyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db)
  181. basicSetting, err := energyBasicSettingDb.EggEnergyBasicSettingGetOne()
  182. if err != nil {
  183. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  184. return
  185. }
  186. // 2. 计算当前还能看几个广告
  187. recordsDb := implement.NewEggEnergyUserWatchRecordsDb(db.Db)
  188. records, err := recordsDb.EggEnergyUserWatchRecordsGetOneByParams(map[string]interface{}{
  189. "key": "uid",
  190. "value": user.Id,
  191. })
  192. if err != nil {
  193. return
  194. }
  195. var videoRewardSystem md2.VideoRewardSystemStruct
  196. utils.Unserialize([]byte(basicSetting.VideoRewardSystem), &videoRewardSystem)
  197. redisKey := fmt.Sprintf(md2.UserNextWatchAdDate, user.Id)
  198. var residueWatchAdNum int
  199. if records == nil {
  200. residueWatchAdNum = utils.StrToInt(videoRewardSystem.RewardTotalNum)
  201. } else {
  202. now := time.Now()
  203. residueWatchAdNum = records.ResidueWatchAdNum
  204. if records.NextWatchAdDate.Before(now) {
  205. //TODO::下一轮时间已在当前时间之前
  206. residueWatchAdNum = utils.StrToInt(videoRewardSystem.RewardTotalNum)
  207. records.ResidueWatchAdNum = residueWatchAdNum
  208. _, err = recordsDb.EggEnergyUserWatchRecordsUpdate(records.Id, records, "residue_watch_ad_num")
  209. if err != nil {
  210. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  211. return
  212. }
  213. cache.SetEx(redisKey, "", 60*60*24)
  214. }
  215. }
  216. nextWatchAdDate, _ := cache.GetString(redisKey)
  217. var nextWatchAdTimes = utils.TimeParseStd(nextWatchAdDate).Unix() - time.Now().Unix()
  218. utils.FilePutContents("nextWatchAdDate", utils.SerializeStr(map[string]interface{}{
  219. "nextWatchAdDate": nextWatchAdDate,
  220. "next_watch_ad_times": nextWatchAdTimes,
  221. "uid": utils.Int64ToStr(user.Id),
  222. "time": time.Now().Format("2006-01-02 15:04:05.000"),
  223. }))
  224. resp := md.HomePageWatchAdRuleResp{
  225. ResidueWatchAdNum: residueWatchAdNum,
  226. WatchAdRewardActivePoints: videoRewardSystem.RewardValue,
  227. NextWatchAdDate: nextWatchAdDate,
  228. EachRoundHour: videoRewardSystem.EachRoundHour,
  229. }
  230. e.OutSuc(c, resp, nil)
  231. }
  232. const HomePageRealTimeRedisKey = "Home_Page_Real_Time_Cache_Key"
  233. // RealTimePrice
  234. // @Summary 蛋蛋星球-主页-实时数据(获取)
  235. // @Tags 主页
  236. // @Description 实时数据(获取)
  237. // @Accept json
  238. // @Produce json
  239. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  240. // @Success 200 {object} md.RealTimePriceResp "具体数据"
  241. // @Failure 400 {object} md.Response "具体错误"
  242. // @Router /api/v1/homePage/realTimePrice [get]
  243. func RealTimePrice(c *gin.Context) {
  244. var isRises, userCount, risesValue, nowPrice interface{}
  245. var rises float64
  246. redisKey := HomePageRealTimeRedisKey
  247. redisValue, err := cache.GetString(redisKey)
  248. if err != nil {
  249. if err.Error() == "redigo: nil returned" {
  250. now := time.Now()
  251. err, rises, isRises, nowPrice, _ = svc.CalcTodayEggEnergyPriceRises(db.Db, now)
  252. if err != nil {
  253. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  254. return
  255. }
  256. userDb := implement.NewUserDb(db.Db)
  257. userCount, err = userDb.UserCount()
  258. if err != nil {
  259. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  260. return
  261. }
  262. decimalRate := decimal.NewFromInt(100) //百分比
  263. risesValue, _ = decimal.NewFromFloat(rises).Mul(decimalRate).Float64()
  264. // 缓存 5 s
  265. cache.SetEx(redisKey, utils.SerializeStr(map[string]interface{}{
  266. "user_count": userCount,
  267. "is_rises": isRises,
  268. "rises": risesValue,
  269. "egg_energy_now_price": nowPrice,
  270. }), 5)
  271. } else {
  272. e.OutErr(c, e.ERR, err.Error())
  273. return
  274. }
  275. } else {
  276. var result map[string]interface{}
  277. err1 := json.Unmarshal([]byte(redisValue), &result)
  278. if err1 != nil {
  279. e.OutErr(c, e.ERR, err1.Error())
  280. return
  281. }
  282. userCount = result["user_count"]
  283. isRises = result["is_rises"]
  284. risesValue = result["rises"]
  285. nowPrice = result["egg_energy_now_price"]
  286. }
  287. isRisesResp, ok := isRises.(bool)
  288. if !ok {
  289. e.OutErr(c, e.ERR, "断言失败")
  290. }
  291. resp := md.RealTimePriceResp{
  292. UserCount: utils.AnyToInt64(userCount),
  293. NowPrice: utils.AnyToString(nowPrice),
  294. IsRises: isRisesResp,
  295. Rises: utils.AnyToString(risesValue),
  296. }
  297. e.OutSuc(c, resp, nil)
  298. }
  299. // IsCanSignIn
  300. // @Summary 蛋蛋星球-主页-是否能签到(获取)
  301. // @Tags 主页
  302. // @Description 是否可以签到(获取)
  303. // @Accept json
  304. // @Produce json
  305. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  306. // @Success 200 {object} md.IsCanSignInResp "具体数据"
  307. // @Failure 400 {object} md.Response "具体错误"
  308. // @Router /api/v1/homePage/isCanSignIn [get]
  309. func IsCanSignIn(c *gin.Context) {
  310. val, exists := c.Get("user")
  311. if !exists {
  312. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  313. return
  314. }
  315. user, ok := val.(*model.User)
  316. if !ok {
  317. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  318. return
  319. }
  320. //1、查找 `OneCirclesPublicPlatoonBasicSetting` 基础设置
  321. energyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db)
  322. eggEnergyBasicSetting, err := energyBasicSettingDb.EggEnergyBasicSettingGetOneByParams(map[string]interface{}{
  323. "key": "is_open",
  324. "value": 1,
  325. })
  326. if err != nil {
  327. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  328. return
  329. }
  330. var videoRewardSystem *md2.VideoRewardSystemStruct
  331. err = json.Unmarshal([]byte(eggEnergyBasicSetting.VideoRewardSystem), &videoRewardSystem)
  332. if err != nil {
  333. e.OutErr(c, e.ERR, err.Error())
  334. return
  335. }
  336. rewardTotalNum := utils.StrToInt(videoRewardSystem.RewardTotalNum)
  337. //2、查询当前用户观看视屏记录
  338. watchRecordsDb := implement.NewEggEnergyUserWatchRecordsDb(db.Db)
  339. userWatchRecords, err := watchRecordsDb.EggEnergyUserWatchRecordsGetOneByParams(map[string]interface{}{
  340. "key": "uid",
  341. "value": user.Id,
  342. })
  343. if err != nil {
  344. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  345. return
  346. }
  347. var isCan bool
  348. now := time.Now()
  349. if userWatchRecords != nil && userWatchRecords.ResidueWatchAdNum == rewardTotalNum && userWatchRecords.NextWatchAdDate.After(now) {
  350. isCan = true
  351. }
  352. utils.FilePutContents("HomePageIsCanSignIn", utils.SerializeStr(map[string]interface{}{
  353. "user_phone": user.Phone,
  354. "user_uid": user.Id,
  355. "is_can": isCan,
  356. "time": now.Format("2006-01-02 15:04:05"),
  357. }))
  358. resp := md.IsCanSignInResp{
  359. IsCan: isCan,
  360. }
  361. e.OutSuc(c, resp, nil)
  362. return
  363. }
  364. // IsCanGetRedPackage
  365. // @Summary 蛋蛋星球-主页-是否领取红包(获取)
  366. // @Tags 主页
  367. // @Description 是否可以领取红包(获取)
  368. // @Accept json
  369. // @Produce json
  370. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  371. // @Success 200 {object} md.IsCanGetRedPackageResp "具体数据"
  372. // @Failure 400 {object} md.Response "具体错误"
  373. // @Router /api/v1/homePage/isCanGetRedPackage [get]
  374. func IsCanGetRedPackage(c *gin.Context) {
  375. val, exists := c.Get("user")
  376. if !exists {
  377. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  378. return
  379. }
  380. user, ok := val.(*model.User)
  381. if !ok {
  382. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  383. return
  384. }
  385. // 1. 红包活动是否开启
  386. redPackageDb := implement.NewNewUserRedPackageDb(db.Db)
  387. redPackage, err := redPackageDb.NewUserRedPackageGetOne()
  388. if err != nil {
  389. e.OutErr(c, e.ERR, err.Error())
  390. return
  391. }
  392. // 2. 用户已有红包活动记录
  393. userRecordsDb := implement.NewNewUserRedPackageWithUserRecordsDb(db.Db)
  394. records, err := userRecordsDb.NewUserRedPackageWithUserRecordsGetLastPendingByParams(map[string]interface{}{
  395. "key": "uid",
  396. "value": user.Id,
  397. })
  398. if err != nil {
  399. e.OutErr(c, e.ERR_DB_ORM, nil)
  400. return
  401. }
  402. isCan := false
  403. if redPackage != nil {
  404. if redPackage.IsOpen == 1 && records != nil {
  405. isCan = true
  406. }
  407. }
  408. resp := md.IsCanGetRedPackageResp{
  409. IsCan: isCan,
  410. }
  411. e.OutSuc(c, resp, nil)
  412. }