feat: add log page status filter

This commit is contained in:
engigu
2026-02-28 08:40:14 +08:00
parent 22e3e89ba0
commit dd8a887399
4 changed files with 43 additions and 8 deletions
+4
View File
@@ -21,6 +21,7 @@ func (lc *LogController) GetLogs(c *gin.Context) {
p := utils.ParsePagination(c) p := utils.ParsePagination(c)
taskID, _ := strconv.Atoi(c.DefaultQuery("task_id", "0")) taskID, _ := strconv.Atoi(c.DefaultQuery("task_id", "0"))
taskName := c.DefaultQuery("task_name", "") taskName := c.DefaultQuery("task_name", "")
status := c.DefaultQuery("status", "")
var logs []models.TaskLog var logs []models.TaskLog
var total int64 var total int64
@@ -29,6 +30,9 @@ func (lc *LogController) GetLogs(c *gin.Context) {
if taskID > 0 { if taskID > 0 {
query = query.Where("task_id = ?", taskID) query = query.Where("task_id = ?", taskID)
} }
if status != "" {
query = query.Where("status = ?", status)
}
// 按任务名称过滤 // 按任务名称过滤
if taskName != "" { if taskName != "" {
+2 -1
View File
@@ -98,12 +98,13 @@ export const api = {
results: () => request('/execute/results') results: () => request('/execute/results')
}, },
logs: { logs: {
list: (params?: { page?: number; page_size?: number; task_id?: number; task_name?: string }) => { list: (params?: { page?: number; page_size?: number; task_id?: number; task_name?: string; status?: string }) => {
const query = new URLSearchParams() const query = new URLSearchParams()
if (params?.page) query.set('page', String(params.page)) if (params?.page) query.set('page', String(params.page))
if (params?.page_size) query.set('page_size', String(params.page_size)) if (params?.page_size) query.set('page_size', String(params.page_size))
if (params?.task_id) query.set('task_id', String(params.task_id)) if (params?.task_id) query.set('task_id', String(params.task_id))
if (params?.task_name) query.set('task_name', params.task_name) if (params?.task_name) query.set('task_name', params.task_name)
if (params?.status) query.set('status', params.status)
return request<LogListResponse>(`/logs?${query}`) return request<LogListResponse>(`/logs?${query}`)
}, },
get: (id: number) => request<LogDetail>(`/logs/${id}`), get: (id: number) => request<LogDetail>(`/logs/${id}`),
+1 -1
View File
@@ -27,7 +27,7 @@ const statItems = [
{ key: 'envs', label: '环境变量', icon: Variable, route: '/environments' }, { key: 'envs', label: '环境变量', icon: Variable, route: '/environments' },
{ key: 'logs', label: '日志总数', icon: ScrollText, route: '/history' }, { key: 'logs', label: '日志总数', icon: ScrollText, route: '/history' },
{ key: 'scheduled', label: '调度注册', icon: Clock, route: '/tasks' }, { key: 'scheduled', label: '调度注册', icon: Clock, route: '/tasks' },
{ key: 'running', label: '正在运行', icon: Play, route: '/tasks' }, { key: 'running', label: '正在运行', icon: Play, route: '/history?status=running' },
] ]
const isDark = ref(document.documentElement.classList.contains('dark')) const isDark = ref(document.documentElement.classList.contains('dark'))
+36 -6
View File
@@ -5,6 +5,7 @@ import { TASK_STATUS, TASK_TYPE } from '@/constants'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input' import { Input } from '@/components/ui/input'
import Pagination from '@/components/Pagination.vue' import Pagination from '@/components/Pagination.vue'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import LogViewer from './LogViewer.vue' import LogViewer from './LogViewer.vue'
import { import {
RefreshCw, X, Search, Maximize2, GitBranch, Terminal, RefreshCw, X, Search, Maximize2, GitBranch, Terminal,
@@ -33,6 +34,7 @@ const logs = ref<TaskLog[]>([])
const selectedLog = ref<TaskLog | null>(null) const selectedLog = ref<TaskLog | null>(null)
const filterKeyword = ref('') const filterKeyword = ref('')
const filterTaskId = ref<number | undefined>(undefined) const filterTaskId = ref<number | undefined>(undefined)
const filterStatus = ref<string | undefined>(undefined)
const currentPage = ref(1) const currentPage = ref(1)
const total = ref(0) const total = ref(0)
@@ -60,7 +62,7 @@ const decompressedOutput = computed(() => {
async function loadLogs() { async function loadLogs() {
try { try {
const params: { page: number; page_size: number; task_id?: number; task_name?: string } = { const params: { page: number; page_size: number; task_id?: number; task_name?: string; status?: string } = {
page: currentPage.value, page: currentPage.value,
page_size: pageSize.value page_size: pageSize.value
} }
@@ -70,6 +72,9 @@ async function loadLogs() {
if (filterKeyword.value.trim()) { if (filterKeyword.value.trim()) {
params.task_name = filterKeyword.value.trim() params.task_name = filterKeyword.value.trim()
} }
if (filterStatus.value && filterStatus.value !== 'all') {
params.status = filterStatus.value
}
const response = await api.logs.list(params) const response = await api.logs.list(params)
logs.value = response.data logs.value = response.data
total.value = response.total total.value = response.total
@@ -86,6 +91,11 @@ function handleSearch() {
}, 300) }, 300)
} }
function handleStatusChange() {
currentPage.value = 1
loadLogs()
}
function handlePageChange(page: number) { function handlePageChange(page: number) {
currentPage.value = page currentPage.value = page
loadLogs() loadLogs()
@@ -278,20 +288,25 @@ function getTaskTypeTitle(type: string) {
} }
onMounted(() => { onMounted(() => {
// 从 URL 读取 task_id 参数 // 从 URL 读取参数
const taskIdParam = route.query.task_id const taskIdParam = route.query.task_id
if (taskIdParam) { if (taskIdParam) {
filterTaskId.value = Number(taskIdParam) filterTaskId.value = Number(taskIdParam)
} }
const statusParam = route.query.status
if (statusParam) {
filterStatus.value = String(statusParam)
}
loadLogs() loadLogs()
}) })
// 监听路由变化 // 监听路由变化
watch(() => route.query.task_id, (newTaskId) => { watch(() => route.query, (newQuery) => {
filterTaskId.value = newTaskId ? Number(newTaskId) : undefined filterTaskId.value = newQuery.task_id ? Number(newQuery.task_id) : undefined
filterStatus.value = newQuery.status ? String(newQuery.status) : undefined
currentPage.value = 1 currentPage.value = 1
loadLogs() loadLogs()
}) }, { deep: true })
</script> </script>
<template> <template>
@@ -304,9 +319,24 @@ watch(() => route.query.task_id, (newTaskId) => {
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<div class="relative flex-1 sm:flex-none"> <div class="relative flex-1 sm:flex-none">
<Search class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" /> <Search class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
<Input v-model="filterKeyword" placeholder="搜索任务..." class="h-9 pl-9 w-full sm:w-56 text-sm" <Input v-model="filterKeyword" placeholder="搜索任务..." class="h-9 pl-9 w-full sm:w-40 md:w-56 text-sm"
@input="handleSearch" /> @input="handleSearch" />
</div> </div>
<div class="relative flex-1 sm:flex-none">
<Select v-model="filterStatus" @update:model-value="handleStatusChange">
<SelectTrigger class="h-9 w-full sm:w-28 text-sm">
<SelectValue placeholder="状态" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">所有状态</SelectItem>
<SelectItem value="running">正在运行</SelectItem>
<SelectItem value="success">成功</SelectItem>
<SelectItem value="failed">失败</SelectItem>
<SelectItem value="timeout">超时</SelectItem>
<SelectItem value="cancelled">取消</SelectItem>
</SelectContent>
</Select>
</div>
<Button variant="outline" size="icon" class="h-9 w-9 shrink-0" @click="loadLogs" title="刷新"> <Button variant="outline" size="icon" class="h-9 w-9 shrink-0" @click="loadLogs" title="刷新">
<RefreshCw class="h-4 w-4" /> <RefreshCw class="h-4 w-4" />
</Button> </Button>