From 52068279c6a0f52e7659c2b7fd1c959b1a2f884d Mon Sep 17 00:00:00 2001 From: engigu Date: Thu, 25 Dec 2025 20:28:20 +0800 Subject: [PATCH] feat: opt page style --- internal/controllers/dashboard_controller.go | 30 +- internal/utils/pagination.go | 5 + web/src/api/index.ts | 4 +- web/src/components/ui/button/index.ts | 2 +- .../components/ui/dialog/DialogContent.vue | 2 +- .../ui/dialog/DialogScrollContent.vue | 4 +- web/src/views/dashboard/Dashboard.vue | 64 ++- web/src/views/history/History.vue | 70 ++- web/src/views/tasks/RepoDialog.vue | 228 +++++++++ web/src/views/tasks/TaskDialog.vue | 231 +++++++++ web/src/views/tasks/Tasks.vue | 462 ++---------------- 11 files changed, 634 insertions(+), 468 deletions(-) create mode 100644 web/src/views/tasks/RepoDialog.vue create mode 100644 web/src/views/tasks/TaskDialog.vue diff --git a/internal/controllers/dashboard_controller.go b/internal/controllers/dashboard_controller.go index d05d458..e5b2069 100644 --- a/internal/controllers/dashboard_controller.go +++ b/internal/controllers/dashboard_controller.go @@ -72,11 +72,19 @@ type DailyStats struct { Failed int `json:"failed"` } -// GetSendStats 获取最近30天发送统计 +// GetSendStats 获取发送统计 func (dc *DashboardController) GetSendStats(c *gin.Context) { - // 获取最近30天的日期范围 + // 获取天数参数,默认30天 + days := 30 + if d := c.Query("days"); d != "" { + if parsed, err := utils.ParseInt(d); err == nil && parsed > 0 && parsed <= 90 { + days = parsed + } + } + + // 获取日期范围 now := time.Now() - startDay := now.AddDate(0, 0, -29).Format("2006-01-02") + startDay := now.AddDate(0, 0, -(days - 1)).Format("2006-01-02") var stats []models.SendStats database.DB.Where("day >= ?", startDay).Find(&stats) @@ -97,8 +105,8 @@ func (dc *DashboardController) GetSendStats(c *gin.Context) { } // 填充缺失的日期 - result := make([]DailyStats, 0, 30) - for i := 29; i >= 0; i-- { + result := make([]DailyStats, 0, days) + for i := days - 1; i >= 0; i-- { day := now.AddDate(0, 0, -i).Format("2006-01-02") if ds, ok := dayMap[day]; ok { result = append(result, *ds) @@ -122,10 +130,18 @@ type TaskStats struct { Count int `json:"count"` } -// GetTaskStats 获取最近30天任务执行占比 +// GetTaskStats 获取任务执行占比 func (dc *DashboardController) GetTaskStats(c *gin.Context) { + // 获取天数参数,默认30天 + days := 30 + if d := c.Query("days"); d != "" { + if parsed, err := utils.ParseInt(d); err == nil && parsed > 0 && parsed <= 90 { + days = parsed + } + } + now := time.Now() - startDay := now.AddDate(0, 0, -29).Format("2006-01-02") + startDay := now.AddDate(0, 0, -(days - 1)).Format("2006-01-02") // 按 task_id 聚合统计 var results []struct { diff --git a/internal/utils/pagination.go b/internal/utils/pagination.go index 188de3d..3a76358 100644 --- a/internal/utils/pagination.go +++ b/internal/utils/pagination.go @@ -9,6 +9,11 @@ import ( "github.com/gin-gonic/gin" ) +// ParseInt 解析字符串为整数 +func ParseInt(s string) (int, error) { + return strconv.Atoi(s) +} + // Pagination 分页参数 type Pagination struct { Page int diff --git a/web/src/api/index.ts b/web/src/api/index.ts index 46436d1..94ff8d1 100644 --- a/web/src/api/index.ts +++ b/web/src/api/index.ts @@ -104,8 +104,8 @@ export const api = { dashboard: { stats: () => request('/stats'), sentence: () => request<{ sentence: string }>('/sentence'), - sendStats: () => request('/sendstats'), - taskStats: () => request('/taskstats') + sendStats: (days?: number) => request(`/sendstats${days ? `?days=${days}` : ''}`), + taskStats: (days?: number) => request(`/taskstats${days ? `?days=${days}` : ''}`) }, settings: { changePassword: (data: { old_password: string; new_password: string }) => diff --git a/web/src/components/ui/button/index.ts b/web/src/components/ui/button/index.ts index 26e2c55..350505f 100644 --- a/web/src/components/ui/button/index.ts +++ b/web/src/components/ui/button/index.ts @@ -17,7 +17,7 @@ export const buttonVariants = cva( secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: - "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 active:scale-90 active:bg-primary/20 dark:active:bg-primary/30", link: "text-primary underline-offset-4 hover:underline", }, size: { diff --git a/web/src/components/ui/dialog/DialogContent.vue b/web/src/components/ui/dialog/DialogContent.vue index 7f86b47..99dae59 100644 --- a/web/src/components/ui/dialog/DialogContent.vue +++ b/web/src/components/ui/dialog/DialogContent.vue @@ -34,7 +34,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits) v-bind="{ ...$attrs, ...forwarded }" :class=" cn( - 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg', + 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] max-h-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg overflow-y-auto custom-scrollbar', props.class, )" > diff --git a/web/src/components/ui/dialog/DialogScrollContent.vue b/web/src/components/ui/dialog/DialogScrollContent.vue index f2475db..59caa3e 100644 --- a/web/src/components/ui/dialog/DialogScrollContent.vue +++ b/web/src/components/ui/dialog/DialogScrollContent.vue @@ -27,12 +27,12 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)