689 lines
39 KiB
HTML
689 lines
39 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>业务全景与状态机 - RailwaySystem SYFJGYD学员管理系统</title>
|
||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%231d4ed8' d='M12 2c-4 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h2.23l2-2H14l2 2h2v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-3.58-4-8-4z'/></svg>">
|
||
<link rel="stylesheet" href="assets/docs.css">
|
||
<style>
|
||
/* 业务流图专属容器与样式 */
|
||
.flow-diagram-card {
|
||
background: #ffffff;
|
||
border: 1px solid var(--border-light);
|
||
border-radius: var(--radius-lg);
|
||
padding: 2rem;
|
||
box-shadow: var(--shadow-card);
|
||
margin-bottom: 2.5rem;
|
||
}
|
||
.flow-canvas-wrap {
|
||
width: 100%;
|
||
overflow-x: auto;
|
||
padding: 1rem 0;
|
||
}
|
||
.flow-svg {
|
||
min-width: 980px;
|
||
width: 100%;
|
||
height: auto;
|
||
display: block;
|
||
}
|
||
|
||
/* 节点可点击交互效果 */
|
||
.flow-node {
|
||
cursor: pointer;
|
||
transition: transform 0.15s ease, filter 0.15s ease;
|
||
}
|
||
.flow-node:hover {
|
||
filter: drop-shadow(0 4px 8px rgba(30, 64, 175, 0.18));
|
||
}
|
||
.flow-node:hover rect {
|
||
stroke: var(--rail-blue);
|
||
stroke-width: 2px;
|
||
}
|
||
.flow-node text {
|
||
pointer-events: none;
|
||
user-select: none;
|
||
}
|
||
|
||
/* 节点卡片速览网格 */
|
||
.flow-step-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||
gap: 1.25rem;
|
||
margin-top: 1.5rem;
|
||
}
|
||
.step-clickable-card {
|
||
background: #ffffff;
|
||
border: 1px solid var(--border-light);
|
||
border-radius: var(--radius-md);
|
||
padding: 1.25rem;
|
||
cursor: pointer;
|
||
box-shadow: var(--shadow-card);
|
||
transition: all 0.2s ease;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.step-clickable-card:hover {
|
||
border-color: var(--rail-blue-border);
|
||
transform: translateY(-2px);
|
||
box-shadow: var(--shadow-card-hover);
|
||
}
|
||
.step-clickable-card.side-branch {
|
||
border-left: 4px solid #0284c7;
|
||
background: #fcfdfe;
|
||
}
|
||
.step-clickable-card.support-layer {
|
||
border-left: 4px solid #6366f1;
|
||
background: #fbfbfe;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- 顶部主导航 -->
|
||
<nav class="navbar">
|
||
<div class="nav-brand-wrap">
|
||
<a href="index.html" class="nav-brand">
|
||
<svg viewBox="0 0 24 24"><path d="M12 2c-4 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h2.23l2-2H14l2 2h2v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-3.58-4-8-4zM7.5 17c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm9 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm1.5-6H6V6h12v5z"/></svg>
|
||
<div>
|
||
<div class="brand-title">RailwaySystem</div>
|
||
<div class="brand-sub">SYFJGYD学员管理系统</div>
|
||
</div>
|
||
</a>
|
||
<span class="brand-pill">Final Candidate · 待正式部署</span>
|
||
</div>
|
||
|
||
<ul class="nav-menu">
|
||
<li><a href="index.html" class="nav-link">首页</a></li>
|
||
<li><a href="business-flow.html" class="nav-link active">业务</a></li>
|
||
<li><a href="architecture.html" class="nav-link">系统</a></li>
|
||
<li><a href="testing.html" class="nav-link">质量</a></li>
|
||
<li><a href="release-status.html" class="nav-link">发布</a></li>
|
||
<li><a href="modules.html" class="nav-link">14大业务模块清单</a></li>
|
||
<li><a href="data-model.html" class="nav-link">实体关系模型(ER)</a></li>
|
||
<li><a href="deployment.html" class="nav-link">部署拓扑与脚本Delta</a></li>
|
||
<li><a href="http://192.168.139.218:9980/sict/railwaysystem/-/blob/feat/cicd-pipeline/docs/handbook/08-deployment-and-release.md" target="_blank" rel="noopener noreferrer" class="nav-handbook-link">> 查阅部署发布手册</a></li>
|
||
<li><a href="http://192.168.139.218:9980/sict/railwaysystem/-/blob/feat/cicd-pipeline/docs/README.md" target="_blank" rel="noopener noreferrer" class="nav-back-link">← 文档中心</a></li>
|
||
</ul>
|
||
</nav>
|
||
|
||
<!-- 页面主体容器 -->
|
||
<main class="page-container">
|
||
|
||
<header class="page-hero">
|
||
<div class="hero-pretitle">Business Process Architecture</div>
|
||
<h1 class="hero-title-main">业务全景流程与状态机</h1>
|
||
<p class="hero-lead-text">
|
||
主视觉聚焦于基础资源编排至结训考核的线性主脉络,解耦呈现后勤住宿支线与电子班牌硬件支撑层。点击任意节点可展开查看其状态机、业务约束与技术契约。
|
||
</p>
|
||
</header>
|
||
|
||
<!-- 流程图视觉卡片 -->
|
||
<section class="flow-diagram-card">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; flex-wrap: wrap; gap: 0.75rem;">
|
||
<div>
|
||
<h2 style="font-size: 1.25rem; font-weight: 700; color: var(--navy-900);">全业务生命周期协同拓扑</h2>
|
||
<p style="font-size: 0.82rem; color: var(--text-muted); margin-top: 0.2rem;">点击拓扑节点查看抽屉详情,支持键盘 ESC 快速退出</p>
|
||
</div>
|
||
<div style="display: flex; gap: 0.85rem; align-items: center; font-size: 0.8rem;">
|
||
<span style="display: inline-flex; align-items: center; gap: 4px;"><span style="width: 12px; height: 12px; background: #eff6ff; border: 1px solid #1d4ed8; border-radius: 2px;"></span> 主干链路</span>
|
||
<span style="display: inline-flex; align-items: center; gap: 4px;"><span style="width: 12px; height: 12px; background: #f0f9ff; border: 1px solid #0284c7; border-radius: 2px;"></span> 住宿支线</span>
|
||
<span style="display: inline-flex; align-items: center; gap: 4px;"><span style="width: 12px; height: 12px; background: #eef2ff; border: 1px solid #6366f1; border-radius: 2px;"></span> 班牌支撑</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flow-canvas-wrap">
|
||
<svg class="flow-svg" viewBox="0 0 1120 420" xmlns="http://www.w3.org/2000/svg">
|
||
<defs>
|
||
<marker id="arrow-blue" markerWidth="8" markerHeight="8" refX="6" refY="4" orient="auto">
|
||
<path d="M0,1 L7,4 L0,7 Z" fill="#1d4ed8" />
|
||
</marker>
|
||
<marker id="arrow-cyan" markerWidth="8" markerHeight="8" refX="6" refY="4" orient="auto">
|
||
<path d="M0,1 L7,4 L0,7 Z" fill="#0284c7" />
|
||
</marker>
|
||
<marker id="arrow-purple" markerWidth="8" markerHeight="8" refX="6" refY="4" orient="auto">
|
||
<path d="M0,1 L7,4 L0,7 Z" fill="#6366f1" />
|
||
</marker>
|
||
</defs>
|
||
|
||
<!-- 区域背景标注 -->
|
||
<rect x="10" y="20" width="1100" height="150" rx="12" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1" stroke-dasharray="4 4" />
|
||
<text x="25" y="42" font-size="12" font-weight="700" fill="#64748b">CORE TRAINING LIFECYCLE (核心业务主脉络)</text>
|
||
|
||
<rect x="420" y="195" width="240" height="95" rx="8" fill="#f0f9ff" stroke="#bae6fd" stroke-width="1" />
|
||
<text x="435" y="218" font-size="11" font-weight="700" fill="#0284c7">LOGISTICS BRANCH (后勤住宿支线)</text>
|
||
|
||
<rect x="420" y="310" width="460" height="95" rx="8" fill="#eef2ff" stroke="#c7d2fe" stroke-width="1" />
|
||
<text x="435" y="333" font-size="11" font-weight="700" fill="#6366f1">FACILITIES LAYER (电子班牌显示支撑层)</text>
|
||
|
||
<!-- 主干流程连接线 -->
|
||
<!-- 1 -> 2 -->
|
||
<line x1="115" y1="95" x2="145" y2="95" stroke="#1d4ed8" stroke-width="2" marker-end="url(#arrow-blue)" />
|
||
<!-- 2 -> 3 -->
|
||
<line x1="245" y1="95" x2="275" y2="95" stroke="#1d4ed8" stroke-width="2" marker-end="url(#arrow-blue)" />
|
||
<!-- 3 -> 4 -->
|
||
<line x1="375" y1="95" x2="405" y2="95" stroke="#1d4ed8" stroke-width="2" marker-end="url(#arrow-blue)" />
|
||
<!-- 4 -> 5 -->
|
||
<line x1="505" y1="95" x2="535" y2="95" stroke="#1d4ed8" stroke-width="2" marker-end="url(#arrow-blue)" />
|
||
<!-- 5 -> 6 -->
|
||
<line x1="635" y1="95" x2="665" y2="95" stroke="#1d4ed8" stroke-width="2" marker-end="url(#arrow-blue)" />
|
||
<!-- 6 -> 7 -->
|
||
<line x1="765" y1="95" x2="795" y2="95" stroke="#1d4ed8" stroke-width="2" marker-end="url(#arrow-blue)" />
|
||
<!-- 7 -> 8 -->
|
||
<line x1="895" y1="95" x2="925" y2="95" stroke="#1d4ed8" stroke-width="2" marker-end="url(#arrow-blue)" />
|
||
<!-- 8 -> 9 -->
|
||
<line x1="1025" y1="95" x2="1045" y2="95" stroke="#1d4ed8" stroke-width="2" marker-end="url(#arrow-blue)" />
|
||
|
||
<!-- 支线与支撑连接线 -->
|
||
<!-- 4 -> 住宿支线 -->
|
||
<path d="M 455 125 L 455 235 L 475 235" fill="none" stroke="#0284c7" stroke-width="1.8" stroke-dasharray="3 3" marker-end="url(#arrow-cyan)" />
|
||
<!-- 5 -> 班牌支撑 -->
|
||
<path d="M 585 125 L 585 350 L 595 350" fill="none" stroke="#6366f1" stroke-width="1.8" stroke-dasharray="3 3" marker-end="url(#arrow-purple)" />
|
||
<!-- 班牌 -> 7 课次 -->
|
||
<path d="M 720 350 L 720 125" fill="none" stroke="#6366f1" stroke-width="1.8" stroke-dasharray="3 3" marker-end="url(#arrow-purple)" />
|
||
|
||
<!-- 节点 1: 基础资源 -->
|
||
<g class="flow-node" onclick="handleNodeClick('resource')">
|
||
<rect x="25" y="65" width="90" height="60" rx="8" fill="#ffffff" stroke="#cbd5e1" stroke-width="1.5" />
|
||
<text x="70" y="92" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">1. 基础资源</text>
|
||
<text x="70" y="110" text-anchor="middle" font-size="10" fill="#64748b">师资/教室/场地</text>
|
||
</g>
|
||
|
||
<!-- 节点 2: 开班计划 -->
|
||
<g class="flow-node" onclick="handleNodeClick('plan')">
|
||
<rect x="155" y="65" width="90" height="60" rx="8" fill="#ffffff" stroke="#cbd5e1" stroke-width="1.5" />
|
||
<text x="200" y="92" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">2. 开班计划</text>
|
||
<text x="200" y="110" text-anchor="middle" font-size="10" fill="#64748b">拟定班期/容量</text>
|
||
</g>
|
||
|
||
<!-- 节点 3: 本期课程 -->
|
||
<g class="flow-node" onclick="handleNodeClick('course')">
|
||
<rect x="285" y="65" width="90" height="60" rx="8" fill="#ffffff" stroke="#cbd5e1" stroke-width="1.5" />
|
||
<text x="330" y="92" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">3. 本期课程</text>
|
||
<text x="330" y="110" text-anchor="middle" font-size="10" fill="#64748b">师资绑定/学时</text>
|
||
</g>
|
||
|
||
<!-- 节点 4: 参训人员 -->
|
||
<g class="flow-node" onclick="handleNodeClick('enrollment')">
|
||
<rect x="415" y="65" width="90" height="60" rx="8" fill="#ffffff" stroke="#cbd5e1" stroke-width="1.5" />
|
||
<text x="460" y="92" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">4. 参训人员</text>
|
||
<text x="460" y="110" text-anchor="middle" font-size="10" fill="#64748b">名单导入/防超限</text>
|
||
</g>
|
||
|
||
<!-- 节点 5: 排课准备 -->
|
||
<g class="flow-node" onclick="handleNodeClick('scheduling')">
|
||
<rect x="545" y="65" width="90" height="60" rx="8" fill="#ffffff" stroke="#cbd5e1" stroke-width="1.5" />
|
||
<text x="590" y="92" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">5. 排课准备</text>
|
||
<text x="590" y="110" text-anchor="middle" font-size="10" fill="#64748b">四维预检/XOR互斥</text>
|
||
</g>
|
||
|
||
<!-- 节点 6: 开班报到 -->
|
||
<g class="flow-node" onclick="handleNodeClick('report')">
|
||
<rect x="675" y="65" width="90" height="60" rx="8" fill="#ffffff" stroke="#cbd5e1" stroke-width="1.5" />
|
||
<text x="720" y="92" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">6. 开班报到</text>
|
||
<text x="720" y="110" text-anchor="middle" font-size="10" fill="#64748b">现场核验/状态联动</text>
|
||
</g>
|
||
|
||
<!-- 节点 7: 正式培训 -->
|
||
<g class="flow-node" onclick="handleNodeClick('training')">
|
||
<rect x="805" y="65" width="90" height="60" rx="8" fill="#ffffff" stroke="#cbd5e1" stroke-width="1.5" />
|
||
<text x="850" y="92" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">7. 正式培训</text>
|
||
<text x="850" y="110" text-anchor="middle" font-size="10" fill="#64748b">课表执行/课次授课</text>
|
||
</g>
|
||
|
||
<!-- 节点 8: 课程考勤 -->
|
||
<g class="flow-node" onclick="handleNodeClick('attendance')">
|
||
<rect x="935" y="65" width="90" height="60" rx="8" fill="#ffffff" stroke="#cbd5e1" stroke-width="1.5" />
|
||
<text x="980" y="92" text-anchor="middle" font-size="13" font-weight="700" fill="#0f172a">8. 课程考勤</text>
|
||
<text x="980" y="110" text-anchor="middle" font-size="10" fill="#64748b">签到签退/留痕修正</text>
|
||
</g>
|
||
|
||
<!-- 节点 9: 结训与分析 -->
|
||
<g class="flow-node" onclick="handleNodeClick('completion')">
|
||
<rect x="1055" y="65" width="45" height="60" rx="8" fill="#ffffff" stroke="#cbd5e1" stroke-width="1.5" />
|
||
<text x="1077" y="92" text-anchor="middle" font-size="11" font-weight="700" fill="#0f172a">9.结训</text>
|
||
<text x="1077" y="110" text-anchor="middle" font-size="9" fill="#64748b">保护</text>
|
||
</g>
|
||
|
||
<!-- 支线节点: 后勤住宿 -->
|
||
<g class="flow-node" onclick="handleNodeClick('dormitory')">
|
||
<rect x="485" y="225" width="160" height="55" rx="8" fill="#ffffff" stroke="#0284c7" stroke-width="1.5" />
|
||
<text x="565" y="250" text-anchor="middle" font-size="12" font-weight="700" fill="#0284c7">后勤住宿准备 (支线)</text>
|
||
<text x="565" y="268" text-anchor="middle" font-size="10" fill="#64748b">住宿标记 · 房间分配 · 入住</text>
|
||
</g>
|
||
|
||
<!-- 支撑层节点: 电子班牌 -->
|
||
<g class="flow-node" onclick="handleNodeClick('board')">
|
||
<rect x="585" y="340" width="280" height="55" rx="8" fill="#ffffff" stroke="#6366f1" stroke-width="1.5" />
|
||
<text x="725" y="363" text-anchor="middle" font-size="12" font-weight="700" fill="#4f46e5">电子班牌终端映射 (支撑层)</text>
|
||
<text x="725" y="381" text-anchor="middle" font-size="10" fill="#64748b">UUID主键 · 教室绑定0/1/N · 课表降级</text>
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 节点图文卡片清单(供直观速查与点击唤起抽屉) -->
|
||
<section class="content-section">
|
||
<div class="section-header">
|
||
<div>
|
||
<h2 class="section-title">业务主链环节与支线速览</h2>
|
||
<p class="section-subtitle">点击任意卡片即可在右侧展开该环节的角色、规则约束、状态机流转与物理接口。</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flow-step-grid">
|
||
<div class="step-clickable-card" onclick="handleNodeClick('resource')">
|
||
<div class="card-top">
|
||
<span class="badge badge-pass">环节 1 · 主干</span>
|
||
<span class="card-code">Master Data</span>
|
||
</div>
|
||
<h3 class="card-title" style="margin-bottom: 0.4rem;">基础资源录入与治理</h3>
|
||
<p class="card-body-text">建立教师、学员主档、标准化课程、理论教室与演练场地。强校验手机号唯一性与脱敏存储。</p>
|
||
<div style="font-size: 0.78rem; color: var(--rail-blue); font-weight: 600;">点击查看规则 →</div>
|
||
</div>
|
||
|
||
<div class="step-clickable-card" onclick="handleNodeClick('plan')">
|
||
<div class="card-top">
|
||
<span class="badge badge-pass">环节 2 · 主干</span>
|
||
<span class="card-code">Plan Lifecycle</span>
|
||
</div>
|
||
<h3 class="card-title" style="margin-bottom: 0.4rem;">开班计划拟定</h3>
|
||
<p class="card-body-text">生成 32 位 UUID 计划,强制初始状态为 0:草稿。校验起止日期有效性与招生容量。</p>
|
||
<div style="font-size: 0.78rem; color: var(--rail-blue); font-weight: 600;">点击查看规则 →</div>
|
||
</div>
|
||
|
||
<div class="step-clickable-card" onclick="handleNodeClick('course')">
|
||
<div class="card-top">
|
||
<span class="badge badge-pass">环节 3 · 主干</span>
|
||
<span class="card-code">Plan Courses</span>
|
||
</div>
|
||
<h3 class="card-title" style="margin-bottom: 0.4rem;">本期课程与师资绑定</h3>
|
||
<p class="card-body-text">建立计划与课程的 N:M 关联,指定主讲教师,系统自动汇总开班总学时并保持数据一致性。</p>
|
||
<div style="font-size: 0.78rem; color: var(--rail-blue); font-weight: 600;">点击查看规则 →</div>
|
||
</div>
|
||
|
||
<div class="step-clickable-card" onclick="handleNodeClick('enrollment')">
|
||
<div class="card-top">
|
||
<span class="badge badge-pass">环节 4 · 主干</span>
|
||
<span class="card-code">Enrollment Guard</span>
|
||
</div>
|
||
<h3 class="card-title" style="margin-bottom: 0.4rem;">参训人员入班与防超额</h3>
|
||
<p class="card-body-text">学员初始参训状态为 0:待报到。严格校验容量上限 (40031) 及重复报名拦截 (40030)。</p>
|
||
<div style="font-size: 0.78rem; color: var(--rail-blue); font-weight: 600;">点击查看规则 →</div>
|
||
</div>
|
||
|
||
<div class="step-clickable-card" onclick="handleNodeClick('scheduling')">
|
||
<div class="card-top">
|
||
<span class="badge badge-pass">环节 5 · 主干</span>
|
||
<span class="card-code">Scheduling Engine</span>
|
||
</div>
|
||
<h3 class="card-title" style="margin-bottom: 0.4rem;">排课四维冲突预检</h3>
|
||
<p class="card-body-text">智能检测教师时段、场地占用与班级重叠。支持 Warning 级别确认保存,硬阻断场地 XOR 互斥。</p>
|
||
<div style="font-size: 0.78rem; color: var(--rail-blue); font-weight: 600;">点击查看规则 →</div>
|
||
</div>
|
||
|
||
<div class="step-clickable-card" onclick="handleNodeClick('report')">
|
||
<div class="card-top">
|
||
<span class="badge badge-pass">环节 6 · 主干</span>
|
||
<span class="card-code">Report Confirm</span>
|
||
</div>
|
||
<h3 class="card-title" style="margin-bottom: 0.4rem;">现场开班报到确认</h3>
|
||
<p class="card-body-text">核验报到时限与资格,强事务联动学员状态至 1:已报到,并记录精确报到时间,防重复报到。</p>
|
||
<div style="font-size: 0.78rem; color: var(--rail-blue); font-weight: 600;">点击查看规则 →</div>
|
||
</div>
|
||
|
||
<div class="step-clickable-card" onclick="handleNodeClick('attendance')">
|
||
<div class="card-top">
|
||
<span class="badge badge-pass">环节 8 · 主干</span>
|
||
<span class="card-code">Attendance Actions</span>
|
||
</div>
|
||
<h3 class="card-title" style="margin-bottom: 0.4rem;">课堂考勤打卡与审计</h3>
|
||
<p class="card-body-text">签到签退幂等性保证,重复签到签退保留初次时间。人工代签/补签自动记录 manual_flag=1 审计留痕。</p>
|
||
<div style="font-size: 0.78rem; color: var(--rail-blue); font-weight: 600;">点击查看规则 →</div>
|
||
</div>
|
||
|
||
<div class="step-clickable-card" onclick="handleNodeClick('completion')">
|
||
<div class="card-top">
|
||
<span class="badge badge-pass">环节 9 · 主干</span>
|
||
<span class="card-code">Plan Complete</span>
|
||
</div>
|
||
<h3 class="card-title" style="margin-bottom: 0.4rem;">结训流转与退训保护</h3>
|
||
<p class="card-body-text">计划流转为 2:已结束,在读活动学员自动批量流转为 4:已完成。历史退训记录严格锁定防破坏。</p>
|
||
<div style="font-size: 0.78rem; color: var(--rail-blue); font-weight: 600;">点击查看规则 →</div>
|
||
</div>
|
||
|
||
<div class="step-clickable-card side-branch" onclick="handleNodeClick('dormitory')">
|
||
<div class="card-top">
|
||
<span class="badge badge-info">支线 · 后勤</span>
|
||
<span class="card-code">Accommodation</span>
|
||
</div>
|
||
<h3 class="card-title" style="margin-bottom: 0.4rem;">后勤住宿管理支线</h3>
|
||
<p class="card-body-text">学员报名时勾选 accommodationRequired 触发宿舍分配,管理房间可用床位与入住注销。</p>
|
||
<div style="font-size: 0.78rem; color: var(--rail-cyan); font-weight: 600;">点击查看支线 →</div>
|
||
</div>
|
||
|
||
<div class="step-clickable-card support-layer" onclick="handleNodeClick('board')">
|
||
<div class="card-top">
|
||
<span class="badge badge-neutral" style="color: #6366f1; background: #eef2ff; border-color: #c7d2fe;">支撑 · 物联</span>
|
||
<span class="card-code">Electronic Board</span>
|
||
</div>
|
||
<h3 class="card-title" style="margin-bottom: 0.4rem;">电子班牌显示支撑层</h3>
|
||
<p class="card-body-text">教室绑定 0/1/N 班牌关系,课表 timetable 智能降级映射 boardSn,支持逻辑删除保护。</p>
|
||
<div style="font-size: 0.78rem; color: #6366f1; font-weight: 600;">点击查看支撑 →</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</main>
|
||
|
||
<!-- 侧边抽屉组件 (Drawer) -->
|
||
<div class="drawer-backdrop" id="drawer-backdrop">
|
||
<div class="drawer-panel">
|
||
<div class="drawer-header">
|
||
<h3 class="drawer-title" id="drawer-title">节点详情</h3>
|
||
<button class="drawer-close" id="drawer-close-btn" type="button" aria-label="关闭">×</button>
|
||
</div>
|
||
<div class="drawer-body" id="drawer-body">
|
||
<!-- 动态注入内容 -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<footer class="site-footer">
|
||
<p>RailwaySystem SYFJGYD学员管理系统 · 交付候选版 (Final Candidate)</p>
|
||
<p style="margin-top: 0.35rem; color: var(--text-muted);">
|
||
业务流程与状态机规范 · <a href="http://192.168.139.218:9980/sict/railwaysystem/-/blob/feat/cicd-pipeline/docs/handbook/02-business-process.md" target="_blank" rel="noopener noreferrer">查阅业务流程详细手册</a>
|
||
</p>
|
||
</footer>
|
||
|
||
<script src="assets/docs.js"></script>
|
||
<script>
|
||
// 抽屉详情字典库 (据实编写,无扩写)
|
||
const nodeDetails = {
|
||
resource: {
|
||
title: "1. 基础资源录入与治理 (Master Data)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">核心业务角色与职责</div>
|
||
<p><strong>教务管理员</strong>:在开学或开班前,统一录入师资档案(姓名、职称、联系电话)、学员主档、标准课程库以及校区空间(理论教室、实训演练基地)。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">关键业务规则与约束</div>
|
||
<ul style="padding-left: 1.25rem; line-height: 1.8;">
|
||
<li><strong>教师手机号唯一性</strong>:同一手机号不可重复录入,重复时触发业务错误拦截(40001)。</li>
|
||
<li><strong>学员脱敏与哈希保护</strong>:学员身份证存储密文与哈希,列表及详情接口仅返回末4位脱敏掩码,避免明文泄露。</li>
|
||
<li><strong>空间互斥 XOR 属性</strong>:理论教室与实训场地在底层物理模型中属于独立实体,供后续排课互斥引用。</li>
|
||
</ul>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口契约</div>
|
||
<pre><code>POST /train/teacher
|
||
POST /train/student
|
||
POST /train/course
|
||
POST /train/classroom
|
||
POST /train/training-site</code></pre>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">物理数据模型</div>
|
||
<p><code>train_teacher</code>, <code>train_student</code>, <code>train_course</code>, <code>train_classroom_info</code>, <code>train_training_site</code></p>
|
||
</div>
|
||
`
|
||
},
|
||
plan: {
|
||
title: "2. 培训班计划拟定 (Training Plan)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">核心业务角色与职责</div>
|
||
<p><strong>培训主管 / 教务科</strong>:拟定开班方案,录入培训班名称、起止日期、报到截止日期、计划招生人数上限及办班地点。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">状态机与业务约束</div>
|
||
<ul style="padding-left: 1.25rem; line-height: 1.8;">
|
||
<li><strong>主键生成</strong>:后端自动生成全局唯一的 32 位 UUID 主键。</li>
|
||
<li><strong>初始状态机</strong>:创建成功后,计划状态强制为 <code>0:草稿 (DRAFT)</code>。</li>
|
||
<li><strong>时间窗口校验</strong>:起始时间必须小于结束时间,且报到截止时间不得晚于培训起始时间。</li>
|
||
</ul>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口契约</div>
|
||
<pre><code>POST /train/plans
|
||
GET /train/plans/{id}
|
||
PUT /train/plans/{id}</code></pre>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">物理数据模型</div>
|
||
<p><code>train_class_plan</code> (字段: <code>plan_id</code>, <code>plan_name</code>, <code>plan_status</code>, <code>start_time</code>, <code>end_time</code>, <code>recruit_num</code>)</p>
|
||
</div>
|
||
`
|
||
},
|
||
course: {
|
||
title: "3. 计划课程与师资绑定 (Plan Courses)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">核心业务角色与职责</div>
|
||
<p><strong>教务排课员</strong>:为处于草稿状态的培训班指定本期教学大纲中的课程清单,并指派授课教师。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">关键业务规则</div>
|
||
<ul style="padding-left: 1.25rem; line-height: 1.8;">
|
||
<li><strong>关联一致性</strong>:支持批量绑定 <code>cIds</code>,生成 <code>train_plan_course</code> 映射。</li>
|
||
<li><strong>学时汇总</strong>:系统根据所选课程的 <code>c_duration</code> 自动累加该班期总课时。</li>
|
||
</ul>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口契约</div>
|
||
<pre><code>POST /train/plans/{id}/courses
|
||
GET /train/plans/{id}/courses</code></pre>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">物理数据模型</div>
|
||
<p><code>train_plan_course</code> (字段: <code>plan_course_id</code>, <code>plan_id</code>, <code>c_id</code>, <code>t_id</code>, <code>remark</code>)</p>
|
||
</div>
|
||
`
|
||
},
|
||
enrollment: {
|
||
title: "4. 学员入班与招生容量守卫 (Enrollment)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">核心业务角色与职责</div>
|
||
<p><strong>站段劳资 / 培训管理员</strong>:根据各站段参训名单,将合格在册学员批量或逐一报名单录入培训班。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">状态机与安全拦截规则</div>
|
||
<ul style="padding-left: 1.25rem; line-height: 1.8;">
|
||
<li><strong>初始参训状态</strong>:入班成功后,参训状态初始为 <code>0:待报到 (PENDING)</code>。</li>
|
||
<li><strong>同一计划重复报名拦截</strong>:严格唯一索引拦截,返回业务码 <code>40030: ENROLLMENT_ALREADY_EXISTS</code>。</li>
|
||
<li><strong>计划招生容量超限拦截</strong>:入班人数达到 <code>recruit_num</code> 上限时,拦截返回 <code>40031: ENROLLMENT_CAPACITY_EXCEEDED</code>。</li>
|
||
<li><strong>停用学员拦截</strong>:若学员主档状态为 <code>status=0</code>,拒绝入班。</li>
|
||
</ul>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口契约</div>
|
||
<pre><code>POST /train/plans/{id}/enrollments
|
||
GET /train/plans/{id}/enrollments
|
||
PUT /train/enrollments/{id}/status</code></pre>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">物理数据模型</div>
|
||
<p><code>train_enrollment</code> (字段: <code>enrollment_id</code>, <code>plan_id</code>, <code>student_id</code>, <code>enrollment_status</code>, <code>accommodation_required</code>)</p>
|
||
</div>
|
||
`
|
||
},
|
||
scheduling: {
|
||
title: "5. 排课四维冲突预检与保存 (Scheduling)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">核心业务角色与职责</div>
|
||
<p><strong>教务排课员</strong>:在开课前编制课次(Lesson),安排上课时段、授课教师及教学空间。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">排课预检与硬阻断规则</div>
|
||
<ul style="padding-left: 1.25rem; line-height: 1.8;">
|
||
<li><strong>四维冲突预检</strong>:检测教师时段冲突 (TEACHER)、教室占用 (CLASSROOM Warning)、场地占用 (SITE Warning) 及班级课次重叠 (PLAN_OVERLAP Warning)。</li>
|
||
<li><strong>Warning 非硬阻断</strong>:教室、场地与班级重叠为 Warning 级别,管理员确认后标准 POST 正常保存,禁止任何旁路 force 参数。</li>
|
||
<li><strong>场地 XOR 互斥硬阻断</strong>:<code>venue_type</code> 严格控制理论教室与实训场地二选一,不可同时传或同时为空。</li>
|
||
<li><strong>非法时间硬阻断</strong>:起止时间倒挂拦截(40010);已结束计划禁止排课(40012)。</li>
|
||
</ul>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口契约</div>
|
||
<pre><code>POST /train/lessons/check-conflict
|
||
POST /train/plans/{id}/lessons
|
||
GET /train/plans/{id}/timetable</code></pre>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">物理数据模型</div>
|
||
<p><code>train_lesson</code> (字段: <code>lesson_id</code>, <code>plan_course_id</code>, <code>venue_type</code>, <code>class_room_id</code>, <code>site_id</code>, <code>start_time</code>, <code>end_time</code>)</p>
|
||
</div>
|
||
`
|
||
},
|
||
report: {
|
||
title: "6. 现场开班报到确认 (Report Confirm)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">核心业务角色与职责</div>
|
||
<p><strong>基地教务值班员 / 学员</strong>:学员到达培训基地现场,通过刷卡、人脸或人工核验完成开班报到。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">报到状态联动与防重复机制</div>
|
||
<ul style="padding-left: 1.25rem; line-height: 1.8;">
|
||
<li><strong>状态强事务流转</strong>:调用报到确认接口后,生成 <code>train_class_report</code> 记录,同时将学员在 <code>train_enrollment</code> 的状态由 <code>0:待报到</code> 更新为 <code>1:已报到</code>,并写入 <code>join_time</code>。</li>
|
||
<li><strong>重复报到拦截</strong>:已报到学员再次报到时直接拦截,返回业务错误码 <code>40050</code>。</li>
|
||
<li><strong>报到时限校验</strong>:超过计划设定的 <code>report_deadline</code> 需由管理员特别确认。</li>
|
||
</ul>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口契约</div>
|
||
<pre><code>POST /train/enrollments/{enrollmentId}/report
|
||
GET /train/report/list</code></pre>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">物理数据模型</div>
|
||
<p><code>train_class_report</code> (字段: <code>report_id</code>, <code>enrollment_id</code>, <code>report_time</code>, <code>report_way</code>, <code>verify_note</code>)</p>
|
||
</div>
|
||
`
|
||
},
|
||
training: {
|
||
title: "7. 正式培训与课表执行 (Training Execution)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">核心业务角色与职责</div>
|
||
<p><strong>任课教师 / 学员</strong>:依照课表安排,在指定理论教室或实训场地开展教学。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">业务支持特性</div>
|
||
<ul style="padding-left: 1.25rem; line-height: 1.8;">
|
||
<li><strong>课表聚合视图</strong>:<code>GET /train/plans/{id}/timetable</code> 统一映射聚合 <code>courseName</code>, <code>teacherName</code>, <code>venueName</code> 及 <code>boardSn</code>。</li>
|
||
<li><strong>现场物联呈现</strong>:教室门口电子班牌实时显示当前课程与教师信息。</li>
|
||
</ul>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口契约</div>
|
||
<pre><code>GET /train/plans/{id}/timetable</code></pre>
|
||
</div>
|
||
`
|
||
},
|
||
attendance: {
|
||
title: "8. 课程考勤打卡与审计留痕 (Attendance)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">核心业务角色与职责</div>
|
||
<p><strong>授课教师 / 随班班主任</strong>:跟踪学员课次到课率,处理签到、签退及异常请假补签。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">考勤幂等性与审计规范</div>
|
||
<ul style="padding-left: 1.25rem; line-height: 1.8;">
|
||
<li><strong>签到签退幂等性</strong>:重复请求签到或签退时,保持首次打卡时间 <code>signInTime / signOutTime</code>,杜绝覆盖。</li>
|
||
<li><strong>人工代签留痕</strong>:管理员或教师人工修改考勤状态时,系统自动置 <code>manual_flag = 1</code>,记录修改人与修改备注供合规追溯。</li>
|
||
</ul>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口契约</div>
|
||
<pre><code>POST /train/attendance/sign-in
|
||
POST /train/attendance/sign-out
|
||
PUT /train/attendance/{checkinId}
|
||
GET /train/attendance/list</code></pre>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">物理数据模型</div>
|
||
<p><code>train_student_checkin</code> (字段: <code>checkin_id</code>, <code>enrollment_id</code>, <code>lesson_id</code>, <code>sign_in_time</code>, <code>sign_out_time</code>, <code>manual_flag</code>)</p>
|
||
</div>
|
||
`
|
||
},
|
||
completion: {
|
||
title: "9. 结训生命周期与退训保护 (Plan Completion)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">核心业务角色与职责</div>
|
||
<p><strong>教务科主管</strong>:培训周期结束、考核完毕后,发起班期正式结训动作。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">强事务联动与退训保护不变量</div>
|
||
<ul style="padding-left: 1.25rem; line-height: 1.8;">
|
||
<li><strong>计划状态变更</strong>:<code>train_class_plan.plan_status</code> 由 <code>1:进行中</code> 变更为 <code>2:已结束</code>。</li>
|
||
<li><strong>在读活动学员自动完成</strong>:状态为 <code>0:待报到</code> 或 <code>1:已报到</code> 的学员,参训状态自动批量流转为 <code>4:已完成</code>,且 <code>complete_time</code> 真实写入。</li>
|
||
<li><strong>历史退训学员状态防误覆盖 (核心保护)</strong>:提前申请退训的学员 (<code>enrollmentStatus = 3</code>) 状态严格保持为 3,<code>complete_time</code> 保持为空,严禁被批量完成逻辑覆盖。</li>
|
||
</ul>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口契约</div>
|
||
<pre><code>POST /train/plans/{id}/complete</code></pre>
|
||
</div>
|
||
`
|
||
},
|
||
dormitory: {
|
||
title: "后勤住宿管理支线 (Accommodation)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">业务定位与流程衔接</div>
|
||
<p><strong>后勤宿管人员</strong>:作为核心教学的辅助支线,在学员报名时由 <code>accommodationRequired = 1</code> 触发,分配基地宿舍床位,结训时同步退宿交接。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口与数据表</div>
|
||
<pre><code>GET /train/dormitory/list
|
||
POST /train/dormitory/check-in
|
||
POST /train/dormitory/check-out</code></pre>
|
||
<p>物理表:<code>train_dormitory_info</code>, <code>train_accommodation</code></p>
|
||
</div>
|
||
`
|
||
},
|
||
board: {
|
||
title: "电子班牌显示支撑层 (Electronic Board)",
|
||
html: `
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">物联设备支撑定位</div>
|
||
<p><strong>设备管理与现场终端</strong>:作为教学排课的呈现层,将物理班牌与教室绑定,并在课表及前端路由 <code>/equip/board</code> 中输出信息。</p>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">核心验证规则与降级逻辑</div>
|
||
<ul style="padding-left: 1.25rem; line-height: 1.8;">
|
||
<li><strong>UUID 主键生成</strong>:自动生成 32 位 UUID 主键,默认在线状态 <code>board_status = 0</code>。</li>
|
||
<li><strong>教室绑定 0/1/N 映射</strong>:<code>GET /train/classroom/{id}</code> 准确返回绑定的班牌数组。</li>
|
||
<li><strong>课表 boardSn 智能降级规则</strong>:
|
||
<br>· 教室未绑板:<code>boardSn = null</code>;
|
||
<br>· 教室恰好绑 1 块板:<code>boardSn = 班牌序列号</code>;
|
||
<br>· 教室绑定 >1 块板:<code>boardSn = null</code> (避免多板歧义降级)。
|
||
</li>
|
||
<li><strong>逻辑删除保障</strong>:执行删除后,底层置 <code>del_flag = '2'</code>,常规查询接口不可见。</li>
|
||
</ul>
|
||
</div>
|
||
<div class="drawer-section">
|
||
<div class="drawer-section-title">技术接口与物理表</div>
|
||
<pre><code>POST /train/board
|
||
GET /train/board/list
|
||
DELETE /train/board/{id}</code></pre>
|
||
<p>物理表:<code>train_electronic_board</code> (主键 <code>board_id</code> 32 位 UUID)</p>
|
||
</div>
|
||
`
|
||
}
|
||
};
|
||
|
||
function handleNodeClick(nodeKey) {
|
||
const data = nodeDetails[nodeKey];
|
||
if (!data) return;
|
||
window.openDrawer(data.title, data.html);
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|