mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-03-30 02:44:40 +00:00
fix(dashboard): prefer username in user usage trend
This commit is contained in:
@@ -96,6 +96,7 @@ type UserUsageTrendPoint struct {
|
||||
Date string `json:"date"`
|
||||
UserID int64 `json:"user_id"`
|
||||
Email string `json:"email"`
|
||||
Username string `json:"username"`
|
||||
Requests int64 `json:"requests"`
|
||||
Tokens int64 `json:"tokens"`
|
||||
Cost float64 `json:"cost"` // 标准计费
|
||||
|
||||
@@ -1114,6 +1114,7 @@ func (r *usageLogRepository) GetUserUsageTrend(ctx context.Context, startTime, e
|
||||
TO_CHAR(u.created_at, '%s') as date,
|
||||
u.user_id,
|
||||
COALESCE(us.email, '') as email,
|
||||
COALESCE(us.username, '') as username,
|
||||
COUNT(*) as requests,
|
||||
COALESCE(SUM(u.input_tokens + u.output_tokens + u.cache_creation_tokens + u.cache_read_tokens), 0) as tokens,
|
||||
COALESCE(SUM(u.total_cost), 0) as cost,
|
||||
@@ -1122,7 +1123,7 @@ func (r *usageLogRepository) GetUserUsageTrend(ctx context.Context, startTime, e
|
||||
LEFT JOIN users us ON u.user_id = us.id
|
||||
WHERE u.user_id IN (SELECT user_id FROM top_users)
|
||||
AND u.created_at >= $4 AND u.created_at < $5
|
||||
GROUP BY date, u.user_id, us.email
|
||||
GROUP BY date, u.user_id, us.email, us.username
|
||||
ORDER BY date ASC, tokens DESC
|
||||
`, dateFormat)
|
||||
|
||||
@@ -1142,7 +1143,7 @@ func (r *usageLogRepository) GetUserUsageTrend(ctx context.Context, startTime, e
|
||||
results = make([]UserUsageTrendPoint, 0)
|
||||
for rows.Next() {
|
||||
var row UserUsageTrendPoint
|
||||
if err = rows.Scan(&row.Date, &row.UserID, &row.Email, &row.Requests, &row.Tokens, &row.Cost, &row.ActualCost); err != nil {
|
||||
if err = rows.Scan(&row.Date, &row.UserID, &row.Email, &row.Username, &row.Requests, &row.Tokens, &row.Cost, &row.ActualCost); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = append(results, row)
|
||||
|
||||
@@ -1155,6 +1155,7 @@ export interface UserUsageTrendPoint {
|
||||
date: string
|
||||
user_id: number
|
||||
email: string
|
||||
username: string
|
||||
requests: number
|
||||
tokens: number
|
||||
cost: number // 标准计费
|
||||
|
||||
@@ -415,23 +415,29 @@ const lineOptions = computed(() => ({
|
||||
const userTrendChartData = computed(() => {
|
||||
if (!userTrend.value?.length) return null
|
||||
|
||||
// Extract display name from email (part before @)
|
||||
const getDisplayName = (email: string, userId: number): string => {
|
||||
if (email && email.includes('@')) {
|
||||
return email.split('@')[0]
|
||||
const getDisplayName = (point: UserUsageTrendPoint): string => {
|
||||
const username = point.username?.trim()
|
||||
if (username) {
|
||||
return username
|
||||
}
|
||||
return t('admin.redeem.userPrefix', { id: userId })
|
||||
|
||||
const email = point.email?.trim()
|
||||
if (email) {
|
||||
return email
|
||||
}
|
||||
|
||||
return t('admin.redeem.userPrefix', { id: point.user_id })
|
||||
}
|
||||
|
||||
// Group by user
|
||||
const userGroups = new Map<string, { name: string; data: Map<string, number> }>()
|
||||
// Group by user_id to avoid merging different users with the same display name
|
||||
const userGroups = new Map<number, { name: string; data: Map<string, number> }>()
|
||||
const allDates = new Set<string>()
|
||||
|
||||
userTrend.value.forEach((point) => {
|
||||
allDates.add(point.date)
|
||||
const key = getDisplayName(point.email, point.user_id)
|
||||
const key = point.user_id
|
||||
if (!userGroups.has(key)) {
|
||||
userGroups.set(key, { name: key, data: new Map() })
|
||||
userGroups.set(key, { name: getDisplayName(point), data: new Map() })
|
||||
}
|
||||
userGroups.get(key)!.data.set(point.date, point.tokens)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user