| | |
| | | /> |
| | | |
| | | <ElCard class="art-table-card"> |
| | | <ArtTableHeader v-model:columns="columnChecks" :loading="loading" @refresh="loadPageData" /> |
| | | <ArtTableHeader v-model:columns="columnChecks" :loading="loading" @refresh="loadPageData"> |
| | | <template #left> |
| | | <ElSpace wrap> |
| | | <ElButton |
| | | v-if="!autoRunEnabled" |
| | | type="primary" |
| | | plain |
| | | :loading="autoRunLoading" |
| | | @click="handleToggleAutoRun(true)" |
| | | > |
| | | 自动下发任务 |
| | | </ElButton> |
| | | <ElButton |
| | | v-else |
| | | type="warning" |
| | | plain |
| | | :loading="autoRunLoading" |
| | | @click="handleToggleAutoRun(false)" |
| | | > |
| | | 暂停自动下发 |
| | | </ElButton> |
| | | </ElSpace> |
| | | </template> |
| | | </ArtTableHeader> |
| | | |
| | | <ArtTable |
| | | :loading="loading" |
| | |
| | | /> |
| | | </ElCard> |
| | | |
| | | <TaskFlowStepDialog |
| | | v-model:visible="flowStepDialogVisible" |
| | | :task-row="activeTaskRow" |
| | | /> |
| | | |
| | | <TaskDetailDrawer |
| | | v-model:visible="detailDrawerVisible" |
| | | :loading="detailLoading" |
| | |
| | | @refresh="loadDetailResources" |
| | | @size-change="handleDetailSizeChange" |
| | | @current-change="handleDetailCurrentChange" |
| | | @flow-step="handleOpenFlowStepFromDetail" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ElMessage } from 'element-plus' |
| | | import { computed, onMounted, reactive, ref } from 'vue' |
| | | import { computed, h, onMounted, onUnmounted, reactive, ref } from 'vue' |
| | | import { useTableColumns } from '@/hooks/core/useTableColumns' |
| | | import { guardRequestWithMessage } from '@/utils/sys/requestGuard' |
| | | import { |
| | |
| | | fetchCompleteTask, |
| | | fetchPickTask, |
| | | fetchRemoveTask, |
| | | fetchTaskDetail, |
| | | fetchTaskAutoRunFlag, |
| | | fetchTaskItemPage, |
| | | fetchTaskPage, |
| | | fetchTopTask |
| | | fetchTopTask, |
| | | fetchUpdateTaskAutoRunFlag |
| | | } from '@/api/task' |
| | | import TaskDetailDrawer from './modules/task-detail-drawer.vue' |
| | | import TaskExpandPanel from './modules/task-expand-panel.vue' |
| | | import TaskFlowStepDialog from './modules/task-flow-step-dialog.vue' |
| | | import { createTaskTableColumns } from './taskTable.columns' |
| | | import { |
| | | buildTaskPageQueryParams, |
| | |
| | | const detailData = ref({}) |
| | | const detailTableData = ref([]) |
| | | const activeTaskRow = ref(null) |
| | | const flowStepDialogVisible = ref(false) |
| | | const autoRunEnabled = ref(false) |
| | | const autoRunLoading = ref(false) |
| | | let refreshTimer = null |
| | | |
| | | const pagination = reactive({ |
| | | current: 1, |
| | |
| | | |
| | | async function openDetailDrawer(row) { |
| | | activeTaskRow.value = row |
| | | detailData.value = normalizeTaskRow(row) |
| | | detailPagination.current = 1 |
| | | detailDrawerVisible.value = true |
| | | await loadDetailResources() |
| | | } |
| | | |
| | | function handleOpenFlowStepFromDetail() { |
| | | if (!activeTaskRow.value) { |
| | | return |
| | | } |
| | | flowStepDialogVisible.value = true |
| | | } |
| | | |
| | | async function handleActionClick(action, row) { |
| | | try { |
| | | if (action.key === 'view') { |
| | | await openDetailDrawer(row) |
| | | return |
| | | } |
| | | |
| | | if (action.key === 'flowStep') { |
| | | activeTaskRow.value = row |
| | | flowStepDialogVisible.value = true |
| | | return |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | const { columns, columnChecks } = useTableColumns(() => createTaskTableColumns(handleActionClick)) |
| | | const { columns, columnChecks } = useTableColumns(() => |
| | | createTaskTableColumns({ |
| | | handleActionClick, |
| | | createExpandContent: (row) => ({ |
| | | name: 'TaskExpandPanelHost', |
| | | render() { |
| | | return h(TaskExpandPanel, { row }) |
| | | } |
| | | }) |
| | | }) |
| | | ) |
| | | |
| | | function updatePaginationState(target, response, fallbackCurrent, fallbackSize) { |
| | | target.total = Number(response?.total || 0) |
| | |
| | | } |
| | | } |
| | | |
| | | async function loadAutoRunConfig() { |
| | | autoRunLoading.value = true |
| | | try { |
| | | const response = await guardRequestWithMessage(fetchTaskAutoRunFlag(), { val: false }, { |
| | | timeoutMessage: '自动下发配置加载超时,已停止等待' |
| | | }) |
| | | const rawValue = response?.val |
| | | autoRunEnabled.value = |
| | | rawValue === true || rawValue === 'true' || rawValue === 1 || rawValue === '1' |
| | | } finally { |
| | | autoRunLoading.value = false |
| | | } |
| | | } |
| | | |
| | | async function handleToggleAutoRun(enabled) { |
| | | autoRunLoading.value = true |
| | | try { |
| | | await fetchUpdateTaskAutoRunFlag(enabled) |
| | | autoRunEnabled.value = enabled |
| | | ElMessage.success(enabled ? '已开启自动下发任务' : '已暂停自动下发任务') |
| | | } catch (error) { |
| | | ElMessage.error(error?.message || '自动下发配置更新失败') |
| | | } finally { |
| | | autoRunLoading.value = false |
| | | } |
| | | } |
| | | |
| | | async function loadDetailResources() { |
| | | if (!activeTaskRow.value?.id) { |
| | | return |
| | |
| | | |
| | | detailLoading.value = true |
| | | try { |
| | | const [detailResponse, taskItemResponse] = await Promise.all([ |
| | | guardRequestWithMessage(fetchTaskDetail(activeTaskRow.value.id), {}, { |
| | | timeoutMessage: '任务详情加载超时,已停止等待' |
| | | const taskItemResponse = await guardRequestWithMessage( |
| | | fetchTaskItemPage({ |
| | | taskId: activeTaskRow.value.id, |
| | | current: detailPagination.current, |
| | | pageSize: detailPagination.size |
| | | }), |
| | | guardRequestWithMessage( |
| | | fetchTaskItemPage({ |
| | | taskId: activeTaskRow.value.id, |
| | | current: detailPagination.current, |
| | | pageSize: detailPagination.size |
| | | }), |
| | | { |
| | | records: [], |
| | | total: 0, |
| | | current: detailPagination.current, |
| | | size: detailPagination.size |
| | | }, |
| | | { timeoutMessage: '任务明细加载超时,已停止等待' } |
| | | ) |
| | | ]) |
| | | { |
| | | records: [], |
| | | total: 0, |
| | | current: detailPagination.current, |
| | | size: detailPagination.size |
| | | }, |
| | | { timeoutMessage: '任务明细加载超时,已停止等待' } |
| | | ) |
| | | |
| | | detailData.value = normalizeTaskRow(detailResponse) |
| | | detailData.value = normalizeTaskRow(activeTaskRow.value) |
| | | detailTableData.value = Array.isArray(taskItemResponse?.records) |
| | | ? taskItemResponse.records.map((record) => normalizeTaskItemRow(record)) |
| | | : [] |
| | | updatePaginationState(detailPagination, taskItemResponse, detailPagination.current, detailPagination.size) |
| | | } catch (error) { |
| | | detailTableData.value = [] |
| | | ElMessage.error(error?.message || '任务明细加载失败') |
| | | } finally { |
| | | detailLoading.value = false |
| | | } |
| | |
| | | loadDetailResources() |
| | | } |
| | | |
| | | onMounted(loadPageData) |
| | | function startAutoRefresh() { |
| | | clearAutoRefresh() |
| | | refreshTimer = window.setInterval(() => { |
| | | void loadPageData() |
| | | }, 5000) |
| | | } |
| | | |
| | | function clearAutoRefresh() { |
| | | if (refreshTimer) { |
| | | window.clearInterval(refreshTimer) |
| | | refreshTimer = null |
| | | } |
| | | } |
| | | |
| | | onMounted(async () => { |
| | | await Promise.all([loadPageData(), loadAutoRunConfig()]) |
| | | startAutoRefresh() |
| | | }) |
| | | |
| | | onUnmounted(() => { |
| | | clearAutoRefresh() |
| | | }) |
| | | </script> |