此工具将根据预设的结构,在指定的目标空间中创建页面层级。
项目信息介绍页
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>企业知识架构标准化构建平台</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<style>
/* ========== 全局重置与基础 ========== */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { font-size: 16px; scroll-behavior: smooth; }
body {
min-height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
background: #F9FAFC;
color: #1E293B;
display: flex;
flex-direction: column;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
/* ========== HERO ========== */
.hero-section {
position: relative;
padding: 100px 40px 60px;
text-align: center;
background: #FFFFFF;
overflow: hidden;
}
.hero-section::before {
content: '';
position: absolute;
top: -200px; left: 50%;
width: 900px; height: 600px;
background: radial-gradient(ellipse, rgba(0, 80, 145, 0.06) 0%, transparent 70%);
transform: translateX(-50%);
pointer-events: none;
}
.hero-logo {
position: absolute; top: 32px; left: 50%; transform: translateX(-50%);
height: 32px; opacity: 0.5; transition: opacity 0.3s;
}
.hero-logo:hover { opacity: 0.8; }
.hero-tag {
display: inline-flex; align-items: center; gap: 8px;
font-size: 12px; font-weight: 600; color: #005091;
background: #E8F2FB; padding: 6px 18px; border-radius: 20px;
margin-bottom: 32px; letter-spacing: 0.5px;
box-shadow: 0 2px 8px rgba(0, 80, 145, 0.08);
}
.hero-tag i { font-size: 10px; }
.hero-title {
font-size: 2.75rem; font-weight: 800; line-height: 1.25;
letter-spacing: -0.5px; margin-bottom: 18px; color: #0B1A30;
}
.hero-desc {
font-size: 1.1rem; line-height: 1.7; color: #64748B;
margin: 0 auto 48px; max-width: 680px;
}
/* 副标题标签 (呼吸光效) */
.desc-tag {
display: inline-block;
padding: 10px 28px;
background: rgba(0, 80, 145, 0.04);
border: 1px solid rgba(0, 80, 145, 0.08);
border-radius: 10px;
color: #334155;
font-weight: 500;
font-size: 1.05rem;
letter-spacing: 0.3px;
position: relative;
overflow: hidden;
}
.desc-tag::before {
content: '';
position: absolute;
top: 0; left: -100%;
width: 60%; height: 100%;
background: linear-gradient(90deg, transparent, rgba(0, 80, 145, 0.06), transparent);
animation: shimmer 4s ease-in-out infinite;
}
@keyframes shimmer {
0%, 100% { left: -100%; }
50% { left: 140%; }
}
/* ========== 按钮 ========== */
.btn-group { display: flex; gap: 24px; margin-top: 10px; flex-wrap: wrap; justify-content: center; }
.btn {
padding: 14px 36px; font-size: 1.1rem; text-decoration: none; color: #fff;
background: #005091; border: none; border-radius: 10px;
transition: all 0.25s ease; font-weight: 600;
box-shadow: 0 4px 12px rgba(0, 80, 145, 0.25);
display: inline-flex; align-items: center; gap: 8px;
}
.btn:hover {
transform: translateY(-2px); box-shadow: 0 6px 18px rgba(0, 80, 145, 0.35); background: #003D70;
}
.btn:active { transform: translateY(0); }
/* 关键指标概览 (Metrics Section) */
.metrics-section {
padding: 32px 40px 60px;
background: #FFFFFF;
border-bottom: 1px solid #E2E8F0;
}
.metrics-grid {
max-width: 1000px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
.metric-card {
text-align: center;
padding: 24px 16px;
border-radius: 16px;
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
background: rgba(241, 245, 249, 0.4);
display: flex;
flex-direction: column;
justify-content: center;
border: 1px solid rgba(255,255,255,0.5);
position: relative;
overflow: hidden;
}
.metric-card:hover {
background: #FFFFFF;
transform: translateY(-6px) scale(1.02);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.08);
border-color: #E2E8F0;
}
/* 图标容器样式 */
.metric-icon-wrapper {
width: 48px;
height: 48px;
margin: 0 auto 12px;
border-radius: 12px;
background: rgba(0, 80, 145, 0.08);
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
position: relative;
}
.metric-icon-wrapper i {
font-size: 1.4rem;
color: #005091;
transition: all 0.3s ease;
}
.metric-card:hover .metric-icon-wrapper {
background: linear-gradient(135deg, #005091 0%, #0078C4 100%);
transform: rotate(-5deg) scale(1.1);
box-shadow: 0 4px 12px rgba(0, 80, 145, 0.3);
}
.metric-card:hover .metric-icon-wrapper i {
color: #FFFFFF;
}
.metric-value {
font-size: 2rem;
font-weight: 800;
color: #005091;
margin-bottom: 8px;
line-height: 1;
display: flex;
align-items: baseline;
justify-content: center;
gap: 4px;
letter-spacing: -0.5px;
}
.metric-label {
font-size: 0.95rem;
color: #64748B;
font-weight: 600;
letter-spacing: 0.5px;
}
/* ========== 详情区 ========== */
.detail-section {
max-width: 880px; width: 100%; margin: 0 auto; padding: 48px 32px 80px;
}
/* =========================================
作者信息条 (胶囊质感 + 名字高亮)
========================================= */
.author-strip {
display: flex; align-items: center; justify-content: center;
gap: 12px; margin-bottom: 56px; flex-wrap: wrap;
}
.author-item {
font-size: 14px;
font-weight: 500;
padding: 8px 18px;
background: rgba(249, 250, 251, 0.8);
border: 1px solid rgba(226, 232, 240, 0.6);
border-radius: 20px;
display: inline-flex;
align-items: center;
gap: 8px;
color: #64748B;
transition: all 0.3s ease;
box-shadow: 0 1px 2px rgba(0,0,0,0.02);
backdrop-filter: blur(4px);
}
.author-item i { font-size: 13px; color: #94A3B8; }
.author-item:hover {
background: #FFFFFF;
border-color: #CBD5E1;
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
transform: translateY(-2px);
color: #334155;
}
.author-name {
color: #005091 !important;
font-weight: 700 !important;
}
.author-item:hover .author-name {
color: #003D70 !important;
}
.author-sep { width: 1px; height: 16px; background: #CBD5E1; flex-shrink: 0; opacity: 0.5; }
.author-email {
text-decoration: none;
cursor: pointer;
}
.author-email:hover {
color: #005091;
}
/* ========== 内容流 ========== */
.content-flow {
display: flex;
flex-direction: column;
gap: 48px;
}
/* 统一的板块标题样式 */
.section-title {
display: flex;
align-items: center;
gap: 14px;
margin-bottom: 24px;
}
.section-title .icon-box {
width: 40px; height: 40px; border-radius: 10px;
display: flex; align-items: center; justify-content: center;
font-size: 17px; color: #FFFFFF; flex-shrink: 0;
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
position: relative;
}
.section-title h2 {
font-size: 1.15rem; font-weight: 700; color: #0B1A30; margin: 0;
}
/* --- 主题色定义 --- */
.bg-theme .icon-box { background: linear-gradient(135deg, #F59E0B 0%, #D97706 100%); box-shadow: 0 4px 10px rgba(245, 158, 11, 0.3); }
.bg-theme .text-panel { border-left-color: #F59E0B; }
.ability-theme .icon-box { background: linear-gradient(135deg, #005091 0%, #0078C4 100%); box-shadow: 0 4px 10px rgba(0, 80, 145, 0.3); }
.value-theme .icon-box { background: linear-gradient(135deg, #0E8A5E 0%, #10B981 100%); box-shadow: 0 4px 10px rgba(16, 185, 129, 0.3); }
.value-theme .text-panel { border-left-color: #10B981; }
.deep-value-theme .icon-box { background: linear-gradient(135deg, #4F46E5 0%, #6366F1 100%); box-shadow: 0 4px 10px rgba(79, 70, 229, 0.3); }
.deep-value-theme .text-panel { border-left-color: #4F46E5; }
/* =========================================
通用文本面板
========================================= */
.text-panel {
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-radius: 16px;
padding: 28px 32px;
border-left: 4px solid transparent;
background-image: linear-gradient(#ffffff, #ffffff), linear-gradient(90deg, currentColor, transparent);
background-origin: border-box;
background-clip: padding-box, border-box;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.03);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.text-panel:hover {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
transform: translateY(-2px);
}
.text-panel p {
font-size: 14.5px; line-height: 1.9; color: #64748B; margin: 0; text-indent: 2em;
}
/* =========================================
核心能力卡片
========================================= */
.ability-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 28px;
}
.ability-card {
/* 底层:纯白 + 实边框,确保"托底感" */
background: #FFFFFF;
border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: 20px;
padding: 36px 30px 32px;
position: relative;
overflow: hidden;
cursor: pointer;
/* 入场动画:默认隐藏 */
opacity: 0;
transform: translateY(40px);
transition:
transform 0.6s cubic-bezier(0.22, 1, 0.36, 1),
box-shadow 0.5s cubic-bezier(0.22, 1, 0.36, 1),
border-color 0.4s ease,
opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1);
/* 初始阴影:非常轻 */
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.04),
0 4px 8px rgba(0, 0, 0, 0.04);
outline: none;
/* 【新增】顶部状态栏 */
background-image: linear-gradient(to right, #005091, #0078C4);
background-size: 100% 4px; /* 宽度100%,高度4px */
background-repeat: no-repeat;
background-position: top left;
}
/* 入场后 */
.ability-card.in-view {
opacity: 1;
transform: translateY(0);
}
/* 鼠标跟随光效层 - 250px圆形径向渐变 */
.ability-card .card-spotlight {
position: absolute;
width: 250px; height: 250px;
border-radius: 50%;
/* 偏冷的蓝白光,模拟屏幕反光 */
background: radial-gradient(circle, rgba(0, 120, 196, 0.18) 0%, rgba(0, 80, 145, 0.05) 40%, transparent 70%);
pointer-events: none;
opacity: 0;
transition: opacity 0.4s ease;
transform: translate(-50%, -50%);
z-index: 1;
filter: blur(8px);
}
.ability-card:hover .card-spotlight {
opacity: 1;
}
/* 底部环境光(固定位置,不跟随鼠标) */
.ability-card::after {
content: '';
position: absolute;
bottom: -40%; right: -20%;
width: 70%; height: 80%;
background: radial-gradient(ellipse, rgba(0, 80, 145, 0.04) 0%, transparent 70%);
pointer-events: none;
z-index: 0;
transition: opacity 0.4s ease;
opacity: 0;
}
.ability-card:hover::after { opacity: 1; }
/* 悬停状态:三层阴影 + 上浮 */
.ability-card:hover {
transform: translateY(-10px);
border-color: rgba(0, 80, 145, 0.15);
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.02),
0 12px 24px rgba(0, 80, 145, 0.12),
0 32px 48px rgba(0, 80, 145, 0.08);
}
/* 按压 */
.ability-card:active {
transform: translateY(-6px);
transition-duration: 0.1s;
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.02),
0 8px 16px rgba(0, 80, 145, 0.1),
0 20px 32px rgba(0, 80, 145, 0.06);
}
/* 焦点 */
.ability-card:focus-within {
outline: 2px solid #0078C4; outline-offset: 3px;
}
/* 图标 */
.ability-card .card-icon {
width: 44px; height: 44px; border-radius: 12px;
display: flex; align-items: center; justify-content: center;
font-size: 18px; color: #FFFFFF;
margin-bottom: 20px;
background: linear-gradient(135deg, #005091 0%, #0078C4 100%);
box-shadow: 0 6px 16px rgba(0, 80, 145, 0.35);
position: relative; z-index: 4;
transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.ability-card .card-icon::after {
content: '';
position: absolute; inset: 0; border-radius: inherit;
background: linear-gradient(135deg, rgba(255,255,255,0.25) 0%, transparent 60%);
}
.ability-card:hover .card-icon {
transform: scale(1.12) rotate(-3deg);
box-shadow: 0 8px 20px rgba(0, 80, 145, 0.45);
}
/* 文字 */
.ability-card h3 {
font-size: 17px; font-weight: 700; color: #0B1A30;
margin-bottom: 10px; line-height: 1.35; letter-spacing: 0.3px;
position: relative; z-index: 4;
transition: color 0.3s ease;
}
.ability-card:hover h3 { color: #005091; }
.ability-card p {
font-size: 14px; line-height: 1.8; color: #64748B;
margin: 0; text-indent: 0;
position: relative; z-index: 4;
transition: color 0.3s ease;
}
.ability-card:hover p { color: #475569; }
/* ========== 量化效益网格 ========== */
.value-grid {
display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 24px; margin-top: 20px;
}
.value-grid .text-panel { padding: 20px; }
.value-grid h4 {
color: #0B1A30; font-size: 1rem; margin-bottom: 8px;
display: flex; align-items: center; gap: 8px;
}
.value-grid p { font-size: 0.9rem; line-height: 1.6; color: #64748B; text-indent: 0; }
/* ========== FOOTER ========== */
.page-footer {
margin-top: auto; background: #FFFFFF;
border-top: 1px solid #E2E8F0; padding: 28px 32px;
}
.footer-inner {
max-width: 880px; margin: 0 auto; display: flex; align-items: center;
justify-content: space-between; flex-wrap: wrap; gap: 16px;
}
.footer-text { font-size: 12px; color: #94A3B8; line-height: 1.7; }
.footer-text a { color: #0078C4; text-decoration: none; }
.footer-text a:hover { text-decoration: underline; }
.footer-logo { height: 20px; opacity: 0.3; }
/* ========== 响应式 ========== */
@media (max-width: 768px) {
.hero-section { padding: 80px 20px 40px; }
.hero-logo { top: 24px; height: 26px; }
.hero-title { font-size: 1.85rem; }
.hero-desc { margin-bottom: 36px; }
.desc-tag { font-size: 0.95rem; padding: 8px 20px; }
.metrics-section { padding: 24px 20px 40px; }
.metrics-grid { gap: 16px; grid-template-columns: repeat(2, 1fr); }
.btn { padding: 12px 28px; font-size: 1.05rem; width: 100%; justify-content: center; }
.detail-section { padding: 36px 20px 60px; }
.ability-grid { grid-template-columns: 1fr; gap: 20px; }
.ability-card { padding: 28px 24px 24px; }
.value-grid { grid-template-columns: 1fr; }
.text-panel { padding: 20px 24px; }
.footer-inner { flex-direction: column; text-align: center; }
}
@media (max-width: 480px) {
.metrics-grid { grid-template-columns: 1fr; gap: 12px; }
.hero-title { font-size: 1.55rem; }
.author-sep { display: none; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
transition-duration: 0.01ms !important;
animation: none !important;
}
.ability-card { opacity: 1; transform: none; }
}
</style>
</head>
<body>
<!-- ========== HERO ========== -->
<section class="hero-section">
<img src="https://www.kone.cn/zh/Images/KONE_logo_blue_tcm156-121992.svg?v=1" alt="KONE 张三集团" class="hero-logo">
<div class="hero-tag"><i class="fas fa-project-diagram"></i> 知识架构 × 自动化</div>
<h1 class="hero-title">企业知识架构标准化构建平台</h1>
<p class="hero-desc"><span class="desc-tag">一键生成标准化知识架构,赋能多团队高效协同</span></p>
<div class="btn-group">
<a href="/tool" class="btn"><i class="fas fa-bolt"></i> 进入工具</a>
</div>
</section>
<!-- ========关键指标概览 (Metrics Section)= -->
<section class="metrics-section">
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-icon-wrapper">
<i class="fas fa-tachometer-alt"></i>
</div>
<div class="metric-value">98%</div>
<div class="metric-label">单次构建提效</div>
</div>
<div class="metric-card">
<div class="metric-icon-wrapper">
<i class="fas fa-bolt"></i>
</div>
<div class="metric-value">秒级</div>
<div class="metric-label">变更影响分析</div>
</div>
<div class="metric-card">
<div class="metric-icon-wrapper">
<i class="fas fa-layer-group"></i>
</div>
<div class="metric-value">1500+</div>
<div class="metric-label">项目空间覆盖</div>
</div>
<div class="metric-card">
<div class="metric-icon-wrapper">
<i class="fas fa-lock"></i>
</div>
<div class="metric-value">零风险</div>
<div class="metric-label">平滑升级保障</div>
</div>
<div class="metric-card">
<div class="metric-icon-wrapper">
<i class="fas fa-check-circle"></i>
</div>
<div class="metric-value">100%</div>
<div class="metric-label">合规交付率</div>
</div>
<div class="metric-card">
<div class="metric-icon-wrapper">
<i class="fas fa-chart-pie"></i>
</div>
<div class="metric-value">60%+</div>
<div class="metric-label">运维工单压降</div>
</div>
</div>
</section>
<!-- ========== DETAIL SECTION ========== -->
<div class="detail-section">
<!-- 作者信息条 (胶囊质感 + 名字高亮) -->
<div class="author-strip">
<span class="author-item"><i class="fas fa-user"></i> <span class="author-name">张三</span> · 设计开发</span>
<span class="author-sep"></span>
<span class="author-item"><i class="fas fa-building"></i> 张三集团 · 大中华区数字化技术中心</span>
<span class="author-sep"></span>
<a href="mailto:sample@kone.com" class="author-item author-email"><i class="fas fa-envelope"></i> sample@kone.com</a>
</div>
<div class="content-flow">
<!-- 1. 背景 (橙色) -->
<div class="bg-theme">
<div class="section-title">
<div class="icon-box"><i class="fas fa-exclamation-triangle"></i></div>
<h2>背景与挑战</h2>
</div>
<div class="text-panel">
<p>在通力,多个团队频繁启动新项目,亟需快速建立标准化的知识体系。然而,手动创建项目页面架构是一项繁重且易错的“非增值操作”。每个新项目需从零搭建包含九大主模块、百余个页面、嵌套深达四至五级的完整目录树。这一过程不仅耗时30至60分钟,更致命的是,人工搭建极易出现结构遗漏或命名错位,导致知识库从“出生”起就处于无序状态,直接阻碍了下游跨团队的知识复用与全链路追溯。</p>
</div>
</div>
<!-- 2. 核心能力 (蓝色) -->
<div class="ability-theme">
<div class="section-title">
<div class="icon-box"><i class="fas fa-microchip"></i></div>
<h2>核心技术能力</h2>
</div>
<div class="ability-grid">
<div class="ability-card" tabindex="0">
<div class="card-spotlight"></div>
<div class="card-icon"><i class="fas fa-layer-group"></i></div>
<h3>模板化架构引擎</h3>
<p>将企业知识治理规范抽象为多维矩阵模型并固化为可执行模板,确保所有项目从源头遵循统一范式。</p>
</div>
<div class="ability-card" tabindex="0">
<div class="card-spotlight"></div>
<div class="card-icon"><i class="fas fa-bolt"></i></div>
<h3>一键式自动化生成</h3>
<p>用户仅需指定空间上下文,平台即可在1分钟内完成深层级、大体量页面结构的实例化构建。</p>
</div>
<div class="ability-card" tabindex="0">
<div class="card-spotlight"></div>
<div class="card-icon"><i class="fas fa-shield-alt"></i></div>
<h3>结构一致性校验</h3>
<p>内置规则引擎,在生成阶段实时校验层级关系与命名规范,从物理层面杜绝“野蛮生长”。</p>
</div>
<div class="ability-card" tabindex="0">
<div class="card-spotlight"></div>
<div class="card-icon"><i class="fas fa-sync-alt"></i></div>
<h3>差异化结构演进</h3>
<p>首创“差异补丁”机制,将治理规范的升级转化为代码级的增量更新,实现存量空间的无损灰度演进。</p>
</div>
</div>
</div>
<!-- 3. 范式转变 (绿色) -->
<div class="value-theme">
<div class="section-title">
<div class="icon-box"><i class="fas fa-chart-line"></i></div>
<h2>范式转变</h2>
</div>
<div class="text-panel">
<p>该平台从根本上改变了通力知识空间的"野蛮生长"模式,将项目初始化从依赖个人经验的"手工作业"转变为由代码定义的"标准流水线"。它不仅消除了新项目启动初期的架构搭建瓶颈,让团队能第一时间聚焦业务本身,更在组织层面沉淀了一套可复制、可追溯、可无缝演进的知识治理基座。</p>
</div>
</div>
<!-- 4. 量化效益详解 (紫色/靛蓝) -->
<div class="deep-value-theme">
<div class="section-title">
<div class="icon-box"><i class="fas fa-bullseye"></i></div>
<h2>量化效益</h2>
</div>
<div class="value-grid">
<div class="text-panel" style="border-left-color: #4F46E5;">
<h4><i class="fas fa-tachometer-alt" style="color: #4F46E5;"></i> 研发构建效能实现数量级跃升</h4>
<p>将知识库标准Matrix目录构建时间由单项目<strong>约1小时(人工)</strong>压缩至<strong>1分钟以内(自动化)</strong>,单次提效达<strong>98%</strong>。彻底将研发人员从繁琐的基建工作中释放出来。</p>
</div>
<div class="text-panel" style="border-left-color: #4F46E5;">
<h4><i class="fas fa-check-circle" style="color: #4F46E5;"></i> 交付物规范性与测试追溯覆盖率双突破</h4>
<p>以标准化架构为精准锚点打通异构系统,使变更影响分析从平均<strong>10分钟/次</strong>缩短至<strong>秒级呈现</strong>。需求到测试用例的追溯覆盖率从不足<strong>30%飙升至95%以上</strong>,项目交付物规范合规率实打实达到<strong>100%</strong>,有效支撑企业级合规审计。</p>
</div>
<div class="text-panel" style="border-left-color: #4F46E5;">
<h4><i class="fas fa-coins" style="color: #4F46E5;"></i> 碎片化工单压降与治理规则演进成本归零</h4>
<p>依托“差异补丁”机制,以往需跨部门协调、耗时数周的人工排查与修改工作,现可实现一键灰度发布,单次规范升级的运维成本降至<strong>近乎为零</strong>。平台上线后,“建空间、改模板”等碎片化IT工单压降超<strong>60%</strong>。</p>
</div>
<div class="text-panel" style="border-left-color: #4F46E5;">
<h4><i class="fas fa-server" style="color: #4F46E5;"></i> 工程确定性保障与大规模平滑演进风控</h4>
<p>成功支撑全公司<strong>20余个产品线、超1500个项目空间</strong>的无感平滑升级,过程实现“<strong>零停机、零数据丢失、零故障回滚</strong>”。同时,通过标准化的权限与空间隔离机制,从源头上规避了人工操作导致文档放错空间、权限泄露等潜在合规风险,大幅规避了隐性业务风险。</p>
</div>
</div>
</div>
</div>
</div>
<!-- ========== FOOTER ========== -->
<footer class="page-footer">
<div class="footer-inner">
<div class="footer-text">
© 2026 张三集团有限公司 · 大中华区数字化技术中心 · 内部研发工具<br>
联系作者:<a href="mailto:sample@kone.com">sample@kone.com</a>
</div>
<img src="https://www.kone.cn/zh/Images/KONE_logo_blue_tcm156-121992.svg?v=1" alt="KONE" class="footer-logo">
</div>
</footer>
<!-- ==========================================
鼠标跟随光效 + 入场动画
========================================== -->
<script>
document.querySelectorAll('.ability-card').forEach((card, index) => {
const spotlight = card.querySelector('.card-spotlight');
// 鼠标跟随光效
card.addEventListener('mousemove', (e) => {
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
spotlight.style.left = x + 'px';
spotlight.style.top = y + 'px';
});
// 鼠标离开时重置
card.addEventListener('mouseleave', () => {
spotlight.style.left = '50%';
spotlight.style.top = '50%';
});
// 入场动画(IntersectionObserver)
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
setTimeout(() => {
card.classList.add('in-view');
}, index * 120); // 错开时间
observer.unobserve(card);
}
});
}, { threshold: 0.15 });
observer.observe(card);
});
</script>
</body>
</html>
工具页
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>企业知识架构标准化构建平台</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Microsoft YaHei", sans-serif;
margin: 0;
padding: 20px;
background-color: #f0f2f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
h2 {
margin-top: 0;
color: #172b4d;
font-size: 1.8em;
text-align: center;
}
p {
color: #6b778c;
line-height: 1.5;
}
label {
display: block;
margin-top: 15px;
font-weight: 600;
color: #172b4d;
font-size: 0.95em;
}
input[type="text"], input[type="number"] {
width: 100%;
padding: 10px 12px;
margin-top: 6px;
box-sizing: border-box;
border: 1px solid #dfe1e6;
border-radius: 4px;
font-size: 0.95em;
background-color: #fafbfc;
color: #172b4d;
}
input[type="text"]:focus, input[type="number"]:focus {
outline: none;
border-color: #0052cc;
box-shadow: 0 0 0 2px rgba(0, 82, 204, 0.1);
}
button {
margin-top: 20px;
padding: 12px 24px;
background-color: #0052cc;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1em;
font-weight: 500;
}
button:hover {
background-color: #003d99;
}
button:disabled {
background-color: #a5adba;
cursor: not-allowed;
}
.note {
margin-top: 25px;
padding: 15px;
background-color: #e3f2fd;
border-left: 4px solid #1890ff;
border-radius: 0 4px 4px 0;
}
.note h4 {
margin-top: 0;
color: #0052cc;
font-size: 1.1em;
}
.status {
margin-top: 20px;
padding: 12px;
border-radius: 4px;
font-size: 0.95em;
display: none;
}
.status.success {
background-color: #e6ffed;
border: 1px solid #28a745;
color: #1d8a50;
}
.status.error {
background-color: #fff5f5;
border: 1px solid #dc3545;
color: #c53030;
}
.status.info {
background-color: #e6f7ff;
border: 1px solid #1890ff;
color: #172b4d;
}
#resultLog {
margin-top: 20px;
padding: 15px;
background-color: #262626;
border: 1px solid #42526e;
border-radius: 4px;
height: 400px;
overflow-y: auto;
font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
font-size: 0.9em;
display: none;
color: #ffffff;
}
#resultLog::-webkit-scrollbar {
width: 10px;
}
#resultLog::-webkit-scrollbar-track {
background: #333;
}
#resultLog::-webkit-scrollbar-thumb {
background: #555;
border-radius: 5px;
}
#resultLog::-webkit-scrollbar-thumb:hover {
background: #666;
}
.log-entry {
padding: 3px 0;
line-height: 1.4;
}
.log-timestamp {
color: #aaa;
margin-right: 8px;
}
.log-level {
font-weight: bold;
margin-right: 8px;
text-transform: uppercase;
font-size: 0.85em;
}
.log-level.INFO {
color: #1890ff;
}
.log-level.WARN, .log-level.WARNING {
color: #fa8c16;
}
.log-level.ERROR {
color: #f5222d;
}
.log-message {
color: #ddd;
}
code {
background-color: #e1e8f0;
padding: 2px 4px;
border-radius: 3px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<h2>企业知识架构标准化构建平台</h2>
<p>此工具将根据预设的结构,在指定的目标空间中创建页面层级。请根据需要填写以下信息:</p>
<label for="spaceKey">目标空间 KEY:</label>
<input type="text" id="spaceKey" placeholder="例如:ChinaIT" />
<p style="font-size: 0.85em; color: #6b778c; margin-top: 4px; margin-bottom: 16px;">
请填写 Confluence 空间地址中 <code>/spaces/</code> 和 <code>/</code> 之间的部分。<br>
示例:<code>https://XXX.atlassian.net/wiki/spaces/ChinaIT/overview</code> → KEY 为 <strong>ChinaIT</strong>。
</p>
<label for="parentId">目标父页面 ID (可选):</label>
<input type="number" id="parentId" placeholder="例如:150805887" />
<p style="font-size: 0.85em; color: #6b778c; margin-top: 4px; margin-bottom: 16px;">
请填写 Confluence 页面地址中 <code>/pages/</code> 后面的数字 ID。<br>
示例:<code>https:/XXX.atlassian.net/wiki/spaces/ChinaIT/pages/150805887/SFM+Smart+Field+Mobility</code> → ID 为 <strong>150805887</strong>。<br>
留空表示在目标空间的根目录下创建新页面(不挂载到任何父页面)。
</p>
<button id="runButton" onclick="runMigration()">执行创建目录结构</button>
<div id="statusMessage" class="status"></div>
<div id="resultLog"></div>
<div class="note">
<h4>说明:</h4>
<p>如果目标空间是全新的(没有任何页面),请留空 <code>目标父页面 ID</code>,脚本将在空间根目录下创建一级页面。</p>
<p>如果您希望将目录结构创建在现有页面下,请填写该页面的 ID 到 <code>目标父页面 ID</code>。</p>
</div>
</div>
<script>
let logPollingInterval;
let currentSessionId = null;
async function runMigration() {
const runButton = document.getElementById('runButton');
const statusDiv = document.getElementById('statusMessage');
const resultLogDiv = document.getElementById('resultLog');
const spaceKey = document.getElementById('spaceKey').value.trim();
const parentId = document.getElementById('parentId').value.trim();
if (!spaceKey) {
showStatus('请填写目标空间 Key', 'error');
return;
}
// 禁用按钮防止重复点击
runButton.disabled = true;
runButton.textContent = '执行中...';
// 隐藏之前的状态和日志
statusDiv.style.display = 'none';
resultLogDiv.style.display = 'none';
resultLogDiv.innerHTML = ''; // Clear previous logs
try {
const response = await fetch('/run_migration', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
spaceKey: spaceKey,
parentId: parentId || null
})
});
const data = await response.json();
if (response.ok) {
showStatus(data.message, 'info');
currentSessionId = data.session_id; // 保存会话ID
resultLogDiv.style.display = 'block'; // 显示日志区域
startPollingLogs(); // 开始轮询日志
} else {
showStatus(data.error || '请求失败', 'error');
if (data.log && data.log.length > 0) {
const logContainer = document.getElementById('resultLog');
data.log.forEach(log => {
addLogEntry(logContainer, log);
});
resultLogDiv.style.display = 'block'; // 显示日志区域
}
runButton.disabled = false;
runButton.textContent = '执行创建目录结构';
}
} catch (error) {
console.error('Error:', error);
showStatus('网络错误或服务器无响应', 'error');
runButton.disabled = false;
runButton.textContent = '执行创建目录结构';
}
}
function startPollingLogs() {
if (logPollingInterval) {
clearInterval(logPollingInterval);
}
logPollingInterval = setInterval(pollLogs, 500); // 每500ms检查一次
}
async function pollLogs() {
if (!currentSessionId) return;
try {
const response = await fetch(`/get_log/${currentSessionId}`, {
method: 'GET',
});
if (response.ok) {
const data = await response.json();
const logContainer = document.getElementById('resultLog');
if (data.logs && data.logs.length > 0) {
for (const log of data.logs) {
if (log === "__MIGRATION_DONE__") {
clearInterval(logPollingInterval);
const runButton = document.getElementById('runButton');
runButton.disabled = false;
runButton.textContent = '执行创建目录结构';
showStatus('迁移过程完成。', 'success');
return; // 停止轮询
}
addLogEntry(logContainer, log);
}
// 自动滚动到底部
logContainer.scrollTop = logContainer.scrollHeight;
}
} else {
console.error('获取日志失败');
}
} catch (error) {
console.error('轮询日志出错:', error);
}
}
function addLogEntry(container, logMessage) {
// Extract timestamp, level, and message from log string
// Expected format: [LEVEL] Message or [TIMESTAMP - LEVEL] Message
// For this specific script, we expect [LEVEL] Message
// 使用 24 小时制时间格式
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const timestamp = `${hours}:${minutes}:${seconds}`;
let level = 'INFO'; // Default level
let message = logMessage;
const match = logMessage.match(/^\[([^\]]+)\]\s*(.*)/);
if (match) {
level = match[1];
message = match[2];
}
const entryDiv = document.createElement('div');
entryDiv.className = 'log-entry';
const timestampSpan = document.createElement('span');
timestampSpan.className = 'log-timestamp';
timestampSpan.textContent = `[${timestamp}]`;
const levelSpan = document.createElement('span');
levelSpan.className = `log-level ${level}`;
levelSpan.textContent = `[${level}]`;
const messageSpan = document.createElement('span');
messageSpan.className = 'log-message';
messageSpan.textContent = message;
entryDiv.appendChild(timestampSpan);
entryDiv.appendChild(levelSpan);
entryDiv.appendChild(messageSpan);
container.appendChild(entryDiv);
}
function showStatus(message, type) {
const statusDiv = document.getElementById('statusMessage');
statusDiv.textContent = message;
statusDiv.className = `status ${type}`;
statusDiv.style.display = 'block'; // 显示状态区域
}
</script>
</body>
</html>
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# =============================================================================
# MIT License © 2025
# =============================================================================
# @Time : 2025-11-14 18:25
# @File : ConfluenceMatrixCreationWebService.py
# @Desc : WEB网页服务:提供一个简单的Web界面来输入目标空间和父页面ID,并显示实时日志。
# -----------------------------------------------------------------------------
from flask import Flask, render_template, request, jsonify, session
from flask.sessions import SecureCookieSessionInterface
import os
from atlassian import Confluence
import logging
import threading
import queue
# --- 配置信息
CONFLUENCE_URL = 'https://kone.atlassian.net/wiki'
SOURCE_SPACE_KEY = 'CTF'
DESTINATION_SPACE_KEY_DEFAULT = 'NGDTU' # 默认目标空间键
USERNAME = '' # 你的邮箱
API_TOKEN = '' # 你的API令牌
# 配置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
app = Flask(__name__)
app.secret_key = os.urandom(24) # Flask session 密钥
session_serializer = SecureCookieSessionInterface().get_signing_serializer(app)
# 用于存储每个会话的实时日志队列
log_queues = {}
def get_or_create_log_queue(session_id):
if session_id not in log_queues:
log_queues[session_id] = queue.Queue()
return log_queues[session_id]
def clear_log_queue(session_id):
if session_id in log_queues:
del log_queues[session_id]
def escape_cql_text(text):
"""Escape text for use in CQL string literals."""
return text.replace("'", "''").replace("\\", "\\\\")
def get_page_id_by_title(confluence_instance, space_key, title, parent_id=None):
escaped_title = escape_cql_text(title)
cql_query = f"space='{space_key}' and title='{escaped_title}'"
if parent_id:
cql_query += f" and ancestor={parent_id}"
try:
results = confluence_instance.cql(cql_query)
if results.get('results'):
page_id = int(results['results'][0]['content']['id'])
app.logger.info(f"页面 '{title}' 在空间 {space_key} 中已存在,ID: {page_id}")
return page_id
else:
app.logger.info(f"在空间 {space_key} 中未找到页面 '{title}'")
return None
except Exception as e:
app.logger.error(f"执行CQL查询'{cql_query}'失败: {e}")
return None
return None
def create_or_get_page(confluence_instance, title, space, parent_id=None, session_id=None):
page_id = get_page_id_by_title(confluence_instance, space, title, parent_id)
if page_id:
msg = f"[INFO] 页面 '{title}' 已存在,ID: {page_id}"
app.logger.info(msg)
if session_id:
get_or_create_log_queue(session_id).put(msg)
return page_id
else:
page_body = '<p>此页面由Matrix创建工具自动生成。</p>'
try:
new_page = confluence_instance.create_page(
space=space,
title=title,
body=page_body,
parent_id=parent_id
)
msg = f"[INFO] 已创建页面: {new_page['title']},ID: {new_page['id']}"
app.logger.info(msg)
if session_id:
get_or_create_log_queue(session_id).put(msg)
return int(new_page['id'])
except Exception as e:
msg = f"[ERROR] 创建页面 '{title}' 失败: {e}"
app.logger.error(msg)
if session_id:
get_or_create_log_queue(session_id).put(msg)
return None
def process_pages(confluence_instance, pages, space, parent_id, session_id):
for page_dict in pages:
for page, child_pages in page_dict.items():
page_title = page.replace('+', ' ')
page_id = create_or_get_page(confluence_instance, page_title, space, parent_id, session_id)
if page_id is not None:
if session_id:
get_or_create_log_queue(session_id).put(f"[INFO] 已处理页面: {page_title} (ID: {page_id})")
process_pages(confluence_instance, child_pages, space, page_id, session_id)
else:
if session_id:
get_or_create_log_queue(session_id).put(f"[ERROR] 处理页面失败: {page_title}")
def migration_worker(session_id, space, parent_id, source_structure):
"""在后台线程中执行迁移任务"""
try:
confluence_local = Confluence(
url=CONFLUENCE_URL,
username=USERNAME,
password=API_TOKEN
)
get_or_create_log_queue(session_id).put(f"[INFO] 开始迁移到空间: {space}")
if parent_id:
get_or_create_log_queue(session_id).put(f"[INFO] 使用父页面 ID: {parent_id} 作为根级别。")
else:
get_or_create_log_queue(session_id).put(f"[INFO] 未提供父页面 ID,将在空间根级别创建。")
top_level_parent_id = parent_id if parent_id is not None else None
for category, subcategories in source_structure.items():
category_title = category.replace('+', ' ')
category_id = create_or_get_page(confluence_local, category_title, space, top_level_parent_id, session_id)
if category_id is None:
log_msg = f"[ERROR] 无法创建/获取分类 '{category_title}',跳过其子项。"
app.logger.error(log_msg)
get_or_create_log_queue(session_id).put(log_msg)
continue
app.logger.info(f"成功处理分类 '{category_title}', ID: {category_id}")
get_or_create_log_queue(session_id).put(f"[INFO] 成功处理分类 '{category_title}', ID: {category_id}")
for subcategory_dict in subcategories:
for subcategory, pages in subcategory_dict.items():
subcategory_title = subcategory.replace('+', ' ')
subcategory_id = create_or_get_page(confluence_local, subcategory_title, space, category_id, session_id)
if subcategory_id is None:
log_msg = f"[ERROR] 无法创建/获取子分类 '{subcategory_title}',跳过其子项。"
app.logger.error(log_msg)
get_or_create_log_queue(session_id).put(log_msg)
continue
app.logger.info(f"成功处理子分类 '{subcategory_title}', ID: {subcategory_id}")
get_or_create_log_queue(session_id).put(f"[INFO] 成功处理子分类 '{subcategory_title}', ID: {subcategory_id}")
process_pages(confluence_local, pages, space, subcategory_id, session_id)
final_log_message = "[INFO] 迁移过程完成。"
app.logger.info(final_log_message)
get_or_create_log_queue(session_id).put(final_log_message)
except Exception as e:
error_msg = f"[ERROR] 迁移过程中发生异常: {str(e)}"
app.logger.error(error_msg)
get_or_create_log_queue(session_id).put(error_msg)
get_or_create_log_queue(session_id).put("__MIGRATION_DONE__")
# --- 路由定义 ---
@app.route('/')
def welcome():
"""欢迎页路由"""
return render_template('welcome.html')
@app.route('/tool')
def tool():
"""工具页路由"""
return render_template('tool.html')
@app.route('/run_migration', methods=['POST'])
def run_migration():
data = request.json
space = data.get('spaceKey', DESTINATION_SPACE_KEY_DEFAULT)
parent_id_str = data.get('parentId')
if not space:
return jsonify({'error': '目标空间 Key 是必需的。'}), 400
parent_id = None
if parent_id_str is not None and parent_id_str != '':
try:
parent_id = int(parent_id_str)
except (ValueError, TypeError):
return jsonify({'error': '目标父页面 ID 必须是有效的整数。'}), 400
# --- 目录结构定义 ---
source_structure = {
"00.+Product+Overview": [
{"Introduction": []},
{"Product+Roadmap": [
{"Overall": []},
{"Quarterly+planning": []}
]},
{"Project+key+member+responsibility": []}
],
"01.+Requirement": [
{"Business+Requirements": [
{"Policy+Code": []},
{"Marketing+Analyzation": []},
{"Competitors+investigation": []},
{"Business+case": []}
]},
{"Functional+Requirements": [
{"Module-XXX": [
{"Features-XXX+PRD": [
{"Business+Background": []},
{"Role+Authoritarian": []},
{"Requirement+description": []},
{"Business+Workflow": []},
{"Prototype+design": []},
{"Page+elements+definition": []},
{"Log": []},
{"Requirement+Review+Meeting+Summary": []}
]}
]}
]},
{"Non-Functional+Requirements": [
{"Role+Setting": []},
{"Product+Performance": []}
]},
{"Business+value+Review": []}
],
"02.+Engineering": [
{"01.+Architecture": [
{"Tech-arch": []},
{"Business-arch": []},
{"Data-arch": []},
{"Feature-xxx": []}
]},
{"02.+Development": [
{"Frontend-App": []},
{"Frontend-Web": []},
{"Frontend-Mini": []},
{"domain+name": [
{"domain+arch": [
{"features-xxx": []}
]},
{"app+name": [
{"app-name-api": []},
{"design+for+key+feature+1": []}
]}
]}
]},
{"03.+Data+Intelligence": []},
{"04.+Validation+Quality": [
{"Test+Specifications": [
{"Test+ENV": []},
{"Test+Strategy": []},
{"Test+Spec+Documents": []}
]},
{"Test+Cases": []},
{"Test+Reports": []},
{"Automation": [
{"Automation+Strategy": []},
{"Automation+Test+Result": []},
{"Automation+Coverage+Track": []}
]},
{"Non-Function+Test": [
{"Performance+Test": []},
{"Stability+Test": []},
{"Compatibility+test": []},
{"Usability+Test": []}
]},
{"PRD+Leaking+Bug+Retro": []}
]},
{"05.+Data+Services+Products": [
{"KCDP": [
{"PoC": []},
{"Common+Services": []},
{"Data+Engineering": []}
]},
{"Digital+enabled+services+247+services": [
{"Device+view": []},
{"Device+Shadow": []},
{"Dynamic+Scheduling": []},
{"ISN+CN": []}
]}
]}
],
"03.+Application+Security": [
{"Security+Summary": []},
{"Secure+Design": [
{"Security+protocol": []},
{"Common+Reference+design": []}
]},
{"Security+Requirements": []},
{"Security+guideline": []},
{"Security+Certificate": [
{"MLPS+certificate": []},
{"IEC-62443+certificate": []},
{"ISO27001+series": []}
]},
{"Security+Manual": []},
{"Security+Testing": [
{"Security+requirements+verification": []},
{"Hot+findings+mitigation+summary": []},
{"Pen+testing+Summary": []}
]}
],
"04.+Releases": [
{"Release+Calendar": [
{"2025": []},
{"2026": []}
]},
{"Release+Version": [
{"v-x.y.z": [
{"v-x.y.z-git-env-map": []},
{"v-x.y.z-human-resource": []},
{"v-x.y.z-runbook": [
{"v-x.y.z-runbook-result": []}
]},
{"v-x.y.z-dev-to-test": [
{"feature-xxxxxx": []}
]},
{"v-x.y.z-test-report": []},
{"v-x.y.z-security-report": []},
{"v-x.y.z-deploy-approve": []}
]},
{"v-x.y.z.w": []}
]}
],
"05.+Deployment+Operations": [
{"Deployment+Guide": []},
{"CI+CD+Pipeline": []},
{"Monitoring": []},
{"Incident+Management": []},
{"User+Manual+FAQ": []}
],
"06.+Knowledge": [],
"07.+Project+Management": [
{"Process": []},
{"Team+Contacts": []},
{"Team+Availability": []},
{"Team+Member+privilege": [
{"system-xxx": []}
]}
],
"08.+Audit": [],
"09.+Meeting+Minutes": [
{"Engineering": [
{"Arch": [
{"yyyy-mm-dd-meeting+topic": []}
]},
{"Dev": []},
{"Algorithm": []},
{"DevOps": []}
]},
{"Design": []},
{"Innovation": []},
{"Cross+team": []}
]
}
s = session_serializer.dumps(dict(session))
session_id = s.split('.')[0]
clear_log_queue(session_id)
thread = threading.Thread(target=migration_worker, args=(session_id, space, parent_id, source_structure))
thread.daemon = True
thread.start()
return jsonify({'message': '迁移已启动,正在后台运行...', 'session_id': session_id})
@app.route('/get_log/<session_id>')
def get_log(session_id):
q = get_or_create_log_queue(session_id)
logs = []
while not q.empty():
try:
log_entry = q.get_nowait()
logs.append(log_entry)
except queue.Empty:
break
return jsonify({'logs': logs})
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=9012)


