1535 lines
57 KiB
HTML
1535 lines
57 KiB
HTML
<!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">
|
||
<style>
|
||
:root {
|
||
--primary: #00684a;
|
||
--primary-light: #e6f3f0;
|
||
--success: #52c41a;
|
||
--success-bg: #f6ffed;
|
||
--warning: #faad14;
|
||
--warning-bg: #fffbe6;
|
||
--error: #ff4d4f;
|
||
--error-bg: #fff1f0;
|
||
--text: #333333;
|
||
--text-light: #666666;
|
||
--border: #e8e8e8;
|
||
--bg: #f9f9f9;
|
||
--white: #ffffff;
|
||
--shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||
}
|
||
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
color: var(--text);
|
||
background-color: var(--bg);
|
||
}
|
||
|
||
/* 布局 */
|
||
.layout {
|
||
display: flex;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.sidebar {
|
||
width: 220px;
|
||
background-color: var(--white);
|
||
border-right: 1px solid var(--border);
|
||
position: fixed;
|
||
height: 100vh;
|
||
box-shadow: var(--shadow);
|
||
z-index: 10;
|
||
}
|
||
|
||
.main {
|
||
flex: 1;
|
||
margin-left: 220px;
|
||
padding: 24px;
|
||
}
|
||
|
||
/* 侧边栏样式 */
|
||
.sidebar-header {
|
||
padding: 16px;
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
|
||
.logo {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.logo i {
|
||
font-size: 20px;
|
||
color: var(--primary);
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.logo h1 {
|
||
font-size: 16px;
|
||
color: var(--text);
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
.user-info {
|
||
padding: 16px;
|
||
border-bottom: 1px solid var(--border);
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.avatar {
|
||
width: 32px;
|
||
height: 32px;
|
||
background-color: var(--primary);
|
||
color: white;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.user-info .name {
|
||
font-weight: 500;
|
||
}
|
||
|
||
.user-info .role {
|
||
color: var(--text-light);
|
||
font-size: 12px;
|
||
}
|
||
|
||
.menu {
|
||
list-style: none;
|
||
padding: 8px 0;
|
||
}
|
||
|
||
.menu-item {
|
||
padding: 0;
|
||
}
|
||
|
||
.menu-link {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 10px 16px;
|
||
color: var(--text);
|
||
text-decoration: none;
|
||
position: relative;
|
||
}
|
||
|
||
.menu-link i {
|
||
margin-right: 8px;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.menu-link:hover {
|
||
background-color: var(--primary-light);
|
||
color: var(--primary);
|
||
}
|
||
|
||
.menu-item.active .menu-link {
|
||
background-color: var(--primary-light);
|
||
color: var(--primary);
|
||
font-weight: 500;
|
||
}
|
||
|
||
.menu-item.active .menu-link::before {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
bottom: 0;
|
||
width: 3px;
|
||
background-color: var(--primary);
|
||
}
|
||
|
||
.submenu {
|
||
list-style: none;
|
||
background-color: rgba(0, 0, 0, 0.02);
|
||
padding: 0;
|
||
overflow: hidden;
|
||
display: none;
|
||
}
|
||
|
||
.menu-item.active .submenu {
|
||
display: block;
|
||
}
|
||
|
||
.submenu-item a {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 8px 16px 8px 40px;
|
||
color: var(--text);
|
||
text-decoration: none;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.submenu-item a:hover {
|
||
color: var(--primary);
|
||
}
|
||
|
||
.submenu-item i {
|
||
margin-right: 8px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.submenu-item.active a {
|
||
color: var(--primary);
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* 主内容区样式 */
|
||
.page-header {
|
||
margin-bottom: 24px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.page-title {
|
||
font-size: 20px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.breadcrumb {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 12px;
|
||
font-size: 13px;
|
||
color: var(--text-light);
|
||
}
|
||
|
||
.breadcrumb a {
|
||
color: var(--primary);
|
||
text-decoration: none;
|
||
}
|
||
|
||
.breadcrumb-separator {
|
||
margin: 0 8px;
|
||
}
|
||
|
||
/* 卡片组件 */
|
||
.card {
|
||
background-color: var(--white);
|
||
border-radius: 8px;
|
||
box-shadow: var(--shadow);
|
||
margin-bottom: 24px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.card-header {
|
||
padding: 16px;
|
||
border-bottom: 1px solid var(--border);
|
||
font-weight: 500;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.card-body {
|
||
padding: 16px;
|
||
}
|
||
|
||
/* 按钮样式 */
|
||
.btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 32px;
|
||
padding: 0 16px;
|
||
font-size: 14px;
|
||
border-radius: 4px;
|
||
border: 1px solid transparent;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
font-weight: 400;
|
||
}
|
||
|
||
.btn i {
|
||
margin-right: 6px;
|
||
}
|
||
|
||
.btn-primary {
|
||
background-color: var(--primary);
|
||
color: white;
|
||
border-color: var(--primary);
|
||
}
|
||
|
||
.btn-primary:hover {
|
||
background-color: #005a40;
|
||
border-color: #005a40;
|
||
}
|
||
|
||
.btn-default {
|
||
background-color: white;
|
||
border-color: var(--border);
|
||
color: var(--text);
|
||
}
|
||
|
||
.btn-default:hover {
|
||
border-color: var(--primary);
|
||
color: var(--primary);
|
||
}
|
||
|
||
.btn-sm {
|
||
height: 28px;
|
||
padding: 0 12px;
|
||
font-size: 13px;
|
||
}
|
||
|
||
/* 评查点信息 */
|
||
.checkpoint-info {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 16px;
|
||
background-color: var(--primary-light);
|
||
border-radius: 8px;
|
||
margin-bottom: 24px;
|
||
}
|
||
|
||
.checkpoint-info i {
|
||
font-size: 24px;
|
||
color: var(--primary);
|
||
margin-right: 12px;
|
||
}
|
||
|
||
.checkpoint-title {
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.checkpoint-desc {
|
||
color: var(--text-light);
|
||
font-size: 13px;
|
||
}
|
||
|
||
/* 文档选择 */
|
||
.document-selector {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 16px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.document-item {
|
||
padding: 12px;
|
||
border: 1px solid var(--border);
|
||
border-radius: 8px;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
display: flex;
|
||
align-items: center;
|
||
min-width: 220px;
|
||
position: relative;
|
||
}
|
||
|
||
.document-item:hover {
|
||
border-color: var(--primary);
|
||
background-color: var(--primary-light);
|
||
}
|
||
|
||
.document-item.selected {
|
||
border-color: var(--primary);
|
||
background-color: var(--primary-light);
|
||
}
|
||
|
||
.document-item .doc-icon {
|
||
margin-right: 12px;
|
||
font-size: 24px;
|
||
}
|
||
|
||
.document-item .doc-name {
|
||
font-weight: 500;
|
||
font-size: 14px;
|
||
max-width: 180px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.document-item .selection-indicator {
|
||
position: absolute;
|
||
top: 8px;
|
||
right: 8px;
|
||
width: 18px;
|
||
height: 18px;
|
||
border-radius: 50%;
|
||
background-color: var(--primary);
|
||
color: white;
|
||
font-size: 12px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
opacity: 0;
|
||
transition: opacity 0.2s;
|
||
}
|
||
|
||
.document-item.selected .selection-indicator {
|
||
opacity: 1;
|
||
}
|
||
|
||
/* 结果展示 */
|
||
.results-wrapper {
|
||
margin-top: 24px;
|
||
}
|
||
|
||
.result-stats {
|
||
display: flex;
|
||
gap: 16px;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.stat-item {
|
||
background-color: var(--white);
|
||
border-radius: 8px;
|
||
padding: 12px;
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
box-shadow: var(--shadow);
|
||
}
|
||
|
||
.stat-icon {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 8px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 12px;
|
||
}
|
||
|
||
.stat-icon.success {
|
||
background-color: var(--success-bg);
|
||
color: var(--success);
|
||
}
|
||
|
||
.stat-icon.warning {
|
||
background-color: var(--warning-bg);
|
||
color: var(--warning);
|
||
}
|
||
|
||
.stat-icon.error {
|
||
background-color: var(--error-bg);
|
||
color: var(--error);
|
||
}
|
||
|
||
.stat-icon i {
|
||
font-size: 20px;
|
||
}
|
||
|
||
.stat-content {
|
||
flex: 1;
|
||
}
|
||
|
||
.stat-title {
|
||
color: var(--text-light);
|
||
font-size: 13px;
|
||
}
|
||
|
||
.stat-value {
|
||
font-size: 20px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.result-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr;
|
||
gap: 12px;
|
||
width: 100%;
|
||
}
|
||
|
||
.result-header-row {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr;
|
||
gap: 12px;
|
||
margin-bottom: 8px;
|
||
font-weight: 500;
|
||
background-color: var(--bg);
|
||
border-radius: 4px;
|
||
padding: 10px 0;
|
||
}
|
||
|
||
.result-row {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr;
|
||
gap: 12px;
|
||
margin-bottom: 16px;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
box-shadow: var(--shadow);
|
||
}
|
||
|
||
.result-row.success {
|
||
border-left: 4px solid var(--success);
|
||
}
|
||
|
||
.result-row.warning {
|
||
border-left: 4px solid var(--warning);
|
||
}
|
||
|
||
.result-row.error {
|
||
border-left: 4px solid var(--error);
|
||
}
|
||
|
||
.result-cell {
|
||
padding: 16px;
|
||
background-color: white;
|
||
position: relative;
|
||
}
|
||
|
||
.result-cell.header {
|
||
padding: 8px 16px;
|
||
background-color: var(--bg);
|
||
font-weight: 500;
|
||
text-align: center;
|
||
}
|
||
|
||
/* 文档信息单元格 */
|
||
.doc-info {
|
||
border-right: 1px solid var(--border);
|
||
}
|
||
|
||
.doc-title {
|
||
display: flex;
|
||
align-items: center;
|
||
font-weight: 500;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.doc-title i {
|
||
margin-right: 8px;
|
||
font-size: 18px;
|
||
}
|
||
|
||
.doc-badge {
|
||
display: inline-block;
|
||
padding: 2px 6px;
|
||
border-radius: 4px;
|
||
font-size: 12px;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.doc-badge.success {
|
||
background-color: var(--success-bg);
|
||
color: var(--success);
|
||
}
|
||
|
||
.doc-badge.warning {
|
||
background-color: var(--warning-bg);
|
||
color: var(--warning);
|
||
}
|
||
|
||
.doc-badge.error {
|
||
background-color: var(--error-bg);
|
||
color: var(--error);
|
||
}
|
||
|
||
.doc-meta {
|
||
font-size: 12px;
|
||
color: var(--text-light);
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.doc-meta span:not(:last-child)::after {
|
||
content: "·";
|
||
margin: 0 4px;
|
||
}
|
||
|
||
/* 抽取和评查结果单元格 */
|
||
.extract-result {
|
||
border-right: 1px solid var(--border);
|
||
}
|
||
|
||
.result-status {
|
||
display: flex;
|
||
align-items: center;
|
||
font-weight: 500;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.result-status i {
|
||
margin-right: 6px;
|
||
}
|
||
|
||
.result-status.success {
|
||
color: var(--success);
|
||
}
|
||
|
||
.result-status.warning {
|
||
color: var(--warning);
|
||
}
|
||
|
||
.result-status.error {
|
||
color: var(--error);
|
||
}
|
||
|
||
.result-message {
|
||
margin-bottom: 10px;
|
||
color: var(--text-light);
|
||
font-size: 13px;
|
||
}
|
||
|
||
.result-code {
|
||
padding: 10px;
|
||
background-color: var(--bg);
|
||
border-radius: 4px;
|
||
font-family: "SFMono-Regular", Consolas, monospace;
|
||
font-size: 12px;
|
||
white-space: pre-wrap;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.mt-2 {
|
||
margin-top: 8px;
|
||
}
|
||
|
||
/* 标签页样式 */
|
||
.tabs {
|
||
margin-bottom: 20px;
|
||
border-bottom: 1px solid var(--border);
|
||
display: flex;
|
||
}
|
||
|
||
.tab {
|
||
padding: 10px 20px;
|
||
cursor: pointer;
|
||
font-weight: 500;
|
||
position: relative;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.tab:hover {
|
||
color: var(--primary);
|
||
}
|
||
|
||
.tab.active {
|
||
color: var(--primary);
|
||
}
|
||
|
||
.tab.active::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
bottom: -1px;
|
||
width: 100%;
|
||
height: 2px;
|
||
background-color: var(--primary);
|
||
}
|
||
|
||
.tab-content {
|
||
display: none;
|
||
}
|
||
|
||
.tab-content.active {
|
||
display: block;
|
||
}
|
||
|
||
/* 规则展示 */
|
||
.rule-display {
|
||
background-color: #f8f8f8;
|
||
padding: 12px;
|
||
border-radius: 8px;
|
||
font-family: "SFMono-Regular", Consolas, monospace;
|
||
overflow-x: auto;
|
||
white-space: pre-wrap;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.rule-name {
|
||
color: #d73a49;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.rule-operator {
|
||
color: #6f42c1;
|
||
}
|
||
|
||
.rule-param {
|
||
color: #005cc5;
|
||
}
|
||
|
||
.rule-desc {
|
||
color: var(--text-light);
|
||
font-size: 13px;
|
||
}
|
||
|
||
/* 预览区域 */
|
||
.preview-panel {
|
||
width: 100%;
|
||
height: 300px;
|
||
border: 1px solid var(--border);
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.preview-header {
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid var(--border);
|
||
background-color: var(--bg);
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.preview-title {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.preview-title i {
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.preview-content {
|
||
flex: 1;
|
||
padding: 16px;
|
||
overflow: auto;
|
||
}
|
||
|
||
.highlight {
|
||
background-color: rgba(82, 196, 26, 0.2);
|
||
border: 1px solid var(--success);
|
||
padding: 1px 2px;
|
||
}
|
||
|
||
/* 主体内容样式 */
|
||
.check-list {
|
||
list-style: none;
|
||
}
|
||
|
||
.check-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 6px;
|
||
}
|
||
|
||
.check-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.check-item i {
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.check-item i.success {
|
||
color: var(--success);
|
||
}
|
||
|
||
.check-item i.error {
|
||
color: var(--error);
|
||
}
|
||
|
||
.action-footer {
|
||
margin-top: 20px;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="layout">
|
||
<!-- 侧边栏 -->
|
||
<div class="sidebar">
|
||
<div class="sidebar-header">
|
||
<div class="logo">
|
||
<i class="ri-file-search-line"></i>
|
||
<h1>中国烟草AI审核系统</h1>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="user-info">
|
||
<div class="avatar">管</div>
|
||
<div>
|
||
<div class="name">管理员</div>
|
||
<div class="role">系统管理员</div>
|
||
</div>
|
||
</div>
|
||
|
||
<ul class="menu">
|
||
<li class="menu-item">
|
||
<a href="index.html" class="menu-link">
|
||
<i class="ri-home-line"></i>
|
||
<span>首页</span>
|
||
</a>
|
||
</li>
|
||
|
||
<li class="menu-item">
|
||
<a href="#" class="menu-link">
|
||
<i class="ri-file-list-line"></i>
|
||
<span>文档管理</span>
|
||
<i class="ri-arrow-down-s-line"></i>
|
||
</a>
|
||
<ul class="submenu">
|
||
<li class="submenu-item">
|
||
<a href="文档-上传.html">
|
||
<i class="ri-upload-line"></i>
|
||
<span>上传文档</span>
|
||
</a>
|
||
</li>
|
||
<li class="submenu-item">
|
||
<a href="文档-列表.html">
|
||
<i class="ri-file-list-line"></i>
|
||
<span>文档列表</span>
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
|
||
<li class="menu-item active">
|
||
<a href="#" class="menu-link">
|
||
<i class="ri-list-check"></i>
|
||
<span>评查规则</span>
|
||
<i class="ri-arrow-down-s-line"></i>
|
||
</a>
|
||
<ul class="submenu">
|
||
<li class="submenu-item">
|
||
<a href="评查点分组列表.html">
|
||
<i class="ri-folder-line"></i>
|
||
<span>评查点分组</span>
|
||
</a>
|
||
</li>
|
||
<li class="submenu-item">
|
||
<a href="评查点列表.html">
|
||
<i class="ri-list-check"></i>
|
||
<span>评查点列表</span>
|
||
</a>
|
||
</li>
|
||
<li class="submenu-item">
|
||
<a href="新增评查点.html">
|
||
<i class="ri-add-line"></i>
|
||
<span>新增评查点</span>
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
|
||
<li class="menu-item">
|
||
<a href="#" class="menu-link">
|
||
<i class="ri-file-search-line"></i>
|
||
<span>评查结果</span>
|
||
<i class="ri-arrow-down-s-line"></i>
|
||
</a>
|
||
<ul class="submenu">
|
||
<li class="submenu-item">
|
||
<a href="评查详情页面.html">
|
||
<i class="ri-file-text-line"></i>
|
||
<span>评查详情</span>
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- 主内容区 -->
|
||
<div class="main">
|
||
<div class="breadcrumb">
|
||
<a href="index.html">首页</a>
|
||
<span class="breadcrumb-separator">/</span>
|
||
<a href="评查点列表.html">评查规则库</a>
|
||
<span class="breadcrumb-separator">/</span>
|
||
<a href="评查点列表.html">评查点列表</a>
|
||
<span class="breadcrumb-separator">/</span>
|
||
<span>评查点测试</span>
|
||
</div>
|
||
|
||
<div class="page-header">
|
||
<h1 class="page-title">评查点测试</h1>
|
||
<div>
|
||
<button class="btn btn-default" onclick="history.back()">
|
||
<i class="ri-arrow-left-line"></i> 返回
|
||
</button>
|
||
<button class="btn btn-primary" id="save-result-btn" onclick="saveResults()">
|
||
<i class="ri-save-line"></i> 保存测试结果
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 评查点信息 -->
|
||
<div class="checkpoint-info">
|
||
<i class="ri-checkbox-circle-line"></i>
|
||
<div>
|
||
<h2 class="checkpoint-title">合同审核-甲方主体信息完整性检查</h2>
|
||
<p class="checkpoint-desc">检查合同中甲方主体信息是否完整,包括名称、地址、统一社会信用代码等必要信息。</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 标签页 -->
|
||
<div class="tabs">
|
||
<div class="tab active" data-tab="check">评查</div>
|
||
<div class="tab" data-tab="rules">规则</div>
|
||
</div>
|
||
|
||
<!-- 评查标签页内容 -->
|
||
<div class="tab-content active" id="check-tab">
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<span>选择测试文档</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="document-selector">
|
||
<div class="document-item" data-doc-id="1" onclick="selectDocument(this, 1)">
|
||
<div class="doc-icon"><i class="ri-file-text-line text-red-500"></i></div>
|
||
<div class="doc-name">烟草销售合同2023.docx</div>
|
||
<div class="selection-indicator"><i class="ri-check-line"></i></div>
|
||
</div>
|
||
|
||
<div class="document-item" data-doc-id="2" onclick="selectDocument(this, 2)">
|
||
<div class="doc-icon"><i class="ri-file-pdf-line text-red-500"></i></div>
|
||
<div class="doc-name">设备采购合同模板.pdf</div>
|
||
<div class="selection-indicator"><i class="ri-check-line"></i></div>
|
||
</div>
|
||
|
||
<div class="document-item" data-doc-id="3" onclick="selectDocument(this, 3)">
|
||
<div class="doc-icon"><i class="ri-file-word-line text-blue-500"></i></div>
|
||
<div class="doc-name">行政处罚决定书.docx</div>
|
||
<div class="selection-indicator"><i class="ri-check-line"></i></div>
|
||
</div>
|
||
|
||
<div class="document-item" data-doc-id="4" onclick="selectDocument(this, 4)">
|
||
<div class="doc-icon"><i class="ri-file-text-line text-green-500"></i></div>
|
||
<div class="doc-name">专卖许可证申请表.docx</div>
|
||
<div class="selection-indicator"><i class="ri-check-line"></i></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="text-align: center; margin-top: 16px;">
|
||
<button class="btn btn-primary" onclick="runTest()">
|
||
<i class="ri-play-line"></i> 运行测试
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 测试结果区域 -->
|
||
<div id="test-result-container" style="display:none;">
|
||
<!-- 测试结果统计 -->
|
||
<div class="result-stats">
|
||
<div class="stat-item">
|
||
<div class="stat-icon success">
|
||
<i class="ri-checkbox-circle-line"></i>
|
||
</div>
|
||
<div class="stat-content">
|
||
<div class="stat-title">通过</div>
|
||
<div class="stat-value" id="pass-count">1</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-item">
|
||
<div class="stat-icon warning">
|
||
<i class="ri-error-warning-line"></i>
|
||
</div>
|
||
<div class="stat-content">
|
||
<div class="stat-title">存在问题</div>
|
||
<div class="stat-value" id="warning-count">2</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-item">
|
||
<div class="stat-icon error">
|
||
<i class="ri-close-circle-line"></i>
|
||
</div>
|
||
<div class="stat-content">
|
||
<div class="stat-title">失败</div>
|
||
<div class="stat-value" id="error-count">1</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 结果列表 -->
|
||
<div class="card">
|
||
<div class="card-header">测试结果详情</div>
|
||
<div class="card-body">
|
||
<!-- 三列结果布局 -->
|
||
<div class="result-grid">
|
||
<!-- 第一行:表头 -->
|
||
<div class="result-header-row">
|
||
<div class="result-cell header">文档信息</div>
|
||
<div class="result-cell header">抽取结果</div>
|
||
<div class="result-cell header">评查结果</div>
|
||
</div>
|
||
|
||
<!-- 烟草销售合同 -->
|
||
<div class="result-row success">
|
||
<!-- 文档信息 -->
|
||
<div class="result-cell doc-info">
|
||
<div class="doc-title">
|
||
<i class="ri-file-text-line"></i>
|
||
<span>烟草销售合同2023.docx</span>
|
||
</div>
|
||
<div class="doc-badge success">通过</div>
|
||
<div class="doc-meta">
|
||
<span>32KB</span>
|
||
<span>2023-10-15</span>
|
||
</div>
|
||
<button class="btn btn-default btn-sm mt-2" onclick="showPreview(1)">
|
||
<i class="ri-eye-line"></i> 预览文档
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 抽取结果 -->
|
||
<div class="result-cell extract-result">
|
||
<div class="result-status success">
|
||
<i class="ri-checkbox-circle-fill"></i>
|
||
<span>抽取成功</span>
|
||
</div>
|
||
<p class="result-message">成功提取甲方完整信息</p>
|
||
<div class="result-code">甲方(供方):XX烟草公司
|
||
地址:XX省XX市XX区XX路XX号
|
||
法定代表人:张XX
|
||
联系电话:123-4567-8901
|
||
统一社会信用代码:91XXXXXXXXXXXXXXXXX</div>
|
||
</div>
|
||
|
||
<!-- 评查结果 -->
|
||
<div class="result-cell check-result">
|
||
<div class="result-status success">
|
||
<i class="ri-checkbox-circle-fill"></i>
|
||
<span>评查通过</span>
|
||
</div>
|
||
<p class="result-message">甲方信息完整,包含了必要的信用代码和地址信息,且信息足够详细</p>
|
||
<ul class="check-list">
|
||
<li class="check-item">
|
||
<i class="ri-checkbox-circle-fill success"></i>
|
||
<span>包含统一社会信用代码</span>
|
||
</li>
|
||
<li class="check-item">
|
||
<i class="ri-checkbox-circle-fill success"></i>
|
||
<span>包含地址信息</span>
|
||
</li>
|
||
<li class="check-item">
|
||
<i class="ri-checkbox-circle-fill success"></i>
|
||
<span>信息长度足够,共144个字符</span>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 规则标签页内容 -->
|
||
<div class="tab-content" id="rules-tab">
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<span>抽取规则</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="rule-display">
|
||
<span class="rule-name">EXTRACT</span> <span class="rule-operator">(</span>
|
||
<span class="rule-param">"甲方信息"</span>,
|
||
<span class="rule-operator">REGEX</span><span class="rule-operator">(</span><span class="rule-param">"甲方.*?(?:公司|单位|企业).*?(?:地址|住所|所在地).*?[\u4e00-\u9fa5]{5,}"</span><span class="rule-operator">)</span>
|
||
<span class="rule-operator">)</span></div>
|
||
<p class="rule-desc">此评查点将提取合同中甲方信息部分,检查是否包含公司名称和地址等必要信息。</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<span>评查规则</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="rule-display">
|
||
<span class="rule-name">CHECK</span> <span class="rule-operator">(</span>
|
||
<span class="rule-param">"甲方信息"</span>,
|
||
<span class="rule-operator">CONTAINS</span><span class="rule-operator">(</span><span class="rule-param">"信用代码"</span><span class="rule-operator">)</span>
|
||
<span class="rule-operator">AND</span>
|
||
<span class="rule-operator">CONTAINS</span><span class="rule-operator">(</span><span class="rule-param">"地址"</span><span class="rule-operator">)</span>
|
||
<span class="rule-operator">AND</span>
|
||
<span class="rule-operator">LENGTH</span><span class="rule-operator">()</span> <span class="rule-operator">></span> <span class="rule-param">50</span>
|
||
<span class="rule-operator">)</span></div>
|
||
<p class="rule-desc">评查规则检查甲方信息是否包含必要字段(如统一社会信用代码、地址)且信息是否足够详细。</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 文档预览模态框 -->
|
||
<div id="preview-modal" style="display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0,0,0,0.5); z-index: 100; align-items: center; justify-content: center;">
|
||
<div style="width: 80%; max-width: 800px; background-color: white; border-radius: 8px; overflow: hidden; max-height: 80vh; display: flex; flex-direction: column;">
|
||
<div style="padding: 16px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center;">
|
||
<h3 id="preview-title">文档预览</h3>
|
||
<button class="btn btn-default btn-sm" onclick="closePreview()">
|
||
<i class="ri-close-line"></i>
|
||
</button>
|
||
</div>
|
||
|
||
<div style="flex: 1; padding: 16px; overflow: auto;">
|
||
<div id="preview-content"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 文档数据
|
||
const documents = [
|
||
{
|
||
id: 1,
|
||
name: "烟草销售合同2023.docx",
|
||
content: `
|
||
<div style="font-family: SimSun, serif; line-height: 1.8; padding: 20px;">
|
||
<h2 style="text-align: center; font-size: 18px; font-weight: bold;">烟草产品销售合同</h2>
|
||
<p style="text-align: right;">合同编号:XS-2023-1025-001</p>
|
||
|
||
<div style="margin: 20px 0;">
|
||
<p><strong>甲方(供方):</strong>XX烟草公司</p>
|
||
<p>地址:XX省XX市XX区XX路XX号</p>
|
||
<p>法定代表人:张XX</p>
|
||
<p>联系电话:123-4567-8901</p>
|
||
<p>统一社会信用代码:91XXXXXXXXXXXXXXXXX</p>
|
||
<p> </p>
|
||
<p><strong>乙方(需方):</strong>YY贸易有限公司</p>
|
||
<p>地址:XX省XX市XX区YY路YY号</p>
|
||
<p>法定代表人:李YY</p>
|
||
<p>联系电话:123-4567-8902</p>
|
||
</div>
|
||
|
||
<p>根据《中华人民共和国民法典》及有关法律法规的规定,经双方协商一致,签订本合同,共同遵守。</p>
|
||
|
||
<div style="margin-top: 20px;">
|
||
<h3>第一条 总则</h3>
|
||
<p>1.1 本合同适用于甲乙双方之间的烟草制品买卖事宜。</p>
|
||
<p>1.2 双方应本着平等互利、诚实信用的原则履行本合同。</p>
|
||
</div>
|
||
</div>
|
||
`,
|
||
extractResult: {
|
||
status: "success",
|
||
extracted: "甲方(供方):XX烟草公司\n地址:XX省XX市XX区XX路XX号\n法定代表人:张XX\n联系电话:123-4567-8901\n统一社会信用代码:91XXXXXXXXXXXXXXXXX",
|
||
message: "成功提取甲方完整信息",
|
||
highlightRange: [315, 480]
|
||
},
|
||
checkResult: {
|
||
status: "success",
|
||
message: "甲方信息完整,包含了必要的信用代码和地址信息,且信息足够详细",
|
||
details: [
|
||
{ rule: "CONTAINS(\"信用代码\")", result: true, message: "包含统一社会信用代码" },
|
||
{ rule: "CONTAINS(\"地址\")", result: true, message: "包含地址信息" },
|
||
{ rule: "LENGTH() > 50", result: true, message: "信息长度足够,共144个字符" }
|
||
]
|
||
}
|
||
},
|
||
{
|
||
id: 2,
|
||
name: "设备采购合同模板.pdf",
|
||
content: `
|
||
<div style="font-family: SimSun, serif; line-height: 1.8; padding: 20px;">
|
||
<h2 style="text-align: center; font-size: 18px; font-weight: bold;">设备采购合同</h2>
|
||
<p style="text-align: right;">合同编号:CG-2023-0506-002</p>
|
||
|
||
<div style="margin: 20px 0;">
|
||
<p><strong>甲方(买方):</strong>XX烟草公司</p>
|
||
<p> </p>
|
||
<p><strong>乙方(卖方):</strong>ZZ设备制造有限公司</p>
|
||
<p>地址:XX省XX市XX区ZZ路ZZ号</p>
|
||
<p>法定代表人:王ZZ</p>
|
||
<p>联系电话:123-4567-8903</p>
|
||
</div>
|
||
|
||
<p>根据《中华人民共和国民法典》及相关法律法规的规定,经双方协商一致,签订本合同,共同遵守。</p>
|
||
|
||
<div style="margin-top: 20px;">
|
||
<h3>第一条 合同标的</h3>
|
||
<p>1.1 乙方按照本合同约定向甲方提供以下设备:</p>
|
||
<p>设备名称:卷烟生产线</p>
|
||
<p>规格型号:XYZ-2023</p>
|
||
<p>数量:1套</p>
|
||
</div>
|
||
</div>
|
||
`,
|
||
extractResult: {
|
||
status: "error",
|
||
extracted: "甲方(买方):XX烟草公司",
|
||
message: "甲方信息不完整,缺少地址、法定代表人等必要信息",
|
||
highlightRange: [315, 335]
|
||
},
|
||
checkResult: {
|
||
status: "error",
|
||
message: "甲方信息不完整,缺少必要的信用代码和地址信息",
|
||
details: [
|
||
{ rule: "CONTAINS(\"信用代码\")", result: false, message: "未包含统一社会信用代码" },
|
||
{ rule: "CONTAINS(\"地址\")", result: false, message: "未包含地址信息" },
|
||
{ rule: "LENGTH() > 50", result: false, message: "信息长度不足,仅20个字符" }
|
||
]
|
||
}
|
||
},
|
||
{
|
||
id: 3,
|
||
name: "行政处罚决定书.docx",
|
||
content: `
|
||
<div style="font-family: SimSun, serif; line-height: 1.8; padding: 20px;">
|
||
<h2 style="text-align: center; font-size: 18px; font-weight: bold;">行政处罚决定书</h2>
|
||
<p style="text-align: right;">处罚文号:烟市监罚〔2023〕10号</p>
|
||
|
||
<div style="margin: 20px 0;">
|
||
<p><strong>当事人:</strong>王某某</p>
|
||
<p>性别:男</p>
|
||
<p>年龄:45岁</p>
|
||
<p>住址:XX省XX市XX区XX小区XX号</p>
|
||
<p>身份证号:3XXXXXXXXXXXXX</p>
|
||
</div>
|
||
|
||
<p>经查,当事人于2023年5月10日在未取得烟草专卖零售许可证的情况下,在XX市XX区XX路XX号门店销售卷烟。上述行为违反了《中华人民共和国烟草专卖法》第二十条的规定。</p>
|
||
|
||
<div style="margin-top: 20px;">
|
||
<h3>处罚决定</h3>
|
||
<p>根据《中华人民共和国烟草专卖法实施条例》第六十条的规定,决定给予当事人以下行政处罚:</p>
|
||
<p>1. 没收违法所得500元;</p>
|
||
<p>2. 处以罚款2000元。</p>
|
||
</div>
|
||
</div>
|
||
`,
|
||
extractResult: {
|
||
status: "warning",
|
||
extracted: null,
|
||
message: "文档类型不适用,无法提取甲方信息。此类型文档不包含合同主体信息。",
|
||
highlightRange: null
|
||
},
|
||
checkResult: {
|
||
status: "warning",
|
||
message: "不适用于此类文档,无法执行评查规则",
|
||
details: [
|
||
{ rule: "文档类型检查", result: false, message: "文档不是合同类型,不适用当前评查点" }
|
||
]
|
||
}
|
||
},
|
||
{
|
||
id: 4,
|
||
name: "专卖许可证申请表.docx",
|
||
content: `
|
||
<div style="font-family: SimSun, serif; line-height: 1.8; padding: 20px;">
|
||
<h2 style="text-align: center; font-size: 18px; font-weight: bold;">烟草专卖零售许可证申请表</h2>
|
||
|
||
<div style="margin: 20px 0; border: 1px solid #ddd; padding: 15px;">
|
||
<p><strong>申请人(单位):</strong>张某某</p>
|
||
<p><strong>经营场所地址:</strong>XX省XX市XX区XX街XX号</p>
|
||
<p><strong>联系电话:</strong>1XX-XXXX-XXXX</p>
|
||
<p><strong>身份证号码:</strong>4XXXXXXXXXXXXX</p>
|
||
<p><strong>申请类型:</strong>新办</p>
|
||
<p><strong>经营范围:</strong>卷烟零售</p>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px;">
|
||
<p><strong>承诺事项:</strong></p>
|
||
<p>1. 本人提交的所有申请材料真实、有效、合法。</p>
|
||
<p>2. 本人承诺在取得烟草专卖零售许可证后,严格遵守烟草专卖管理法律法规,不违规经营。</p>
|
||
<p>3. 如有不实,本人愿意承担相应的法律责任。</p>
|
||
</div>
|
||
|
||
<div style="margin-top: 30px; text-align: right;">
|
||
<p>申请人(签章):张某某</p>
|
||
<p>申请日期:2023年6月15日</p>
|
||
</div>
|
||
</div>
|
||
`,
|
||
extractResult: {
|
||
status: "warning",
|
||
extracted: null,
|
||
message: "文档类型不适用,无法提取甲方信息。此类型文档不是合同文本。",
|
||
highlightRange: null
|
||
},
|
||
checkResult: {
|
||
status: "warning",
|
||
message: "不适用于此类文档,无法执行评查规则",
|
||
details: [
|
||
{ rule: "文档类型检查", result: false, message: "文档不是合同类型,不适用当前评查点" }
|
||
]
|
||
}
|
||
}
|
||
];
|
||
|
||
// 全局变量
|
||
let selectedDocuments = [];
|
||
let highlightEnabled = true;
|
||
|
||
// 初始化标签页
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// 标签页切换
|
||
const tabs = document.querySelectorAll('.tab');
|
||
tabs.forEach(tab => {
|
||
tab.addEventListener('click', function() {
|
||
// 移除所有标签的激活状态
|
||
tabs.forEach(t => t.classList.remove('active'));
|
||
// 为当前标签添加激活状态
|
||
this.classList.add('active');
|
||
|
||
// 隐藏所有标签内容
|
||
const tabContents = document.querySelectorAll('.tab-content');
|
||
tabContents.forEach(content => content.classList.remove('active'));
|
||
|
||
// 显示当前标签对应的内容
|
||
const tabId = this.getAttribute('data-tab');
|
||
document.getElementById(`${tabId}-tab`).classList.add('active');
|
||
});
|
||
});
|
||
|
||
// 初始化菜单交互
|
||
document.querySelectorAll('.menu-item > .menu-link').forEach(link => {
|
||
link.addEventListener('click', function(e) {
|
||
if (this.nextElementSibling && this.nextElementSibling.classList.contains('submenu')) {
|
||
e.preventDefault();
|
||
const menuItem = this.parentElement;
|
||
menuItem.classList.toggle('active');
|
||
}
|
||
});
|
||
});
|
||
|
||
// 初始化预览模态框
|
||
document.getElementById('preview-modal').addEventListener('click', function(e) {
|
||
if (e.target === this) {
|
||
closePreview();
|
||
}
|
||
});
|
||
});
|
||
|
||
// 选择文档
|
||
function selectDocument(element, docId) {
|
||
if (element.classList.contains('selected')) {
|
||
// 取消选择
|
||
element.classList.remove('selected');
|
||
selectedDocuments = selectedDocuments.filter(id => id !== docId);
|
||
} else {
|
||
// 选择文档
|
||
element.classList.add('selected');
|
||
selectedDocuments.push(docId);
|
||
}
|
||
}
|
||
|
||
// 运行测试
|
||
function runTest() {
|
||
if (selectedDocuments.length === 0) {
|
||
alert('请至少选择一个测试文档');
|
||
return;
|
||
}
|
||
|
||
// 显示测试结果区域
|
||
document.getElementById('test-result-container').style.display = 'block';
|
||
|
||
// 清空现有结果
|
||
const resultsContainer = document.querySelector('.result-grid');
|
||
// 保留表头行
|
||
const headerRow = resultsContainer.querySelector('.result-header-row');
|
||
resultsContainer.innerHTML = '';
|
||
resultsContainer.appendChild(headerRow);
|
||
|
||
// 结果统计
|
||
let passCount = 0;
|
||
let warningCount = 0;
|
||
let errorCount = 0;
|
||
|
||
// 为每个选中的文档生成测试结果
|
||
selectedDocuments.forEach(docId => {
|
||
const doc = documents.find(d => d.id === docId);
|
||
if (!doc) return;
|
||
|
||
// 更新统计数据
|
||
if (doc.checkResult.status === 'success') {
|
||
passCount++;
|
||
} else if (doc.checkResult.status === 'warning') {
|
||
warningCount++;
|
||
} else if (doc.checkResult.status === 'error') {
|
||
errorCount++;
|
||
}
|
||
|
||
// 创建结果行
|
||
const resultRow = document.createElement('div');
|
||
resultRow.className = `result-row ${doc.checkResult.status}`;
|
||
|
||
// 文档信息单元格
|
||
resultRow.innerHTML = `
|
||
<!-- 文档信息 -->
|
||
<div class="result-cell doc-info">
|
||
<div class="doc-title">
|
||
<i class="ri-file-text-line"></i>
|
||
<span>${doc.name}</span>
|
||
</div>
|
||
<div class="doc-badge ${doc.checkResult.status}">
|
||
${doc.checkResult.status === 'success' ? '通过' :
|
||
doc.checkResult.status === 'warning' ? '存在问题' : '失败'}
|
||
</div>
|
||
<div class="doc-meta">
|
||
<span>${Math.floor(Math.random() * 100) + 10}KB</span>
|
||
<span>2023-${Math.floor(Math.random() * 12) + 1}-${Math.floor(Math.random() * 28) + 1}</span>
|
||
</div>
|
||
<button class="btn btn-default btn-sm mt-2" onclick="showPreview(${doc.id})">
|
||
<i class="ri-eye-line"></i> 预览文档
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 抽取结果 -->
|
||
<div class="result-cell extract-result">
|
||
<div class="result-status ${doc.extractResult.status}">
|
||
<i class="ri-${doc.extractResult.status === 'success' ? 'checkbox-circle-fill' :
|
||
doc.extractResult.status === 'warning' ? 'error-warning-fill' : 'close-circle-fill'}"></i>
|
||
<span>${doc.extractResult.status === 'success' ? '抽取成功' :
|
||
doc.extractResult.status === 'warning' ? '抽取有问题' : '抽取失败'}</span>
|
||
</div>
|
||
<p class="result-message">${doc.extractResult.message}</p>
|
||
${doc.extractResult.extracted ?
|
||
`<div class="result-code">${doc.extractResult.extracted}</div>` : ''}
|
||
</div>
|
||
|
||
<!-- 评查结果 -->
|
||
<div class="result-cell check-result">
|
||
<div class="result-status ${doc.checkResult.status}">
|
||
<i class="ri-${doc.checkResult.status === 'success' ? 'checkbox-circle-fill' :
|
||
doc.checkResult.status === 'warning' ? 'error-warning-fill' : 'close-circle-fill'}"></i>
|
||
<span>${doc.checkResult.status === 'success' ? '评查通过' :
|
||
doc.checkResult.status === 'warning' ? '评查有问题' : '评查不通过'}</span>
|
||
</div>
|
||
<p class="result-message">${doc.checkResult.message}</p>
|
||
${doc.checkResult.details ?
|
||
`<ul class="check-list">
|
||
${doc.checkResult.details.map(detail => `
|
||
<li class="check-item">
|
||
<i class="ri-${detail.result ? 'checkbox-circle-fill success' : 'close-circle-fill error'}"></i>
|
||
<span>${detail.message}</span>
|
||
</li>
|
||
`).join('')}
|
||
</ul>` : ''}
|
||
</div>
|
||
`;
|
||
|
||
resultsContainer.appendChild(resultRow);
|
||
});
|
||
|
||
// 更新统计数字
|
||
document.getElementById('pass-count').textContent = passCount;
|
||
document.getElementById('warning-count').textContent = warningCount;
|
||
document.getElementById('error-count').textContent = errorCount;
|
||
|
||
// 滚动到结果区域
|
||
document.getElementById('test-result-container').scrollIntoView({
|
||
behavior: 'smooth'
|
||
});
|
||
}
|
||
|
||
// 显示文档预览
|
||
function showPreview(docId) {
|
||
const doc = documents.find(d => d.id === docId);
|
||
if (!doc) return;
|
||
|
||
// 设置预览标题
|
||
document.getElementById('preview-title').textContent = doc.name;
|
||
|
||
// 设置预览内容
|
||
const previewContent = document.getElementById('preview-content');
|
||
previewContent.innerHTML = doc.content;
|
||
|
||
// 如果有高亮区域,应用高亮
|
||
if (highlightEnabled && doc.extractResult && doc.extractResult.highlightRange) {
|
||
applyHighlight(previewContent, doc.extractResult.highlightRange);
|
||
}
|
||
|
||
// 显示预览模态框
|
||
document.getElementById('preview-modal').style.display = 'flex';
|
||
}
|
||
|
||
// 关闭预览
|
||
function closePreview() {
|
||
document.getElementById('preview-modal').style.display = 'none';
|
||
}
|
||
|
||
// 应用高亮
|
||
function applyHighlight(container, range) {
|
||
if (!range) return;
|
||
|
||
const [start, end] = range;
|
||
const text = container.textContent;
|
||
|
||
// 这是一个简化的实现,实际项目中可能需要更复杂的DOM操作
|
||
let currentIndex = 0;
|
||
function processNode(node) {
|
||
if (node.nodeType === 3) { // 文本节点
|
||
const text = node.textContent;
|
||
const nodeLength = text.length;
|
||
|
||
// 检查是否需要高亮这个节点
|
||
if (currentIndex + nodeLength > start && currentIndex < end) {
|
||
// 计算高亮部分
|
||
const highlightStart = Math.max(0, start - currentIndex);
|
||
const highlightEnd = Math.min(nodeLength, end - currentIndex);
|
||
|
||
if (highlightStart > 0 || highlightEnd < nodeLength) {
|
||
// 需要拆分节点
|
||
const beforeText = text.substring(0, highlightStart);
|
||
const highlightText = text.substring(highlightStart, highlightEnd);
|
||
const afterText = text.substring(highlightEnd);
|
||
|
||
const fragment = document.createDocumentFragment();
|
||
|
||
if (beforeText) {
|
||
fragment.appendChild(document.createTextNode(beforeText));
|
||
}
|
||
|
||
if (highlightText) {
|
||
const highlightSpan = document.createElement('span');
|
||
highlightSpan.className = 'highlight';
|
||
highlightSpan.textContent = highlightText;
|
||
fragment.appendChild(highlightSpan);
|
||
}
|
||
|
||
if (afterText) {
|
||
fragment.appendChild(document.createTextNode(afterText));
|
||
}
|
||
|
||
node.parentNode.replaceChild(fragment, node);
|
||
} else {
|
||
// 整个节点都需要高亮
|
||
const highlightSpan = document.createElement('span');
|
||
highlightSpan.className = 'highlight';
|
||
highlightSpan.textContent = text;
|
||
node.parentNode.replaceChild(highlightSpan, node);
|
||
}
|
||
}
|
||
|
||
currentIndex += nodeLength;
|
||
} else if (node.nodeType === 1) { // 元素节点
|
||
Array.from(node.childNodes).forEach(child => {
|
||
processNode(child);
|
||
});
|
||
}
|
||
}
|
||
|
||
// 从容器开始处理节点
|
||
Array.from(container.childNodes).forEach(node => {
|
||
processNode(node);
|
||
});
|
||
}
|
||
|
||
// 保存测试结果
|
||
function saveResults() {
|
||
if (!document.getElementById('test-result-container').style.display ||
|
||
document.getElementById('test-result-container').style.display === 'none') {
|
||
alert('请先运行测试后再保存结果');
|
||
return;
|
||
}
|
||
|
||
alert('测试结果已保存!此评查点规则测试有效。');
|
||
setTimeout(() => {
|
||
window.location.href = document.referrer || '评查点列表.html';
|
||
}, 1000);
|
||
}
|
||
</script>
|
||
</body>
|
||
</html> |