1308 lines
50 KiB
HTML
1308 lines
50 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://cdnjs.cloudflare.com/ajax/libs/remixicon/2.5.0/remixicon.css" rel="stylesheet">
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
|
|
<!-- <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);
|
|
}
|
|
|
|
.layout-container {
|
|
display: flex;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.sidebar {
|
|
width: 240px;
|
|
background-color: white;
|
|
border-right: 1px solid var(--border-color);
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
bottom: 0;
|
|
overflow-y: auto;
|
|
z-index: 10;
|
|
}
|
|
|
|
.main-content {
|
|
margin-left: 240px;
|
|
width: calc(100% - 240px);
|
|
padding: 24px;
|
|
background-color: var(--bg-gray);
|
|
}
|
|
|
|
.sidebar-menu-item a {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 12px 16px;
|
|
border-radius: 4px;
|
|
margin: 0 8px;
|
|
color: var(--text-color);
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.sidebar-menu-item:hover a {
|
|
background-color: var(--primary-light);
|
|
color: var(--primary-color);
|
|
}
|
|
|
|
.sidebar-menu-item.active a {
|
|
background-color: var(--primary-light);
|
|
color: var(--primary-color);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.ant-card {
|
|
border-radius: 6px;
|
|
border: 1px solid var(--border-color);
|
|
background-color: white;
|
|
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: 24px;
|
|
}
|
|
|
|
.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-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);
|
|
}
|
|
|
|
.ant-btn i {
|
|
margin-right: 6px;
|
|
}
|
|
|
|
.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); }
|
|
.bg-success { background-color: #f6ffed; }
|
|
.bg-warning { background-color: #fffbe6; }
|
|
.bg-error { background-color: #fff2f0; }
|
|
|
|
.form-label {
|
|
display: block;
|
|
font-size: 14px;
|
|
color: var(--text-color);
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.form-input {
|
|
width: 100%;
|
|
border: 1px solid #d9d9d9;
|
|
border-radius: 4px;
|
|
padding: 8px 12px;
|
|
font-size: 14px;
|
|
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-select {
|
|
width: 100%;
|
|
border: 1px solid #d9d9d9;
|
|
border-radius: 4px;
|
|
padding: 8px 12px;
|
|
font-size: 14px;
|
|
background-color: white;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.form-textarea {
|
|
width: 100%;
|
|
border: 1px solid #d9d9d9;
|
|
border-radius: 4px;
|
|
padding: 8px 12px;
|
|
font-size: 14px;
|
|
min-height: 120px;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
/* Upload area styles */
|
|
.upload-area {
|
|
border: 2px dashed #d9d9d9;
|
|
border-radius: 8px;
|
|
padding: 40px;
|
|
text-align: center;
|
|
background-color: #fafafa;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.upload-area:hover, .upload-area.dragover {
|
|
border-color: var(--primary-color);
|
|
background-color: var(--primary-light);
|
|
}
|
|
|
|
.upload-icon {
|
|
font-size: 48px;
|
|
color: var(--text-secondary);
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.upload-text {
|
|
color: var(--text-secondary);
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.upload-tip {
|
|
font-size: 12px;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
/* Progress bar styles */
|
|
.progress-container {
|
|
margin-top: 24px;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.progress-bar {
|
|
height: 8px;
|
|
background-color: #f0f0f0;
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.progress-bar-inner {
|
|
height: 100%;
|
|
background-color: var(--primary-color);
|
|
border-radius: 4px;
|
|
transition: width 0.3s ease;
|
|
width: 0%;
|
|
}
|
|
|
|
.progress-text {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
font-size: 12px;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
/* Status steps styles */
|
|
.steps-container {
|
|
margin: 32px 0;
|
|
}
|
|
|
|
.step-item {
|
|
position: relative;
|
|
padding-left: 28px;
|
|
padding-bottom: 32px;
|
|
}
|
|
|
|
.step-item:last-child {
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
.step-item::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: 6px;
|
|
top: 0;
|
|
bottom: 0;
|
|
width: 2px;
|
|
background-color: #e8e8e8;
|
|
}
|
|
|
|
.step-item:last-child::before {
|
|
display: none;
|
|
}
|
|
|
|
.step-icon {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
width: 14px;
|
|
height: 14px;
|
|
border-radius: 50%;
|
|
background-color: #d9d9d9;
|
|
z-index: 1;
|
|
}
|
|
|
|
.step-item.active .step-icon {
|
|
background-color: var(--primary-color);
|
|
}
|
|
|
|
.step-item.done .step-icon {
|
|
background-color: var(--success-color);
|
|
}
|
|
|
|
.step-item.error .step-icon {
|
|
background-color: var(--error-color);
|
|
}
|
|
|
|
.step-content {
|
|
padding-top: 0;
|
|
}
|
|
|
|
.step-title {
|
|
font-weight: 500;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.step-description {
|
|
font-size: 12px;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.step-item.active .step-title {
|
|
color: var(--primary-color);
|
|
}
|
|
|
|
/* Loading animation */
|
|
.loading-spinner {
|
|
position: absolute;
|
|
display: inline-block;
|
|
width: 16px;
|
|
height: 16px;
|
|
border: 2px solid rgba(255, 255, 255, 0.3);
|
|
border-top: 2px solid var(--primary-color);
|
|
border-radius: 50%;
|
|
animation: spin 1s linear infinite;
|
|
left: 50%;
|
|
top: 50%;
|
|
transform: translate(-50%, -50%);
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% { transform: translate(-50%, -50%) rotate(0deg); }
|
|
100% { transform: translate(-50%, -50%) rotate(360deg); }
|
|
}
|
|
|
|
/* Table styles */
|
|
.ant-table {
|
|
width: 100%;
|
|
border-collapse: separate;
|
|
border-spacing: 0;
|
|
}
|
|
|
|
.ant-table th, .ant-table td {
|
|
padding: 16px;
|
|
border-bottom: 1px solid var(--border-color);
|
|
text-align: left;
|
|
}
|
|
|
|
.ant-table th {
|
|
background-color: #fafafa;
|
|
color: var(--text-color);
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.ant-table tr:hover td {
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
/* File type badges */
|
|
.file-type-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.file-type-badge i {
|
|
margin-right: 4px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.file-type-contract {
|
|
background-color: #e6f7ff;
|
|
color: #1890ff;
|
|
}
|
|
|
|
.file-type-license {
|
|
background-color: #f6ffed;
|
|
color: #52c41a;
|
|
}
|
|
|
|
.file-type-punishment {
|
|
background-color: #fff7e6;
|
|
color: #fa8c16;
|
|
}
|
|
|
|
/* Status badge */
|
|
.status-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.status-waiting {
|
|
background-color: #f9f0ff;
|
|
color: #722ed1;
|
|
}
|
|
|
|
.status-processing {
|
|
background-color: #e6f7ff;
|
|
color: #1890ff;
|
|
}
|
|
|
|
.status-success {
|
|
background-color: #f6ffed;
|
|
color: #52c41a;
|
|
}
|
|
|
|
.status-error {
|
|
background-color: #fff1f0;
|
|
color: #f5222d;
|
|
}
|
|
|
|
/* File info list */
|
|
.file-info-list {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
.file-info-item {
|
|
display: flex;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.file-info-label {
|
|
flex: 0 0 80px;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.file-info-value {
|
|
flex: 1;
|
|
}
|
|
|
|
/* Animation for parsing */
|
|
@keyframes pulse {
|
|
0% {
|
|
transform: scale(1);
|
|
opacity: 1;
|
|
}
|
|
50% {
|
|
transform: scale(1.05);
|
|
opacity: 0.8;
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.pulse-animation {
|
|
animation: pulse 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
/* Responsive adjustments */
|
|
@media (max-width: 768px) {
|
|
.layout-container {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.sidebar {
|
|
position: static;
|
|
width: 100%;
|
|
height: auto;
|
|
}
|
|
|
|
.main-content {
|
|
margin-left: 0;
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
/* 横向步骤样式 */
|
|
.steps-container-horizontal {
|
|
margin: 32px 0;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
position: relative;
|
|
}
|
|
|
|
.steps-container-horizontal::before {
|
|
content: "";
|
|
position: absolute;
|
|
top: 14px;
|
|
left: 0;
|
|
right: 0;
|
|
height: 2px;
|
|
background-color: #e8e8e8;
|
|
z-index: 0;
|
|
}
|
|
|
|
.step-item-horizontal {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
flex: 1;
|
|
text-align: center;
|
|
z-index: 1;
|
|
}
|
|
|
|
.step-icon-horizontal {
|
|
width: 30px;
|
|
height: 30px;
|
|
border-radius: 50%;
|
|
background-color: #d9d9d9;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-bottom: 8px;
|
|
position: relative;
|
|
z-index: 2;
|
|
}
|
|
|
|
.step-icon-horizontal i {
|
|
display: none;
|
|
color: white;
|
|
font-size: 16px;
|
|
position: absolute;
|
|
left: 50%;
|
|
top: 50%;
|
|
transform: translate(-50%, -50%);
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.step-item-horizontal.active .step-icon-horizontal {
|
|
background-color: var(--primary-color);
|
|
}
|
|
|
|
.step-item-horizontal.done .step-icon-horizontal {
|
|
background-color: var(--success-color);
|
|
}
|
|
|
|
.step-item-horizontal.done .step-icon-horizontal i {
|
|
display: inline-block;
|
|
}
|
|
|
|
.step-item-horizontal.error .step-icon-horizontal {
|
|
background-color: var(--error-color);
|
|
}
|
|
|
|
.step-content-horizontal {
|
|
padding: 0 8px;
|
|
max-width: 140px;
|
|
}
|
|
|
|
.step-title-horizontal {
|
|
font-weight: 500;
|
|
margin-bottom: 4px;
|
|
font-size: 14px;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.step-description-horizontal {
|
|
font-size: 12px;
|
|
color: var(--text-secondary);
|
|
line-height: 1.3;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.step-item-horizontal.active .step-title-horizontal {
|
|
color: var(--primary-color);
|
|
}
|
|
|
|
/* 响应式调整 */
|
|
@media (max-width: 768px) {
|
|
.steps-container-horizontal {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.steps-container-horizontal::before {
|
|
display: none;
|
|
}
|
|
|
|
.step-item-horizontal {
|
|
flex-direction: row;
|
|
align-items: flex-start;
|
|
margin-bottom: 20px;
|
|
width: 100%;
|
|
}
|
|
|
|
.step-content-horizontal {
|
|
text-align: left;
|
|
margin-left: 12px;
|
|
max-width: none;
|
|
}
|
|
|
|
.step-icon-horizontal {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
</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 active">
|
|
<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">
|
|
<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>
|
|
</div>
|
|
|
|
<!-- 页面头部 -->
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h2 class="text-xl font-medium">待审核文件上传</h2>
|
|
</div>
|
|
|
|
<!-- 文件类型选择 -->
|
|
<div class="ant-card">
|
|
<div class="ant-card-header">
|
|
<h3>选择文件类型</h3>
|
|
</div>
|
|
<div class="ant-card-body">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div>
|
|
<label class="form-label">文件类型 <span class="text-error">*</span></label>
|
|
<select class="form-select" id="fileType">
|
|
<option value="">请选择文件类型</option>
|
|
<option value="contract">合同文档</option>
|
|
<option value="license">专卖许可证</option>
|
|
<option value="punishment">行政处罚决定书</option>
|
|
<option value="other">其他文档</option>
|
|
</select>
|
|
<div class="form-tip mt-1">不同类型的文档将应用不同的审核规则</div>
|
|
</div>
|
|
<div>
|
|
<label class="form-label">审核优先级</label>
|
|
<select class="form-select">
|
|
<option value="normal">普通</option>
|
|
<option value="high">优先</option>
|
|
<option value="urgent">紧急</option>
|
|
</select>
|
|
<div class="form-tip mt-1">优先级影响文档在队列中的处理顺序</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 文件上传区域 -->
|
|
<div class="ant-card">
|
|
<div class="ant-card-header">
|
|
<h3>文件上传</h3>
|
|
</div>
|
|
<div class="ant-card-body">
|
|
<div id="uploadArea" class="upload-area">
|
|
<input type="file" id="fileInput" style="display: none;" multiple />
|
|
<i class="ri-upload-cloud-2-line upload-icon"></i>
|
|
<div class="upload-text font-medium mb-2">点击或拖拽文件到此区域上传</div>
|
|
<p class="upload-tip mb-2">支持单个或批量上传,文件格式:PDF、Word、Excel、图片</p>
|
|
<button class="ant-btn ant-btn-primary" id="selectFileBtn">
|
|
<i class="ri-file-upload-line"></i> 选择文件
|
|
</button>
|
|
</div>
|
|
|
|
<!-- 上传进度区域 (初始隐藏) -->
|
|
<div id="progressContainer" class="progress-container hidden">
|
|
<div class="mb-2 flex justify-between items-center">
|
|
<span class="font-medium" id="uploadingFileName">文件名.pdf</span>
|
|
<span class="text-secondary text-sm" id="uploadSizeInfo">2.5MB / 5MB</span>
|
|
</div>
|
|
<div class="progress-bar">
|
|
<div class="progress-bar-inner" id="progressBar" style="width: 0%"></div>
|
|
</div>
|
|
<div class="progress-text">
|
|
<span id="progressPercentage">0%</span>
|
|
<span id="uploadSpeed">0KB/s</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 处理状态步骤条 (初始隐藏) - 横向版 -->
|
|
<div id="processingSteps" class="steps-container-horizontal hidden" style="display: none !important;">
|
|
<div class="step-item-horizontal" id="step1">
|
|
<div class="step-icon-horizontal">
|
|
<i class="ri-check-line"></i>
|
|
</div>
|
|
<div class="step-content-horizontal">
|
|
<div class="step-title-horizontal">文件上传</div>
|
|
<div class="step-description-horizontal">正在上传文件到服务器...</div>
|
|
</div>
|
|
</div>
|
|
<div class="step-item-horizontal" id="step2">
|
|
<div class="step-icon-horizontal">
|
|
<i class="ri-check-line"></i>
|
|
</div>
|
|
<div class="step-content-horizontal">
|
|
<div class="step-title-horizontal">文档转换拆分</div>
|
|
<div class="step-description-horizontal">转换文档格式,拆分文档内容</div>
|
|
</div>
|
|
</div>
|
|
<div class="step-item-horizontal" id="step3">
|
|
<div class="step-icon-horizontal">
|
|
<i class="ri-check-line"></i>
|
|
</div>
|
|
<div class="step-content-horizontal">
|
|
<div class="step-title-horizontal">评查点抽取</div>
|
|
<div class="step-description-horizontal">DeepSeek 抽取中</div>
|
|
</div>
|
|
</div>
|
|
<div class="step-item-horizontal" id="step4">
|
|
<div class="step-icon-horizontal">
|
|
<i class="ri-check-line"></i>
|
|
</div>
|
|
<div class="step-content-horizontal">
|
|
<div class="step-title-horizontal">评查点审核</div>
|
|
<div class="step-description-horizontal">DeepSeek 评查中</div>
|
|
</div>
|
|
</div>
|
|
<div class="step-item-horizontal" id="step5">
|
|
<div class="step-icon-horizontal">
|
|
<i class="ri-check-line"></i>
|
|
</div>
|
|
<div class="step-content-horizontal">
|
|
<div class="step-title-horizontal">审核准备</div>
|
|
<div class="step-description-horizontal">文档已准备就绪,等待审核</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 上传完成后的文件信息 (初始隐藏) -->
|
|
<div id="fileInfoContainer" class="hidden">
|
|
<div class="bg-success p-4 rounded-md mb-4">
|
|
<div class="flex items-center text-success mb-2">
|
|
<i class="ri-checkbox-circle-line text-xl mr-2"></i>
|
|
<span class="font-medium">评查成功</span>
|
|
</div>
|
|
<p class="text-sm">文件已成功上传并评查完成,请查看结果</p>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div>
|
|
<h4 class="font-medium mb-3">文件信息</h4>
|
|
<ul class="file-info-list">
|
|
<li class="file-info-item">
|
|
<span class="file-info-label">文件名:</span>
|
|
<span class="file-info-value" id="infoFileName">销售合同.pdf</span>
|
|
</li>
|
|
<li class="file-info-item">
|
|
<span class="file-info-label">文件大小:</span>
|
|
<span class="file-info-value" id="infoFileSize">5.2MB</span>
|
|
</li>
|
|
<li class="file-info-item">
|
|
<span class="file-info-label">上传时间:</span>
|
|
<span class="file-info-value" id="infoUploadTime">2023-10-25 14:30:45</span>
|
|
</li>
|
|
<li class="file-info-item">
|
|
<span class="file-info-label">文件类型:</span>
|
|
<span class="file-info-value" id="infoFileType">合同文档</span>
|
|
</li>
|
|
<li class="file-info-item">
|
|
<span class="file-info-label">审核规则:</span>
|
|
<span class="file-info-value" id="infoRuleGroup">系统自动选择</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div>
|
|
<h4 class="font-medium mb-3">解析结果预览</h4>
|
|
<div class="bg-gray-50 p-3 rounded-md border border-gray-200">
|
|
<div class="mb-2">
|
|
<span class="text-secondary text-sm">合同编号:</span>
|
|
<span id="previewContractNo">XS-2023-1025-001</span>
|
|
</div>
|
|
<div class="mb-2">
|
|
<span class="text-secondary text-sm">合同名称:</span>
|
|
<span id="previewContractName">烟草制品销售合同</span>
|
|
</div>
|
|
<div class="mb-2">
|
|
<span class="text-secondary text-sm">签约日期:</span>
|
|
<span id="previewSignDate">2023年10月20日</span>
|
|
</div>
|
|
<div class="mb-2">
|
|
<span class="text-secondary text-sm">合同金额:</span>
|
|
<span id="previewAmount">¥ 1,580,000.00</span>
|
|
</div>
|
|
<div>
|
|
<span class="text-secondary text-sm">当事人:</span>
|
|
<span id="previewParties">甲方:XX烟草公司,乙方:YY贸易有限公司</span>
|
|
</div>
|
|
</div>
|
|
<div class="mt-4">
|
|
<button class="ant-btn ant-btn-primary">
|
|
<i class="ri-file-search-line"></i> 查看详情并审核
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 上传队列 -->
|
|
<div class="ant-card">
|
|
<div class="ant-card-header">
|
|
<div class="flex justify-between items-center">
|
|
<h3>上传队列</h3>
|
|
<span class="text-secondary text-sm">共 3 个文件</span>
|
|
</div>
|
|
</div>
|
|
<div class="ant-card-body">
|
|
<table class="ant-table">
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 40%">文件名</th>
|
|
<th style="width: 15%">文件类型</th>
|
|
<th style="width: 15%">大小</th>
|
|
<th style="width: 15%">状态</th>
|
|
<th style="width: 15%">操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>
|
|
<div class="flex items-center">
|
|
<i class="ri-file-pdf-line text-red-500 mr-2 text-lg"></i>
|
|
<span class="truncate">烟草产品销售合同(2023版).pdf</span>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="file-type-badge file-type-contract">
|
|
<i class="ri-file-list-3-line"></i>合同文档
|
|
</span>
|
|
</td>
|
|
<td>5.2MB</td>
|
|
<td>
|
|
<span class="status-badge status-processing">
|
|
<i class="ri-loader-4-line mr-1"></i>解析中
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<button class="ant-btn ant-btn-sm ant-btn-default" disabled>
|
|
<i class="ri-eye-line"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<div class="flex items-center">
|
|
<i class="ri-file-word-2-line text-blue-500 mr-2 text-lg"></i>
|
|
<span class="truncate">专卖许可证申请表.docx</span>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="file-type-badge file-type-license">
|
|
<i class="ri-vip-crown-line"></i>专卖许可证
|
|
</span>
|
|
</td>
|
|
<td>2.8MB</td>
|
|
<td>
|
|
<span class="status-badge status-waiting">
|
|
<i class="ri-time-line mr-1"></i>等待中
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<button class="ant-btn ant-btn-sm ant-btn-default" disabled>
|
|
<i class="ri-eye-line"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<div class="flex items-center">
|
|
<i class="ri-file-pdf-line text-red-500 mr-2 text-lg"></i>
|
|
<span class="truncate">XX公司违规处罚决定书.pdf</span>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="file-type-badge file-type-punishment">
|
|
<i class="ri-scales-line"></i>行政处罚
|
|
</span>
|
|
</td>
|
|
<td>3.1MB</td>
|
|
<td>
|
|
<span class="status-badge status-success">
|
|
<i class="ri-checkbox-circle-line mr-1"></i>已完成
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<button class="ant-btn ant-btn-sm ant-btn-default">
|
|
<i class="ri-eye-line"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// 在DOM加载之前就执行的代码,确保元素初始隐藏
|
|
document.getElementById('processingSteps').style.display = 'none';
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// 立即执行,确保所有状态区域初始隐藏
|
|
document.getElementById('progressContainer').classList.add('hidden');
|
|
const processingSteps = document.getElementById('processingSteps');
|
|
processingSteps.classList.add('hidden');
|
|
processingSteps.style.display = 'none'; // 双重保险
|
|
document.getElementById('fileInfoContainer').classList.add('hidden');
|
|
|
|
// 确保上传区域初始显示
|
|
document.getElementById('uploadArea').classList.remove('hidden');
|
|
|
|
// 文件类型选择联动
|
|
const fileTypeSelect = document.getElementById('fileType');
|
|
|
|
fileTypeSelect.addEventListener('change', function() {
|
|
// 启用规则组下拉菜单
|
|
ruleGroupSelect.disabled = false;
|
|
ruleGroupSelect.innerHTML = ''; // 清空选项
|
|
|
|
// 根据文件类型添加对应的规则组选项
|
|
switch(fileTypeSelect.value) {
|
|
case 'contract':
|
|
addOptions(ruleGroupSelect, [
|
|
{ value: 'contract-base', text: '合同基本要素检查' },
|
|
{ value: 'contract-sales', text: '销售合同专项检查' },
|
|
{ value: 'contract-purchase', text: '采购合同专项检查' }
|
|
]);
|
|
break;
|
|
case 'license':
|
|
addOptions(ruleGroupSelect, [
|
|
{ value: 'license-base', text: '许可证基本要素检查' },
|
|
{ value: 'license-retail', text: '零售许可证专项检查' }
|
|
]);
|
|
break;
|
|
case 'punishment':
|
|
addOptions(ruleGroupSelect, [
|
|
{ value: 'punishment-base', text: '行政处罚文书检查' },
|
|
{ value: 'punishment-standard', text: '处罚标准合规性检查' }
|
|
]);
|
|
break;
|
|
case 'other':
|
|
addOptions(ruleGroupSelect, [
|
|
{ value: 'other-base', text: '通用文档检查' }
|
|
]);
|
|
break;
|
|
default:
|
|
ruleGroupSelect.disabled = true;
|
|
ruleGroupSelect.innerHTML = '<option value="">请先选择文件类型</option>';
|
|
}
|
|
});
|
|
|
|
// 添加选项辅助函数
|
|
function addOptions(selectElement, options) {
|
|
options.forEach(option => {
|
|
const optionElement = document.createElement('option');
|
|
optionElement.value = option.value;
|
|
optionElement.textContent = option.text;
|
|
selectElement.appendChild(optionElement);
|
|
});
|
|
}
|
|
|
|
// 文件上传区域点击事件
|
|
const uploadArea = document.getElementById('uploadArea');
|
|
const fileInput = document.getElementById('fileInput');
|
|
const selectFileBtn = document.getElementById('selectFileBtn');
|
|
|
|
uploadArea.addEventListener('click', function(e) {
|
|
if (e.target !== selectFileBtn && e.target.parentNode !== selectFileBtn) {
|
|
fileInput.click();
|
|
}
|
|
});
|
|
|
|
selectFileBtn.addEventListener('click', function() {
|
|
fileInput.click();
|
|
});
|
|
|
|
// 拖拽上传
|
|
uploadArea.addEventListener('dragover', function(e) {
|
|
e.preventDefault();
|
|
this.classList.add('dragover');
|
|
});
|
|
|
|
uploadArea.addEventListener('dragleave', function() {
|
|
this.classList.remove('dragover');
|
|
});
|
|
|
|
uploadArea.addEventListener('drop', function(e) {
|
|
e.preventDefault();
|
|
this.classList.remove('dragover');
|
|
|
|
const files = e.dataTransfer.files;
|
|
if (files.length > 0) {
|
|
fileInput.files = files;
|
|
handleFileUpload(files);
|
|
}
|
|
});
|
|
|
|
// 文件选择事件
|
|
fileInput.addEventListener('change', function() {
|
|
if (this.files.length > 0) {
|
|
handleFileUpload(this.files);
|
|
}
|
|
});
|
|
|
|
// 处理文件上传
|
|
function handleFileUpload(files) {
|
|
// 检查文件类型是否已选择
|
|
if (!fileTypeSelect.value) {
|
|
alert('请先选择文件类型');
|
|
return;
|
|
}
|
|
|
|
// 隐藏上传区域
|
|
document.getElementById('uploadArea').classList.add('hidden');
|
|
|
|
// 显示上传进度区域
|
|
const progressContainer = document.getElementById('progressContainer');
|
|
progressContainer.classList.remove('hidden');
|
|
|
|
// 确保处理步骤区域此时是隐藏的
|
|
const processingSteps = document.getElementById('processingSteps');
|
|
processingSteps.classList.add('hidden');
|
|
processingSteps.style.display = 'none';
|
|
|
|
// 设置上传文件信息
|
|
const uploadingFileName = document.getElementById('uploadingFileName');
|
|
const uploadSizeInfo = document.getElementById('uploadSizeInfo');
|
|
const progressBar = document.getElementById('progressBar');
|
|
const progressPercentage = document.getElementById('progressPercentage');
|
|
const uploadSpeed = document.getElementById('uploadSpeed');
|
|
|
|
// 使用第一个文件作为示例
|
|
const file = files[0];
|
|
uploadingFileName.textContent = file.name;
|
|
uploadSizeInfo.textContent = `${formatFileSize(file.size)}`;
|
|
|
|
// 重置进度条
|
|
progressBar.style.width = '0%';
|
|
progressPercentage.textContent = '0%';
|
|
|
|
// 模拟上传进度
|
|
let progress = 0;
|
|
const progressInterval = setInterval(() => {
|
|
progress += 5;
|
|
progressBar.style.width = `${progress}%`;
|
|
progressPercentage.textContent = `${progress}%`;
|
|
uploadSpeed.textContent = `${Math.random().toFixed(2) * 100 + 50}KB/s`;
|
|
|
|
if (progress >= 100) {
|
|
clearInterval(progressInterval);
|
|
uploadSpeed.textContent = '完成';
|
|
|
|
// 只有在上传完成后才显示处理步骤
|
|
processingSteps.classList.remove('hidden');
|
|
processingSteps.style.display = 'flex';
|
|
simulateProcessing();
|
|
}
|
|
}, 200);
|
|
}
|
|
|
|
// 模拟文档处理流程
|
|
function simulateProcessing() {
|
|
const steps = [
|
|
document.getElementById('step1'),
|
|
document.getElementById('step2'),
|
|
document.getElementById('step3'),
|
|
document.getElementById('step4'),
|
|
document.getElementById('step5')
|
|
];
|
|
|
|
// 重置所有步骤状态
|
|
steps.forEach((step, index) => {
|
|
step.classList.remove('active', 'done');
|
|
// 移除任何现有的加载动画
|
|
const existingSpinner = step.querySelector('.loading-spinner');
|
|
if (existingSpinner) {
|
|
existingSpinner.remove();
|
|
}
|
|
});
|
|
|
|
// 步骤描述文本 - 添加进行中和已完成两种状态
|
|
const stepDescriptions = [
|
|
{
|
|
inProgress: "正在上传文件到服务器...",
|
|
completed: "文件上传已完成"
|
|
},
|
|
{
|
|
inProgress: "转换文档格式,拆分文档内容",
|
|
completed: "转换文档格式并拆分文档完成"
|
|
},
|
|
{
|
|
inProgress: "DeepSeek 抽取中",
|
|
completed: "DeepSeek 抽取已完成"
|
|
},
|
|
{
|
|
inProgress: "DeepSeek 评查中",
|
|
completed: "DeepSeek 评查已完成"
|
|
},
|
|
{
|
|
inProgress: "文档已准备就绪,等待审核",
|
|
completed: "审核准备已就绪"
|
|
}
|
|
];
|
|
|
|
// 设置第一步为完成状态
|
|
steps[0].classList.add('done');
|
|
steps[0].querySelector('.step-description-horizontal').textContent = stepDescriptions[0].completed;
|
|
|
|
let currentStep = 1;
|
|
|
|
const processInterval = setInterval(() => {
|
|
if (currentStep >= steps.length) {
|
|
clearInterval(processInterval);
|
|
showFileInfo();
|
|
return;
|
|
}
|
|
|
|
// 激活当前步骤
|
|
steps[currentStep].classList.add('active');
|
|
|
|
// 将描述文本设置为进行中状态
|
|
steps[currentStep].querySelector('.step-description-horizontal').textContent = stepDescriptions[currentStep].inProgress;
|
|
|
|
// 移除已存在的加载动画(如果有)
|
|
const existingSpinner = steps[currentStep].querySelector('.loading-spinner');
|
|
if (existingSpinner) {
|
|
existingSpinner.remove();
|
|
}
|
|
|
|
// 创建并添加spinner - 确保居中添加
|
|
const spinner = document.createElement('span');
|
|
spinner.className = 'loading-spinner';
|
|
steps[currentStep].querySelector('.step-icon-horizontal').appendChild(spinner);
|
|
|
|
// 在一段时间后将当前步骤标记为完成
|
|
setTimeout(() => {
|
|
steps[currentStep].classList.remove('active');
|
|
steps[currentStep].classList.add('done');
|
|
|
|
// 移除loading spinner
|
|
const spinner = steps[currentStep].querySelector('.loading-spinner');
|
|
if (spinner) spinner.remove();
|
|
|
|
// 更新描述文本为完成状态
|
|
steps[currentStep].querySelector('.step-description-horizontal').textContent = stepDescriptions[currentStep].completed;
|
|
|
|
currentStep++;
|
|
}, 2000);
|
|
|
|
}, 2500);
|
|
}
|
|
|
|
// 显示文件信息
|
|
function showFileInfo() {
|
|
setTimeout(() => {
|
|
// 隐藏上传区域和进度条
|
|
document.getElementById('uploadArea').classList.add('hidden');
|
|
document.getElementById('progressContainer').classList.add('hidden');
|
|
|
|
// 显示文件信息
|
|
const fileInfoContainer = document.getElementById('fileInfoContainer');
|
|
fileInfoContainer.classList.remove('hidden');
|
|
|
|
// 设置文件信息
|
|
document.getElementById('infoFileName').textContent = document.getElementById('uploadingFileName').textContent;
|
|
document.getElementById('infoFileSize').textContent = document.getElementById('uploadSizeInfo').textContent;
|
|
document.getElementById('infoUploadTime').textContent = getCurrentTime();
|
|
document.getElementById('infoFileType').textContent = getFileTypeText(document.getElementById('fileType').value);
|
|
document.getElementById('infoRuleGroup').textContent = "系统自动选择";
|
|
|
|
// 添加解析结果的动画效果
|
|
const previewElements = [
|
|
document.getElementById('previewContractNo'),
|
|
document.getElementById('previewContractName'),
|
|
document.getElementById('previewSignDate'),
|
|
document.getElementById('previewAmount'),
|
|
document.getElementById('previewParties')
|
|
];
|
|
|
|
previewElements.forEach((el, index) => {
|
|
setTimeout(() => {
|
|
el.classList.add('pulse-animation');
|
|
}, index * 200);
|
|
});
|
|
}, 1000);
|
|
}
|
|
|
|
// 获取当前时间
|
|
function getCurrentTime() {
|
|
const now = new Date();
|
|
const year = now.getFullYear();
|
|
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
const day = String(now.getDate()).padStart(2, '0');
|
|
const hours = String(now.getHours()).padStart(2, '0');
|
|
const minutes = String(now.getMinutes()).padStart(2, '0');
|
|
const seconds = String(now.getSeconds()).padStart(2, '0');
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
}
|
|
|
|
// 格式化文件大小
|
|
function formatFileSize(bytes) {
|
|
if (bytes === 0) return '0 Bytes';
|
|
|
|
const k = 1024;
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
}
|
|
|
|
// 获取文件类型文本
|
|
function getFileTypeText(value) {
|
|
switch(value) {
|
|
case 'contract': return '合同文档';
|
|
case 'license': return '专卖许可证';
|
|
case 'punishment': return '行政处罚决定书';
|
|
case 'other': return '其他文档';
|
|
default: return '未知类型';
|
|
}
|
|
}
|
|
|
|
// 初始化上传队列表格的交互
|
|
const queueViewButtons = document.querySelectorAll('.ant-table .ant-btn');
|
|
queueViewButtons.forEach(btn => {
|
|
if (!btn.disabled) {
|
|
btn.addEventListener('click', function() {
|
|
const row = this.closest('tr');
|
|
const fileName = row.querySelector('td:first-child span').textContent;
|
|
alert(`查看文件详情: ${fileName}`);
|
|
});
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |