118 lines
2.6 KiB
Go
118 lines
2.6 KiB
Go
package repositories
|
||
|
||
import (
|
||
// "log"
|
||
"time"
|
||
|
||
"github.com/niangaodev/art-code/config"
|
||
"github.com/niangaodev/art-code/models"
|
||
)
|
||
|
||
// Helper to parse date string to unix timestamp
|
||
func parseDateToUnix(dateStr string, isEnd bool) int64 {
|
||
if dateStr == "" {
|
||
return 0
|
||
}
|
||
// Try parsing with time first
|
||
t, err := time.ParseInLocation("2006-01-02 15:04", dateStr, time.Local)
|
||
if err == nil {
|
||
if isEnd {
|
||
// HH:mm:59
|
||
return t.Add(59 * time.Second).Unix()
|
||
}
|
||
return t.Unix()
|
||
}
|
||
|
||
// Try parsing just date
|
||
t, err = time.ParseInLocation("2006-01-02", dateStr, time.Local)
|
||
if err == nil {
|
||
if isEnd {
|
||
// 23:59:59
|
||
return t.Add(24*time.Hour - 1*time.Second).Unix()
|
||
}
|
||
return t.Unix()
|
||
}
|
||
|
||
return 0
|
||
}
|
||
|
||
// CreateAccessLog 创建访问日志
|
||
func CreateAccessLog(log *models.AccessLog) error {
|
||
return config.DB.Create(log).Error
|
||
}
|
||
|
||
// UVTrendData UV趋势数据
|
||
type UVTrendData struct {
|
||
Date string `json:"date"`
|
||
Count int `json:"value"`
|
||
YoY float64 `json:"yoy"`
|
||
MoM float64 `json:"mom"`
|
||
}
|
||
|
||
// GetDailyUV 获取UV趋势
|
||
func GetDailyUV(startDate, endDate string) ([]UVTrendData, error) {
|
||
query := config.DB.Model(&models.UserAccessLog{}).
|
||
Select("FROM_UNIXTIME(access_time, '%Y-%m-%d') as date, COUNT(DISTINCT user_ip) as count")
|
||
|
||
if startDate != "" {
|
||
startUnix := parseDateToUnix(startDate, false)
|
||
query = query.Where("access_time >= ?", startUnix)
|
||
} else {
|
||
// 默认最近7天
|
||
startUnix := time.Now().AddDate(0, 0, -6).Unix()
|
||
query = query.Where("access_time >= ?", startUnix)
|
||
}
|
||
|
||
if endDate != "" {
|
||
endUnix := parseDateToUnix(endDate, true)
|
||
query = query.Where("access_time <= ?", endUnix)
|
||
}
|
||
|
||
var results []UVTrendData
|
||
err := query.Group("date").
|
||
Order("date ASC").
|
||
Scan(&results).Error
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 暂未实现真实的同比环比计算逻辑,设为0
|
||
for i := range results {
|
||
results[i].YoY = 0
|
||
results[i].MoM = 0
|
||
}
|
||
|
||
return results, nil
|
||
}
|
||
|
||
// GetUserRegions 获取用户地域分布
|
||
func GetUserRegions(startDate, endDate string) ([]struct {
|
||
Region string
|
||
Count int
|
||
}, error) {
|
||
query := config.DB.Model(&models.UserAccessLog{}).
|
||
Select("COALESCE(NULLIF(user_location, ''), 'Unknown') as region, COUNT(DISTINCT user_ip) as count")
|
||
|
||
if startDate != "" {
|
||
startUnix := parseDateToUnix(startDate, false)
|
||
query = query.Where("access_time >= ?", startUnix)
|
||
}
|
||
|
||
if endDate != "" {
|
||
endUnix := parseDateToUnix(endDate, true)
|
||
query = query.Where("access_time <= ?", endUnix)
|
||
}
|
||
|
||
var results []struct {
|
||
Region string
|
||
Count int
|
||
}
|
||
err := query.Group("region").
|
||
Order("count DESC").
|
||
Limit(20).
|
||
Scan(&results).Error
|
||
|
||
return results, err
|
||
}
|