update: task items添加过滤

This commit is contained in:
Kerwin
2025-08-11 17:51:04 +08:00
parent b567531a7d
commit 25c7c47c96
7 changed files with 96 additions and 46 deletions

View File

@@ -314,10 +314,10 @@ func (r *ResourceRepositoryImpl) SearchWithFilters(params map[string]interface{}
if pageSizeVal, ok := params["page_size"].(int); ok && pageSizeVal > 0 {
pageSize = pageSizeVal
fmt.Printf("原始pageSize: %d\n", pageSize)
// 限制最大page_size为1000
if pageSize > 1000 {
pageSize = 1000
fmt.Printf("pageSize超过1000限制为: %d\n", pageSize)
// 限制最大page_size为10000管理后台需要更大的数据量
if pageSize > 10000 {
pageSize = 10000
fmt.Printf("pageSize超过10000,限制为: %d\n", pageSize)
}
fmt.Printf("最终pageSize: %d\n", pageSize)
}

View File

@@ -280,7 +280,7 @@ func (h *TaskHandler) GetTaskItems(c *gin.Context) {
}
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10000"))
status := c.Query("status")
items, total, err := h.repoMgr.TaskItemRepository.GetListByTaskID(uint(taskID), page, pageSize, status)

View File

@@ -16,7 +16,7 @@
placeholder="请输入资源内容格式标题和URL为一组..."
:autosize="{ minRows: 10, maxRows: 15 }"
show-count
:maxlength="10000"
:maxlength="100000"
/>
</div>
</div>

View File

@@ -48,6 +48,7 @@
@update:page="handlePageChange"
@update:page-size="handlePageSizeChange"
:row-key="(row: any) => row.id"
virtual-scroll
max-height="500"
/>
</div>
@@ -66,7 +67,7 @@ const loading = ref(false)
const resources = ref<any[]>([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(20)
const pageSize = ref(10000)
// 搜索条件
const searchQuery = ref('')
@@ -79,9 +80,9 @@ const resourceApi = useResourceApi()
// 分页配置
const pagination = reactive({
page: 1,
pageSize: 20,
pageSize: 10000,
itemCount: 0,
pageSizes: [10, 20, 50, 100],
pageSizes: [10000, 20000, 50000, 100000],
showSizePicker: true,
showQuickJumper: true,
prefix: ({ itemCount }: any) => `${itemCount}`

View File

@@ -201,7 +201,7 @@
v-model:page="currentPage"
v-model:page-size="pageSize"
:item-count="total"
:page-sizes="[20, 50, 100, 200]"
:page-sizes="[10000, 20000, 50000, 100000]"
show-size-picker
show-quick-jumper
@update:page="handlePageChange"
@@ -259,7 +259,7 @@ const loading = ref(false)
const resources = ref([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(20)
const pageSize = ref(10000)
// 搜索条件
const searchQuery = ref('')

View File

@@ -26,28 +26,6 @@ export const parseApiResponse = <T>(response: any): T => {
// 检查是否是包含success字段的响应格式如登录接口
if (response && typeof response === 'object' && 'success' in response && 'data' in response) {
if (response.success) {
// 特殊处理资源接口返回的data格式转换为resources格式
if (response.data && Array.isArray(response.data) && response.total !== undefined) {
return {
resources: response.data,
total: response.total,
page: response.page,
page_size: response.page_size
} as T
}
// 特殊处理资源接口返回的data.list格式转换为resources格式
if (response.data && response.data.list && Array.isArray(response.data.list)) {
return {
resources: response.data.list,
total: response.data.total,
page: response.data.page,
page_size: response.data.limit
} as T
}
// 特殊处理失败资源接口返回完整的data结构
if (response.data && response.data.data && Array.isArray(response.data.data) && response.data.total !== undefined) {
return response.data
}
// 特殊处理登录接口直接返回data部分包含token和user
if (response.data && response.data.token && response.data.user) {
console.log('parseApiResponse - 登录接口处理返回data:', response.data)

View File

@@ -160,8 +160,22 @@
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm">
<div class="p-3 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
<h2 class="text-base font-semibold text-gray-900 dark:text-white">任务项列表</h2>
<div class="flex items-center space-x-3">
<!-- 状态过滤 -->
<div class="flex items-center space-x-2">
<span class="text-sm text-gray-500 dark:text-gray-400">状态:</span>
<n-select
v-model:value="statusFilter"
:options="statusOptions"
placeholder="全部状态"
size="small"
style="width: 120px"
@update:value="onStatusFilterChange"
/>
</div>
<span class="text-sm text-gray-500 dark:text-gray-400"> {{ total }} </span>
</div>
</div>
<div class="overflow-x-auto">
<n-data-table
@@ -171,7 +185,10 @@
:pagination="itemsPaginationConfig"
size="small"
:scroll-x="600"
virtual-scroll
:max-height="400"
:bordered="false"
:empty="emptyConfig"
/>
</div>
</div>
@@ -198,23 +215,35 @@ const message = useMessage()
const dialog = useDialog()
// 数据状态
const task = ref(null)
const taskItems = ref([])
const task = ref<any>(null)
const taskItems = ref<any[]>([])
const loading = ref(false)
const itemsLoading = ref(false)
const actionLoading = ref(false)
// 分页配置
const currentPage = ref(1)
const pageSize = ref(20)
const pageSize = ref(10000)
const total = ref(0)
// 状态过滤
const statusFilter = ref('')
// 状态选项
const statusOptions = [
{ label: '全部状态', value: '' },
{ label: '待处理', value: 'pending' },
{ label: '处理中', value: 'processing' },
{ label: '已完成', value: 'completed' },
{ label: '失败', value: 'failed' }
]
const itemsPaginationConfig = computed(() => ({
page: currentPage.value,
pageSize: pageSize.value,
itemCount: total.value,
showSizePicker: true,
pageSizes: [10, 20, 50, 100],
pageSizes: [1000, 5000, 10000, 20000],
onChange: (page: number) => {
currentPage.value = page
fetchTaskItems()
@@ -325,27 +354,49 @@ const fetchTaskItems = async () => {
const { useTaskApi } = await import('~/composables/useApi')
const taskApi = useTaskApi()
const params = {
const params: any = {
page: currentPage.value,
page_size: pageSize.value
}
// 添加状态过滤
if (statusFilter.value && statusFilter.value !== '') {
params.status = statusFilter.value
}
const response = await taskApi.getTaskItems(parseInt(route.params.id as string), params) as any
// 正确处理API响应包括items为null的情况
if (response && response.items) {
taskItems.value = response.items
taskItems.value = response.items || []
total.value = response.total || 0
} else {
taskItems.value = []
total.value = 0
}
} catch (error) {
console.error('获取任务项列表失败:', error)
message.error('获取任务项列表失败')
// 发生错误时也要重置数据
taskItems.value = []
total.value = 0
} finally {
itemsLoading.value = false
}
}
// 状态过滤变化处理
const onStatusFilterChange = () => {
currentPage.value = 1
// 立即清空当前数据,避免显示旧数据
taskItems.value = []
total.value = 0
fetchTaskItems()
}
// 任务操作
const startTask = async () => {
if (!task.value) return
actionLoading.value = true
try {
const success = await taskStore.startTask(task.value.id)
@@ -364,6 +415,7 @@ const startTask = async () => {
}
const pauseTask = async () => {
if (!task.value) return
actionLoading.value = true
try {
const success = await taskStore.pauseTask(task.value.id)
@@ -382,6 +434,7 @@ const pauseTask = async () => {
}
const resumeTask = async () => {
if (!task.value) return
actionLoading.value = true
try {
const success = await taskStore.startTask(task.value.id)
@@ -400,6 +453,7 @@ const resumeTask = async () => {
}
const retryTask = async () => {
if (!task.value) return
actionLoading.value = true
try {
const success = await taskStore.startTask(task.value.id)
@@ -418,6 +472,7 @@ const retryTask = async () => {
}
const deleteTask = async () => {
if (!task.value) return
dialog.warning({
title: '确认删除',
content: '确定要删除这个任务吗?此操作不可恢复。',
@@ -426,7 +481,7 @@ const deleteTask = async () => {
onPositiveClick: async () => {
actionLoading.value = true
try {
const success = await taskStore.deleteTask(task.value.id)
const success = await taskStore.deleteTask(task.value!.id)
if (success) {
message.success('任务删除成功')
router.push('/admin/tasks')
@@ -451,9 +506,9 @@ const getTaskTypeText = (type: string) => {
return typeMap[type] || type
}
const getTaskTypeColor = (type: string) => {
const colorMap: Record<string, string> = {
transfer: 'blue'
const getTaskTypeColor = (type: string): 'error' | 'default' | 'primary' | 'info' | 'success' | 'warning' => {
const colorMap: Record<string, 'error' | 'default' | 'primary' | 'info' | 'success' | 'warning'> = {
transfer: 'primary'
}
return colorMap[type] || 'default'
}
@@ -469,8 +524,8 @@ const getTaskStatusText = (status: string) => {
return statusMap[status] || status
}
const getTaskStatusColor = (status: string) => {
const colorMap: Record<string, string> = {
const getTaskStatusColor = (status: string): 'error' | 'default' | 'primary' | 'info' | 'success' | 'warning' => {
const colorMap: Record<string, 'error' | 'default' | 'primary' | 'info' | 'success' | 'warning'> = {
pending: 'warning',
running: 'info',
completed: 'success',
@@ -484,6 +539,22 @@ const formatDate = (date: string) => {
return new Date(date).toLocaleString('zh-CN')
}
// 空状态配置
const emptyConfig = computed(() => ({
description: statusFilter.value ? `暂无${getTaskItemStatusText(statusFilter.value)}状态的任务项` : '暂无任务项记录'
}))
// 获取任务项状态文本
const getTaskItemStatusText = (status: string) => {
const statusMap: Record<string, string> = {
pending: '待处理',
processing: '处理中',
completed: '已完成',
failed: '失败'
}
return statusMap[status] || status
}
// 页面加载
onMounted(async () => {
await fetchTask()