feat: 后台添加大模型配置管理页面
- 新增 /admin/llm_config 页面 - 支持配置API地址、Key、模型名称、参数 - 支持测试连接和恢复默认配置 - 配置保存到数据库,翻译服务动态读取 - 所有后台页面侧边栏添加入口
This commit is contained in:
106
admin.py
106
admin.py
@@ -662,3 +662,109 @@ def api_user_add_package(user_id):
|
||||
'name': user_package.package_name,
|
||||
'remaining': user_package.remaining_count
|
||||
}})
|
||||
|
||||
|
||||
# ==================== LLM大模型配置 ====================
|
||||
@admin_bp.route('/llm_config')
|
||||
@admin_required
|
||||
def llm_config():
|
||||
"""LLM配置页面"""
|
||||
from config import LLM_CONFIG
|
||||
|
||||
# 从数据库获取配置,如果没有则使用默认值
|
||||
config = {
|
||||
'api_base': DynamicConfig.get('llm_api_base', LLM_CONFIG.get('api_base')),
|
||||
'api_key': DynamicConfig.get('llm_api_key', LLM_CONFIG.get('api_key')),
|
||||
'model': DynamicConfig.get('llm_model', LLM_CONFIG.get('model')),
|
||||
'max_tokens': DynamicConfig.get('llm_max_tokens', LLM_CONFIG.get('max_tokens')),
|
||||
'chunk_size': DynamicConfig.get('llm_chunk_size', LLM_CONFIG.get('chunk_size')),
|
||||
'timeout': DynamicConfig.get('llm_timeout', LLM_CONFIG.get('timeout')),
|
||||
}
|
||||
|
||||
return render_template('admin/llm_config.html', config=config)
|
||||
|
||||
|
||||
@admin_bp.route('/llm_config/save', methods=['POST'])
|
||||
@admin_required
|
||||
def save_llm_config():
|
||||
"""保存LLM配置"""
|
||||
data = request.json
|
||||
|
||||
DynamicConfig.set('llm_api_base', data.get('api_base'), category='llm', user_id=session.get('user_id'))
|
||||
DynamicConfig.set('llm_api_key', data.get('api_key'), category='llm', user_id=session.get('user_id'))
|
||||
DynamicConfig.set('llm_model', data.get('model'), category='llm', user_id=session.get('user_id'))
|
||||
DynamicConfig.set('llm_max_tokens', data.get('max_tokens'), category='llm', value_type='int', user_id=session.get('user_id'))
|
||||
DynamicConfig.set('llm_chunk_size', data.get('chunk_size'), category='llm', value_type='int', user_id=session.get('user_id'))
|
||||
DynamicConfig.set('llm_timeout', data.get('timeout'), category='llm', value_type='int', user_id=session.get('user_id'))
|
||||
|
||||
# 记录日志
|
||||
log = OperationLog(
|
||||
user_id=session.get('user_id'),
|
||||
username='admin',
|
||||
action='update_llm_config',
|
||||
detail='更新大模型配置'
|
||||
)
|
||||
db.session.add(log)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({'success': True})
|
||||
|
||||
|
||||
@admin_bp.route('/llm_config/test', methods=['POST'])
|
||||
@admin_required
|
||||
def test_llm_connection():
|
||||
"""测试LLM连接"""
|
||||
data = request.json
|
||||
|
||||
try:
|
||||
from openai import OpenAI
|
||||
|
||||
client = OpenAI(
|
||||
api_key=data.get('api_key', 'sk-test'),
|
||||
base_url=data.get('api_base'),
|
||||
)
|
||||
|
||||
# 发送简单测试请求
|
||||
response = client.chat.completions.create(
|
||||
model=data.get('model'),
|
||||
messages=[{"role": "user", "content": "Hello"}],
|
||||
max_tokens=10,
|
||||
timeout=10,
|
||||
)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'model': data.get('model'),
|
||||
'response': response.choices[0].message.content[:50] if response.choices else 'OK'
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'error': str(e)})
|
||||
|
||||
|
||||
@admin_bp.route('/llm_config/reset', methods=['POST'])
|
||||
@admin_required
|
||||
def reset_llm_config():
|
||||
"""恢复默认LLM配置"""
|
||||
from config import LLM_CONFIG
|
||||
|
||||
# 删除数据库中的LLM配置
|
||||
DynamicConfig.query.filter_by(category='llm').delete()
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({'success': True})
|
||||
|
||||
|
||||
# ==================== 获取当前LLM配置(供其他模块使用) ====================
|
||||
def get_llm_config():
|
||||
"""获取当前LLM配置"""
|
||||
from config import LLM_CONFIG
|
||||
|
||||
return {
|
||||
'api_base': DynamicConfig.get('llm_api_base', LLM_CONFIG.get('api_base')),
|
||||
'api_key': DynamicConfig.get('llm_api_key', LLM_CONFIG.get('api_key')),
|
||||
'model': DynamicConfig.get('llm_model', LLM_CONFIG.get('model')),
|
||||
'max_tokens': DynamicConfig.get('llm_max_tokens', LLM_CONFIG.get('max_tokens')),
|
||||
'chunk_size': DynamicConfig.get('llm_chunk_size', LLM_CONFIG.get('chunk_size')),
|
||||
'timeout': DynamicConfig.get('llm_timeout', LLM_CONFIG.get('timeout')),
|
||||
}
|
||||
@@ -274,6 +274,13 @@ class TranslationTask:
|
||||
|
||||
# 启动翻译线程
|
||||
def run_translation():
|
||||
# 动态获取LLM配置
|
||||
if app:
|
||||
with app.app_context():
|
||||
from admin import get_llm_config
|
||||
llm_config = get_llm_config()
|
||||
config['LLM_CONFIG'] = llm_config
|
||||
|
||||
service = TranslationService(config)
|
||||
task['status'] = 'processing'
|
||||
task['started_at'] = datetime.now().isoformat()
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<li class="nav-item"><a class="nav-link active" href="{{ url_for('admin.cache_list') }}"><i class="bi bi-database"></i> 缓存管理</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -93,6 +93,11 @@
|
||||
<i class="bi bi-list-check"></i> 操作日志
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('admin.llm_config') }}">
|
||||
<i class="bi bi-cpu"></i> 大模型配置
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('admin.settings') }}">
|
||||
<i class="bi bi-sliders"></i> 系统配置
|
||||
|
||||
187
templates/admin/llm_config.html
Normal file
187
templates/admin/llm_config.html
Normal file
@@ -0,0 +1,187 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>大模型配置 - 后台管理</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet">
|
||||
<style>
|
||||
body { background-color: #f5f5f5; }
|
||||
.sidebar { position: fixed; top: 0; left: 0; height: 100vh; width: 250px; background: #343a40; padding-top: 60px; }
|
||||
.sidebar .nav-link { color: #adb5bd; padding: 12px 20px; }
|
||||
.sidebar .nav-link:hover, .sidebar .nav-link.active { color: #fff; background: rgba(255,255,255,0.1); }
|
||||
.main-content { margin-left: 250px; padding: 20px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="sidebar">
|
||||
<div class="position-absolute top-0 w-100 p-3 border-bottom border-secondary">
|
||||
<h5 class="text-white mb-0"><i class="bi bi-gear-fill"></i> 后台管理</h5>
|
||||
</div>
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.dashboard') }}"><i class="bi bi-speedometer2"></i> 数据概览</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.users') }}"><i class="bi bi-people"></i> 用户管理</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.translations') }}"><i class="bi bi-file-text"></i> 翻译记录</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.cache_list') }}"><i class="bi bi-database"></i> 缓存管理</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link active" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
<a href="/" class="btn btn-outline-light btn-sm w-100"><i class="bi bi-house"></i> 返回前台</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="main-content">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h6 class="mb-0"><i class="bi bi-cpu"></i> 大模型接口配置</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="llmConfigForm">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">API 地址</label>
|
||||
<input type="text" class="form-control" name="api_base" value="{{ config.api_base }}" placeholder="http://localhost:1234/v1">
|
||||
<small class="text-muted">LLM服务的API endpoint</small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">API Key</label>
|
||||
<input type="text" class="form-control" name="api_key" value="{{ config.api_key }}" placeholder="sk-xxx">
|
||||
<small class="text-muted">如果不需要可留空</small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">模型名称</label>
|
||||
<input type="text" class="form-control" name="model" value="{{ config.model }}" placeholder="qwen/qwen3.5-35b">
|
||||
<small class="text-muted">使用的模型ID</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">最大输出Token</label>
|
||||
<input type="number" class="form-control" name="max_tokens" value="{{ config.max_tokens }}" placeholder="8000">
|
||||
<small class="text-muted">每次翻译最大输出长度</small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">分块大小</label>
|
||||
<input type="number" class="form-control" name="chunk_size" value="{{ config.chunk_size }}" placeholder="2000">
|
||||
<small class="text-muted">PDF文本分块大小</small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">超时时间(秒)</label>
|
||||
<input type="number" class="form-control" name="timeout" value="{{ config.timeout }}" placeholder="180">
|
||||
<small class="text-muted">API请求超时时间</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<button type="submit" class="btn btn-primary"><i class="bi bi-check-lg"></i> 保存配置</button>
|
||||
<button type="button" class="btn btn-outline-secondary" onclick="testConnection()"><i class="bi bi-plug"></i> 测试连接</button>
|
||||
<button type="button" class="btn btn-outline-warning" onclick="resetToDefault()"><i class="bi bi-arrow-counterclockwise"></i> 恢复默认</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="testResult" class="mt-3" style="display:none;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-3">
|
||||
<div class="card-header"><h6 class="mb-0"><i class="bi bi-info-circle"></i> 常用模型配置参考</h6></div>
|
||||
<div class="card-body">
|
||||
<table class="table table-sm">
|
||||
<thead class="table-light">
|
||||
<tr><th>服务商</th><th>API地址</th><th>模型示例</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>本地LM Studio</td><td>http://localhost:1234/v1</td><td>根据加载的模型</td></tr>
|
||||
<tr><td>OpenAI</td><td>https://api.openai.com/v1</td><td>gpt-4, gpt-3.5-turbo</td></tr>
|
||||
<tr><td>DeepSeek</td><td>https://api.deepseek.com/v1</td><td>deepseek-chat</td></tr>
|
||||
<tr><td>阿里百炼</td><td>https://dashscope.aliyuncs.com/compatible-mode/v1</td><td>qwen-turbo, qwen-plus</td></tr>
|
||||
<tr><td>SiliconFlow</td><td>https://api.siliconflow.cn/v1</td><td>Qwen/Qwen2.5-72B-Instruct</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
document.getElementById('llmConfigForm').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const formData = new FormData(this);
|
||||
const data = {};
|
||||
formData.forEach((value, key) => {
|
||||
if (key === 'max_tokens' || key === 'chunk_size' || key === 'timeout') {
|
||||
data[key] = parseInt(value) || 0;
|
||||
} else {
|
||||
data[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
fetch('/admin/llm_config/save', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
alert('配置已保存!');
|
||||
} else {
|
||||
alert('保存失败: ' + res.error);
|
||||
}
|
||||
})
|
||||
.catch(err => alert('请求失败: ' + err));
|
||||
});
|
||||
|
||||
function testConnection() {
|
||||
const formData = new FormData(document.getElementById('llmConfigForm'));
|
||||
const data = {};
|
||||
formData.forEach((value, key) => {
|
||||
if (key === 'max_tokens' || key === 'chunk_size' || key === 'timeout') {
|
||||
data[key] = parseInt(value) || 0;
|
||||
} else {
|
||||
data[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
const resultDiv = document.getElementById('testResult');
|
||||
resultDiv.style.display = 'block';
|
||||
resultDiv.innerHTML = '<div class="alert alert-info">正在测试连接...</div>';
|
||||
|
||||
fetch('/admin/llm_config/test', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
resultDiv.innerHTML = '<div class="alert alert-success"><i class="bi bi-check-circle"></i> 连接成功!模型: ' + res.model + '</div>';
|
||||
} else {
|
||||
resultDiv.innerHTML = '<div class="alert alert-danger"><i class="bi bi-x-circle"></i> 连接失败: ' + res.error + '</div>';
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
resultDiv.innerHTML = '<div class="alert alert-danger"><i class="bi bi-x-circle"></i> 请求失败: ' + err + '</div>';
|
||||
});
|
||||
}
|
||||
|
||||
function resetToDefault() {
|
||||
if (confirm('确定恢复默认配置吗?')) {
|
||||
fetch('/admin/llm_config/reset', {method: 'POST'})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
location.reload();
|
||||
} else {
|
||||
alert('恢复失败: ' + res.error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -25,6 +25,7 @@
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.cache_list') }}"><i class="bi bi-database"></i> 缓存管理</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link active" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.packages') }}"><i class="bi bi-box-seam"></i> 数据包套餐</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link active" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<li class="nav-item"><a class="nav-link active" href="{{ url_for('admin.packages') }}"><i class="bi bi-box-seam"></i> 数据包套餐</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
<li class="nav-item"><a class="nav-link active" href="{{ url_for('admin.packages') }}"><i class="bi bi-box-seam"></i> 数据包套餐</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.cache_list') }}"><i class="bi bi-database"></i> 缓存管理</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link active" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.cache_list') }}"><i class="bi bi-database"></i> 缓存管理</a></li>
|
||||
<li class="nav-item"><a class="nav-link active" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.cache_list') }}"><i class="bi bi-database"></i> 缓存管理</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.cache_list') }}"><i class="bi bi-database"></i> 缓存管理</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.cache_list') }}"><i class="bi bi-database"></i> 缓存管理</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.packages') }}"><i class="bi bi-box-seam"></i> 数据包套餐</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link active" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.cache_list') }}"><i class="bi bi-database"></i> 缓存管理</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
|
||||
</ul>
|
||||
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
|
||||
|
||||
Reference in New Issue
Block a user