蛋蛋星球-客户端
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 

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