重新构建路由和配置样式文件
This commit is contained in:
@@ -0,0 +1,935 @@
|
||||
<!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">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #00684a;
|
||||
--primary-hover: #005a40;
|
||||
--primary-light: rgba(0, 104, 74, 0.1);
|
||||
--success-color: #52c41a;
|
||||
--warning-color: #faad14;
|
||||
--error-color: #ff4d4f;
|
||||
--text-color: rgba(0, 0, 0, 0.85);
|
||||
--text-secondary: rgba(0, 0, 0, 0.45);
|
||||
--border-color: #f0f0f0;
|
||||
--bg-gray: #f5f5f5;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
line-height: 1.5;
|
||||
color: var(--text-color);
|
||||
background-color: var(--bg-gray);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.layout-container {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin-left: 280px;
|
||||
padding: 24px;
|
||||
width: calc(100% - 280px);
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.breadcrumb-item {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.breadcrumb-item:last-child {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.breadcrumb-item:not(:last-child)::after {
|
||||
content: '/';
|
||||
margin: 0 8px;
|
||||
color: #d9d9d9;
|
||||
}
|
||||
|
||||
.text-primary { color: var(--primary-color); }
|
||||
.text-success { color: var(--success-color); }
|
||||
.text-warning { color: var(--warning-color); }
|
||||
.text-error { color: var(--error-color); }
|
||||
.text-secondary { color: var(--text-secondary); }
|
||||
|
||||
.bg-primary { background-color: var(--primary-color); }
|
||||
.bg-primary-light { background-color: var(--primary-light); }
|
||||
.hover\:underline:hover { text-decoration: underline; }
|
||||
|
||||
.ant-card {
|
||||
background-color: white;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.ant-card-header {
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ant-card-body {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.ant-btn {
|
||||
border-radius: 4px;
|
||||
padding: 8px 16px;
|
||||
font-size: 14px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.ant-btn i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.ant-btn-primary {
|
||||
background-color: var(--primary-color);
|
||||
border: 1px solid var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.ant-btn-primary:hover {
|
||||
background-color: var(--primary-hover);
|
||||
border-color: var(--primary-hover);
|
||||
}
|
||||
|
||||
.ant-btn-default {
|
||||
background-color: white;
|
||||
border: 1px solid #d9d9d9;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.ant-btn-default:hover {
|
||||
border-color: var(--primary-color);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
font-size: 14px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.form-input, .form-select, .form-textarea {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
font-size: 14px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.form-input:focus, .form-select:focus, .form-textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 2px rgba(0, 104, 74, 0.2);
|
||||
}
|
||||
|
||||
.form-textarea {
|
||||
resize: vertical;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.form-code-editor {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
min-height: 300px;
|
||||
line-height: 1.5;
|
||||
font-size: 14px;
|
||||
padding: 12px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.var-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 2px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
background-color: rgba(0, 104, 74, 0.1);
|
||||
color: var(--primary-color);
|
||||
margin-right: 6px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.var-badge i {
|
||||
font-size: 14px;
|
||||
margin-left: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.var-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.help-text {
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.var-input-group {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.var-input-group .form-input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.var-input-group .ant-btn {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.type-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 3px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.type-common {
|
||||
background-color: rgba(0, 104, 74, 0.1);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.type-extraction {
|
||||
background-color: rgba(82, 196, 26, 0.1);
|
||||
color: var(--success-color);
|
||||
}
|
||||
|
||||
.type-evaluation {
|
||||
background-color: rgba(250, 173, 20, 0.1);
|
||||
color: var(--warning-color);
|
||||
}
|
||||
|
||||
.type-summary {
|
||||
background-color: rgba(24, 144, 255, 0.1);
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.example-section {
|
||||
margin-top: 8px;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.example-header {
|
||||
font-weight: 500;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.read-only-field {
|
||||
background-color: #f5f5f5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 44px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
transition: .4s;
|
||||
border-radius: 34px;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
left: 3px;
|
||||
bottom: 2px;
|
||||
background-color: white;
|
||||
transition: .4s;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: var(--primary-color);
|
||||
}
|
||||
|
||||
input:focus + .slider {
|
||||
box-shadow: 0 0 1px var(--primary-color);
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 12px 16px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.alert i {
|
||||
margin-right: 8px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background-color: #e6f7ff;
|
||||
border: 1px solid #91d5ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
background-color: #fffbe6;
|
||||
border: 1px solid #ffe58f;
|
||||
color: #faad14;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="layout-container">
|
||||
<!-- 引入导航侧边栏 -->
|
||||
<div id="nav-container"></div>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<div class="main-content">
|
||||
<!-- 面包屑导航 -->
|
||||
<div class="breadcrumb">
|
||||
<span class="breadcrumb-item">首页</span>
|
||||
<span class="breadcrumb-item">评查规则库</span>
|
||||
<span class="breadcrumb-item">
|
||||
<a href="提示词-列表.html" class="text-primary hover:underline">提示词模板管理</a>
|
||||
</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 id="view-mode-alert" style="display: none;" class="alert alert-info">
|
||||
<i class="ri-information-line"></i>
|
||||
<div>
|
||||
<div>您正在查看系统预设模板,此模板不可修改。如需基于此模板创建新模板,请点击"复制创建"按钮。</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模板表单 -->
|
||||
<div class="ant-card">
|
||||
<div class="ant-card-header">提示词模板信息</div>
|
||||
<div class="ant-card-body p-4">
|
||||
<form id="template-form">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<!-- 模板名称 -->
|
||||
<div class="form-group mb-3">
|
||||
<label class="form-label mb-1">模板名称 <span class="text-error">*</span></label>
|
||||
<input type="text" class="form-input py-1" name="template_name" id="template-name" placeholder="请输入模板名称" required>
|
||||
<div class="help-text text-xs">建议使用"文档类型-功能"的命名方式</div>
|
||||
</div>
|
||||
|
||||
<!-- 模板类型 -->
|
||||
<div class="form-group mb-3">
|
||||
<label class="form-label mb-1">模板类型 <span class="text-error">*</span></label>
|
||||
<select class="form-select py-1" name="template_type" id="template-type" required>
|
||||
<option value="">请选择模板类型</option>
|
||||
<option value="Common">通用(Common) - 适用于多种场景的通用提示词</option>
|
||||
<option value="Extraction">抽取(Extraction) - 从文档抽取结构化信息</option>
|
||||
<option value="Evaluation">评估(Evaluation) - 对文档内容进行评估</option>
|
||||
<option value="Summary">摘要(Summary) - 生成文档内容摘要</option>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 模板描述 -->
|
||||
<div class="form-group mb-3">
|
||||
<label class="form-label mb-1">模板描述</label>
|
||||
<textarea class="form-textarea py-1" name="description" id="template-description" placeholder="请简要描述此模板的功能和用途" rows="2"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<!-- 模板状态 -->
|
||||
<div class="form-group mb-3">
|
||||
<label class="form-label mb-1">模板状态</label>
|
||||
<div class="flex items-center mt-1">
|
||||
<label class="switch mr-2">
|
||||
<input type="checkbox" id="status-toggle" name="status" value="1" checked>
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span id="status-text">启用</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模板版本 -->
|
||||
<div class="form-group mb-3">
|
||||
<label class="form-label mb-1">模板版本</label>
|
||||
<input type="text" class="form-input py-1" name="version" id="template-version" placeholder="例如:v1.0" value="v1.0" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模板内容编辑 -->
|
||||
<div class="ant-card">
|
||||
<div class="ant-card-header">提示词模板内容</div>
|
||||
<div class="ant-card-body">
|
||||
<div class="alert alert-warning mb-4">
|
||||
<i class="ri-information-line"></i>
|
||||
<div>
|
||||
<div>模板内容支持使用变量,变量格式为 <code>{varName}</code>,在使用时会自动替换。系统将自动识别模板中的变量。</div>
|
||||
<div class="mt-1">例如:<code>请从以下{docType}文档中抽取关键信息...</code></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">模板内容 <span class="text-error">*</span></label>
|
||||
<textarea class="form-code-editor w-full" name="template_content" id="template-content" rows="15" placeholder="在此输入提示词模板内容..." required></textarea>
|
||||
<div class="help-text">提示词模板是AI完成特定任务的指令,请清晰描述任务需求和输出格式</div>
|
||||
</div>
|
||||
|
||||
<!-- 变量识别区域 -->
|
||||
<div class="form-group mt-6">
|
||||
<label class="form-label">已识别的变量</label>
|
||||
<div class="alert alert-info mb-3">
|
||||
<i class="ri-lightbulb-line"></i>
|
||||
<div>
|
||||
<div>系统已自动识别出模板中的变量。变量以 <code>{varName}</code> 形式在模板中使用,无需手动定义。</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="var-container" id="var-container">
|
||||
<!-- 变量标签会动态添加在这里 -->
|
||||
<div class="text-secondary text-sm italic" id="no-vars-message">暂未识别到任何变量,请在模板内容中使用 {变量名} 格式添加变量</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" id="variables-json" name="variables" value="{}">
|
||||
</div>
|
||||
|
||||
<!-- 模板效果预览 -->
|
||||
<div class="form-group mt-6">
|
||||
<label class="form-label">模板效果预览</label>
|
||||
<div class="example-section">
|
||||
<div class="example-header">变量赋值示例:</div>
|
||||
<div id="example-vars" class="mb-3">
|
||||
<div class="var-input-group">
|
||||
<input type="text" class="form-input" value="docType" readonly>
|
||||
<input type="text" class="form-input" id="example-docType" placeholder="示例值,如 销售合同">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="example-header">预览效果:</div>
|
||||
<div id="preview-content" class="bg-gray-50 p-4 rounded border border-gray-200">
|
||||
<!-- 预览内容将动态生成 -->
|
||||
<div class="text-gray-400 italic">根据变量值生成的模板预览将显示在这里...</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end mt-3">
|
||||
<button type="button" class="ant-btn ant-btn-default" id="preview-btn">
|
||||
<i class="ri-eye-line"></i> 更新预览
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部按钮区域 -->
|
||||
<div class="flex justify-between mt-6">
|
||||
<div>
|
||||
<button id="clone-btn" style="display: none;" class="ant-btn ant-btn-default">
|
||||
<i class="ri-file-copy-line"></i> 复制创建
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="ant-btn ant-btn-default mr-2" onclick="window.location.href='提示词-列表.html'">
|
||||
<i class="ri-close-line"></i> 取消
|
||||
</button>
|
||||
<button id="save-btn-bottom" class="ant-btn ant-btn-primary">
|
||||
<i class="ri-save-line"></i> 保存
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 全局变量
|
||||
let isViewMode = false;
|
||||
let isCloneMode = false;
|
||||
let isEditMode = false;
|
||||
let templateId = null;
|
||||
let variables = {};
|
||||
|
||||
// 加载导航栏并初始化页面
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// 加载导航栏
|
||||
fetch('nav.html')
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
document.getElementById('nav-container').innerHTML = html;
|
||||
})
|
||||
.catch(error => console.error('加载导航栏失败:', error));
|
||||
|
||||
// 获取URL参数
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
templateId = urlParams.get('id');
|
||||
const mode = urlParams.get('mode') || 'create';
|
||||
|
||||
// 根据模式设置页面状态
|
||||
if (mode === 'view') {
|
||||
isViewMode = true;
|
||||
document.getElementById('page-title').textContent = '查看提示词模板';
|
||||
document.getElementById('header-title').textContent = '查看提示词模板';
|
||||
document.getElementById('view-mode-alert').style.display = 'flex';
|
||||
document.getElementById('clone-btn').style.display = 'inline-flex';
|
||||
|
||||
// 禁用所有输入控件
|
||||
disableAllInputs();
|
||||
|
||||
// 隐藏底部保存按钮,顶部保存按钮改为"返回"
|
||||
document.getElementById('save-btn-bottom').style.display = 'none';
|
||||
document.getElementById('save-btn').innerHTML = '<i class="ri-arrow-left-line"></i> 返回列表';
|
||||
document.getElementById('save-btn').onclick = function() {
|
||||
window.location.href = '提示词-列表.html';
|
||||
};
|
||||
} else if (mode === 'edit') {
|
||||
isEditMode = true;
|
||||
document.getElementById('page-title').textContent = '编辑提示词模板';
|
||||
document.getElementById('header-title').textContent = '编辑提示词模板';
|
||||
} else if (mode === 'clone') {
|
||||
isCloneMode = true;
|
||||
document.getElementById('page-title').textContent = '复制创建提示词模板';
|
||||
document.getElementById('header-title').textContent = '复制创建提示词模板';
|
||||
|
||||
// 给模板名称添加"(副本)"后缀
|
||||
const templateNameInput = document.getElementById('template-name');
|
||||
templateNameInput.addEventListener('input', function() {
|
||||
if (!this.value.includes('(副本)') && !this._hasAppendedCopy) {
|
||||
this.value += ' (副本)';
|
||||
this._hasAppendedCopy = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 如果是编辑、查看或复制模式,加载模板数据
|
||||
if (templateId) {
|
||||
loadTemplateData(templateId);
|
||||
}
|
||||
|
||||
// 绑定事件处理程序
|
||||
bindEventHandlers();
|
||||
});
|
||||
|
||||
// 加载模板数据
|
||||
function loadTemplateData(id) {
|
||||
// 模拟从服务器获取数据
|
||||
// 实际应用中应该使用AJAX请求获取数据
|
||||
const templateData = getTemplateById(id);
|
||||
|
||||
if (!templateData) {
|
||||
alert('未找到模板数据!');
|
||||
window.location.href = '提示词-列表.html';
|
||||
return;
|
||||
}
|
||||
|
||||
// 填充表单字段
|
||||
document.getElementById('template-name').value = isCloneMode
|
||||
? templateData.template_name + ' (副本)'
|
||||
: templateData.template_name;
|
||||
|
||||
document.getElementById('template-type').value = templateData.template_type;
|
||||
document.getElementById('template-description').value = templateData.description;
|
||||
document.getElementById('status-toggle').checked = templateData.status === 1;
|
||||
document.getElementById('status-text').textContent = templateData.status === 1 ? '启用' : '停用';
|
||||
document.getElementById('template-version').value = isCloneMode ? 'v1.0' : templateData.version;
|
||||
document.getElementById('template-content').value = templateData.template_content;
|
||||
|
||||
// 自动检测变量
|
||||
detectVariables();
|
||||
|
||||
// 解析变量并添加示例值
|
||||
try {
|
||||
const loadedVars = JSON.parse(templateData.variables || '{}');
|
||||
// 更新示例输入框的值
|
||||
for (const [key, value] of Object.entries(loadedVars)) {
|
||||
const exampleInput = document.getElementById(`example-${key}`);
|
||||
if (exampleInput && value !== key) {
|
||||
exampleInput.setAttribute('placeholder', `示例值,如 ${value}`);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析变量失败:', e);
|
||||
}
|
||||
|
||||
// 更新预览
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
// 禁用所有输入控件(查看模式使用)
|
||||
function disableAllInputs() {
|
||||
const inputs = document.querySelectorAll('input, textarea, select');
|
||||
inputs.forEach(input => {
|
||||
input.disabled = true;
|
||||
input.classList.add('read-only-field');
|
||||
});
|
||||
|
||||
// 隐藏添加变量按钮
|
||||
document.getElementById('add-var-btn').style.display = 'none';
|
||||
|
||||
// 隐藏变量删除图标
|
||||
document.querySelectorAll('.var-badge i').forEach(icon => {
|
||||
icon.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// 绑定事件处理程序
|
||||
function bindEventHandlers() {
|
||||
// 状态切换
|
||||
const statusToggle = document.getElementById('status-toggle');
|
||||
statusToggle.addEventListener('change', function() {
|
||||
document.getElementById('status-text').textContent = this.checked ? '启用' : '停用';
|
||||
});
|
||||
|
||||
// 监听模板内容变化,自动识别变量
|
||||
const templateContent = document.getElementById('template-content');
|
||||
templateContent.addEventListener('input', detectVariables);
|
||||
|
||||
// 更新预览按钮
|
||||
const previewBtn = document.getElementById('preview-btn');
|
||||
previewBtn.addEventListener('click', updatePreview);
|
||||
|
||||
// 复制创建按钮
|
||||
const cloneBtn = document.getElementById('clone-btn');
|
||||
cloneBtn.addEventListener('click', function() {
|
||||
window.location.href = `提示词-新增修改.html?id=${templateId}&mode=clone`;
|
||||
});
|
||||
|
||||
// 保存按钮
|
||||
const saveBtn = document.getElementById('save-btn');
|
||||
const saveBtnBottom = document.getElementById('save-btn-bottom');
|
||||
|
||||
const saveHandler = function() {
|
||||
if (isViewMode) return;
|
||||
|
||||
// 在保存前再次检测变量
|
||||
detectVariables();
|
||||
|
||||
// 表单验证
|
||||
const form = document.getElementById('template-form');
|
||||
if (!form.checkValidity()) {
|
||||
form.reportValidity();
|
||||
return;
|
||||
}
|
||||
|
||||
const templateContent = document.getElementById('template-content').value.trim();
|
||||
if (!templateContent) {
|
||||
alert('请输入模板内容');
|
||||
document.getElementById('template-content').focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// 收集表单数据
|
||||
const formData = {
|
||||
id: isCloneMode ? null : templateId,
|
||||
template_name: document.getElementById('template-name').value,
|
||||
template_type: document.getElementById('template-type').value,
|
||||
description: document.getElementById('template-description').value,
|
||||
status: document.getElementById('status-toggle').checked ? 1 : 0,
|
||||
version: document.getElementById('template-version').value,
|
||||
template_content: templateContent,
|
||||
variables: document.getElementById('variables-json').value,
|
||||
created_by: 'admin' // 当前登录用户
|
||||
};
|
||||
|
||||
console.log('保存数据:', formData);
|
||||
|
||||
// 实际应用中应使用AJAX请求保存数据
|
||||
alert('保存成功!');
|
||||
window.location.href = '提示词-列表.html';
|
||||
};
|
||||
|
||||
saveBtn.addEventListener('click', saveHandler);
|
||||
saveBtnBottom.addEventListener('click', saveHandler);
|
||||
}
|
||||
|
||||
// 自动检测模板内容中的变量
|
||||
function detectVariables() {
|
||||
const content = document.getElementById('template-content').value;
|
||||
const regex = /{([^{}]+)}/g;
|
||||
let match;
|
||||
let detectedVars = {};
|
||||
|
||||
// 清空现有变量
|
||||
variables = {};
|
||||
document.getElementById('var-container').innerHTML = '';
|
||||
document.getElementById('example-vars').innerHTML = '';
|
||||
|
||||
// 查找所有变量
|
||||
while ((match = regex.exec(content)) !== null) {
|
||||
const varName = match[1].trim();
|
||||
if (varName && !detectedVars[varName]) {
|
||||
detectedVars[varName] = varName;
|
||||
variables[varName] = varName;
|
||||
|
||||
// 添加变量标签
|
||||
addVariableBadge(varName);
|
||||
|
||||
// 添加到示例变量输入框
|
||||
addExampleVarInput(varName);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新变量JSON
|
||||
document.getElementById('variables-json').value = JSON.stringify(variables);
|
||||
|
||||
// 显示或隐藏提示消息
|
||||
const noVarsMessage = document.getElementById('no-vars-message');
|
||||
if (Object.keys(variables).length > 0) {
|
||||
if (noVarsMessage) noVarsMessage.style.display = 'none';
|
||||
} else {
|
||||
if (noVarsMessage) noVarsMessage.style.display = 'block';
|
||||
else {
|
||||
const container = document.getElementById('var-container');
|
||||
container.innerHTML = '<div class="text-secondary text-sm italic" id="no-vars-message">暂未识别到任何变量,请在模板内容中使用 {变量名} 格式添加变量</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加变量标签
|
||||
function addVariableBadge(name, description) {
|
||||
const container = document.getElementById('var-container');
|
||||
const badge = document.createElement('div');
|
||||
badge.className = 'var-badge';
|
||||
badge.dataset.varName = name;
|
||||
badge.innerHTML = `${name}${description && description !== name ? ': ' + description : ''}`;
|
||||
container.appendChild(badge);
|
||||
}
|
||||
|
||||
// 添加示例变量输入框
|
||||
function addExampleVarInput(name) {
|
||||
const container = document.getElementById('example-vars');
|
||||
|
||||
// 检查是否已存在
|
||||
if (document.getElementById(`example-${name}`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const inputGroup = document.createElement('div');
|
||||
inputGroup.className = 'var-input-group';
|
||||
inputGroup.innerHTML = `
|
||||
<input type="text" class="form-input" value="${name}" readonly>
|
||||
<input type="text" class="form-input" id="example-${name}" placeholder="示例值">
|
||||
`;
|
||||
container.appendChild(inputGroup);
|
||||
}
|
||||
|
||||
// 移除变量
|
||||
function removeVariable(name) {
|
||||
if (isViewMode) return;
|
||||
|
||||
// 从变量对象中删除
|
||||
delete variables[name];
|
||||
|
||||
// 更新隐藏字段
|
||||
document.getElementById('variables-json').value = JSON.stringify(variables);
|
||||
|
||||
// 移除变量标签
|
||||
const badge = document.querySelector(`.var-badge[data-var-name="${name}"]`);
|
||||
if (badge) {
|
||||
badge.remove();
|
||||
}
|
||||
|
||||
// 移除示例变量输入框
|
||||
const exampleInput = document.getElementById(`example-${name}`);
|
||||
if (exampleInput) {
|
||||
exampleInput.closest('.var-input-group').remove();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新预览内容
|
||||
function updatePreview() {
|
||||
const templateContent = document.getElementById('template-content').value;
|
||||
let previewContent = templateContent;
|
||||
|
||||
// 替换变量
|
||||
for (const [key, _] of Object.entries(variables)) {
|
||||
const exampleValue = document.getElementById(`example-${key}`)?.value || `[${key}]`;
|
||||
const regex = new RegExp(`{${key}}`, 'g');
|
||||
previewContent = previewContent.replace(regex, exampleValue);
|
||||
}
|
||||
|
||||
// 更新预览区域
|
||||
const previewDiv = document.getElementById('preview-content');
|
||||
previewDiv.innerHTML = `<pre style="white-space: pre-wrap;">${previewContent}</pre>`;
|
||||
}
|
||||
|
||||
// 模拟根据ID获取模板数据(实际应使用AJAX请求)
|
||||
function getTemplateById(id) {
|
||||
// 模拟的模板数据
|
||||
const templates = {
|
||||
'1': {
|
||||
id: 1,
|
||||
template_name: '行政处罚-抽取通用模板',
|
||||
template_type: 'Extraction',
|
||||
description: '本模板用于抽取行政处罚决定书编号等信息',
|
||||
template_content: `你是一个专业的文档信息抽取助手。请从以下{docType}文档中抽取关键信息:
|
||||
|
||||
1. 处罚决定书编号
|
||||
2. 处罚对象名称
|
||||
3. 处罚事由
|
||||
4. 处罚依据
|
||||
5. 处罚内容
|
||||
6. 处罚金额
|
||||
7. 发文日期
|
||||
|
||||
请将结果以JSON格式输出,包含以上字段。如果某个字段在文档中未找到,则该字段的值设为null。`,
|
||||
variables: '{"docType":"文档类型"}',
|
||||
status: 1,
|
||||
version: 'v1.0',
|
||||
created_by: 'system'
|
||||
},
|
||||
'2': {
|
||||
id: 2,
|
||||
template_name: '销售合同-甲方信息评估',
|
||||
template_type: 'Evaluation',
|
||||
description: '评估销售合同中甲方信息是否完整',
|
||||
template_content: `你是一个专业的合同审核助手。请评估以下{docType}中甲方信息的完整性:
|
||||
|
||||
请检查以下要素是否存在且完整:
|
||||
1. 甲方全称
|
||||
2. 注册地址
|
||||
3. 统一社会信用代码
|
||||
4. 法定代表人
|
||||
5. 联系方式
|
||||
|
||||
请给出评估结果,并标明缺失或不完整的信息。`,
|
||||
variables: '{"docType":"文档类型"}',
|
||||
status: 1,
|
||||
version: 'v1.2',
|
||||
created_by: 'admin'
|
||||
},
|
||||
'3': {
|
||||
id: 3,
|
||||
template_name: '专卖许可证-摘要模板',
|
||||
template_type: 'Summary',
|
||||
description: '生成专卖许可证申请文件的内容摘要',
|
||||
template_content: `你是一个专业的文档摘要助手。请为以下{docType}生成一份简洁的摘要:
|
||||
|
||||
摘要应包含以下要点:
|
||||
1. 申请人基本信息
|
||||
2. 许可证类型
|
||||
3. 申请事项
|
||||
4. 经营范围
|
||||
5. 申请日期
|
||||
|
||||
请控制摘要在200字以内,保留关键信息。`,
|
||||
variables: '{"docType":"文档类型"}',
|
||||
status: 1,
|
||||
version: 'v1.0',
|
||||
created_by: 'admin'
|
||||
},
|
||||
'4': {
|
||||
id: 4,
|
||||
template_name: '采购合同-乙方资质抽取',
|
||||
template_type: 'Extraction',
|
||||
description: '抽取采购合同中乙方的资质信息',
|
||||
template_content: `你是一个专业的合同信息抽取助手。请从以下{docType}中抽取乙方的资质信息:
|
||||
|
||||
需要抽取的信息包括:
|
||||
1. 乙方全称
|
||||
2. 资质证书类型
|
||||
3. 资质证书编号
|
||||
4. 资质等级
|
||||
5. 证书有效期
|
||||
|
||||
请将结果以JSON格式输出,包含以上字段。`,
|
||||
variables: '{"docType":"文档类型"}',
|
||||
status: 0,
|
||||
version: 'v1.1',
|
||||
created_by: 'zhangsan'
|
||||
},
|
||||
'5': {
|
||||
id: 5,
|
||||
template_name: '合同通用-关键条款评估',
|
||||
template_type: 'Evaluation',
|
||||
description: '评估合同中关键条款是否明确、合规',
|
||||
template_content: `你是一个专业的{industry}行业合同审核助手。请评估以下合同中的关键条款是否明确、合规:
|
||||
|
||||
请重点关注以下条款:
|
||||
1. 合同标的
|
||||
2. 价格条款
|
||||
3. 付款条件
|
||||
4. 交付方式
|
||||
5. 违约责任
|
||||
6. 争议解决
|
||||
|
||||
请对每一项给出评估结果,并指出不明确或存在风险的条款。`,
|
||||
variables: '{"industry":"行业类型","docType":"文档类型"}',
|
||||
status: 1,
|
||||
version: 'v2.0',
|
||||
created_by: 'lisi'
|
||||
}
|
||||
};
|
||||
|
||||
return templates[id] || null;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user