重构了main.html的主函数
重构了大量的页面的sidebar 优化了代码结构
This commit is contained in:
392
web/js/services/system.js
Normal file
392
web/js/services/system.js
Normal file
@@ -0,0 +1,392 @@
|
||||
/**
|
||||
* 系统监控服务
|
||||
* 处理系统性能指标获取和展示
|
||||
*/
|
||||
|
||||
// 日志自动刷新相关变量
|
||||
let logRefreshTimer = null;
|
||||
let logCountdownTimer = null;
|
||||
let logCurrentInterval = 10;
|
||||
let logFullContent = '';
|
||||
|
||||
// 设置自动刷新间隔
|
||||
function setRefreshInterval() {
|
||||
const select = document.getElementById('logRefreshInterval');
|
||||
const countdownEl = document.getElementById('logRefreshCountdown');
|
||||
const secondsEl = document.getElementById('countdownNumber');
|
||||
|
||||
if (!select) return;
|
||||
|
||||
logCurrentInterval = parseInt(select.value) || 10;
|
||||
|
||||
// 清除之前的定时器
|
||||
if (logRefreshTimer) {
|
||||
clearInterval(logRefreshTimer);
|
||||
logRefreshTimer = null;
|
||||
}
|
||||
if (logCountdownTimer) {
|
||||
clearInterval(logCountdownTimer);
|
||||
logCountdownTimer = null;
|
||||
}
|
||||
|
||||
// 如果选择关闭,不显示倒计时
|
||||
if (select.value === '0') {
|
||||
countdownEl.classList.add('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示倒计时
|
||||
countdownEl.classList.remove('hidden');
|
||||
secondsEl.textContent = logCurrentInterval;
|
||||
|
||||
// 启动倒计时
|
||||
let countdown = logCurrentInterval;
|
||||
logCountdownTimer = setInterval(() => {
|
||||
countdown--;
|
||||
if (countdown <= 0) {
|
||||
countdown = logCurrentInterval;
|
||||
}
|
||||
secondsEl.textContent = countdown;
|
||||
}, 1000);
|
||||
|
||||
// 启动自动刷新
|
||||
logRefreshTimer = setInterval(() => {
|
||||
if (typeof refreshLogs === 'function') {
|
||||
refreshLogs();
|
||||
}
|
||||
}, logCurrentInterval * 1000);
|
||||
}
|
||||
|
||||
// 获取系统性能监控数据
|
||||
async function fetchSystemMetrics() {
|
||||
try {
|
||||
const response = await fetch(`${window.API_BASE}/health`);
|
||||
const result = await response.json();
|
||||
if (result.code === 0 && result.data) {
|
||||
const data = result.data;
|
||||
// 更新CPU使用率
|
||||
const cpuEl = document.getElementById('cpuUsage');
|
||||
if (cpuEl && data.cpu_percent !== undefined) {
|
||||
cpuEl.textContent = data.cpu_percent;
|
||||
cpuEl.className = data.cpu_percent > 80 ? 'text-red-500 font-medium' : '';
|
||||
}
|
||||
// 更新内存使用率
|
||||
const memEl = document.getElementById('memUsage');
|
||||
if (memEl && data.memory_percent !== undefined) {
|
||||
memEl.textContent = data.memory_percent;
|
||||
memEl.className = data.memory_percent > 80 ? 'text-red-500 font-medium' : '';
|
||||
}
|
||||
// 更新磁盘使用率
|
||||
const diskEl = document.getElementById('diskUsage');
|
||||
if (diskEl && data.disk_percent !== undefined) {
|
||||
diskEl.textContent = data.disk_percent;
|
||||
diskEl.className = data.disk_percent > 80 ? 'text-red-500 font-medium' : '';
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取系统监控数据失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 停止日志自动刷新(离开页面时调用)
|
||||
function stopLogAutoRefresh() {
|
||||
if (logRefreshTimer) {
|
||||
clearInterval(logRefreshTimer);
|
||||
logRefreshTimer = null;
|
||||
}
|
||||
if (logCountdownTimer) {
|
||||
clearInterval(logCountdownTimer);
|
||||
logCountdownTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 刷新日志
|
||||
function refreshLogs() {
|
||||
if (typeof switchLogTab === 'function') {
|
||||
const currentLogTab = window.currentLogTab || 'system';
|
||||
if (currentLogTab === 'system') {
|
||||
if (typeof loadLogFiles === 'function' && document.getElementById('logTypeSelect')?.value) {
|
||||
loadSelectedLog();
|
||||
} else {
|
||||
loadLogFiles();
|
||||
}
|
||||
} else {
|
||||
loadTrainingLogFiles();
|
||||
}
|
||||
} else {
|
||||
loadLogFiles();
|
||||
}
|
||||
// 重置倒计时
|
||||
const select = document.getElementById('logRefreshInterval');
|
||||
const secondsEl = document.getElementById('countdownNumber');
|
||||
if (select && select.value !== '0' && secondsEl) {
|
||||
secondsEl.textContent = logCurrentInterval;
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动到日志底部
|
||||
function scrollToLogBottom() {
|
||||
const logContent = document.getElementById('logContent');
|
||||
if (logContent) {
|
||||
logContent.scrollTop = logContent.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// 当前日志类型:system 或 training
|
||||
window.currentLogTab = 'system';
|
||||
|
||||
// 切换日志类型标签
|
||||
function switchLogTab(tab) {
|
||||
window.currentLogTab = tab;
|
||||
const systemTab = document.getElementById('logTabSystem');
|
||||
const trainingTab = document.getElementById('logTabTraining');
|
||||
const systemOptions = document.getElementById('systemLogOptions');
|
||||
const trainingOptions = document.getElementById('trainingLogOptions');
|
||||
|
||||
if (tab === 'system') {
|
||||
systemTab.className = 'px-4 py-1.5 text-sm rounded-md transition-colors bg-white shadow-sm text-primary';
|
||||
trainingTab.className = 'px-4 py-1.5 text-sm rounded-md transition-colors text-gray-600 hover:text-gray-800';
|
||||
systemOptions.classList.remove('hidden');
|
||||
trainingOptions.classList.add('hidden');
|
||||
loadLogFiles();
|
||||
} else {
|
||||
trainingTab.className = 'px-4 py-1.5 text-sm rounded-md transition-colors bg-white shadow-sm text-primary';
|
||||
systemTab.className = 'px-4 py-1.5 text-sm rounded-md transition-colors text-gray-600 hover:text-gray-800';
|
||||
trainingOptions.classList.remove('hidden');
|
||||
systemOptions.classList.add('hidden');
|
||||
loadTrainingLogFiles();
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化日志查看器
|
||||
function initLogViewer() {
|
||||
const datePicker = document.getElementById('logDatePicker');
|
||||
if (datePicker) {
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
datePicker.value = today;
|
||||
}
|
||||
// 加载默认日志类型
|
||||
loadLogFiles();
|
||||
// 启动自动刷新
|
||||
setRefreshInterval();
|
||||
}
|
||||
|
||||
// 加载训练日志文件列表
|
||||
async function loadTrainingLogFiles() {
|
||||
const logSelect = document.getElementById('trainingLogSelect');
|
||||
if (!logSelect) return;
|
||||
|
||||
logSelect.innerHTML = '<option value="">加载中...</option>';
|
||||
|
||||
try {
|
||||
const response = await fetch(`${window.API_BASE}/training-log-files`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.code === 0 && result.data) {
|
||||
logSelect.innerHTML = '<option value="">请选择训练日志</option>';
|
||||
result.data.forEach(log => {
|
||||
const option = document.createElement('option');
|
||||
option.value = log.file;
|
||||
option.textContent = `${log.name} (PID: ${log.pid}, ${log.date}, ${log.size})`;
|
||||
logSelect.appendChild(option);
|
||||
});
|
||||
// 如果有日志文件,自动加载第一个
|
||||
if (result.data.length > 0) {
|
||||
logSelect.value = result.data[0].file;
|
||||
loadSelectedTrainingLog();
|
||||
} else {
|
||||
document.getElementById('logContent').textContent = '暂无训练日志';
|
||||
document.getElementById('logFileInfo').textContent = '无训练日志';
|
||||
}
|
||||
} else {
|
||||
logSelect.innerHTML = '<option value="">暂无训练日志</option>';
|
||||
document.getElementById('logContent').textContent = '暂无训练日志';
|
||||
document.getElementById('logFileInfo').textContent = '无训练日志';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载训练日志列表失败:', error);
|
||||
logSelect.innerHTML = '<option value="">加载失败</option>';
|
||||
document.getElementById('logContent').textContent = '加载训练日志列表失败: ' + error.message;
|
||||
}
|
||||
}
|
||||
|
||||
// 加载选中的训练日志
|
||||
async function loadSelectedTrainingLog() {
|
||||
const logSelect = document.getElementById('trainingLogSelect');
|
||||
const logFile = logSelect.value;
|
||||
const logContent = document.getElementById('logContent');
|
||||
const logFileInfo = document.getElementById('logFileInfo');
|
||||
|
||||
if (!logFile) {
|
||||
logContent.textContent = '请选择训练日志';
|
||||
logFileInfo.textContent = '无训练日志';
|
||||
return;
|
||||
}
|
||||
|
||||
logContent.textContent = '加载中...';
|
||||
logFileInfo.textContent = '加载中...';
|
||||
|
||||
try {
|
||||
const response = await fetch(`${window.API_BASE}/training-log-content?file=${encodeURIComponent(logFile)}`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.code === 0 && result.data) {
|
||||
logFullContent = result.data.content || '';
|
||||
logContent.textContent = logFullContent || '(空日志)';
|
||||
logFileInfo.textContent = result.data.file + ' (' + result.data.size + ')';
|
||||
// 清空搜索
|
||||
document.getElementById('logSearchInput').value = '';
|
||||
document.getElementById('logMatchCount').textContent = '';
|
||||
// 滚动到底部
|
||||
scrollToLogBottom();
|
||||
} else {
|
||||
logContent.textContent = '加载失败: ' + (result.message || '未知错误');
|
||||
logFileInfo.textContent = '加载失败';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载训练日志内容失败:', error);
|
||||
logContent.textContent = '加载失败: ' + error.message;
|
||||
logFileInfo.textContent = '加载失败';
|
||||
}
|
||||
}
|
||||
|
||||
// 加载日志文件列表
|
||||
async function loadLogFiles() {
|
||||
const datePicker = document.getElementById('logDatePicker');
|
||||
const logTypeSelect = document.getElementById('logTypeSelect');
|
||||
const selectedDate = datePicker ? datePicker.value : new Date().toISOString().split('T')[0];
|
||||
|
||||
if (!logTypeSelect) return;
|
||||
logTypeSelect.innerHTML = '<option value="">加载中...</option>';
|
||||
|
||||
try {
|
||||
const response = await fetch(`${window.API_BASE}/log-files?date=${selectedDate}`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.code === 0 && result.data) {
|
||||
logTypeSelect.innerHTML = '<option value="">请选择日志文件</option>';
|
||||
result.data.forEach(log => {
|
||||
const option = document.createElement('option');
|
||||
option.value = log.file;
|
||||
option.textContent = log.name + ' (' + log.size + ')';
|
||||
logTypeSelect.appendChild(option);
|
||||
});
|
||||
// 如果有日志文件,自动加载第一个
|
||||
if (result.data.length > 0) {
|
||||
logTypeSelect.value = result.data[0].file;
|
||||
loadSelectedLog();
|
||||
} else {
|
||||
logTypeSelect.innerHTML = '<option value="">暂无日志文件</option>';
|
||||
document.getElementById('logContent').textContent = '该日期暂无日志文件';
|
||||
document.getElementById('logFileInfo').textContent = '无日志文件';
|
||||
}
|
||||
} else {
|
||||
logTypeSelect.innerHTML = '<option value="">暂无日志文件</option>';
|
||||
document.getElementById('logContent').textContent = '该日期暂无日志文件';
|
||||
document.getElementById('logFileInfo').textContent = '无日志文件';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载日志文件列表失败:', error);
|
||||
logTypeSelect.innerHTML = '<option value="">加载失败</option>';
|
||||
document.getElementById('logContent').textContent = '加载日志文件列表失败: ' + error.message;
|
||||
}
|
||||
}
|
||||
|
||||
// 加载选中的日志
|
||||
async function loadSelectedLog() {
|
||||
const logTypeSelect = document.getElementById('logTypeSelect');
|
||||
const logFile = logTypeSelect.value;
|
||||
const logContent = document.getElementById('logContent');
|
||||
const logFileInfo = document.getElementById('logFileInfo');
|
||||
|
||||
if (!logFile) {
|
||||
logContent.textContent = '请选择日志文件';
|
||||
logFileInfo.textContent = '无日志文件';
|
||||
return;
|
||||
}
|
||||
|
||||
logContent.textContent = '加载中...';
|
||||
logFileInfo.textContent = '加载中...';
|
||||
|
||||
try {
|
||||
const response = await fetch(`${window.API_BASE}/log-content?file=${encodeURIComponent(logFile)}`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.code === 0) {
|
||||
logFullContent = result.data.content || '';
|
||||
logContent.textContent = logFullContent || '(空日志)';
|
||||
logFileInfo.textContent = result.data.file + ' (' + result.data.size + ')';
|
||||
// 清空搜索框和匹配计数
|
||||
document.getElementById('logSearchInput').value = '';
|
||||
document.getElementById('logMatchCount').textContent = '';
|
||||
// 滚动到最底部
|
||||
scrollToLogBottom();
|
||||
} else {
|
||||
logContent.textContent = '加载失败: ' + (result.message || '未知错误');
|
||||
logFileInfo.textContent = '加载失败';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载日志内容失败:', error);
|
||||
logContent.textContent = '加载日志内容失败: ' + error.message;
|
||||
logFileInfo.textContent = '加载失败';
|
||||
}
|
||||
}
|
||||
|
||||
// 过滤日志内容
|
||||
function filterLogContent() {
|
||||
const searchInput = document.getElementById('logSearchInput');
|
||||
const matchCount = document.getElementById('logMatchCount');
|
||||
const logContent = document.getElementById('logContent');
|
||||
|
||||
if (!searchInput || !matchCount || !logContent) return;
|
||||
|
||||
const keyword = searchInput.value.trim();
|
||||
|
||||
if (!keyword) {
|
||||
logContent.textContent = logFullContent || '(空日志)';
|
||||
matchCount.textContent = '';
|
||||
scrollToLogBottom();
|
||||
return;
|
||||
}
|
||||
|
||||
const lines = logFullContent.split('\n');
|
||||
const matchingLines = lines.filter(line => line.toLowerCase().includes(keyword.toLowerCase()));
|
||||
|
||||
if (matchingLines.length > 0) {
|
||||
logContent.textContent = matchingLines.join('\n');
|
||||
matchCount.textContent = `(${matchingLines.length}条匹配)`;
|
||||
// 滚动到最底部查看最新匹配
|
||||
scrollToLogBottom();
|
||||
} else {
|
||||
logContent.textContent = '未找到匹配的日志';
|
||||
matchCount.textContent = '(0条匹配)';
|
||||
}
|
||||
}
|
||||
|
||||
// 清空日志内容显示
|
||||
function clearLogContent() {
|
||||
document.getElementById('logContent').textContent = '日志内容将在这里显示...';
|
||||
document.getElementById('logFileInfo').textContent = '请选择日志文件';
|
||||
const logTypeSelect = document.getElementById('logTypeSelect');
|
||||
if (logTypeSelect) logTypeSelect.value = '';
|
||||
document.getElementById('logSearchInput').value = '';
|
||||
document.getElementById('logMatchCount').textContent = '';
|
||||
logFullContent = '';
|
||||
}
|
||||
|
||||
// 导出服务函数
|
||||
window.SystemService = {
|
||||
fetchSystemMetrics,
|
||||
setRefreshInterval,
|
||||
stopLogAutoRefresh,
|
||||
refreshLogs,
|
||||
scrollToLogBottom,
|
||||
switchLogTab,
|
||||
initLogViewer,
|
||||
loadTrainingLogFiles,
|
||||
loadSelectedTrainingLog,
|
||||
loadLogFiles,
|
||||
loadSelectedLog,
|
||||
filterLogContent,
|
||||
clearLogContent
|
||||
};
|
||||
201
web/js/services/training.js
Normal file
201
web/js/services/training.js
Normal file
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* 训练服务模块
|
||||
* 处理训练任务相关的操作和进度跟踪
|
||||
*/
|
||||
|
||||
// 训练进度缓存
|
||||
window.trainingProgressCache = window.trainingProgressCache || {};
|
||||
// 使用 window 避免重复声明
|
||||
if (typeof window._progressRefreshTimer === 'undefined') {
|
||||
window._progressRefreshTimer = null;
|
||||
}
|
||||
|
||||
// 渲染训练进度
|
||||
function renderTrainingProgress(val, row) {
|
||||
const progressData = window.trainingProgressCache[row.id];
|
||||
if (progressData && progressData.status === 'running') {
|
||||
if (progressData.progress > 0) {
|
||||
return `
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm font-medium text-primary">${progressData.progress}%</span>
|
||||
<span class="text-xs text-gray-500">${progressData.step || ''} ${progressData.speed || ''}</span>
|
||||
<span class="text-xs text-gray-400">ETA: ${progressData.eta || '--:--'}</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
return `${val || 0}%`;
|
||||
}
|
||||
|
||||
// 刷新训练进度
|
||||
async function refreshTrainingProgress() {
|
||||
if (typeof window.currentPage !== 'string' || window.currentPage !== 'fine-tune') return;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${window.API_BASE}/fine-tune`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.code === 0 && result.data) {
|
||||
// 刷新运行中或已完成的任务(有进度信息)
|
||||
const activeTasks = result.data.filter(task =>
|
||||
task.status === 'running' || task.status === 'pending'
|
||||
);
|
||||
|
||||
for (const task of activeTasks) {
|
||||
try {
|
||||
// 并行获取进度和PID状态
|
||||
const [progressResponse, statusResponse] = await Promise.all([
|
||||
fetch(`${window.API_BASE}/fine-tune/progress/${task.id}`),
|
||||
fetch(`${window.API_BASE}/fine-tune/${task.id}`)
|
||||
]);
|
||||
const progressResult = await progressResponse.json();
|
||||
const statusResult = await statusResponse.json();
|
||||
|
||||
if (progressResult.code === 0 && progressResult.data) {
|
||||
window.trainingProgressCache[task.id] = progressResult.data;
|
||||
}
|
||||
|
||||
// 如果状态已改变(PID已结束),更新表格中的状态显示
|
||||
if (statusResult.code === 0 && statusResult.data) {
|
||||
const actualStatus = statusResult.data.status;
|
||||
if (task.status !== actualStatus) {
|
||||
// 找到对应的行并更新状态
|
||||
const row = document.querySelector(`tr[data-id="${task.id}"]`);
|
||||
if (row) {
|
||||
const statusCell = row.querySelector('td:nth-child(3)');
|
||||
if (statusCell) {
|
||||
statusCell.innerHTML = `<span class="px-2 py-1 rounded text-xs ${actualStatus === 'running' ? 'bg-green-100 text-green-700' : actualStatus === 'failed' ? 'bg-red-100 text-red-700' : 'bg-blue-100 text-blue-700'}">${actualStatus}</span>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(`获取任务 ${task.id} 信息失败:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('刷新训练进度失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查并更新任务状态(用于 fine-tune 页面)
|
||||
async function checkAndUpdateTaskStatus() {
|
||||
if (typeof window.currentPage !== 'string' || window.currentPage !== 'fine-tune') return;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${window.API_BASE}/fine-tune`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.code === 0 && result.data) {
|
||||
// 获取所有 running 状态的任务
|
||||
const runningTasks = result.data.filter(task => task.status === 'running');
|
||||
|
||||
for (const task of runningTasks) {
|
||||
try {
|
||||
// 调用 status API 获取实际状态(会检查 PID)
|
||||
const statusResponse = await fetch(`${window.API_BASE}/fine-tune/${task.id}`);
|
||||
const statusResult = await statusResponse.json();
|
||||
|
||||
if (statusResult.code === 0 && statusResult.data) {
|
||||
const actualStatus = statusResult.data.status;
|
||||
// 如果实际状态不是 running,更新表格显示
|
||||
if (actualStatus !== 'running') {
|
||||
const row = document.querySelector(`tr[data-id="${task.id}"]`);
|
||||
if (row) {
|
||||
const statusCell = row.querySelector('td:nth-child(3)');
|
||||
if (statusCell) {
|
||||
const statusClass = actualStatus === 'failed'
|
||||
? 'bg-red-100 text-red-700'
|
||||
: 'bg-blue-100 text-blue-700';
|
||||
statusCell.innerHTML = `<span class="px-2 py-1 rounded text-xs ${statusClass}">${actualStatus}</span>`;
|
||||
console.log(`[Status] 任务 ${task.id} 状态已更新: running -> ${actualStatus}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(`检查任务 ${task.id} 状态失败:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('检查任务状态失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 启动训练进度自动刷新
|
||||
function startProgressRefresh() {
|
||||
stopProgressRefresh();
|
||||
window._progressRefreshTimer = setInterval(() => {
|
||||
refreshTrainingProgress();
|
||||
checkAndUpdateTaskStatus();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// 停止训练进度刷新
|
||||
function stopProgressRefresh() {
|
||||
if (window._progressRefreshTimer) {
|
||||
clearInterval(window._progressRefreshTimer);
|
||||
window._progressRefreshTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 停止训练任务
|
||||
async function stopItem(taskId) {
|
||||
window.showConfirm('确认停止', '确定要停止这个训练任务吗?进程将被终止。', async () => {
|
||||
try {
|
||||
const response = await fetch(`${window.API_BASE}/fine-tune/stop/${taskId}`, {
|
||||
method: 'POST'
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.code === 0) {
|
||||
window.showMessage('成功', '训练任务已停止', 'success');
|
||||
// 刷新当前页面
|
||||
const activeLink = document.querySelector('.nav-link.sidebar-item-active');
|
||||
if (activeLink && typeof window.loadPage === 'function') {
|
||||
window.loadPage(activeLink.dataset.page);
|
||||
}
|
||||
} else {
|
||||
window.showMessage('错误', result.message || '停止失败', 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
window.showMessage('错误', '停止失败: ' + error.message, 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 查看训练日志 - 跳转到日志页面
|
||||
async function viewTrainingLog(taskId, taskName) {
|
||||
window.loadPage('logs');
|
||||
}
|
||||
|
||||
// 查看调优任务日志 - 跳转到training-log.html页面
|
||||
function viewFineTuneLogs(taskId, taskName) {
|
||||
// 保存 taskId 到 sessionStorage
|
||||
sessionStorage.setItem('trainingLogTaskId', taskId.toString());
|
||||
sessionStorage.setItem('trainingLogTaskName', taskName);
|
||||
// 跳转到日志页面
|
||||
window.navigateToPage('training-log');
|
||||
}
|
||||
|
||||
// 跳转到训练日志二级页面
|
||||
function navigateToTrainingLog(taskId) {
|
||||
// 传递 taskId 到 sessionStorage
|
||||
sessionStorage.setItem('trainingLogTaskId', taskId.toString());
|
||||
// 跳转到日志页面
|
||||
window.navigateToPage('training-log');
|
||||
}
|
||||
|
||||
// 导出训练服务
|
||||
window.TrainingService = {
|
||||
renderTrainingProgress,
|
||||
refreshTrainingProgress,
|
||||
checkAndUpdateTaskStatus,
|
||||
startProgressRefresh,
|
||||
stopProgressRefresh,
|
||||
stopItem,
|
||||
viewTrainingLog,
|
||||
viewFineTuneLogs,
|
||||
navigateToTrainingLog
|
||||
};
|
||||
Reference in New Issue
Block a user