diff --git a/web/pages/main.html b/web/pages/main.html index 50310b4..6053d53 100644 --- a/web/pages/main.html +++ b/web/pages/main.html @@ -168,7 +168,7 @@ - 模型对比 + 模型部署 @@ -291,10 +291,10 @@ actions: ['report', 'delete'] }, 'model-deploy': { - title: '模型部署', + title: '模型对比', api: 'model-deploy', hasCreate: true, - createText: '新建部署', + createText: '新建对比', columns: [ { title: '服务名称', key: 'model_name' }, { title: '端点', key: 'endpoint' }, @@ -474,6 +474,9 @@ // 加载页面内容 async function loadPage(pageName) { + // 切换页面时清除选中状态 + clearSelection(); + const container = document.getElementById('page-content'); const config = tableConfigs[pageName]; @@ -499,6 +502,7 @@ container.innerHTML = renderToolsPage(config); } else { const data = await fetchData(`${API_BASE}/${config.api}`); + currentPageData = data; // 保存当前页面数据 container.innerHTML = renderTablePage(config, data); } } catch (error) { @@ -533,6 +537,7 @@ const result = await response.json(); if (result.code === 0) { // 刷新当前页面 + clearSelection(); // 清除选中状态 const activeLink = document.querySelector('.nav-link.sidebar-item-active'); if (activeLink) { loadPage(activeLink.dataset.page); @@ -546,6 +551,131 @@ }); } + // 切换单个项的选中状态 + function toggleItemSelection(id, api) { + if (selectedItems.has(id)) { + selectedItems.delete(id); + } else { + selectedItems.add(id); + } + // 重新渲染当前页面以更新UI + refreshCurrentPage(); + } + + // 切换全选/取消全选 + function toggleSelectAll(checkbox, api) { + // 使用保存的当前页面数据 + if (checkbox.checked) { + // 全选当前页面的所有数据 + currentPageData.forEach(item => selectedItems.add(item.id)); + } else { + // 取消全选,移除当前页面所有数据的选中状态 + currentPageData.forEach(item => selectedItems.delete(item.id)); + } + refreshCurrentPage(); + } + + // 清除所有选中项 + function clearSelection() { + selectedItems.clear(); + refreshCurrentPage(); + } + + // 批量删除选中的项 + function batchDeleteItems(api) { + if (selectedItems.size === 0) { + showMessage('提示', '请先选择要删除的项', 'warning'); + return; + } + + showConfirm('批量删除', `确定要删除选中的 ${selectedItems.size} 条记录吗?`, async () => { + const ids = Array.from(selectedItems); + let successCount = 0; + let failCount = 0; + + for (const id of ids) { + try { + const response = await fetch(`${API_BASE}/${api}/${id}`, { + method: 'DELETE' + }); + const result = await response.json(); + if (result.code === 0) { + successCount++; + } else { + failCount++; + } + } catch (error) { + failCount++; + } + } + + clearSelection(); + + // 刷新当前页面 + const activeLink = document.querySelector('.nav-link.sidebar-item-active'); + if (activeLink) { + loadPage(activeLink.dataset.page); + } + + if (failCount === 0) { + showMessage('成功', `成功删除 ${successCount} 条记录`, 'success'); + } else { + showMessage('部分失败', `成功删除 ${successCount} 条,${failCount} 条删除失败`, 'warning'); + } + }); + } + + // 刷新当前页面(重新渲染) + function refreshCurrentPage() { + const activeLink = document.querySelector('.nav-link.sidebar-item-active'); + if (activeLink) { + const pageName = activeLink.dataset.page; + const config = tableConfigs[pageName]; + + if (config.api === 'model-manage' || config.api === 'dataset-manage') { + document.getElementById('page-content').innerHTML = renderTablePage(config, currentPageData); + // 恢复复选框状态 + updateCheckboxStates(); + } + } + } + + // 更新复选框状态(保持选中状态) + function updateCheckboxStates() { + const checkboxes = document.querySelectorAll('tbody input[type="checkbox"]'); + checkboxes.forEach(cb => { + const id = parseInt(cb.getAttribute('onchange').match(/toggleItemSelection\((\d+)/)?.[1] || cb.getAttribute('onchange').match(/toggleItemSelection\(([^,]+)/)?.[1]); + if (selectedItems.has(id)) { + cb.checked = true; + cb.closest('tr').classList.add('bg-blue-50'); + } else { + cb.checked = false; + cb.closest('tr').classList.remove('bg-blue-50'); + } + }); + + // 更新批量操作栏的显示状态 + const batchActions = document.getElementById('batchActions'); + if (batchActions) { + if (selectedItems.size > 0) { + batchActions.classList.remove('hidden'); + batchActions.querySelector('strong').textContent = selectedItems.size; + } else { + batchActions.classList.add('hidden'); + } + } + + // 更新批量删除按钮 + const batchDeleteBtn = document.querySelector('#batchActions button[onclick^="batchDeleteItems"]'); + if (batchDeleteBtn) { + if (selectedItems.size > 0) { + batchDeleteBtn.innerHTML = `批量删除 (${selectedItems.size})`; + } else { + batchDeleteBtn.innerHTML = `批量删除 (0)`; + } + } + } + // 编辑数据集 function editItem(api, id) { if (api === 'dataset-manage') { @@ -605,9 +735,27 @@ ` : ''; + // 是否支持多选(模型管理和数据集管理) + const supportsMultiSelect = config.api === 'model-manage' || config.api === 'dataset-manage'; + + // 批量删除按钮(仅当有选中项时显示) + const batchDeleteButton = supportsMultiSelect && selectedItems.size > 0 ? ` + + ` : ''; + const columns = config.columns; const hasData = data && data.length > 0; + // 多选列头 + const selectAllHeader = supportsMultiSelect ? ` +
| ${col.title} | `).join('')}操作 |
|---|---|
| + + | + ` : ''} ${columns.map(col => `
${col.render ? col.render(item[col.key]) : (item[col.key] || '-')}
@@ -1184,6 +1351,8 @@
// 当前页面状态
let currentPage = 'fine-tune';
let currentParentPage = null;
+ let selectedItems = new Set(); // 存储选中的项ID
+ let currentPageData = []; // 存储当前页面数据
// 显示创建表单页面
function showCreateModal(apiType) {
@@ -1195,6 +1364,8 @@
window.location.href = 'model-eval-create.html';
} else if (apiType === 'dataset-manage') {
window.location.href = 'dataset-create.html';
+ } else if (apiType === 'model-deploy') {
+ window.location.href = 'model-deploy-create.html';
} else {
showMessage('提示', '该功能开发中...', 'info');
}
diff --git a/web/pages/model-deploy-create.html b/web/pages/model-deploy-create.html
new file mode 100644
index 0000000..348e1b8
--- /dev/null
+++ b/web/pages/model-deploy-create.html
@@ -0,0 +1,444 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |