diff --git a/src/main.py b/src/main.py index 89a365f..076a86c 100644 --- a/src/main.py +++ b/src/main.py @@ -129,6 +129,18 @@ def init_database(): update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP )""", + # 模型管理表 + """CREATE TABLE IF NOT EXISTS model_manage ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + type VARCHAR(100), + version VARCHAR(50), + path VARCHAR(500), + description TEXT, + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + )""", + # 系统配置表 """CREATE TABLE IF NOT EXISTS sys_config ( id INT AUTO_INCREMENT PRIMARY KEY, @@ -436,6 +448,32 @@ def delete_permission(id): return jsonify({'code': 0, 'message': '删除成功'}) +# ============ 模型管理接口 ============ +@app.route('/api/model-manage', methods=['GET']) +def get_model_manage(): + return jsonify({'code': 0, 'data': generic_get_all('model_manage')}) + + +@app.route('/api/model-manage', methods=['POST']) +def create_model_manage(): + data = request.json + new_id = generic_create('model_manage', data) + return jsonify({'code': 0, 'message': '创建成功', 'id': new_id}) + + +@app.route('/api/model-manage/', methods=['PUT']) +def update_model_manage(id): + data = request.json + generic_update('model_manage', id, data) + return jsonify({'code': 0, 'message': '更新成功'}) + + +@app.route('/api/model-manage/', methods=['DELETE']) +def delete_model_manage(id): + generic_delete('model_manage', id) + return jsonify({'code': 0, 'message': '删除成功'}) + + # ============ 系统配置接口 ============ @app.route('/api/sys-config', methods=['GET']) def get_sys_config(): diff --git a/web/pages/fine-tune-create.html b/web/pages/fine-tune-create.html index 7112f76..5b9064b 100644 --- a/web/pages/fine-tune-create.html +++ b/web/pages/fine-tune-create.html @@ -48,7 +48,13 @@
-

模型调优 / 创建训练任务

+
+
+ 模型调优 + / + 创建训练任务 +
+
diff --git a/web/pages/main.html b/web/pages/main.html index 553ee12..2b1ccfe 100644 --- a/web/pages/main.html +++ b/web/pages/main.html @@ -84,6 +84,10 @@ + + + 模型管理 + 数据集管理 @@ -95,13 +99,9 @@ - - - 权限管理 - - - 平台配置 + + 平台性能 @@ -242,21 +242,23 @@ ], actions: ['stop', 'detail', 'delete'] }, - 'permission': { - title: '权限管理', - api: 'permission', + 'model-manage': { + title: '模型管理', + api: 'model-manage', hasCreate: true, - createText: '添加用户', + createText: '添加模型', columns: [ - { title: '用户名', key: 'username' }, - { title: '角色', key: 'role' }, - { title: '权限', key: 'permissions', render: (val) => val || '-' }, + { title: '模型名称', key: 'name' }, + { title: '模型类型', key: 'type' }, + { title: '模型版本', key: 'version' }, + { title: '模型路径', key: 'path', render: (val) => val || '-' }, + { title: '描述', key: 'description', render: (val) => val || '-' }, { title: '创建时间', key: 'create_time', render: (val) => val ? new Date(val).toLocaleString('zh-CN') : '-' } ], actions: ['edit', 'delete'] }, 'config': { - title: '平台配置', + title: '平台性能', api: 'sys-config', hasCreate: false, isForm: true, @@ -285,8 +287,21 @@ // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', function() { - // 加载默认页面 - loadPage('fine-tune'); + // 检查URL参数 + const urlParams = new URLSearchParams(window.location.search); + const pageParam = urlParams.get('page'); + + // 加载页面(优先使用URL参数) + const defaultPage = pageParam || 'fine-tune'; + loadPage(defaultPage); + + // 更新侧边栏高亮状态 + document.querySelectorAll('.nav-link').forEach(link => { + if (link.dataset.page === defaultPage) { + link.classList.add('sidebar-item-active'); + link.classList.remove('hover:bg-sidebarBg/20', 'transition-colors'); + } + }); // 绑定导航点击事件 document.querySelectorAll('.nav-link').forEach(link => { @@ -361,25 +376,25 @@ // 删除数据 async function deleteItem(api, id) { - if (!confirm('确定要删除这条记录吗?')) return; - - try { - const response = await fetch(`${API_BASE}/${api}/${id}`, { - method: 'DELETE' - }); - const result = await response.json(); - if (result.code === 0) { - // 刷新当前页面 - const activeLink = document.querySelector('.nav-link.sidebar-item-active'); - if (activeLink) { - loadPage(activeLink.dataset.page); + showConfirm('确认删除', '确定要删除这条记录吗?', async () => { + try { + const response = await fetch(`${API_BASE}/${api}/${id}`, { + method: 'DELETE' + }); + const result = await response.json(); + if (result.code === 0) { + // 刷新当前页面 + const activeLink = document.querySelector('.nav-link.sidebar-item-active'); + if (activeLink) { + loadPage(activeLink.dataset.page); + } + } else { + showMessage('错误', result.message || '删除失败', 'error'); } - } else { - alert(result.message || '删除失败'); + } catch (error) { + showMessage('错误', '删除失败: ' + error.message, 'error'); } - } catch (error) { - alert('删除失败: ' + error.message); - } + }); } // 渲染表格页面 @@ -420,7 +435,7 @@
${config.actions.map(action => ` - @@ -490,7 +505,7 @@ } function saveConfig() { - alert('配置保存功能开发中...'); + showMessage('提示', '配置保存功能开发中...', 'info'); } // 当前页面状态 @@ -499,16 +514,17 @@ // 显示创建表单页面 function showCreateModal(apiType) { - const container = document.getElementById('page-content'); - if (apiType === 'fine-tune') { currentParentPage = currentPage; currentPage = 'fine-tune-create'; + const container = document.getElementById('page-content'); container.innerHTML = renderFineTuneCreatePage(); bindCreatePageEvents(); loadDatasets(); + } else if (apiType === 'model-manage') { + window.location.href = 'model-manage-create.html'; } else { - alert('该功能开发中...'); + showMessage('提示', '该功能开发中...', 'info'); } } @@ -1099,6 +1115,96 @@ } } + // ============ 自定义消息弹窗 ============ + // 显示消息弹窗 + function showMessage(title, message, type = 'info', onConfirm) { + const modal = document.getElementById('customModal'); + const modalTitle = document.getElementById('modalTitle'); + const modalMessage = document.getElementById('modalMessage'); + const modalIcon = document.getElementById('modalIcon'); + const modalConfirmBtn = document.getElementById('modalConfirmBtn'); + const modalConfirmBtn2 = document.getElementById('modalConfirmBtn2'); + const modalBtnGroup = document.getElementById('modalBtnGroup'); + const modalSingleBtnGroup = document.getElementById('modalSingleBtnGroup'); + + // 设置标题 + modalTitle.textContent = title; + modalTitle.className = 'text-lg font-medium text-gray-800 mb-2'; + + // 设置消息 + modalMessage.innerHTML = message; + + // 设置图标和按钮颜色 + if (type === 'success') { + modalIcon.innerHTML = '
'; + } else if (type === 'error') { + modalIcon.innerHTML = '
'; + } else if (type === 'warning') { + modalIcon.innerHTML = '
'; + } else { + modalIcon.innerHTML = '
'; + } + + // 单按钮模式 + modalBtnGroup.classList.add('hidden'); + modalSingleBtnGroup.classList.remove('hidden'); + const confirmBtn = modalConfirmBtn2; + if (type === 'error') { + confirmBtn.className = 'px-6 py-2 bg-danger text-white rounded-lg hover:bg-danger/90 transition-colors'; + } else { + confirmBtn.className = 'px-6 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 transition-colors'; + } + + // 显示弹窗 + modal.classList.remove('hidden'); + document.body.style.overflow = 'hidden'; + + // 绑定确认按钮事件 + confirmBtn.onclick = () => { + closeModal(); + if (onConfirm) onConfirm(); + }; + } + + // 关闭消息弹窗 + function closeModal() { + const modal = document.getElementById('customModal'); + modal.classList.add('hidden'); + document.body.style.overflow = ''; + } + + // 确认弹窗(两个按钮) + function showConfirm(title, message, onConfirm, onCancel) { + const modal = document.getElementById('customModal'); + const modalTitle = document.getElementById('modalTitle'); + const modalMessage = document.getElementById('modalMessage'); + const modalIcon = document.getElementById('modalIcon'); + const modalConfirmBtn = document.getElementById('modalConfirmBtn'); + const modalCancelBtn = document.getElementById('modalCancelBtn'); + const modalBtnGroup = document.getElementById('modalBtnGroup'); + + modalTitle.textContent = title; + modalMessage.innerHTML = message; + modalIcon.innerHTML = '
'; + + modalBtnGroup.classList.remove('hidden'); + modalConfirmBtn.textContent = '确定'; + modalConfirmBtn.className = 'px-6 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 transition-colors'; + + modal.classList.remove('hidden'); + document.body.style.overflow = 'hidden'; + + modalConfirmBtn.onclick = () => { + closeModal(); + if (onConfirm) onConfirm(); + }; + + modalCancelBtn.onclick = () => { + closeModal(); + if (onCancel) onCancel(); + }; + } + // 提交创建表单 async function submitCreateForm() { const form = document.getElementById('createForm'); @@ -1117,15 +1223,15 @@ }; if (!data.name) { - alert('请输入任务名称'); + showMessage('提示', '请输入任务名称', 'warning'); return; } if (!data.base_model) { - alert('请选择基础模型'); + showMessage('提示', '请选择基础模型', 'warning'); return; } if (!data.dataset_id) { - alert('请选择训练集'); + showMessage('提示', '请选择训练集', 'warning'); return; } @@ -1137,15 +1243,40 @@ }); const result = await response.json(); if (result.code === 0) { - alert('创建成功!'); - goBack(); + showMessage('成功', '训练任务创建成功!', 'success', () => { + goBack(); + }); } else { - alert(result.message || '创建失败'); + showMessage('错误', result.message || '创建失败', 'error'); } } catch (error) { - alert('创建失败: ' + error.message); + showMessage('错误', '创建失败: ' + error.message, 'error'); } } + + + diff --git a/web/pages/model-manage-create.html b/web/pages/model-manage-create.html new file mode 100644 index 0000000..0e4c00d --- /dev/null +++ b/web/pages/model-manage-create.html @@ -0,0 +1,358 @@ + + + + + + 添加模型 / 远光软件微调平台 + + + + + + + + + + +
+ +
+
+
+ + + 返回 + + | + 添加模型 +
+
+ +
+
+
+ + +
+ +
+
+ 资源管理 + / + 添加模型 +
+
+ + +
+
+
+ +
+

基本信息

+
+
+ + +

支持中文、英文、数字、下划线,最多100个字符

+
+
+ + +
+
+
+ + +
+

版本信息

+
+ + +

建议使用语义化版本号,如:v1.0.0、v2.1.0

+
+
+ + +
+

模型路径

+
+ + +

支持本地路径或云存储路径(OSS、S3、HDFS等)

+
+
+ + +
+

描述信息

+
+ + +

0 / 500

+
+
+ + +
+
+ + + 取消 + +
+
+
+
+
+
+
+ + + + + + +