96 lines
2.8 KiB
Go
96 lines
2.8 KiB
Go
package weekstar
|
||
|
||
import (
|
||
"fmt"
|
||
"strings"
|
||
"time"
|
||
|
||
"chatapp3-golang/internal/model"
|
||
)
|
||
|
||
// referenceTimeForPage 返回页面应参考的周期时间点,未开始取 startAt,已结束取结束前一秒。
|
||
func (s *WeekStarService) referenceTimeForPage(configRow *model.WeekStarActivityConfig, now time.Time) time.Time {
|
||
if configRow == nil {
|
||
return now
|
||
}
|
||
startAt := s.fromStorageWallClock(configRow.StartAt)
|
||
endAt := s.fromStorageWallClock(configRow.EndAt)
|
||
switch {
|
||
case now.Before(startAt):
|
||
return startAt
|
||
case !now.Before(endAt):
|
||
return endAt.Add(-time.Second)
|
||
default:
|
||
return now
|
||
}
|
||
}
|
||
|
||
// cycleBounds 返回某个时间所在周的起止边界。
|
||
func (s *WeekStarService) cycleBounds(t time.Time) (time.Time, time.Time) {
|
||
start := s.cycleStart(t)
|
||
return start, start.AddDate(0, 0, 7)
|
||
}
|
||
|
||
// cycleStart 计算某个时间所在周的周一 00:00,作为周榜周期起点。
|
||
func (s *WeekStarService) cycleStart(t time.Time) time.Time {
|
||
local := t.In(s.location)
|
||
weekday := int(local.Weekday())
|
||
if weekday == 0 {
|
||
weekday = 7
|
||
}
|
||
startDay := local.AddDate(0, 0, -(weekday - 1))
|
||
return time.Date(startDay.Year(), startDay.Month(), startDay.Day(), 0, 0, 0, 0, s.location)
|
||
}
|
||
|
||
// cycleKey 把周期开始时间格式化为稳定的周期标识,例如 20260414。
|
||
func (s *WeekStarService) cycleKey(start time.Time) string {
|
||
return start.In(s.location).Format("20060102")
|
||
}
|
||
|
||
// toStorageWallClock 把活动时区时间转换为数据库约定的墙上时间存储格式。
|
||
func (s *WeekStarService) toStorageWallClock(t time.Time) time.Time {
|
||
local := t.In(s.location)
|
||
return time.Date(
|
||
local.Year(),
|
||
local.Month(),
|
||
local.Day(),
|
||
local.Hour(),
|
||
local.Minute(),
|
||
local.Second(),
|
||
local.Nanosecond(),
|
||
s.location,
|
||
)
|
||
}
|
||
|
||
// fromStorageWallClock 把数据库里的墙上时间恢复到活动时区,便于业务计算和展示。
|
||
func (s *WeekStarService) fromStorageWallClock(t time.Time) time.Time {
|
||
return time.Date(
|
||
t.Year(),
|
||
t.Month(),
|
||
t.Day(),
|
||
t.Hour(),
|
||
t.Minute(),
|
||
t.Second(),
|
||
t.Nanosecond(),
|
||
s.location,
|
||
)
|
||
}
|
||
|
||
// rankRedisKey 返回某个活动某个周期的实时排行 Redis Key。
|
||
func (s *WeekStarService) rankRedisKey(configID int64, cycleKey string) string {
|
||
return fmt.Sprintf("week-star:rank:%d:%s", configID, cycleKey)
|
||
}
|
||
|
||
// settleLockKey 返回某个活动某个周期的结算锁 Redis Key。
|
||
func (s *WeekStarService) settleLockKey(configID int64, cycleKey string) string {
|
||
return fmt.Sprintf("week-star:settle-lock:%d:%s", configID, cycleKey)
|
||
}
|
||
|
||
// normalizeSysOrigin 兜底系统标识为空时使用默认系统,并统一转成大写。
|
||
func (s *WeekStarService) normalizeSysOrigin(sysOrigin string) string {
|
||
if strings.TrimSpace(sysOrigin) == "" {
|
||
return strings.ToUpper(strings.TrimSpace(s.cfg.WeekStar.DefaultSysOrigin))
|
||
}
|
||
return strings.ToUpper(strings.TrimSpace(sysOrigin))
|
||
}
|