170 lines
3.8 KiB
Go
170 lines
3.8 KiB
Go
package handler
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
"xboard-go/internal/database"
|
|
"xboard-go/internal/model"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// AdminGetTrafficRank returns traffic ranking for nodes or users.
|
|
func AdminGetTrafficRank(c *gin.Context) {
|
|
rankType := c.Query("type") // node or user
|
|
startTimeStr := c.Query("start_time")
|
|
endTimeStr := c.Query("end_time")
|
|
|
|
startTime, _ := strconv.ParseInt(startTimeStr, 10, 64)
|
|
endTime, _ := strconv.ParseInt(endTimeStr, 10, 64)
|
|
|
|
if startTime == 0 {
|
|
startTime = time.Now().AddDate(0, 0, -7).Unix()
|
|
}
|
|
if endTime == 0 {
|
|
endTime = time.Now().Unix()
|
|
}
|
|
|
|
var result []gin.H
|
|
if rankType == "user" {
|
|
type userRank struct {
|
|
ID int `json:"id"`
|
|
Value int64 `json:"value"`
|
|
Email string `json:"name"`
|
|
}
|
|
var ranks []userRank
|
|
database.DB.Model(&model.StatUser{}).
|
|
Select("user_id as id, SUM(u + d) as value").
|
|
Where("record_at >= ? AND record_at <= ?", startTime, endTime).
|
|
Group("user_id").
|
|
Order("value DESC").
|
|
Limit(10).
|
|
Scan(&ranks)
|
|
|
|
var userIDs []int
|
|
for _, r := range ranks {
|
|
userIDs = append(userIDs, r.ID)
|
|
}
|
|
userEmails := loadUserEmailMap(userIDs)
|
|
for _, r := range ranks {
|
|
result = append(result, gin.H{
|
|
"id": fmt.Sprintf("%d", r.ID),
|
|
"name": userEmails[r.ID],
|
|
"value": r.Value,
|
|
})
|
|
}
|
|
} else {
|
|
// Default to node
|
|
type nodeRank struct {
|
|
ID int `json:"id"`
|
|
Value int64 `json:"value"`
|
|
Name string `json:"name"`
|
|
}
|
|
var ranks []nodeRank
|
|
database.DB.Model(&model.StatServer{}).
|
|
Select("server_id as id, SUM(u + d) as value").
|
|
Where("record_at >= ? AND record_at <= ?", startTime, endTime).
|
|
Group("server_id").
|
|
Order("value DESC").
|
|
Limit(10).
|
|
Scan(&ranks)
|
|
|
|
var nodeIDs []int
|
|
for _, r := range ranks {
|
|
nodeIDs = append(nodeIDs, r.ID)
|
|
}
|
|
nodeNames := loadNodeNameMap(nodeIDs)
|
|
for _, r := range ranks {
|
|
result = append(result, gin.H{
|
|
"id": fmt.Sprintf("%d", r.ID),
|
|
"name": nodeNames[r.ID],
|
|
"value": r.Value,
|
|
})
|
|
}
|
|
}
|
|
|
|
Success(c, result)
|
|
}
|
|
|
|
// AdminGetOrderStats returns order-related statistics for charts.
|
|
func AdminGetOrderStats(c *gin.Context) {
|
|
startDateStr := c.Query("start_date")
|
|
endDateStr := c.Query("end_date")
|
|
statType := c.Query("type") // paid_total, paid_count, etc.
|
|
|
|
var startDate int64
|
|
var endDate int64
|
|
|
|
if startDateStr != "" {
|
|
t, _ := time.Parse("2006-01-02", startDateStr)
|
|
startDate = t.Unix()
|
|
} else {
|
|
startDate = time.Now().AddDate(0, 0, -30).Truncate(24 * time.Hour).Unix()
|
|
}
|
|
|
|
if endDateStr != "" {
|
|
t, _ := time.Parse("2006-01-02", endDateStr)
|
|
endDate = t.Unix() + 86399
|
|
} else {
|
|
endDate = time.Now().Unix()
|
|
}
|
|
|
|
var stats []model.Stat
|
|
database.DB.Where("record_at >= ? AND record_at <= ? AND record_type = ?", startDate, endDate, "d").
|
|
Order("record_at ASC").
|
|
Find(&stats)
|
|
|
|
var list []gin.H
|
|
for _, s := range stats {
|
|
dateStr := time.Unix(s.RecordAt, 0).Format("2006-01-02")
|
|
item := gin.H{
|
|
"date": dateStr,
|
|
}
|
|
if statType != "" {
|
|
item["value"] = getStatFieldValue(s, statType)
|
|
} else {
|
|
item["paid_total"] = s.PaidTotal
|
|
item["paid_count"] = s.PaidCount
|
|
item["commission_total"] = s.CommissionTotal
|
|
}
|
|
list = append(list, item)
|
|
}
|
|
|
|
Success(c, gin.H{
|
|
"list": list,
|
|
})
|
|
}
|
|
|
|
|
|
|
|
func loadNodeNameMap(ids []int) map[int]string {
|
|
result := make(map[int]string)
|
|
if len(ids) == 0 {
|
|
return result
|
|
}
|
|
var servers []model.Server
|
|
database.DB.Select("id", "name").Where("id IN ?", ids).Find(&servers)
|
|
for _, s := range servers {
|
|
result[s.ID] = s.Name
|
|
}
|
|
return result
|
|
}
|
|
|
|
func getStatFieldValue(s model.Stat, field string) any {
|
|
switch field {
|
|
case "paid_total":
|
|
return s.PaidTotal
|
|
case "paid_count":
|
|
return s.PaidCount
|
|
case "commission_total":
|
|
return s.CommissionTotal
|
|
case "commission_count":
|
|
return s.CommissionCount
|
|
case "register_count":
|
|
return s.RegisterCount
|
|
default:
|
|
return 0
|
|
}
|
|
}
|