fix(dashboard): 修复用户统计错误

This commit is contained in:
yokowu
2025-07-04 12:21:17 +08:00
parent 380bd73aea
commit 40b76e8e05
4 changed files with 28 additions and 15 deletions

View File

@@ -615,7 +615,7 @@
},
{
"type": "string",
"description": "用户IDjj",
"description": "用户ID选参数",
"name": "user_id",
"in": "query"
}
@@ -716,7 +716,7 @@
},
{
"type": "string",
"description": "用户IDjj",
"description": "用户ID选参数",
"name": "user_id",
"in": "query"
}
@@ -781,7 +781,7 @@
},
{
"type": "string",
"description": "用户IDjj",
"description": "用户ID选参数",
"name": "user_id",
"in": "query"
}
@@ -849,7 +849,7 @@
},
{
"type": "string",
"description": "用户IDjj",
"description": "用户ID选参数",
"name": "user_id",
"in": "query"
}
@@ -962,7 +962,7 @@
},
{
"type": "string",
"description": "用户IDjj",
"description": "用户ID选参数",
"name": "user_id",
"in": "query"
}

View File

@@ -35,7 +35,7 @@ type Statistics struct {
type StatisticsFilter struct {
Precision string `json:"precision" query:"precision" validate:"required,oneof=hour day" default:"day"` // 精度: "hour", "day"
Duration int `json:"duration" query:"duration" validate:"gte=24,lte=90" default:"90"` // 持续时间 (小时或天数)`
UserID string `json:"user_id,omitempty" query:"user_id"` // 用户IDjj
UserID string `json:"user_id,omitempty" query:"user_id"` // 用户ID选参数
}
func (s StatisticsFilter) StartTime() time.Time {

View File

@@ -24,7 +24,7 @@ func NewDashboardHandler(
g.GET("/category-stat", web.BindHandler(h.CategoryStat))
g.GET("/time-stat", web.BindHandler(h.TimeStat))
g.GET("/user-stat", web.BindHandler(h.UserStat))
g.GET("/user-events", web.BindHandler(h.UserEvents))
g.GET("/user-events", web.BaseHandler(h.UserEvents))
g.GET("/user-code-rank", web.BindHandler(h.UserCodeRank))
g.GET("/user-heatmap", web.BaseHandler(h.UserHeatmap))
@@ -117,8 +117,12 @@ func (h *DashboardHandler) UserStat(c *web.Context, req domain.StatisticsFilter)
// @Param filter query domain.StatisticsFilter true "筛选参数"
// @Success 200 {object} web.Resp{data=[]domain.UserEvent}
// @Router /api/v1/dashboard/user-events [get]
func (h *DashboardHandler) UserEvents(c *web.Context, req domain.StatisticsFilter) error {
userEvents, err := h.usecase.UserEvents(c.Request().Context(), req)
func (h *DashboardHandler) UserEvents(c *web.Context) error {
userEvents, err := h.usecase.UserEvents(c.Request().Context(), domain.StatisticsFilter{
Precision: "day",
Duration: 90,
UserID: c.QueryParam("user_id"),
})
if err != nil {
return err
}

View File

@@ -219,6 +219,8 @@ func (d *DashboardRepo) UserEvents(ctx context.Context, req domain.StatisticsFil
}
rs, err := d.db.Task.Query().
WithUser().
WithTaskRecords().
Where(task.ModelType(consts.ModelTypeLLM)).
Where(task.CreatedAtGTE(req.StartTime())).
Where(task.HasUserWith(user.ID(id))).
Order(task.ByCreatedAt(sql.OrderDesc())).
@@ -228,11 +230,18 @@ func (d *DashboardRepo) UserEvents(ctx context.Context, req domain.StatisticsFil
return nil, err
}
return cvt.Iter(rs, func(_ int, v *db.Task) *domain.UserEvent {
return &domain.UserEvent{
Name: v.Edges.User.Username,
CreatedAt: v.CreatedAt.Unix(),
return cvt.Filter(rs, func(_ int, v *db.Task) (*domain.UserEvent, bool) {
name := ""
for _, r := range v.Edges.TaskRecords {
if r.Role == consts.ChatRoleUser {
name = r.Prompt
break
}
}
return &domain.UserEvent{
Name: name,
CreatedAt: v.CreatedAt.Unix(),
}, name != ""
}), nil
}
@@ -265,7 +274,7 @@ func (d *DashboardRepo) UserStat(ctx context.Context, req domain.StatisticsFilte
if err := d.db.Task.Query().
Where(task.CreatedAtGTE(req.StartTime())).
Where(task.HasUserWith(user.ID(id))).
Where(task.WorkModeNotNil()).
Where(task.WorkModeNEQ("")).
Modify(func(s *sql.Selector) {
s.Select(
sql.As("work_mode", "category"),
@@ -280,7 +289,7 @@ func (d *DashboardRepo) UserStat(ctx context.Context, req domain.StatisticsFilte
if err := d.db.Task.Query().
Where(task.CreatedAtGTE(req.StartTime())).
Where(task.HasUserWith(user.ID(id))).
Where(task.ProgramLanguageNotNil()).
Where(task.ProgramLanguageNEQ("")).
Modify(func(s *sql.Selector) {
s.Select(
sql.As("program_language", "category"),