重新构建路由和配置样式文件

This commit is contained in:
2025-03-26 10:04:27 +08:00
parent a42a9990bf
commit 97ccf5a077
141 changed files with 88034 additions and 179 deletions
+625
View File
@@ -0,0 +1,625 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>中国烟草AI合同及卷宗审核系统 - 新增/编辑系统配置</title>
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<!-- 引入外部CSS文件 -->
<link href="../css/main.css" rel="stylesheet">
<style>
.json-editor {
width: 100%;
min-height: 320px;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
font-size: 14px;
line-height: 1.6;
border: 1px solid #e2e8f0;
border-radius: 4px;
padding: 12px;
background-color: #f8f9fc;
color: #374151;
}
.editor-actions {
text-align: right;
margin-top: 8px;
}
.json-error {
color: #e53e3e;
margin-top: 8px;
font-size: 0.875rem;
}
.example-card {
height: 100%;
display: flex;
flex-direction: column;
background-color: #f8f9fc;
border-radius: 4px;
border: 1px solid #e2e8f0;
overflow: hidden;
}
.example-header {
padding: 12px;
border-bottom: 1px solid #e2e8f0;
background-color: #f1f5f9;
}
.example-title {
font-weight: 500;
color: #4a5568;
}
.example-content {
padding: 12px;
flex-grow: 1;
overflow: auto;
}
.example-pre {
margin: 0;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
font-size: 14px;
line-height: 1.6;
color: #374151;
}
.example-footer {
padding: 12px;
border-top: 1px solid #e2e8f0;
background-color: #f1f5f9;
}
/* 标签按钮样式 */
.tag-buttons {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 8px;
}
.tag-button {
display: inline-flex;
align-items: center;
padding: 4px 12px;
border-radius: 16px;
font-size: 12px;
background-color: #f3f4f6;
color: #4b5563;
border: 1px solid #e5e7eb;
cursor: pointer;
transition: all 0.2s;
}
.tag-button:hover {
background-color: rgba(0, 104, 74, 0.1);
border-color: var(--primary-color);
color: var(--primary-color);
}
.tag-button.active {
background-color: rgba(0, 104, 74, 0.15);
border-color: var(--primary-color);
color: var(--primary-color);
}
/* 代码语法高亮基础样式 */
.code-json .key { color: #07a; }
.code-json .string { color: #690; }
.code-json .number { color: #905; }
.code-json .boolean { color: #07a; }
.code-json .null { color: #999; }
</style>
</head>
<body>
<div class="layout-container">
<!-- 侧边栏 -->
<div class="sidebar">
<div class="py-6 px-4 border-b border-gray-100">
<div class="flex items-center">
<i class="ri-file-search-line text-primary text-xl mr-2"></i>
<h2 class="text-lg font-medium">AI审核系统</h2>
</div>
</div>
<div class="py-4">
<div class="sidebar-menu-item">
<a href="#" class="flex items-center text-sm font-medium">
<i class="ri-dashboard-line mr-3"></i>
<span>首页</span>
</a>
</div>
<div class="sidebar-menu-item">
<a href="#" class="flex items-center text-sm font-medium">
<i class="ri-file-upload-line mr-3"></i>
<span>文件上传</span>
</a>
</div>
<div class="sidebar-menu-item">
<a href="#" class="flex items-center text-sm font-medium">
<i class="ri-list-check-2 mr-3"></i>
<span>评查规则库</span>
</a>
</div>
<div class="sidebar-menu-item">
<a href="#" class="flex items-center text-sm font-medium">
<i class="ri-history-line mr-3"></i>
<span>审核历史</span>
</a>
</div>
<div class="sidebar-menu-item active">
<a href="#" class="flex items-center text-sm font-medium">
<i class="ri-settings-3-line mr-3"></i>
<span>系统设置</span>
</a>
</div>
</div>
</div>
<!-- 主内容区 -->
<div class="main-content">
<!-- 面包屑导航 -->
<div class="breadcrumb">
<span class="breadcrumb-item">首页</span>
<span class="breadcrumb-item">系统设置</span>
<span class="breadcrumb-item">系统配置管理</span>
<span class="breadcrumb-item" id="page-title">新增系统配置</span>
</div>
<!-- 页面头部 -->
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-medium" id="header-title">新增系统配置</h2>
<div>
<button class="ant-btn ant-btn-default mr-2" onclick="window.location.href='配置-列表.html'">
<i class="ri-arrow-left-line"></i> 返回
</button>
<button class="ant-btn ant-btn-primary" id="save-btn">
<i class="ri-save-line"></i> 保存
</button>
</div>
</div>
<!-- 表单 -->
<div class="ant-card">
<div class="ant-card-body">
<form id="config-form">
<div class="grid grid-cols-1 gap-6">
<!-- 配置名称和状态放在同一行 -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="form-group">
<label class="form-label">配置名称 <span class="text-red-500">*</span></label>
<input type="text" class="form-input" id="config-name" name="config_name" placeholder="请输入配置名称(如:database_connection" required>
<div class="text-sm text-secondary mt-1">唯一标识符,建议使用下划线命名法</div>
</div>
<div class="form-group">
<label class="form-label">状态</label>
<div class="mt-2">
<label class="inline-flex items-center">
<input type="checkbox" class="form-checkbox" id="is-active" name="is_active" checked>
<span class="ml-2">启用此配置</span>
</label>
</div>
<div class="text-sm text-secondary mt-1">禁用配置后,系统将不会读取此配置</div>
</div>
</div>
<!-- 修改所属模块为输入框+标签按钮(使用中文显示) -->
<div class="form-group">
<label class="form-label">所属模块 <span class="text-red-500">*</span></label>
<input type="text" class="form-input" id="module" name="module" placeholder="请输入或选择所属模块" required>
<div class="tag-buttons" id="module-tags">
<span class="tag-button" data-value="system">系统</span>
<span class="tag-button" data-value="auth">认证</span>
<span class="tag-button" data-value="file">文件</span>
<span class="tag-button" data-value="ai">AI配置</span>
<span class="tag-button" data-value="notification">通知</span>
</div>
<div class="text-sm text-secondary mt-1">将配置按功能模块进行分类,便于管理和查找</div>
</div>
<!-- 修改环境为输入框+标签按钮(使用中文显示,增加通用选项) -->
<div class="form-group">
<label class="form-label">环境 <span class="text-red-500">*</span></label>
<input type="text" class="form-input" id="environment" name="environment" placeholder="请输入或选择环境" required>
<div class="tag-buttons" id="env-tags">
<span class="tag-button" data-value="dev">开发环境</span>
<span class="tag-button" data-value="test">测试环境</span>
<span class="tag-button" data-value="prod">生产环境</span>
<span class="tag-button" data-value="common">通用</span>
</div>
<div class="text-sm text-secondary mt-1">不同环境可以使用相同的配置名称,系统会自动识别当前环境并使用对应配置</div>
</div>
<!-- 修改配置数据为左右等高两栏布局 -->
<div class="form-group">
<label class="form-label">配置数据 (JSON) <span class="text-red-500">*</span></label>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4" style="min-height: 390px;">
<!-- 左侧JSON编辑区 -->
<div class="h-full">
<textarea class="json-editor" id="config-data" name="config_data" required placeholder='请输入JSON格式的配置数据'></textarea>
<div class="editor-actions">
<button type="button" class="ant-btn ant-btn-text" id="btn-format-json">
<i class="ri-braces-line"></i> 格式化JSON
</button>
</div>
<div id="json-error" class="json-error hidden"></div>
</div>
<!-- 右侧示例区 -->
<div class="h-full">
<div class="example-card">
<div class="example-header">
<div class="example-title">配置示例</div>
</div>
<div class="example-content">
<pre class="example-pre" id="example-json"></pre>
</div>
<div class="example-footer">
<div class="text-sm font-medium mb-2">常用配置模板:</div>
<div class="flex flex-wrap gap-2">
<button type="button" class="ant-btn ant-btn-sm" onclick="loadTemplateJson('database')">数据库配置</button>
<button type="button" class="ant-btn ant-btn-sm" onclick="loadTemplateJson('file')">文件存储配置</button>
<button type="button" class="ant-btn ant-btn-sm" onclick="loadTemplateJson('ai')">AI服务配置</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 备注移到最后 -->
<div class="form-group">
<label class="form-label">备注</label>
<textarea class="form-textarea" id="remarks" name="remarks" placeholder="请输入配置备注信息" rows="2"></textarea>
<div class="text-sm text-secondary mt-1">可选填项,用于描述配置的用途、注意事项等</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 获取页面参数
const urlParams = new URLSearchParams(window.location.search);
const configId = urlParams.get('id');
// 判断是新增还是编辑模式
if (configId) {
document.getElementById('page-title').textContent = '编辑系统配置';
document.getElementById('header-title').textContent = '编辑系统配置';
// 加载配置数据
// 实际应用中应通过AJAX请求获取数据
loadConfigData(configId);
}
// 初始化示例JSON
initExampleJson();
// 格式化JSON按钮点击事件
document.getElementById('btn-format-json').addEventListener('click', function() {
formatJSON();
});
// 保存按钮点击事件
document.getElementById('save-btn').addEventListener('click', function() {
saveConfig();
});
// 初始化标签按钮事件
initTagButtons();
});
// 初始化示例JSON
function initExampleJson() {
const exampleObj = {
database: {
host: "db.cluster.com",
port: 5432,
pool_size: 20,
ssl: true
},
cache: {
ttl: 3600,
max_entries: 1000
},
feature_flags: ["new_ui", "analytics_v2"]
};
const exampleElement = document.getElementById('example-json');
exampleElement.innerHTML = syntaxHighlightJson(JSON.stringify(exampleObj, null, 2));
}
// JSON语法高亮
function syntaxHighlightJson(json) {
json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function(match) {
let cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
match = match.replace(':', '');
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="code-json ' + cls + '">' + match + '</span>';
});
}
// 初始化标签按钮事件
function initTagButtons() {
// 模块标签点击事件
document.querySelectorAll('#module-tags .tag-button').forEach(button => {
button.addEventListener('click', function() {
document.getElementById('module').value = this.textContent.trim();
// 更新选中状态
document.querySelectorAll('#module-tags .tag-button').forEach(btn => {
btn.classList.remove('active');
});
this.classList.add('active');
});
});
// 环境标签点击事件
document.querySelectorAll('#env-tags .tag-button').forEach(button => {
button.addEventListener('click', function() {
document.getElementById('environment').value = this.textContent.trim();
// 更新选中状态
document.querySelectorAll('#env-tags .tag-button').forEach(btn => {
btn.classList.remove('active');
});
this.classList.add('active');
});
});
}
// 加载配置数据
function loadConfigData(id) {
// 模拟数据
let configData = {
id: id,
config_name: 'database_connection',
module: 'system',
environment: 'prod',
is_active: true,
remarks: '数据库连接配置,包含主库和从库配置',
config_data: {
database: {
host: "db.cluster.com",
port: 5432,
pool_size: 20,
ssl: true
},
cache: {
ttl: 3600,
max_entries: 1000
},
feature_flags: ["new_ui", "analytics_v2"]
}
};
if (id === '2') {
configData.config_name = 'text_extraction_ai';
configData.module = 'ai';
configData.environment = 'test';
configData.remarks = 'AI文本抽取服务配置';
} else if (id === '3') {
configData.config_name = 'notification_service';
configData.module = 'notification';
configData.environment = 'dev';
configData.is_active = false;
configData.remarks = '通知服务配置,目前处于开发测试阶段';
} else if (id === '4') {
configData.config_name = 'file_storage';
configData.module = 'file';
configData.environment = 'common';
configData.remarks = '文件存储通用配置,适用于所有环境';
}
// 填充表单
document.getElementById('config-name').value = configData.config_name;
document.getElementById('module').value = getModuleDisplayName(configData.module);
document.getElementById('environment').value = getEnvironmentDisplayName(configData.environment);
document.getElementById('is-active').checked = configData.is_active;
document.getElementById('remarks').value = configData.remarks || '';
document.getElementById('config-data').value = JSON.stringify(configData.config_data, null, 2);
// 更新标签选中状态
updateTagSelection('module', configData.module);
updateTagSelection('environment', configData.environment);
}
// 获取模块显示名称
function getModuleDisplayName(moduleCode) {
const moduleMap = {
'system': '系统',
'auth': '认证',
'file': '文件',
'ai': 'AI配置',
'notification': '通知'
};
return moduleMap[moduleCode] || moduleCode;
}
// 获取环境显示名称
function getEnvironmentDisplayName(envCode) {
const envMap = {
'dev': '开发环境',
'test': '测试环境',
'prod': '生产环境',
'common': '通用'
};
return envMap[envCode] || envCode;
}
// 更新标签选中状态
function updateTagSelection(type, value) {
const selector = type === 'module' ? '#module-tags .tag-button' : '#env-tags .tag-button';
document.querySelectorAll(selector).forEach(btn => {
if (btn.getAttribute('data-value') === value) {
btn.classList.add('active');
} else {
btn.classList.remove('active');
}
});
}
// 加载模板JSON
function loadTemplateJson(type) {
let template = {};
if (type === 'database') {
template = {
database: {
host: "localhost",
port: 5432,
username: "db_user",
password: "******",
name: "app_database",
pool_size: 10,
timeout: 5000,
ssl: false
}
};
} else if (type === 'file') {
template = {
storage: {
type: "local", // or "s3", "oss"
path: "/data/uploads",
allowed_types: ["pdf", "docx", "jpg", "png"],
max_size: 10485760, // 10MB
backup_enabled: true
}
};
} else if (type === 'ai') {
template = {
ai_service: {
provider: "openai",
api_key: "sk-******",
model: "gpt-4",
max_tokens: 2000,
temperature: 0.7,
timeout: 30000,
rate_limit: 10 // requests per minute
}
};
}
document.getElementById('config-data').value = JSON.stringify(template, null, 2);
formatJSON();
}
// 格式化JSON
function formatJSON() {
const jsonArea = document.getElementById('config-data');
const jsonError = document.getElementById('json-error');
try {
const jsonStr = jsonArea.value.trim();
if (!jsonStr) {
return;
}
const jsonObj = JSON.parse(jsonStr);
jsonArea.value = JSON.stringify(jsonObj, null, 2);
jsonError.classList.add('hidden');
} catch (error) {
jsonError.textContent = '无效的JSON格式: ' + error.message;
jsonError.classList.remove('hidden');
}
}
// 保存配置
function saveConfig() {
const form = document.getElementById('config-form');
// 表单验证
if (!form.checkValidity()) {
form.reportValidity();
return;
}
// 验证JSON
const jsonArea = document.getElementById('config-data');
const jsonError = document.getElementById('json-error');
let configDataObj = null;
try {
configDataObj = JSON.parse(jsonArea.value);
jsonError.classList.add('hidden');
} catch (error) {
jsonError.textContent = '无效的JSON格式: ' + error.message;
jsonError.classList.remove('hidden');
return;
}
// 获取表单数据
const configName = document.getElementById('config-name').value;
const moduleDisplay = document.getElementById('module').value;
const environmentDisplay = document.getElementById('environment').value;
const isActive = document.getElementById('is-active').checked;
const remarks = document.getElementById('remarks').value;
// 获取模块和环境的实际值
const module = getModuleCodeFromDisplay(moduleDisplay);
const environment = getEnvironmentCodeFromDisplay(environmentDisplay);
// 构建要提交的数据
const formData = {
id: urlParams.get('id') || null,
config_name: configName,
module: module,
environment: environment,
is_active: isActive,
remarks: remarks,
config_data: configDataObj
};
console.log('提交数据:', formData);
// 实际应用中应通过AJAX提交数据
setTimeout(() => {
alert('保存成功!');
window.location.href = '配置-列表.html';
}, 500);
}
// 从显示名称获取模块代码
function getModuleCodeFromDisplay(displayName) {
const moduleMap = {
'系统': 'system',
'认证': 'auth',
'文件': 'file',
'AI配置': 'ai',
'通知': 'notification'
};
return moduleMap[displayName] || displayName;
}
// 从显示名称获取环境代码
function getEnvironmentCodeFromDisplay(displayName) {
const envMap = {
'开发环境': 'dev',
'测试环境': 'test',
'生产环境': 'prod',
'通用': 'common'
};
return envMap[displayName] || displayName;
}
</script>
</body>
</html>