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

hdl_home_page.go 16 KiB

1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
2週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
2週間前
2週間前
2週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
2週間前
1ヶ月前
1ヶ月前
2週間前
1ヶ月前
1ヶ月前
3週間前
1ヶ月前
2週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
3週間前
3週間前
3週間前
3週間前
1週間前
1ヶ月前
3週間前
3週間前
1ヶ月前
3週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1週間前
1週間前
1週間前
1週間前
1週間前
1週間前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  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. utils.FilePutContents("HomePage", utils.SerializeStr(map[string]interface{}{
  133. "user_phone": user.Phone,
  134. "user_uid": user.Id,
  135. "data": map[string]interface{}{
  136. "is_sign": isSign,
  137. "sign_end_date": signCountdown,
  138. "sign_end_timestamp": utils.TimeParseStd(signCountdown).Unix(),
  139. "residue_times": residueTimes,
  140. "total_egg_energy": totalEggEnergyDecimal.String(),
  141. "total_active_points": totalActivePoints,
  142. "egg_energy_now_price": nowPrice,
  143. "initial_price": initialPrice,
  144. "is_rises": isRise,
  145. "rises": rises,
  146. "now_basal_rate": nowBasalRate,
  147. "now_team_rate": NowTeamRate,
  148. "user_count": userCount,
  149. "nickname": user.Nickname,
  150. },
  151. }))
  152. resp := md.HomePageResp{
  153. LeaveTimer: utils.Int64ToStr(residueTimes),
  154. IsSign: isSign,
  155. SignEndTime: signCountdown,
  156. TotalEggEnergy: totalEggEnergyDecimal.String(),
  157. TotalActivePoints: utils.Float64ToStr(totalActivePoints),
  158. InitialPrice: initialPrice,
  159. NowBasalRate: utils.Float64ToStr(nowBasalRate),
  160. NowTeamRate: utils.Float64ToStr(NowTeamRate),
  161. NickName: user.Nickname,
  162. }
  163. e.OutSuc(c, resp, nil)
  164. return
  165. }
  166. // HomePageWatchAdRule
  167. // @Summary 蛋蛋星球-主页-视频奖励规则(获取)
  168. // @Tags 主页
  169. // @Description 视频奖励规则(获取)
  170. // @Accept json
  171. // @Produce json
  172. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  173. // @Success 200 {object} md.HomePageWatchAdRuleResp "具体数据"
  174. // @Failure 400 {object} md.Response "具体错误"
  175. // @Router /api/v1/homePage/adRule [get]
  176. func HomePageWatchAdRule(c *gin.Context) {
  177. val, exists := c.Get("user")
  178. if !exists {
  179. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  180. return
  181. }
  182. user, ok := val.(*model.User)
  183. if !ok {
  184. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  185. return
  186. }
  187. // 1. 查找基础设置
  188. energyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db)
  189. basicSetting, err := energyBasicSettingDb.EggEnergyBasicSettingGetOne()
  190. if err != nil {
  191. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  192. return
  193. }
  194. // 2. 计算当前还能看几个广告
  195. recordsDb := implement.NewEggEnergyUserWatchRecordsDb(db.Db)
  196. records, err := recordsDb.EggEnergyUserWatchRecordsGetOneByParams(map[string]interface{}{
  197. "key": "uid",
  198. "value": user.Id,
  199. })
  200. if err != nil {
  201. return
  202. }
  203. var videoRewardSystem md2.VideoRewardSystemStruct
  204. utils.Unserialize([]byte(basicSetting.VideoRewardSystem), &videoRewardSystem)
  205. redisKey := fmt.Sprintf(md2.UserNextWatchAdDate, user.Id)
  206. var residueWatchAdNum int
  207. if records == nil {
  208. residueWatchAdNum = utils.StrToInt(videoRewardSystem.RewardTotalNum)
  209. } else {
  210. now := time.Now()
  211. residueWatchAdNum = records.ResidueWatchAdNum
  212. if records.NextWatchAdDate.Before(now) {
  213. //TODO::下一轮时间已在当前时间之前
  214. residueWatchAdNum = utils.StrToInt(videoRewardSystem.RewardTotalNum)
  215. records.ResidueWatchAdNum = residueWatchAdNum
  216. _, err = recordsDb.EggEnergyUserWatchRecordsUpdate(records.Id, records, "residue_watch_ad_num")
  217. if err != nil {
  218. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  219. return
  220. }
  221. cache.SetEx(redisKey, "", 60*60*24)
  222. }
  223. }
  224. nextWatchAdDate, _ := cache.GetString(redisKey)
  225. nextWatchAdTimes := utils.TimeParseStd(nextWatchAdDate).Unix() - time.Now().Unix()
  226. if nextWatchAdTimes < 0 {
  227. nextWatchAdTimes = 0
  228. }
  229. var roundRemainingSecs int64
  230. now := time.Now()
  231. //开始时间 以当前时间 往前推多少
  232. signInDb := implement.NewEggSignInDb(db.Db)
  233. nowStr := now.Format("2006-01-02 15:04:05")
  234. has, signIn, err := signInDb.EggSignINGetOneByTimeAndUid("", nowStr, user.Id, 0)
  235. if err != nil {
  236. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  237. return
  238. }
  239. if has {
  240. roundRemainingSecs = utils.TimeParseStd(signIn.EndTime).Unix() - time.Now().Unix()
  241. if roundRemainingSecs < 0 {
  242. roundRemainingSecs = 0
  243. }
  244. }
  245. utils.FilePutContents("nextWatchAdDate", utils.SerializeStr(map[string]interface{}{
  246. "nextWatchAdDate": nextWatchAdDate,
  247. "next_watch_ad_times": nextWatchAdTimes,
  248. "uid": utils.Int64ToStr(user.Id),
  249. "roundRemainingSecs": roundRemainingSecs,
  250. "time": time.Now().Format("2006-01-02 15:04:05.000"),
  251. }))
  252. resp := md.HomePageWatchAdRuleResp{
  253. RewardTotalNum: videoRewardSystem.RewardTotalNum,
  254. ResidueWatchAdNum: residueWatchAdNum,
  255. WatchAdRewardActivePoints: videoRewardSystem.RewardValue,
  256. NextWatchAdDate: nextWatchAdDate,
  257. NextWatchAdSecs: nextWatchAdTimes,
  258. EachRoundHour: videoRewardSystem.EachRoundHour,
  259. RoundRemainingSecs: roundRemainingSecs,
  260. }
  261. e.OutSuc(c, resp, nil)
  262. }
  263. const HomePageRealTimeRedisKey = "Home_Page_Real_Time_Cache_Key"
  264. // RealTimePrice
  265. // @Summary 蛋蛋星球-主页-实时数据(获取)
  266. // @Tags 主页
  267. // @Description 实时数据(获取)
  268. // @Accept json
  269. // @Produce json
  270. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  271. // @Success 200 {object} md.RealTimePriceResp "具体数据"
  272. // @Failure 400 {object} md.Response "具体错误"
  273. // @Router /api/v1/homePage/realTimePrice [get]
  274. func RealTimePrice(c *gin.Context) {
  275. var isRises, userCount, risesValue, nowPrice interface{}
  276. var rises float64
  277. redisKey := HomePageRealTimeRedisKey
  278. redisValue, err := cache.GetString(redisKey)
  279. if err != nil {
  280. if err.Error() == "redigo: nil returned" {
  281. now := time.Now()
  282. err, rises, isRises, nowPrice, _ = svc.CalcTodayEggEnergyPriceRises(db.Db, now)
  283. if err != nil {
  284. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  285. return
  286. }
  287. userDb := implement.NewUserDb(db.Db)
  288. userCount, err = userDb.UserCount()
  289. if err != nil {
  290. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  291. return
  292. }
  293. decimalRate := decimal.NewFromInt(100) //百分比
  294. risesValue = decimal.NewFromFloat(rises).Mul(decimalRate).StringFixed(16)
  295. // 缓存 5 s
  296. cache.SetEx(redisKey, utils.SerializeStr(map[string]interface{}{
  297. "user_count": userCount,
  298. "is_rises": isRises,
  299. "rises": risesValue,
  300. "egg_energy_now_price": nowPrice,
  301. }), 5)
  302. } else {
  303. e.OutErr(c, e.ERR, err.Error())
  304. return
  305. }
  306. } else {
  307. var result map[string]interface{}
  308. err1 := json.Unmarshal([]byte(redisValue), &result)
  309. if err1 != nil {
  310. e.OutErr(c, e.ERR, err1.Error())
  311. return
  312. }
  313. userCount = result["user_count"]
  314. isRises = result["is_rises"]
  315. risesValue = result["rises"]
  316. nowPrice = result["egg_energy_now_price"]
  317. }
  318. isRisesResp, ok := isRises.(bool)
  319. if !ok {
  320. e.OutErr(c, e.ERR, "断言失败")
  321. }
  322. resp := md.RealTimePriceResp{
  323. UserCount: utils.AnyToInt64(userCount),
  324. NowPrice: utils.AnyToString(nowPrice),
  325. IsRises: isRisesResp,
  326. Rises: utils.AnyToString(risesValue),
  327. }
  328. e.OutSuc(c, resp, nil)
  329. }
  330. // IsCanSignIn
  331. // @Summary 蛋蛋星球-主页-是否能签到(获取)
  332. // @Tags 主页
  333. // @Description 是否可以签到(获取)
  334. // @Accept json
  335. // @Produce json
  336. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  337. // @Success 200 {object} md.IsCanSignInResp "具体数据"
  338. // @Failure 400 {object} md.Response "具体错误"
  339. // @Router /api/v1/homePage/isCanSignIn [get]
  340. func IsCanSignIn(c *gin.Context) {
  341. val, exists := c.Get("user")
  342. if !exists {
  343. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  344. return
  345. }
  346. user, ok := val.(*model.User)
  347. if !ok {
  348. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  349. return
  350. }
  351. now := time.Now()
  352. var isCan = false
  353. signInDb := implement.NewEggSignInDb(db.Db)
  354. nowStr := now.Format("2006-01-02 15:04:05")
  355. has, _, err := signInDb.EggSignINGetOneByTimeAndUid("", nowStr, user.Id, 0)
  356. if err != nil {
  357. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  358. return
  359. }
  360. if has {
  361. isCan = false
  362. } else {
  363. //1、查找 `OneCirclesPublicPlatoonBasicSetting` 基础设置
  364. energyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(db.Db)
  365. eggEnergyBasicSetting, err := energyBasicSettingDb.EggEnergyBasicSettingGetOneByParams(map[string]interface{}{
  366. "key": "is_open",
  367. "value": 1,
  368. })
  369. if err != nil {
  370. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  371. return
  372. }
  373. var videoRewardSystem *md2.VideoRewardSystemStruct
  374. err = json.Unmarshal([]byte(eggEnergyBasicSetting.VideoRewardSystem), &videoRewardSystem)
  375. if err != nil {
  376. e.OutErr(c, e.ERR, err.Error())
  377. return
  378. }
  379. rewardTotalNum := utils.StrToInt(videoRewardSystem.RewardTotalNum)
  380. //2、查询当前用户观看视屏记录
  381. watchRecordsDb := implement.NewEggEnergyUserWatchRecordsDb(db.Db)
  382. userWatchRecords, err := watchRecordsDb.EggEnergyUserWatchRecordsGetOneByParams(map[string]interface{}{
  383. "key": "uid",
  384. "value": user.Id,
  385. })
  386. if err != nil {
  387. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  388. return
  389. }
  390. if userWatchRecords != nil && userWatchRecords.ResidueWatchAdNum == rewardTotalNum && userWatchRecords.NextWatchAdDate.After(now) {
  391. isCan = true
  392. }
  393. }
  394. utils.FilePutContents("HomePageIsCanSignIn", utils.SerializeStr(map[string]interface{}{
  395. "user_phone": user.Phone,
  396. "user_uid": user.Id,
  397. "is_can": isCan,
  398. "time": now.Format("2006-01-02 15:04:05"),
  399. }))
  400. resp := md.IsCanSignInResp{
  401. IsCan: isCan,
  402. }
  403. e.OutSuc(c, resp, nil)
  404. return
  405. }
  406. // IsCanGetRedPackage
  407. // @Summary 蛋蛋星球-主页-是否领取红包(获取)
  408. // @Tags 主页
  409. // @Description 是否可以领取红包(获取)
  410. // @Accept json
  411. // @Produce json
  412. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  413. // @Success 200 {object} md.IsCanGetRedPackageResp "具体数据"
  414. // @Failure 400 {object} md.Response "具体错误"
  415. // @Router /api/v1/homePage/isCanGetRedPackage [get]
  416. func IsCanGetRedPackage(c *gin.Context) {
  417. val, exists := c.Get("user")
  418. if !exists {
  419. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  420. return
  421. }
  422. user, ok := val.(*model.User)
  423. if !ok {
  424. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  425. return
  426. }
  427. // 1. 红包活动是否开启
  428. redPackageDb := implement.NewNewUserRedPackageDb(db.Db)
  429. redPackage, err := redPackageDb.NewUserRedPackageGetOne()
  430. if err != nil {
  431. e.OutErr(c, e.ERR, err.Error())
  432. return
  433. }
  434. // 2. 用户已有红包活动记录
  435. userRecordsDb := implement.NewNewUserRedPackageWithUserRecordsDb(db.Db)
  436. records, err := userRecordsDb.NewUserRedPackageWithUserRecordsGetLastPendingByParams(map[string]interface{}{
  437. "key": "uid",
  438. "value": user.Id,
  439. })
  440. if err != nil {
  441. e.OutErr(c, e.ERR_DB_ORM, nil)
  442. return
  443. }
  444. isCan := false
  445. if redPackage != nil {
  446. if redPackage.IsOpen == 1 && records != nil {
  447. isCan = true
  448. }
  449. }
  450. resp := md.IsCanGetRedPackageResp{
  451. IsCan: isCan,
  452. }
  453. e.OutSuc(c, resp, nil)
  454. }