641e33b834
- 语义检索(FAISS + embedding)+ 精确查找(法规名+条号) - RAG 问答(SSE 流式,支持 thinking 折叠显示) - 法规浏览(原文阅读) - 历史记录(检索+对话持久化到 SQLite) - 设置页(系统提示词/模板/LLM 参数可配置) - 检索质量评估脚本 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
127 lines
7.8 KiB
HTML
127 lines
7.8 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>千源法规知识库 — QYLAW</title>
|
|
<link rel="stylesheet" href="/static/css/tailwind.css?v=20260807">
|
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
<style>
|
|
:root { --radius: 0.625rem; }
|
|
body { font-family: 'Inter', system-ui, -apple-system, sans-serif; }
|
|
.mono { font-family: 'JetBrains Mono', 'SF Mono', monospace; }
|
|
.scroll-thin::-webkit-scrollbar { width: 6px; height: 6px; }
|
|
.scroll-thin::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 3px; }
|
|
.scroll-thin::-webkit-scrollbar-track { background: transparent; }
|
|
/* 导航激活态 */
|
|
.nav-active { background: #f1f5f9; color: #0f172a; font-weight: 600; }
|
|
.nav-inactive { color: #64748b; }
|
|
.nav-inactive:hover { background: #f8fafc; color: #334155; }
|
|
/* Markdown 渲染 */
|
|
.md-content h1 { font-size: 1.4em; font-weight: 700; margin: 12px 0 8px; }
|
|
.md-content h2 { font-size: 1.2em; font-weight: 600; margin: 10px 0 6px; border-bottom: 1px solid #e2e8f0; padding-bottom: 4px; }
|
|
.md-content h3 { font-size: 1.05em; font-weight: 600; margin: 8px 0 4px; }
|
|
.md-content p { margin: 6px 0; line-height: 1.7; }
|
|
.md-content ul { list-style: disc; padding-left: 1.5em; margin: 6px 0; }
|
|
.md-content ol { list-style: decimal; padding-left: 1.5em; margin: 6px 0; }
|
|
.md-content li { margin: 3px 0; line-height: 1.6; }
|
|
.md-content blockquote { border-left: 3px solid #cbd5e1; padding: 4px 12px; margin: 8px 0; background: #f8fafc; border-radius: 0 6px 6px 0; color: #475569; }
|
|
.md-content code { background: #f1f5f9; padding: 2px 6px; border-radius: 4px; font-size: 0.85em; font-family: 'JetBrains Mono', monospace; color: #e11d48; }
|
|
.md-content pre { background: #1e293b; color: #e2e8f0; border-radius: 8px; padding: 12px 16px; margin: 8px 0; overflow-x: auto; font-size: 13px; }
|
|
.md-content pre code { background: none; color: inherit; padding: 0; }
|
|
.md-content table { border-collapse: collapse; width: 100%; margin: 8px 0; font-size: 13px; }
|
|
.md-content th { background: #f8fafc; border: 1px solid #e2e8f0; padding: 6px 10px; text-align: left; font-weight: 600; }
|
|
.md-content td { border: 1px solid #e2e8f0; padding: 6px 10px; }
|
|
.md-content tr:nth-child(even) { background: #f8fafc; }
|
|
.md-content strong { font-weight: 600; }
|
|
.md-content a { color: #0f172a; text-decoration: underline; }
|
|
/* 条文高亮 */
|
|
.clause-highlight { background: #fef3c7; border-left: 3px solid #f59e0b; padding: 8px 12px; margin: 4px 0; border-radius: 0 4px 4px 0; }
|
|
/* 加载动画 */
|
|
.spinner { border: 2px solid #e2e8f0; border-top: 2px solid #0f172a; border-radius: 50%; width: 16px; height: 16px; animation: spin 0.8s linear infinite; }
|
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
/* 流式光标 */
|
|
.stream-cursor::after { content: '▊'; animation: blink 1s infinite; color: #0f172a; }
|
|
@keyframes blink { 50% { opacity: 0; } }
|
|
/* 响应式:移动端 Sidebar */
|
|
@media (max-width: 767px) {
|
|
#sidebar { display: none; }
|
|
#sidebar.open { display: flex; position: fixed; top: 56px; left: 0; bottom: 0; z-index: 50; }
|
|
#mobile-menu-btn { display: flex; }
|
|
}
|
|
#mobile-menu-btn { display: none; }
|
|
</style>
|
|
</head>
|
|
<body class="bg-[#f8f9fb] text-gray-900 h-screen flex flex-col overflow-hidden">
|
|
|
|
<!-- Header -->
|
|
<header class="h-14 bg-white/95 backdrop-blur border-b border-gray-200 flex items-center justify-between px-4 md:px-6 shrink-0">
|
|
<div class="flex items-center gap-3">
|
|
<button id="mobile-menu-btn" class="md:hidden p-2 rounded-lg hover:bg-gray-100" aria-label="菜单">
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
|
|
</button>
|
|
<div class="w-8 h-8 rounded-lg bg-gray-900 flex items-center justify-center text-white font-bold text-sm">法</div>
|
|
<div>
|
|
<h1 class="text-sm font-semibold">千源法规知识库</h1>
|
|
<p class="text-xs text-gray-500">17291 篇现行有效法律法规 · 语义检索 + RAG 问答</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center gap-4">
|
|
<div id="stats-badge" class="text-xs text-gray-500 hidden md:flex items-center gap-2">
|
|
<span class="w-2 h-2 rounded-full bg-gray-300" id="status-dot"></span>
|
|
<span id="status-text">加载中</span>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Main -->
|
|
<div class="flex-1 flex overflow-hidden">
|
|
|
|
<!-- Sidebar -->
|
|
<aside id="sidebar" class="w-52 bg-white border-r border-gray-200 flex flex-col shrink-0">
|
|
<nav class="flex-1 p-3 space-y-1">
|
|
<button data-page="rag" class="nav-item nav-active w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
|
|
<span>智能问答</span>
|
|
</button>
|
|
<button data-page="search" class="nav-item nav-inactive w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
|
|
<span>语义检索</span>
|
|
</button>
|
|
<button data-page="browse" class="nav-item nav-inactive w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
|
|
<span>法规浏览</span>
|
|
</button>
|
|
<button data-page="history" class="nav-item nav-inactive w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
|
|
<span>历史记录</span>
|
|
</button>
|
|
<button data-page="settings" class="nav-item nav-inactive w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
|
|
<span>设置</span>
|
|
</button>
|
|
</nav>
|
|
<div class="p-3 border-t border-gray-100">
|
|
<div id="sidebar-stats" class="text-xs text-gray-400 space-y-1">
|
|
<div>索引: <span id="stat-clauses">-</span> 条文</div>
|
|
<div>法规: <span id="stat-laws">-</span> 篇</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- Content -->
|
|
<main id="content" class="flex-1 overflow-y-auto scroll-thin">
|
|
<!-- 页面动态渲染 -->
|
|
</main>
|
|
|
|
</div>
|
|
|
|
<script src="/static/js/app.js?v=20260807"></script>
|
|
<script src="/static/js/search.js?v=20260807"></script>
|
|
<script src="/static/js/rag.js?v=20260807"></script>
|
|
<script src="/static/js/browse.js?v=20260807"></script>
|
|
<script src="/static/js/history.js?v=20260807"></script>
|
|
<script src="/static/js/settings.js?v=20260807"></script>
|
|
</body>
|
|
</html>
|