Files
zdh cc6e012903
Deploy Wiki to Production / deploy (push) Has been cancelled
feat: Loop 工程完全指南 [开发者向] — 新报告页入库
- 四阶段演进:Agent原语→Ralph Loop→调度收敛→系统化
- 16项关键技术理念,标注首创来源
- 六层架构+七大核心原则
- 三大产品对比(Claude Code/Codex/LangChain)
- 五步实战路线图+6种Loop模式速查+避坑指南
- 9项一手资料源链接
2026-06-21 18:45:34 +08:00

789 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>Wiki — 一人公司知识库</title>
<style>
/* ===== Fluent 2 / Windows 11 Design Tokens ===== */
:root {
/* Brand — Fluent 2 Communication Blue */
--color-primary: #0078D4;
--color-primary-hover: #106EBE;
--color-primary-active: #005A9E;
--color-primary-bg: #DEECF9;
/* Functional */
--color-success: #107C10;
--color-warning: #FF8C00;
--color-error: #FF4D4F;
/* Neutral — light */
--bg: #FAF9F8;
--bg-container: #FFFFFF;
--bg-elevated: #F3F2F1;
--border: #E1DFDD;
--border-light: #EDEBE9;
--text-primary: #201F1E;
--text-secondary: #605E5C;
--text-tertiary: #8A8886;
/* Radius */
--radius-xs: 2px;
--radius-sm: 4px;
--radius-md: 6px;
--radius-lg: 8px;
/* Shadows — Fluent 2 elevation */
--shadow-sm: 0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14);
--shadow-md: 0 0 2px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.14);
--shadow-lg: 0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14);
/* Layout */
--header-h: 64px;
--sidebar-w: 260px;
--drawer-bg: #FFFFFF;
/* === Added: Fluent 2 native tokens === */
/* Brand tint/shade chain */
--fluent-primary-tint-40: #EFF6FC;
--fluent-primary-tint-30: #DEECF9;
--fluent-primary-tint-20: #C7E0F4;
--fluent-primary-tint-10: #2B88D8;
--fluent-primary-shade-10: #106EBE;
--fluent-primary-shade-20: #005A9E;
--fluent-primary-shade-30: #004578;
/* Functional backgrounds */
--fluent-success-bg: #DFF6DD;
--fluent-warning-bg: #FFF4CE;
--fluent-error-bg: #FDE7E9;
--fluent-success-border: #A7E3A1;
--fluent-warning-border: #FFD335;
--fluent-error-border: #EEACB2;
/* Neutral alpha overlay */
--fluent-alpha-2: rgba(0,0,0,0.02);
--fluent-alpha-4: rgba(0,0,0,0.04);
--fluent-alpha-8: rgba(0,0,0,0.08);
--fluent-alpha-10: rgba(0,0,0,0.10);
--fluent-alpha-20: rgba(0,0,0,0.20);
--fluent-alpha-30: rgba(0,0,0,0.30);
--fluent-alpha-40: rgba(0,0,0,0.40);
/* Radius — Fluent naming */
--fluent-radius-medium: 4px;
--fluent-radius-large: 6px;
--fluent-radius-xlarge: 8px;
--fluent-radius-circular: 9999px;
/* Shadows — Fluent elevation system */
--fluent-shadow-2: 0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14);
--fluent-shadow-4: 0 0 2px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.14);
--fluent-shadow-8: 0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14);
--fluent-shadow-16: 0 0 2px rgba(0,0,0,0.12), 0 8px 16px rgba(0,0,0,0.14);
--fluent-shadow-28: 0 0 2px rgba(0,0,0,0.12), 0 14px 28px rgba(0,0,0,0.14);
--fluent-shadow-64: 0 0 2px rgba(0,0,0,0.12), 0 32px 64px rgba(0,0,0,0.14);
/* Material */
--fluent-acrylic-default: rgba(255,255,255,0.7);
--fluent-mica-bg: rgba(243,242,241,0.7);
--fluent-smoke-default: rgba(0,0,0,0.4);
--fluent-backdrop-blur: 40px;
/* Motion */
--fluent-easing-accelerate: cubic-bezier(0.9, 0.1, 1.0, 0.2);
--fluent-easing-decelerate: cubic-bezier(0.1, 0.9, 0.2, 1.0);
--fluent-easing-standard: cubic-bezier(0.8, 0.0, 0.2, 1.0);
--fluent-duration-faster: 83ms;
--fluent-duration-fast: 100ms;
--fluent-duration-normal: 167ms;
--fluent-duration-slow: 250ms;
--fluent-duration-slower: 333ms;
/* Typography */
--fluent-font-family-text: 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif;
--fluent-font-family-display: 'Segoe UI Variable Display', 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
--fluent-font-family-monospace: 'Cascadia Code', 'Fira Code', 'SF Mono', Menlo, Monaco, 'Courier New', monospace;
}
/* ===== Dark Theme — Fluent 2 Dark ===== */
[data-theme="dark"] {
--color-primary: #479EF5;
--color-primary-hover: #60A5FA;
--color-primary-active: #3B8AD9;
--color-primary-bg: rgba(71,158,245,0.15);
--bg: #1F1F1F;
--bg-container: #292929;
--bg-elevated: #333333;
--border: #474747;
--border-light: #3D3D3D;
--text-primary: #DADADA;
--text-secondary: #A0A0A0;
--text-tertiary: #7A7A7A;
--drawer-bg: #292929;
/* Dark material */
--fluent-acrylic-default: rgba(47,47,47,0.85);
--fluent-mica-bg: rgba(32,31,30,0.7);
--fluent-smoke-default: rgba(0,0,0,0.6);
/* Dark alpha */
--fluent-alpha-2: rgba(255,255,255,0.02);
--fluent-alpha-4: rgba(255,255,255,0.04);
--fluent-alpha-8: rgba(255,255,255,0.08);
--fluent-alpha-10: rgba(255,255,255,0.10);
--fluent-alpha-20: rgba(255,255,255,0.20);
--fluent-alpha-30: rgba(255,255,255,0.30);
--fluent-alpha-40: rgba(255,255,255,0.40);
/* Dark functional backgrounds */
--fluent-success-bg: rgba(16,124,16,0.15);
--fluent-warning-bg: rgba(255,140,0,0.15);
--fluent-error-bg: rgba(255,77,79,0.15);
}
/* ===== Reset & Base ===== */
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: var(--fluent-font-family-text);
background: var(--bg); color: var(--text-primary);
line-height: 1.4285; font-size: 14px; min-height: 100vh;
-webkit-tap-highlight-color: transparent;
transition: background var(--fluent-duration-normal) var(--fluent-easing-standard),
color var(--fluent-duration-normal) var(--fluent-easing-standard);
}
/* Scrollbar */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); }
/* ===== Header — Fluent 2 Acrylic Command Bar ===== */
.header-bar {
position: sticky; top: 0; height: var(--header-h);
background: var(--fluent-acrylic-default);
backdrop-filter: blur(var(--fluent-backdrop-blur)) saturate(125%);
-webkit-backdrop-filter: blur(var(--fluent-backdrop-blur)) saturate(125%);
border-bottom: 1px solid var(--border-light);
display: flex; align-items: center; justify-content: center;
padding: 0 2rem; z-index: 100; gap: 16px;
}
.header-bar-inner {
display: flex; align-items: center; gap: 16px;
max-width: 1200px; width: 100%;
}
.header-bar .menu-btn {
width: 36px; height: 36px; border: none; background: none;
cursor: pointer; border-radius: var(--radius-sm);
display: flex; align-items: center; justify-content: center;
flex-shrink: 0; padding: 0;
color: var(--text-secondary);
transition: background var(--fluent-duration-fast) var(--fluent-easing-decelerate);
}
.header-bar .menu-btn:hover { background: var(--bg-elevated); }
.header-bar .menu-btn svg { width: 20px; height: 20px; }
.header-bar .brand { display: flex; align-items: baseline; gap: 8px; flex-shrink: 0; }
.header-bar h1 {
font-size: 18px; font-weight: 700;
background: linear-gradient(135deg, #0078D4 0%, #2B88D8 100%);
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
.header-bar .tagline { font-size: 12px; color: var(--text-tertiary); display: inline; }
/* Search — Fluent 2 outline input */
.search-box { flex: 1; min-width: 120px; max-width: 360px; position: relative; }
.search-box input {
width: 100%; padding: 8px 12px 8px 34px;
border: 1px solid var(--border); border-radius: var(--radius-sm);
font-size: 14px; outline: none; background: var(--bg-elevated); color: var(--text-primary);
transition: border-color var(--fluent-duration-fast) var(--fluent-easing-standard),
box-shadow var(--fluent-duration-fast) var(--fluent-easing-standard),
background var(--fluent-duration-fast) var(--fluent-easing-standard);
}
.search-box input::placeholder { color: var(--text-tertiary); }
.search-box input:focus {
border-color: var(--color-primary);
box-shadow: 0 0 0 2px var(--fluent-primary-tint-20);
background: var(--bg-container);
}
.search-box .search-icon {
position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
color: var(--text-tertiary); font-size: 15px; pointer-events: none;
}
/* Theme toggle */
.header-bar .theme-btn {
width: 36px; height: 36px; border: none; background: none;
cursor: pointer; border-radius: var(--radius-sm);
display: flex; align-items: center; justify-content: center;
font-size: 16px; color: var(--text-secondary); flex-shrink: 0; padding: 0;
transition: background var(--fluent-duration-fast) var(--fluent-easing-decelerate);
}
.header-bar .theme-btn:hover { background: var(--bg-elevated); }
/* ===== Mobile Chip Bar — Fluent 2 Tab style ===== */
.chip-bar {
display: none; padding: 10px 16px 0; background: var(--bg-container);
border-bottom: 1px solid var(--border-light);
position: sticky; top: var(--header-h); z-index: 90;
}
.chip-bar-inner {
display: flex; gap: 8px; overflow-x: auto; -webkit-overflow-scrolling: touch;
padding-bottom: 10px; scrollbar-width: none;
}
.chip-bar-inner::-webkit-scrollbar { display: none; }
.chip {
display: inline-flex; align-items: center; gap: 5px;
padding: 6px 12px; border-radius: var(--radius-sm); font-size: 13px; font-weight: 500;
white-space: nowrap; border: 1px solid var(--border);
background: var(--bg-container); color: var(--text-secondary);
cursor: pointer; user-select: none;
-webkit-tap-highlight-color: transparent; min-height: 36px;
transition: background var(--fluent-duration-fast) var(--fluent-easing-decelerate),
border-color var(--fluent-duration-fast) var(--fluent-easing-decelerate),
color var(--fluent-duration-fast) var(--fluent-easing-decelerate);
}
.chip:hover { background: var(--fluent-primary-tint-40); border-color: var(--fluent-primary-tint-20); }
.chip.active {
background: var(--fluent-primary-tint-30);
border-color: var(--color-primary);
color: var(--color-primary);
}
.chip .chip-count { font-size: 11px; background: var(--fluent-alpha-8); border-radius: 10px; padding: 0 5px; }
.chip.active .chip-count { background: var(--fluent-primary-tint-20); color: var(--color-primary); }
/* ===== Layout ===== */
.layout {
display: flex; max-width: 1200px; margin: 0 auto;
min-height: calc(100vh - var(--header-h));
}
/* ===== Sidebar — Fluent 2 NavigationView ===== */
.sidebar {
width: var(--sidebar-w); flex-shrink: 0; background: var(--bg-container);
border-right: 1px solid var(--border); padding: 1.25rem 0;
overflow-y: auto; position: sticky; top: var(--header-h);
height: calc(100vh - var(--header-h));
}
.sidebar .nav-section { padding: 0 16px; margin-bottom: 8px; }
.sidebar .nav-section-title {
font-size: 10px; font-weight: 600; color: var(--text-tertiary);
text-transform: uppercase; letter-spacing: 0.8px; margin-bottom: 4px; padding: 4px 0;
}
.sidebar .nav-item {
display: flex; align-items: center; gap: 8px; padding: 8px 12px;
border-radius: var(--radius-sm); font-size: 13px; color: var(--text-secondary);
cursor: pointer; text-decoration: none; min-height: 40px;
transition: background var(--fluent-duration-fast) var(--fluent-easing-decelerate),
color var(--fluent-duration-fast) var(--fluent-easing-decelerate);
}
.sidebar .nav-item:hover { background: var(--bg-elevated); color: var(--text-primary); }
.sidebar .nav-item.active {
background: var(--fluent-primary-tint-30);
color: var(--color-primary); font-weight: 500;
}
.sidebar .nav-item .nav-icon { font-size: 14px; flex-shrink: 0; width: 20px; text-align: center; }
.sidebar .nav-item .nav-count {
margin-left: auto; font-size: 11px; color: var(--text-tertiary);
background: var(--bg-elevated); border-radius: 10px; padding: 0 6px;
}
.sidebar .nav-item.active .nav-count {
background: var(--fluent-primary-tint-20); color: var(--color-primary);
}
.sidebar .sub-nav {
padding-left: 24px; overflow: hidden; max-height: 0;
transition: max-height var(--fluent-duration-slow) var(--fluent-easing-standard);
}
.sidebar .sub-nav.open { max-height: 500px; }
.sidebar .sub-nav .nav-item { font-size: 12px; padding: 5px 12px; }
.sidebar .theme-section {
padding: 12px 16px; border-top: 1px solid var(--border-light); margin-top: 8px;
}
.sidebar .theme-toggle-btn {
display: flex; align-items: center; gap: 8px; width: 100%;
padding: 8px 12px; border: none; background: none; cursor: pointer;
border-radius: var(--radius-sm); font-size: 13px; color: var(--text-secondary);
min-height: 40px;
transition: background var(--fluent-duration-fast) var(--fluent-easing-decelerate),
color var(--fluent-duration-fast) var(--fluent-easing-decelerate);
}
.sidebar .theme-toggle-btn:hover { background: var(--bg-elevated); color: var(--text-primary); }
/* ===== Drawer — Fluent 2 Flyout ===== */
.drawer-overlay {
display: none; position: fixed; inset: 0;
background: var(--fluent-smoke-default);
z-index: 200; opacity: 0;
transition: opacity var(--fluent-duration-normal) var(--fluent-easing-decelerate);
}
.drawer-overlay.show { display: block; opacity: 1; }
.drawer {
position: fixed; top: 0; left: 0; bottom: 0; width: 280px; max-width: 85vw;
background: var(--drawer-bg); z-index: 201;
transform: translateX(-100%);
transition: transform var(--fluent-duration-slow) var(--fluent-easing-standard);
overflow-y: auto;
}
.drawer-overlay.show .drawer { transform: translateX(0); }
.drawer-header {
display: flex; align-items: center; justify-content: space-between;
padding: 12px 16px; border-bottom: 1px solid var(--border-light);
}
.drawer-header .close-btn {
width: 32px; height: 32px; border: none; background: var(--bg-elevated);
border-radius: var(--radius-sm); cursor: pointer; display: flex;
align-items: center; justify-content: center; font-size: 18px;
color: var(--text-secondary);
transition: background var(--fluent-duration-fast) var(--fluent-easing-decelerate);
}
.drawer-header .close-btn:hover { background: var(--fluent-primary-tint-30); color: var(--color-primary); }
.drawer .theme-toggle-btn {
display: flex; align-items: center; gap: 8px; width: calc(100% - 32px);
margin: 12px 16px; padding: 8px 12px; border: 1px solid var(--border);
background: var(--bg-elevated); cursor: pointer; border-radius: var(--radius-sm);
font-size: 13px; color: var(--text-secondary); min-height: 40px;
transition: background var(--fluent-duration-fast) var(--fluent-easing-decelerate),
color var(--fluent-duration-fast) var(--fluent-easing-decelerate);
}
.drawer .theme-toggle-btn:hover { background: var(--color-primary-bg); color: var(--color-primary); }
/* ===== Main Content ===== */
.main { flex: 1; padding: 32px 40px 64px; min-width: 0; }
.breadcrumb {
font-size: 12px; color: var(--text-tertiary); margin-bottom: 12px;
}
.breadcrumb a { color: var(--text-tertiary); text-decoration: none;
transition: color var(--fluent-duration-fast) var(--fluent-easing-standard);
}
.breadcrumb a:hover { color: var(--color-primary); }
.breadcrumb .sep { margin: 0 4px; }
/* Stats — Fluent 2 Info style */
.stats-bar { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
.stat-item {
display: flex; align-items: baseline; gap: 4px;
padding: 8px 14px; background: var(--bg-container);
border: 1px solid var(--border-light); border-radius: var(--radius-sm);
}
.stat-num { font-size: 18px; font-weight: 700; color: var(--color-primary); }
.stat-label { font-size: 12px; color: var(--text-tertiary); }
/* Section */
.wiki-section { margin-bottom: 28px; }
.wiki-section-title {
font-size: 20px; font-weight: 600; color: var(--text-primary); margin-bottom: 4px;
}
.wiki-section-desc { font-size: 13px; color: var(--text-tertiary); margin-bottom: 14px; }
/* ===== Cards — Fluent 2 Card with elevation ===== */
.all-grid {
display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px;
}
.all-card {
background: var(--bg-container); border: 1px solid var(--border);
border-radius: var(--radius-md); padding: 20px;
box-shadow: var(--fluent-shadow-2);
text-decoration: none; color: var(--text-primary); display: block; cursor: pointer;
transition: box-shadow var(--fluent-duration-normal) var(--fluent-easing-standard),
border-color var(--fluent-duration-normal) var(--fluent-easing-standard);
}
.all-card:hover { box-shadow: var(--fluent-shadow-4); border-color: var(--border); }
.all-card .card-title { font-size: 14px; font-weight: 600; margin-bottom: 4px; }
.all-card .card-desc {
font-size: 12px; color: var(--text-tertiary); line-height: 1.5;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.all-card .card-meta { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.all-card .card-badge {
font-size: 11px; padding: 2px 8px; border-radius: var(--radius-xs); font-weight: 500;
}
.all-card .card-date { font-size: 11px; color: var(--text-tertiary); }
/* ===== Section Expand — 分组条目过多时可折叠 ===== */
.all-grid .section-expand-wrap { grid-column: 1 / -1; text-align: center; padding: 8px 0; }
.section-expand-btn {
display: inline-flex; align-items: center; gap: 6px;
padding: 9px 28px; background: var(--bg-container);
border: 1px solid var(--border); border-radius: var(--radius-sm);
color: var(--color-primary); font-size: 13px; font-weight: 600;
cursor: pointer; font-family: inherit;
transition: all var(--fluent-duration-fast) var(--fluent-easing-standard);
}
.section-expand-btn:hover {
background: var(--color-primary-bg); border-color: var(--color-primary);
}
.section-expand-btn .expand-arrow {
display: inline-block; font-size: 12px;
transition: transform var(--fluent-duration-normal) var(--fluent-easing-standard);
}
.section-expand-btn.expanded .expand-arrow { transform: rotate(180deg); }
.all-card.card-hidden { display: none; }
/* ===== Wiki TOC — Fluent 2 Accordion ===== */
.wiki-toc {
background: var(--bg-container); border: 1px solid var(--border-light);
border-radius: var(--radius-md); overflow: hidden; margin-top: 8px;
}
.wiki-toc-header {
display: flex; align-items: center; gap: 10px; padding: 14px 18px;
background: var(--bg-elevated); border-bottom: 1px solid var(--border-light);
cursor: pointer; user-select: none; min-height: 44px;
transition: background var(--fluent-duration-fast) var(--fluent-easing-decelerate);
}
.wiki-toc-header:hover { background: var(--fluent-primary-tint-30); }
.wiki-toc-header .toc-icon {
font-size: 16px; color: var(--text-secondary);
transition: transform var(--fluent-duration-normal) var(--fluent-easing-standard);
}
.wiki-toc-header.open .toc-icon { transform: rotate(90deg); }
.wiki-toc-header .toc-title { font-size: 14px; font-weight: 600; flex: 1; }
.wiki-toc-header .toc-count { font-size: 12px; color: var(--text-tertiary); }
.wiki-toc-body {
overflow: hidden; max-height: 0;
transition: max-height var(--fluent-duration-slow) var(--fluent-easing-standard);
}
.wiki-toc-body.open { max-height: none; }
.wiki-toc-item {
display: flex; align-items: center; gap: 10px; padding: 12px 18px 12px 42px;
border-bottom: 1px solid var(--border-light);
text-decoration: none; color: var(--text-primary); min-height: 48px;
transition: background var(--fluent-duration-fast) var(--fluent-easing-decelerate);
}
.wiki-toc-item:last-child { border-bottom: none; }
.wiki-toc-item:hover { background: var(--bg-elevated); }
.wiki-toc-item:active { background: var(--fluent-primary-tint-30); }
.wiki-toc-item .item-icon { font-size: 14px; color: var(--text-tertiary); flex-shrink: 0; }
.wiki-toc-item .item-title { flex: 1; font-size: 13px; }
.wiki-toc-item .item-tag {
font-size: 11px; padding: 2px 8px; border-radius: var(--radius-xs);
background: var(--bg-elevated); color: var(--text-tertiary); flex-shrink: 0;
}
/* ===== Responsive — Fluent 2 Breakpoints ===== */
@media (min-width: 1024px) { .chip-bar { display: none !important; } }
@media (max-width: 1023px) {
.sidebar { width: 220px; }
}
@media (max-width: 639px) {
.header-bar { padding: 0 16px; }
.header-bar .tagline { display: none; }
.search-box input { padding: 7px 10px 7px 30px; }
.search-box .search-icon { left: 8px; font-size: 14px; }
.chip-bar { display: block; }
.sidebar { display: none; }
.main { padding: 24px 16px 48px; }
.all-grid { grid-template-columns: 1fr; }
.all-card { padding: 16px; }
.stats-bar { gap: 8px; }
.stat-item { padding: 6px 10px; }
.stat-num { font-size: 16px; }
.wiki-section-title { font-size: 18px; }
.wiki-toc-item { padding: 10px 14px 10px 36px; }
.wiki-toc-header { padding: 12px 14px; }
}
</style>
</head>
<body>
<header class="header-bar">
<div class="header-bar-inner">
<button class="menu-btn" id="menuBtn" aria-label="菜单">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
</button>
<div class="brand">
<h1>Wiki 知识库</h1>
<span class="tagline">一人公司开发团队</span>
</div>
<div class="search-box">
<span class="search-icon">&#x1F50D;</span>
<input type="text" id="searchInput" placeholder="搜索文档..." autocomplete="off">
</div>
<button class="theme-btn" id="themeBtn"></button>
</div>
</header>
<div class="chip-bar"><div class="chip-bar-inner" id="chipBar"></div></div>
<div class="drawer-overlay" id="drawerOverlay">
<div class="drawer">
<div class="drawer-header">
<span style="font-weight:600;font-size:15px;">导航</span>
<button class="close-btn" id="drawerClose">&#x2715;</button>
</div>
<div id="drawerNav"></div>
<button class="theme-toggle-btn" id="drawerThemeBtn"></button>
</div>
</div>
<div class="layout">
<nav class="sidebar" id="sidebar"></nav>
<div class="main" id="main"></div>
</div>
<script>
var htmlEl = document.documentElement;
var themeLabel = '';
function setTheme(t) {
htmlEl.setAttribute('data-theme', t);
localStorage.setItem('wiki-theme', t);
var label = t === 'dark' ? '☀️' : '🌙';
document.getElementById('themeBtn').textContent = label;
document.getElementById('drawerThemeBtn').textContent = label + ' 切换' + (t === 'dark' ? '浅色' : '深色') + '模式';
document.querySelectorAll('.sidebar .theme-toggle-btn').forEach(function(b) { b.textContent = label + ' 切换' + (t === 'dark' ? '浅色' : '深色') + '模式'; });
}
var saved = localStorage.getItem('wiki-theme');
if (saved) { setTheme(saved); }
else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { setTheme('dark'); }
else { setTheme('light'); }
document.getElementById('drawerThemeBtn').addEventListener('click', function() {
setTheme(htmlEl.getAttribute('data-theme') === 'dark' ? 'light' : 'dark');
});
document.getElementById('themeBtn').addEventListener('click', function() {
setTheme(htmlEl.getAttribute('data-theme') === 'dark' ? 'light' : 'dark');
});
const wikiData = [
{ dir: "身份认证与安全", icon: "🔐", desc: "统一身份认证、IAM 选型、零信任安全", color: "pink",
items: [
{ path: "全域智能认证与门户平台/报告/unified-auth-portal-requirements.html", title: "全域智能认证与门户平台需求分析", desc: "企业级统一身份认证与门户平台完整需求拆解,含 13 套系统对接清单、架构设计、实施路线图", date: "2026-05-08" },
{ path: "全域智能认证与门户平台/报告/identity-auth-center-tech-analysis.html", title: "身份认证中心技术解析", desc: "多元化认证、零信任登录、密码代填、CAS 对接深度解析,Keycloak/Casdoor/MaxKey 对比", date: "2026-05-08" },
{ path: "全域智能认证与门户平台/报告/opensource-iam-selection-report.html", title: "开源 IAM 项目选型报告", desc: "5 大开源 IAM 项目匹配度深度对比,含需求矩阵、综合评分与推荐架构蓝图", date: "2026-05-08" }
]},
{ dir: "IoT 与数据平台", icon: "🏭", desc: "物联网数据平台、IoT 架构、数据库迁移", color: "blue",
items: [
{ path: "沈阳顺义-数据-项目建设方案/报告/沈阳顺义数据项目建设方案解读.html", title: "沈阳顺义数据项目建设方案解读", desc: "PHM 数据应用平台 12+3 功能模块拆解、17 项功能要求覆盖、13 项技术指标对照", date: "2026-05-12" },
{ path: "沈阳顺义-数据-项目建设方案/报告/开源项目匹配度分析.html", title: "沈阳顺义项目开源方案匹配度", desc: "10 个开源项目在 IoT 层、数据治理层、算法层的匹配度矩阵与推荐组合", date: "2026-05-12" },
{ path: "沈阳顺义-数据-项目建设方案/报告/开源版专业版功能对比.html", title: "开源版 vs 专业版功能对比", desc: "13 大模块逐项对比,标注开源版已包含/部分包含/缺失功能项", date: "2026-05-12" },
{ path: "沈阳顺义-数据-项目建设方案/报告/需求对比分析报告.html", title: "需求文档 vs 系统实际功能对比", desc: "需求文档与系统实际功能覆盖度对照分析", date: "2026-05-12" },
{ path: "MySQL转PostgreSQL迁移工具/报告/mysql-to-pg-migration-tools.html", title: "MySQL 转 PostgreSQL 迁移工具", desc: "主流迁移工具对比分析,含云厂商方案与开源方案", date: "2026-05-04" }
]},
{ dir: "电商与商业", icon: "🛒", desc: "电商系统、分销推广、商业模式", color: "mint",
items: [
{ path: "金鹿商城电商小程序需求分析/报告/jinlu-deer-mall-requirements-analysis.html", title: "金鹿商城电商小程序需求分析", desc: "需求解读与 CRMEB 差异对比,含限时抢签/活动币/积分商城模块拆解与 26 人天实施计划", date: "2026-05-09" },
{ path: "crmeb-mer-graph-report.html", title: "CRMEB-MER 项目图谱报告", desc: "多商户电商系统的代码结构、依赖图谱与架构深度分析", date: "2026-05-06" },
{ path: "分销商城推广模式调研/报告/分销商城推广模式全景调研.html", title: "分销商城推广模式全景调研", desc: "18 种推广模式系统梳理,含核心机制、收益分析、分润计算、合规框架与选型", date: "2026-05-06" },
{ path: "国内商业业态分类到家/报告/到家业态分类全景.html", title: "国内商业业态分类(到家服务)", desc: "按服务本质分为 5 大板块 92 业态,含楼层收费参考与商业模式对比", date: "2026-05-05" }
]},
{ dir: "AI 开发工具", icon: "🤖", desc: "AI 辅助开发、代码分析、MCP 服务、智能体平台", color: "lavender",
items: [
{ path: "Claude Code 工程师使用指南/报告/claude-code-engineering-guide.html", title: "Claude Code 最佳实践", desc: "Claude Code 在软件工程场景下的最佳实践与工作流指南", date: "2026-04-29" },
{ path: "graphify-rs使用手册/报告/graphify-rs-usage-guide.html", title: "graphify-rs 使用手册", desc: "代码知识图谱工具完整使用指南,含安装、构建、查询、集成", date: "2026-05-08" },
{ path: "Graphify 深度分析报告/代码/graphify-analysis.html", title: "Graphify 代码分析", desc: "Graphify 项目的代码结构、质量指标与重构建议", date: "2026-04-29" },
{ path: "代码图谱工具调研/报告/code-structure-tools-analysis.html", title: "代码图谱工具调研", desc: "主流代码结构与可视化工具的横向对比分析", date: "2026-04-29" },
{ path: "mcp-services-guide/index.html", title: "MCP 服务大全", desc: "适合开发者使用的 MCP 服务大全,含功能对比与快速开始指南", date: "2026-04-29" },
{ path: "智能体平台调研/报告/ai-agent-platform-comparison.html", title: "全功能智能体平台深度对比", desc: "覆盖10个核心平台(GitHub 7+Gitee 3),五大功能维度矩阵:多智能体平面·低代码编排·Harness基建·技能市场·评测服务,含81个开源项目索引与选型建议", date: "2026-06-04" },
{ path: "智能体平台调研/报告/spring-ai-alibaba-deployment-guide.html", title: "Spring AI Alibaba 全功能部署指南", desc: "本地内网环境从零部署全功能平台:WSL2环境准备→PostgreSQL+Nacos+MinIO中间件→全功能模块激活→内网访问配置→运维手册→故障排查,含Docker Compose一键编排与启动脚本", date: "2026-06-05" },
{ path: "AI核心技能原理说明.html", title: "AI 核心技能原理说明", desc: "系统梳理 LLM / Prompt Engineering / Agent / Skills 编排 / RAG / AI Coding / YOLO 七大方向的技术原理与工程实践", date: "2026-06-05" },
]},
{ dir: "企业AI转型", icon: "🚀", desc: "转型方案、成熟度模型、开发流程、角色矩阵、培训体系", color: "pink",
items: [
{ path: "研发型企业AI转型方案/报告/ai-training-roadmap.html", title: "企业AI落地 · 培训路线图", desc: "五阶段学习路径(认知→工具→角色→流程→组织),含角色×阶段矩阵、12周实施节奏、效果度量指标、14份材料速查索引", date: "2026-06-07" },
{ path: "研发型企业AI转型方案/报告/软件企业AI转型全套方案.html", title: "软件企业 AI 转型全套方案", desc: "七大维度完整框架:战略与愿景→工具技术栈→研发流程方法论→组织人才→治理合规→基础设施→度量迭代,含ROI测算与12个月路线图", date: "2026-05-31" },
{ path: "研发型企业AI转型方案/报告/ai-transformation-plan.html", title: "研发型企业 AI 转型方案 V2.0", desc: "五大篇章:工具全景图(7大类30+工具)+ 分级培训 + 售前交付方法论 + 员工绩效评估体系 + 外包AI开发治理框架,含合同条款模板与验收机制", date: "2026-05-31" },
{ path: "研发型企业AI转型方案/报告/ai-dev-workflow.html", title: "AI 驱动开发流程:多模型协同工作流", desc: "Claude Code主力Agent + DeepSeek/Qwen分级调度 + open-code-review质量门禁 + 企业知识库RAG + 个人记忆系统,含12周落地路线图与ROI量化分析", date: "2026-05-30" },
{ path: "研发型企业AI转型方案/报告/ai-dev-workflow-v2.html", title: "AI 开发流程 V2.0:新项目脚手架驱动 + 老项目维护双轨制", desc: "两套完整工作流:新项目以脚手架为基础全量生成(70-90%AI占比),老项目以代码考古驱动增量修改(小步提交≤200行diff),含实操案例与完整Prompt", date: "2026-05-31" },
{ path: "研发型企业AI转型方案/报告/ai-enterprise-maturity-model.html", title: "企业 AI 成熟度五级模型", desc: "L0前AI期→L1萌芽期→L2规范期→L2.5增强期→L3原生期,含每级判定标准、跃迁路径、触发信号与常见陷阱", date: "2026-06-03" },
{ path: "研发型企业AI转型方案/报告/ai-role-level-matrix.html", title: "角色×AI成熟度 效果矩阵", desc: "七角色(开发/工程师/售前/PM/应用顾问/测试/管理层)×五级别全景矩阵,含各角色国内AI工具选型", date: "2026-06-14" },
{ path: "研发型企业AI转型方案/报告/ai-role-level-matrix-interactive.html", title: "角色×AI成熟度 效果矩阵 [交互版]", desc: "可点击交互矩阵:点击任意角色×级别单元格即时查看完整信息,支持键盘导航与级别筛选", date: "2026-06-14" },
{ path: "研发型企业AI转型方案/报告/ai-training-outline-for-it-services.html", title: "AI 赋能 IT 服务团队:培训与落地全套提纲", desc: "融合企业实际需求:工具全景图→四角色赋能矩阵→三阶培训体系→方法论进化→12周落地路线图,面向IT服务企业的端到端AI赋能方案", date: "2026-06-03" },
{ path: "研发型企业AI转型方案/报告/ai-capability-efficiency-strategy.html", title: "AI 红利下行业软件公司应对策略", desc: "效率是底座、能力是天花板:AI 打破三大限制(技术/时间/人力),全链条响应升级(售前→开发→交付→售后),跑在客户预期前面", date: "2026-06-01" },
{ path: "研发型企业AI转型方案/报告/ai-tools-hands-on-training.html", title: "AI 工具实操培训 · 第一课", desc: "Claude Code 安装与使用、DeepSeek API Token 购买、Trae/Qoder/通义灵码等常见工具介绍与选型、现场演示 Git 项目拉取与 AI 启动", date: "2026-06-06" },
{ path: "研发型企业AI转型方案/报告/ai-tools-training-lesson2-gitea.html", title: "AI 工具实操培训 · 第二课", desc: "Docker 部署 Gitea 私服、Access Token 配置、AI Clone→修改→Commit→Push 全流程、实操三个任务:去版权头+代码风格统一+开发第一个功能", date: "2026-06-06" },
{ path: "研发型企业AI转型方案/报告/ai-tools-training-lesson3-presales-demo.html", title: "AI 工具实操培训 · 第三课", desc: "售前演示 Demo 制作:四种场景模板(管理后台/数据大屏/工作流/小程序)、Prompt 模板库、六步速成法、演示话术", date: "2026-06-06" },
{ path: "研发型企业AI转型方案/报告/ai-tools-training-lesson4-bidding.html", title: "AI 工具实操培训 · 第四课", desc: "招投标文件与解决方案编写:标书解读→评分点提取→逐章方案生成→报价分析→答辩PPT,方案周期从5-10天压缩到1-2天", date: "2026-06-06" },
{ path: "研发型企业AI转型方案/报告/ai-tools-training-lesson5-pm.html", title: "AI 工具实操培训 · 第五课", desc: "项目经理AI工作流:需求→WBS自动拆解→排期+甘特图、Gitea数据→进度报告+偏差预警、风险自动识别+登记册+看板", date: "2026-06-06" },
{ path: "研发型企业AI转型方案/报告/ai-tools-training-lesson6-performance.html", title: "AI 工具实操培训 · 第六课", desc: "员工绩效评定:六维指标模型(产出/质量/协作/规范/成长/影响)、Gitea数据采集、AI绩效画像、面谈话术、五条红线", date: "2026-06-06" },
]},
{ dir: "AI Agent 驾驭工程", icon: "🎛️", desc: "Harness → Loop Engineering · Agent 运行时管控 · 自主循环系统设计", color: "pink",
items: [
{ path: "AI Agent 驾驭工程/报告/ai-agent-harness-engineering.html", title: "AI Agent 驾驭工程(Harness Engineering)全面解析", desc: "从提示工程到驾驭工程的三级跃迁:11项核心组件职责、H0-H3四级成熟度模型、四大技术模块架构、三大支柱(前馈·反馈·传感器)、五大设计原则、实战案例与概念辨析", date: "2026-06-14" },
{ path: "AI Agent 驾驭工程/报告/loop-engineering-guide.html", title: "Loop 工程完全指南 [开发者向]", desc: "2026年6月新范式:从手动Prompt到设计自主循环系统。4阶段演进、16项关键技术、6层架构+7大原则、3大产品对比、5步实战路线图、6种Loop模式速查", date: "2026-06-21" },
]},
{ dir: "抖音话题", icon: "🎙️", desc: "行业观点、口播话术、短视频脚本", color: "orange",
items: [
{ path: "抖音话题/报告/ai-transformation-speech-and-script.html", title: "AI转型·演讲稿 + 口播稿", desc: "面向软件企业老板的18分钟演讲稿+90秒短视频口播脚本:六环递进论点链(窗口期→岗位消失→管理崩塌→老板用AI看见→精准激励→商业闭环)", date: "2026-06-03" }
]},
{ dir: "政务与行业", icon: "🏛", desc: "政府招投标、智慧监管、政策解读", color: "pink",
items: [
{ path: "招标投标AI推广应用政策解读/报告/ai-bidding-tendering-policy-analysis.html", title: "招标投标领域AI政策解读", desc: "国家发改委等八部门联合发文,6 大领域 20 个 AI 场景全景拆解与市场机遇", date: "2026-05-09" },
{ path: "招标投标AI推广应用政策解读/报告/provincial-bidding-smart-supervision-platform.html", title: "省级招投标智慧监管平台建设方案", desc: "业务痛点分析、8 大业务场景设计、功能模块规划、系统架构与技术路径", date: "2026-05-09" },
{ path: "市属国企参与物流网建设调研报告/报告/市属国企参与物流网建设调研报告.html", title: "市属国企参与「物流网」建设调研报告", desc: "深国际为主体参与深圳物流网建设的系统调研,含政策背景、沪新对标、四层网络定义、五大方向三项目清单、风险研判与保障建议", date: "2026-05-29" },
{ path: "市属国企参与物流网建设调研报告/报告/物流网调研报告-扩展分析.html", title: "「物流网」调研报告·扩展分析", desc: "四维深度分析:15项数据真实性核验、逻辑链可信性评估、三项目可行性判断、五路径路线性评分,含七项改进建议", date: "2026-05-29" },
{ path: "市属国企参与物流网建设调研报告/报告/物流网建设调研报告-战略优化版.html", title: "「物流网」调研报告·战略优化版", desc: "战略研究部基于深国际2025年报的审慎修订:新增公司全景画像、12项数据修正、财务约束分析、量化KPI体系、竞争对标", date: "2026-05-29" },
{ path: "市属国企参与物流网建设调研报告/报告/物流网建设-调研框架与数据基线.html", title: "物流网建设·调研框架与数据基线", desc: "从深国际实际出发的调研模板:11个模块覆盖自身家底/外部环境/路径规划/压力测试,公开数据已填入、内部数据留白标注", date: "2026-05-29" },
{ path: "深国际综合改革方案/index.html", title: "深国际向物流综合服务商转型综合改革方案(系列)", desc: "两篇系列报告:总纲改革方案(六大举措+50+文献出处)+专家头脑风暴(速赢项目+量化参数+行动清单)", date: "2026-06-03" },
{ path: "银行业Agent建设方案/报告/banking-agent-construction-plan.html", title: "银行业 AI Agent 建设方案", desc: "银行智能中台整体规划:五层架构、多Agent协作、30万存量服务集成策略、多租户隔离、合规中间件", date: "2026-06-10" },
{ path: "银行业Agent建设方案/报告/agentscope-java-openclaw-banking-midplatform.html", title: "AgentScope-Java 复刻 OpenClaw · 银行智能中台", desc: "完整技术架构方案:5层系统设计、Web Dashboard、多租户网关、30万服务自动Tool生成、BitMap预过滤+混合检索、12周里程碑、Java/TypeScript/Vue3全栈代码", date: "2026-06-12" },
{ path: "银行业Agent建设方案/报告/banking-intent-recognition.html", title: "意图识别与工具检索方案", desc: "30万工具×64K上下文的检索漏斗:意图提取NLU、混合检索Dense+Sparse→RRF、Cross-encoder精排、六层准确性保障、银行场景实战走查", date: "2026-06-12" },
{ path: "银行业Agent建设方案/报告/banking-internal-agent-compliance-risks.html", title: "银行内业务Agent:注意事项、约束条件与风险全景", desc: "面向银行员工直接使用的内部Agent:11项法规对标、6条刚性红线、9类风险矩阵、3级场景准入(P0/P1/禁区)、4大合规支柱、3级数据分类、7步行动路线、员工实操自检清单", date: "2026-06-14" },
]},
{ dir: "配送与到家", icon: "🚚", desc: "在线下单、配送调度、到家服务", color: "mint",
items: [
{ path: "在线下单配送抢单小程序调研/报告/delivery-order-grabbing-mini-program-research.html", title: "在线下单配送抢单小程序调研", desc: "Top 5 开源外卖/跑腿/抢单小程序横向对比,含功能完成度矩阵与技术方案", date: "2026-05-05" },
{ path: "交互式演示/tetrahedron-interactive.html", title: "正四面体旋转与展开动画", desc: "鼠标拖拽旋转四面体,点击铰链展开为平面展开图", date: "2026-05-06" }
]},
{ dir: "医疗与健康", icon: "🏥", desc: "中医馆管理、医疗健康系统", color: "blue",
items: [
{ path: "中医馆内部管理系统/报告/中医馆内部管理系统_需求分析对比报告.html", title: "中医馆内部管理系统需求分析报告", desc: "医生端/仓库端/管理后台逐模块对比分析,含 14 项缺失、15 项优化、10 项补充建议,每项注明理由", date: "2026-05-23" },
{ path: "中医馆内部管理系统/报告/中医馆内部管理系统_需求分析对比报告_mobile.html", title: "中医馆需求分析报告(手机版)", desc: "卡片式可折叠布局,支持标签页切换与底部导航,适合手机端阅读的需求分析对比报告", date: "2026-05-23" },
{ path: "中医馆内部管理系统/报告/中医馆内部管理系统_需求文档.md", title: "中医馆内部管理系统需求文档", desc: "基于 XMind 思维导图整理的原始需求文档,含核心业务流程、各终端功能模块、药品分类与系统规则", date: "2026-05-23" }
]},
{ dir: "关于作者", icon: "👤", desc: "个人简历与联系方式", color: "lavender",
items: [
{ path: "张德海_简历.html", title: "张德海 · 个人简历", desc: "20年Java全栈工程师,技术管理者,AI应用实践者 — 完整技术能力、项目经验与工作履历", date: "2026-06-04" },
{ path: "简历AI技术讲解.html", title: "简历 AI 技术讲解", desc: "Agent / Skills / RAG / Function Calling / Prompt Engineering / AI Coding / YOLO / LangChain / MCP 九大技术领域深度讲解", date: "2026-06-08" },
{ path: "Dify部署分析报告.html", title: "Dify 本机部署分析报告", desc: "Dify 1.14.2 完整部署分析:架构拓扑、RAG/Workflow/Agent/插件四大核心功能技术方案、13个容器状态、关键配置与问题诊断", date: "2026-06-08" },
]}
];
const allItems = [];
for (const s of wikiData) { if (s.items) { for (const item of s.items) { allItems.push(Object.assign({}, item, { section: s.dir, icon: s.icon })); } } }
let currentView = 'all';
let searchQuery = '';
var drawerEl = document.getElementById('drawerOverlay');
document.getElementById('menuBtn').addEventListener('click', function() { drawerEl.classList.add('show'); });
document.getElementById('drawerClose').addEventListener('click', function() { drawerEl.classList.remove('show'); });
drawerEl.addEventListener('click', function(e) { if (e.target === drawerEl) drawerEl.classList.remove('show'); });
function buildNav(targetEl) {
var html = '<div class="nav-section"><div class="nav-section-title">导航</div>';
html += '<a class="nav-item' + (currentView === 'all' ? ' active' : '') + '" href="#" data-view="all"><span class="nav-icon">&#x1F3E0;</span><span>全部文档</span><span class="nav-count">' + allItems.length + '</span></a>';
html += '</div>';
for (const section of wikiData) {
if (!section.items) continue;
html += '<div class="nav-section"><div class="nav-section-title">' + section.desc + '</div>';
html += '<a class="nav-item' + (currentView === section.dir ? ' active' : '') + '" href="#" data-view="' + section.dir + '"><span class="nav-icon">' + section.icon + '</span><span>' + section.dir + '</span><span class="nav-count">' + section.items.length + '</span></a>';
html += '<div class="sub-nav' + (currentView === section.dir ? ' open' : '') + '">';
for (const item of section.items) { html += '<a class="nav-item" href="' + item.path + '"><span class="nav-icon">&#x1F4C4;</span><span>' + item.title + '</span></a>'; }
html += '</div></div>';
}
// Theme toggle in sidebar
html += '<div class="theme-section"><button class="theme-toggle-btn" onclick="setTheme(document.documentElement.getAttribute(\'data-theme\')===\'dark\'?\'light\':\'dark\')">' + themeLabel + '</button></div>';
targetEl.innerHTML = html;
targetEl.querySelectorAll('.nav-item[data-view]').forEach(function(el) {
el.addEventListener('click', function(e) { e.preventDefault(); currentView = el.dataset.view; drawerEl.classList.remove('show'); render(); });
});
}
function buildChips() {
var bar = document.getElementById('chipBar');
var html = '<span class="chip' + (currentView === 'all' ? ' active' : '') + '" data-view="all">全部<span class="chip-count">' + allItems.length + '</span></span>';
for (const section of wikiData) {
if (!section.items) continue;
html += '<span class="chip' + (currentView === section.dir ? ' active' : '') + '" data-view="' + section.dir + '">' + section.icon + ' ' + section.dir + '<span class="chip-count">' + section.items.length + '</span></span>';
}
bar.innerHTML = html;
bar.querySelectorAll('.chip').forEach(function(el) {
el.addEventListener('click', function() { currentView = el.dataset.view; render(); });
});
}
function render() {
buildNav(document.getElementById('sidebar'));
buildNav(document.getElementById('drawerNav'));
buildChips();
var main = document.getElementById('main');
if (currentView === 'all') renderAllView(main); else renderSectionView(main);
}
function renderAllView(main) {
var filtered = searchQuery
? allItems.filter(function(i) { return i.title.toLowerCase().indexOf(searchQuery) !== -1 || i.desc.toLowerCase().indexOf(searchQuery) !== -1 || i.section.toLowerCase().indexOf(searchQuery) !== -1; })
: allItems;
var html = '<div class="breadcrumb"><a href="#" data-breadcrumb="all">Wiki 知识库</a></div>';
html += '<div class="stats-bar">';
html += '<div class="stat-item"><span class="stat-num">' + wikiData.length + '</span><span class="stat-label">分类</span></div>';
html += '<div class="stat-item"><span class="stat-num">' + allItems.length + '</span><span class="stat-label">文档</span></div>';
html += '<div class="stat-item"><span class="stat-num">' + filtered.length + '</span><span class="stat-label">' + (searchQuery ? '搜索结果' : '当前展示') + '</span></div>';
html += '</div>';
var VISIBLE_COUNT = 8;
for (const section of wikiData) {
if (!section.items) continue;
const items = searchQuery ? filtered.filter(function(i){ return i.section === section.dir; }) : section.items;
if (!items.length) continue;
var hasMore = !searchQuery && items.length > VISIBLE_COUNT;
html += '<div class="wiki-section" data-section="' + section.dir + '"><div class="wiki-section-title">' + section.icon + ' ' + section.dir + '</div>';
html += '<div class="wiki-section-desc">' + section.desc + '</div>';
html += '<div class="all-grid">';
for (var i = 0; i < items.length; i++) {
const item = items[i];
var hiddenClass = (hasMore && i >= VISIBLE_COUNT) ? ' card-hidden' : '';
html += '<a class="all-card' + hiddenClass + '" href="' + item.path + '"><div class="card-title">' + item.title + '</div>';
html += '<div class="card-desc">' + item.desc + '</div>';
html += '<div class="card-meta"><span class="card-date">' + item.date + '</span></div></a>';
}
if (hasMore) {
var hiddenCount = items.length - VISIBLE_COUNT;
html += '<div class="section-expand-wrap"><button class="section-expand-btn" data-section="' + section.dir + '"><span class="expand-arrow">&#x25BC;</span> 展开全部(还有 ' + hiddenCount + ' 篇)</button></div>';
}
html += '</div></div>';
}
if (!filtered.length) html += '<div style="text-align:center;padding:48px 0;color:var(--text-tertiary)"><div style="font-size:32px;margin-bottom:8px">&#x1F50D;</div><div>没有找到匹配的文档</div></div>';
main.innerHTML = html;
main.querySelector('[data-breadcrumb="all"]')?.addEventListener('click', function(e) { e.preventDefault(); currentView = 'all'; render(); });
// Expand/collapse for sections with many items
main.querySelectorAll('.section-expand-btn').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.preventDefault();
var sectionEl = this.closest('.wiki-section');
var hiddenCards = sectionEl.querySelectorAll('.card-hidden');
var isExpanded = this.classList.toggle('expanded');
hiddenCards.forEach(function(card) { card.style.display = isExpanded ? '' : 'none'; });
var count = hiddenCards.length;
this.innerHTML = isExpanded
? '<span class="expand-arrow">&#x25B2;</span> 收起'
: '<span class="expand-arrow">&#x25BC;</span> 展开全部(还有 ' + count + ' 篇)';
});
});
}
function renderSectionView(main) {
var section = wikiData.find(function(s){ return s.dir === currentView; });
if (!section || !section.items) return;
var filtered = searchQuery ? section.items.filter(function(i) { return i.title.toLowerCase().indexOf(searchQuery) !== -1 || i.desc.toLowerCase().indexOf(searchQuery) !== -1; }) : section.items;
var html = '<div class="breadcrumb"><a href="#" data-breadcrumb="all">Wiki 知识库</a><span class="sep">/</span><span>' + section.icon + ' ' + section.dir + '</span></div>';
html += '<div class="wiki-section"><div class="wiki-section-title">' + section.icon + ' ' + section.dir + '</div>';
html += '<div class="wiki-section-desc">' + section.desc + '</div></div>';
html += '<div class="wiki-toc"><div class="wiki-toc-header open" onclick="this.classList.toggle(\'open\');this.nextElementSibling.classList.toggle(\'open\')"><span class="toc-icon">&#x25B6;</span><span class="toc-title">文档目录</span><span class="toc-count">' + section.items.length + ' 篇</span></div>';
html += '<div class="wiki-toc-body open">';
for (const item of filtered) { html += '<a class="wiki-toc-item" href="' + item.path + '"><span class="item-icon">&#x1F4C4;</span><span class="item-title">' + item.title + '</span><span class="item-tag">' + item.date + '</span></a>'; }
html += '</div></div>';
if (!filtered.length) html += '<div style="text-align:center;padding:48px 0;color:var(--text-tertiary)"><div style="font-size:32px;margin-bottom:8px">&#x1F50D;</div><div>没有找到匹配的文档</div></div>';
main.innerHTML = html;
main.querySelector('[data-breadcrumb="all"]')?.addEventListener('click', function(e) { e.preventDefault(); currentView = 'all'; render(); });
// Expand/collapse for sections with many items
main.querySelectorAll('.section-expand-btn').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.preventDefault();
var sectionEl = this.closest('.wiki-section');
var hiddenCards = sectionEl.querySelectorAll('.card-hidden');
var isExpanded = this.classList.toggle('expanded');
hiddenCards.forEach(function(card) { card.style.display = isExpanded ? '' : 'none'; });
var count = hiddenCards.length;
this.innerHTML = isExpanded
? '<span class="expand-arrow">&#x25B2;</span> 收起'
: '<span class="expand-arrow">&#x25BC;</span> 展开全部(还有 ' + count + ' 篇)';
});
});
}
document.getElementById('searchInput').addEventListener('input', function() { searchQuery = this.value.toLowerCase().trim(); render(); });
render();
</script>
</body>
</html>