From d3ea832b3b53d9b192de3c9e4cd9cc10c4b2a487 Mon Sep 17 00:00:00 2001 From: Yuzhiran Dev Date: Wed, 17 Jun 2026 20:10:56 +0800 Subject: [PATCH] feat: admin.html task management tab (TaskConfig + TaskLog timeline) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add 任务管理 tab button - Show all 7 task modules table with enable/disable switch, schedule, params - Edit dialog for schedule/params editing - Click module to show el-timeline of recent 30 run logs - View result data dialog - Supports toggleModule, saveTaskConfig, loadTaskLogs --- platform/frontend/admin.html | 201 +++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) diff --git a/platform/frontend/admin.html b/platform/frontend/admin.html index 1937f6e..f5f2357 100644 --- a/platform/frontend/admin.html +++ b/platform/frontend/admin.html @@ -35,6 +35,7 @@ 搜索排名 GEO 就绪度 配置管理 + 任务管理 @@ -816,6 +817,122 @@ + +
+
+ 定时任务配置与运行记录 — 共 {{ taskConfigs.length }} 个模块 +
+
加载中...
+ + + + +
{{ resultDialogContent }}
+ +
+
@@ -1465,6 +1582,85 @@ const llmConfigs = ref([]); const formatDate = (dateStr) => { if (!dateStr) return '-'; return new Date(dateStr.replace(' ', 'T')).toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); }; const logout = () => { localStorage.removeItem('authToken'); localStorage.removeItem('userRole'); localStorage.removeItem('currentUser'); window.location.href = '/login.html'; }; + const taskConfigs = ref([]); + const tcLoading = ref(false); + const selectedModule = ref(null); + const showHistory = ref(false); + const taskLogs = ref([]); + const tlLoading = ref(false); + + const loadTaskConfigs = async () => { + tcLoading.value = true; + try { + const data = await api.get('/api/admin/task-configs'); + taskConfigs.value = Array.isArray(data) ? data : (data.data || []); + } catch (e) { ElMessage.error('加载任务配置失败: ' + e.message); } + finally { tcLoading.value = false; } + }; + + const toggleModule = async (row, val) => { + try { + await api.put(`/api/admin/task-configs/${row.module_id}`, { enabled: val }); + row.enabled = val; + ElMessage.success(val ? '已启用' : '已停用'); + } catch (e) { ElMessage.error('操作失败: ' + e.message); } + }; + + const tcEditDialogVisible = ref(false); + const tcEditSaving = ref(false); + const tcEditForm = reactive({ module_id: '', enabled: true, schedule: '', paramsStr: '{}' }); + + const showEditConfig = (row) => { + tcEditForm.module_id = row.module_id; + tcEditForm.enabled = row.enabled; + tcEditForm.schedule = row.schedule || ''; + tcEditForm.paramsStr = row.params ? JSON.stringify(row.params, null, 2) : '{}'; + tcEditDialogVisible.value = true; + }; + + const saveTaskConfig = async () => { + tcEditSaving.value = true; + try { + let params; + try { params = JSON.parse(tcEditForm.paramsStr); } + catch (e) { ElMessage.warning('参数格式不是有效的 JSON'); tcEditSaving.value = false; return; } + await api.put(`/api/admin/task-configs/${tcEditForm.module_id}`, { + enabled: tcEditForm.enabled, + schedule: tcEditForm.schedule, + params: params, + }); + ElMessage.success('保存成功'); + tcEditDialogVisible.value = false; + await loadTaskConfigs(); + } catch (e) { ElMessage.error('保存失败: ' + e.message); } + finally { tcEditSaving.value = false; } + }; + + const selectModule = (row) => { + selectedModule.value = row; + showHistory.value = true; + loadTaskLogs(row); + }; + + const loadTaskLogs = async (row) => { + tlLoading.value = true; + try { + const data = await api.get(`/api/admin/task-configs/history/${row.module_id}?limit=30`); + taskLogs.value = Array.isArray(data) ? data : (data.data || []); + } catch (e) { ElMessage.error('加载运行记录失败: ' + e.message); taskLogs.value = []; } + finally { tlLoading.value = false; } + }; + + const resultDialogVisible = ref(false); + const resultDialogContent = ref(''); + const showResultData = (log) => { + try { + const d = typeof log.result_data === 'string' ? log.result_data : JSON.stringify(log.result_data, null, 2); + resultDialogContent.value = d; + } catch (e) { resultDialogContent.value = String(log.result_data || ''); } + resultDialogVisible.value = true; + }; + const tabLoaders = { llmconfigs: loadLLMConfigs, platformconfigs: loadPlatformConfigs, systemconfigs: loadSystemConfigs, users: fetchUsers, @@ -1473,6 +1669,7 @@ const llmConfigs = ref([]); searchrankings: loadRankings, geo: loadGeoData, configitems: () => { loadSensitiveWords(); loadContentCleanRules(); }, + taskmanagement: loadTaskConfigs, }; const loadedTabs = new Set([]); @@ -1533,6 +1730,10 @@ const llmConfigs = ref([]); loadContentCleanRules, showAddCleanRule, editCleanRule, saveCleanRule, deleteCleanRule, rankings, rankingStats, rankingsLoading, loadRankings, geoOverview, geoReadinessScores, geoLoading, geoTracking, loadGeoData, triggerGeoTrack, + taskConfigs, tcLoading, selectedModule, showHistory, taskLogs, tlLoading, + loadTaskConfigs, selectModule, toggleModule, loadTaskLogs, + tcEditDialogVisible, tcEditSaving, tcEditForm, showEditConfig, saveTaskConfig, + resultDialogVisible, resultDialogContent, showResultData, }; } });