蛋蛋星球-客户端
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 

492 рядки
16 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. 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. }