mirror of
https://github.com/ctwj/urldb.git
synced 2025-11-25 19:37:33 +08:00
update: task items添加过滤
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
placeholder="请输入资源内容,格式:标题和URL为一组..."
|
||||
:autosize="{ minRows: 10, maxRows: 15 }"
|
||||
show-count
|
||||
:maxlength="10000"
|
||||
:maxlength="100000"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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} 条`
|
||||
|
||||
@@ -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('')
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user