From f0039bcbd40e5948a77556bbbef3818a0b08bf42 Mon Sep 17 00:00:00 2001 From: z66 <1415243231@qq.com> Date: Tue, 26 Aug 2025 18:01:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=90=8E=E5=8F=B0=E8=BF=9B?= =?UTF-8?q?=E7=A8=8B=E4=BF=AE=E5=A4=8D=E7=AD=89=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/index.html | 204 ++++++++++++++++++++++++------------------- 1 file changed, 112 insertions(+), 92 deletions(-) diff --git a/templates/index.html b/templates/index.html index 16b6482..e67deb6 100644 --- a/templates/index.html +++ b/templates/index.html @@ -347,7 +347,6 @@ let currentSearchKeyword = ""; let currentServerDirectory = ""; let selectedScriptPath = null; - let scriptStatusMap = {}; // 缓存脚本状态映射 $(function () { loadScripts(); @@ -370,35 +369,28 @@ alert('加载脚本失败:后端返回非数组格式'); return; } - // 只保留有配置的脚本(后端已过滤,前端二次确认) + // 直接保存原始名称,不做额外处理 allScripts = scripts.filter(item => typeof item === 'object' && item !== null && 'name' in item && typeof item.name === 'string' && item.name.trim() !== '' ); - // 批量获取所有脚本的状态和模式 - $.get('/api/scripts/status', function(statusMap) { - scriptStatusMap = statusMap; - currentSearchKeyword = ""; - $('#script-search').val(""); - sortScripts(); - updateConfigScriptSelect(); + currentSearchKeyword = ""; + $('#script-search').val(""); + sortScripts(); + updateConfigScriptSelect(); - if (currentScript) { - const scriptExists = allScripts.some(s => s.name === currentScript); - if (scriptExists) { - $('#config-script').val(currentScript); - loadConfig(currentScript); - updateOutput(); - } else { - currentScript = null; - $('#output-area').empty(); - } + if (currentScript) { + const scriptExists = allScripts.some(s => s.name === currentScript); + if (scriptExists) { + $('#config-script').val(currentScript); + loadConfig(currentScript); + updateOutput(); + } else { + currentScript = null; + $('#output-area').empty(); } - }).fail(function(xhr) { - alert('加载脚本状态失败:' + (xhr.responseJSON?.error || xhr.statusText)); - }); - + } }).fail(function (xhr) { alert('加载脚本列表失败:' + (xhr.responseJSON?.error || xhr.statusText)); allScripts = []; @@ -452,7 +444,7 @@ if (filteredScripts.length === 0) { const tip = currentSearchKeyword ? ` 未找到包含"${currentSearchKeyword}"的脚本` : - ` 暂无配置的脚本`; + ` tasks目录下无脚本文件(支持.bat/.py)`; container.append(`
${tip} @@ -461,79 +453,67 @@ return; } - // 使用文档片段减少DOM重绘 - const fragment = document.createDocumentFragment(); - filteredScripts.forEach(scriptObj => { const scriptName = scriptObj.name.trim(); if (!scriptName) return; const modifyTimeStr = scriptObj.modify_time_str || '未知时间'; - // 从缓存的状态映射表中获取状态和模式 - const statusInfo = scriptStatusMap[scriptName] || { - status: 'stopped', - running: false, - scheduled: false, - mode: 'single-run', - schedule_info: '' - }; + getScriptStatus(scriptName, function (status) { + const statusClass = status.status === 'running' ? 'status-running' : + status.status === 'scheduled' ? 'status-scheduled' : 'status-stopped'; + const statusText = status.status === 'running' ? '运行中' : + status.status === 'scheduled' ? '已调度' : '停止'; + const statusTextClass = `status-text ${status.status}`; - // 状态样式处理 - const statusClass = statusInfo.status === 'running' ? 'status-running' : - statusInfo.status === 'scheduled' ? 'status-scheduled' : 'status-stopped'; - const statusText = statusInfo.status === 'running' ? '运行中' : - statusInfo.status === 'scheduled' ? '已调度' : '停止'; - const statusTextClass = `status-text ${statusInfo.status}`; + let btnClass, btnIcon, btnText, btnClick; + if (status.running || status.scheduled) { + btnClass = 'btn-danger'; + btnIcon = 'bi-stop-fill'; + btnText = '停止'; + btnClick = `stopScript('${escapeHtml(scriptName)}')`; + } else { + btnClass = 'btn-success'; + btnIcon = 'bi-play-fill'; + btnText = '启动'; + btnClick = `startScript('${escapeHtml(scriptName)}')`; + } - // 按钮样式处理 - let btnClass, btnIcon, btnText, btnClick; - if (statusInfo.running || statusInfo.scheduled) { - btnClass = 'btn-danger'; - btnIcon = 'bi-stop-fill'; - btnText = '停止'; - btnClick = `stopScript('${escapeHtml(scriptName)}')`; - } else { - btnClass = 'btn-success'; - btnIcon = 'bi-play-fill'; - btnText = '启动'; - btnClick = `startScript('${escapeHtml(scriptName)}')`; - } - - // 模式文本处理 - const modeText = statusInfo.mode === 'long-running' ? '长期运行' : - statusInfo.mode === 'interval' ? '定时执行' : '单次运行'; - const scheduleInfo = statusInfo.schedule_info ? ` | ${statusInfo.schedule_info}` : ''; - - // 创建DOM元素并添加到文档片段 - const scriptItem = $(` -
-
-
-
- - ${escapeHtml(scriptName)} - ${statusText} -
-
-
- 模式:${modeText}${scheduleInfo} - 最近修改:${modifyTimeStr} + const scriptItemHtml = ` +
+
+
+
+ + ${escapeHtml(scriptName)} + ${statusText} +
+
+ 加载模式信息中...
+
-
-
- `)[0]; - fragment.appendChild(scriptItem); - }); + `; + container.append(scriptItemHtml); - // 一次性将所有元素添加到容器 - container.append(fragment); + getScriptMode(scriptName, function (mode) { + const modeText = mode === 'long-running' ? '长期运行' : + mode === 'interval' ? '定时执行' : '单次运行'; + const scheduleInfo = status.schedule_info ? ` | ${status.schedule_info}` : ''; + $(`.script-item:has(.script-name:contains('${escapeHtml(scriptName)}')) .mode-info`).html(` +
+ 模式:${modeText}${scheduleInfo} + 最近修改:${modifyTimeStr} +
+ `); + }); + }); + }); } function updateConfigScriptSelect() { @@ -545,13 +525,17 @@ typeof scriptObj.name === 'string' && scriptObj.name.trim()) { const scriptName = scriptObj.name.trim(); - const escapedName = escapeHtml(scriptName); + const escapedName = escapeHtml(scriptName); // 转义仅用于显示 + // value使用原始名称,显示文本用转义后的值 select.append(``); } }); - if (currentScript && select.find(`option[value="${currentScript}"]`).length) { - select.val(currentScript); + // 恢复当前选中状态(使用原始名称匹配) + if (currentScript) { + if (select.find(`option[value="${currentScript}"]`).length) { + select.val(currentScript); + } } } @@ -567,7 +551,8 @@ $.get(`/api/start/${encodeURIComponent(scriptName)}`) .done(function (data) { alert(data.msg); - loadScripts(); // 重新加载列表和状态 + updateOutput(); + renderScriptList(); }) .fail(function (xhr) { alert('启动失败:' + (xhr.responseJSON?.error || xhr.statusText)); @@ -578,13 +563,35 @@ $.get(`/api/stop/${encodeURIComponent(scriptName)}`) .done(function (data) { alert(data.msg); - loadScripts(); // 重新加载列表和状态 + updateOutput(); + renderScriptList(); }) .fail(function (xhr) { alert('停止失败:' + (xhr.responseJSON?.error || xhr.statusText)); }); } + function getScriptStatus(scriptName, callback) { + $.get(`/api/status/${encodeURIComponent(scriptName)}`) + .done(function (data) { + callback(data); + }) + .fail(function () { + callback({status: 'stopped', running: false, scheduled: false}); + }); + } + + function getScriptMode(scriptName, callback) { + $.get('/api/config') + .done(function (configs) { + const mode = configs[scriptName]?.mode || 'single-run'; + callback(mode); + }) + .fail(function () { + callback('single-run'); + }); + } + function loadConfig(scriptName) { $.get('/api/config') .done(function (configs) { @@ -644,7 +651,7 @@ data: JSON.stringify({[scriptName]: config}), success: function (data) { alert(data.msg); - loadScripts(); // 保存后刷新列表 + renderScriptList(); }, error: function (xhr) { alert('保存失败:' + (xhr.responseJSON?.error || xhr.statusText)); @@ -801,13 +808,26 @@ document.getElementById('selectScriptBtn').addEventListener('click', function () { if (selectedScriptPath) { const scriptName = selectedScriptPath; - $('#config-script').val(scriptName); + const $select = $('#config-script'); + + // 检查下拉框中是否已有该脚本选项,若没有则手动添加 + if ($select.find(`option[value="${escapeHtml(scriptName)}"]`).length === 0) { + $select.append(``); + } + + // 设置选中值并同步相关状态 + $select.val(scriptName); loadConfig(scriptName); selectScript(scriptName); + + // 刷新脚本列表,确保所有组件同步 + loadScripts(); + const modal = bootstrap.Modal.getInstance(document.getElementById('directoryBrowserModal')); modal.hide(); } }); + \ No newline at end of file