etms/BPMN流程图_业务流程模型.html
liyuchen 512d57c5d9 Code fixes: global vars, date API, deprecated SQL, FTL comments
Fixed Issues:
- globalConfig.js: Added const declarations for 10 undeclared regex variables
- globalConfig.js: Fixed getDay() -> getDate() for date comparison
- Removed 16 deprecated SQL definitions from 4 map.xml files
- Cleaned 615+ commented code blocks from 115 FTL templates

Added:
- CODE_FIX_PLAN.md: Detailed fix plan for remaining issues

Remaining (documented in CODE_FIX_PLAN.md):
- 6 async: false AJAX requests to convert
- 120+ SELECT * to optimize
- 6265+ inline styles to refactor
2026-04-16 17:24:37 +08:00

1925 lines
103 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JCDP教育培训管理系统 - BPMN业务流程模型</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Microsoft YaHei", "Segoe UI", Arial, sans-serif;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
color: #e8e8e8;
min-height: 100vh;
padding: 40px 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 50px;
padding: 40px;
background: rgba(255,255,255,0.05);
border-radius: 20px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255,255,255,0.1);
}
.header h1 {
font-size: 2.5em;
background: linear-gradient(90deg, #00d4ff, #7b2cbf, #ff006e);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 15px;
}
.header .subtitle {
color: #888;
font-size: 1.1em;
}
.header .meta {
margin-top: 20px;
display: flex;
justify-content: center;
gap: 30px;
flex-wrap: wrap;
}
.header .meta-item {
background: rgba(0,212,255,0.1);
padding: 8px 20px;
border-radius: 20px;
border: 1px solid rgba(0,212,255,0.3);
font-size: 0.9em;
}
/* 导航 */
.nav {
display: flex;
justify-content: center;
gap: 15px;
margin-bottom: 40px;
flex-wrap: wrap;
}
.nav a {
padding: 12px 25px;
background: rgba(255,255,255,0.08);
border: 1px solid rgba(255,255,255,0.15);
border-radius: 25px;
color: #fff;
text-decoration: none;
transition: all 0.3s ease;
font-size: 0.95em;
}
.nav a:hover, .nav a.active {
background: linear-gradient(135deg, #00d4ff, #7b2cbf);
border-color: transparent;
transform: translateY(-2px);
box-shadow: 0 5px 20px rgba(0,212,255,0.3);
}
/* 流程卡片 */
.process-card {
background: rgba(255,255,255,0.03);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 20px;
padding: 40px;
margin-bottom: 40px;
backdrop-filter: blur(5px);
}
.process-card h2 {
font-size: 1.8em;
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 15px;
}
.process-card h2 .icon {
font-size: 1.2em;
}
.process-id {
background: linear-gradient(135deg, #667eea, #764ba2);
padding: 5px 15px;
border-radius: 15px;
font-size: 0.5em;
vertical-align: middle;
}
.process-desc {
color: #aaa;
margin-bottom: 30px;
padding-left: 50px;
}
/* BPMN流程图容器 */
.bpmn-container {
background: #fff;
border-radius: 15px;
padding: 30px;
margin-bottom: 30px;
overflow-x: auto;
}
/* SVG流程图样式 */
.bpmn-svg {
display: block;
margin: 0 auto;
}
/* 流程定义表格 */
.process-meta {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-bottom: 30px;
}
.meta-item {
background: rgba(255,255,255,0.05);
padding: 15px 20px;
border-radius: 10px;
border-left: 3px solid #00d4ff;
}
.meta-item .label {
color: #888;
font-size: 0.85em;
margin-bottom: 5px;
}
.meta-item .value {
font-size: 1.1em;
font-weight: 500;
}
/* 参与者区域 */
.participants {
margin-bottom: 30px;
}
.participants h3 {
font-size: 1.2em;
margin-bottom: 15px;
color: #00d4ff;
}
.participant-list {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.participant {
background: linear-gradient(135deg, rgba(102,126,234,0.2), rgba(118,75,162,0.2));
padding: 12px 20px;
border-radius: 25px;
border: 1px solid rgba(102,126,234,0.3);
display: flex;
align-items: center;
gap: 10px;
}
.participant .role {
font-weight: 500;
}
.participant .duty {
color: #888;
font-size: 0.85em;
}
/* 节点详情表格 */
.node-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
font-size: 0.9em;
}
.node-table th {
background: linear-gradient(135deg, #667eea, #764ba2);
color: #fff;
padding: 15px;
text-align: left;
font-weight: 500;
}
.node-table td {
padding: 12px 15px;
border-bottom: 1px solid rgba(255,255,255,0.1);
}
.node-table tr:hover {
background: rgba(255,255,255,0.05);
}
.node-type {
display: inline-block;
padding: 4px 12px;
border-radius: 12px;
font-size: 0.8em;
font-weight: 500;
}
.type-start { background: #4ade80; color: #000; }
.type-end { background: #f87171; color: #000; }
.type-task { background: #60a5fa; color: #000; }
.type-gateway { background: #fbbf24; color: #000; }
.type-subprocess { background: #a78bfa; color: #000; }
/* 流程总览 */
.overview-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin-top: 30px;
}
.overview-card {
background: linear-gradient(135deg, rgba(102,126,234,0.15), rgba(118,75,162,0.15));
border: 1px solid rgba(102,126,234,0.3);
border-radius: 15px;
padding: 25px;
cursor: pointer;
transition: all 0.3s ease;
}
.overview-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0,212,255,0.2);
}
.overview-card h4 {
font-size: 1.1em;
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 10px;
}
.overview-card .pid {
font-size: 0.7em;
background: rgba(0,212,255,0.2);
padding: 3px 10px;
border-radius: 10px;
}
.overview-card p {
color: #aaa;
font-size: 0.9em;
margin-bottom: 15px;
}
.overview-card .tags {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.overview-card .tag {
padding: 4px 12px;
border-radius: 12px;
font-size: 0.75em;
background: rgba(255,255,255,0.1);
}
/* 图例 */
.legend {
display: flex;
justify-content: center;
gap: 25px;
flex-wrap: wrap;
margin: 30px 0;
padding: 20px;
background: rgba(255,255,255,0.03);
border-radius: 15px;
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.9em;
}
.legend-icon {
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
}
/* 状态机样式 */
.state-machine {
background: #fff;
border-radius: 15px;
padding: 30px;
margin: 20px 0;
}
.state-box {
display: inline-flex;
flex-direction: column;
align-items: center;
margin: 10px 20px;
}
.state-circle {
width: 80px;
height: 80px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
color: #fff;
margin-bottom: 10px;
}
.state-value { background: #64748b; }
.state-active { background: #3b82f6; }
.state-complete { background: #22c55e; }
.state-error { background: #ef4444; }
.state-name {
font-size: 0.85em;
color: #333;
}
.arrow {
display: inline-block;
color: #666;
font-size: 1.5em;
vertical-align: middle;
}
/* 页脚 */
.footer {
text-align: center;
margin-top: 50px;
padding: 30px;
color: #666;
font-size: 0.9em;
}
/* 状态颜色 */
.status-pending { color: #fbbf24; }
.status-active { color: #3b82f6; }
.status-complete { color: #22c55e; }
.status-error { color: #ef4444; }
/* 响应式 */
@media (max-width: 768px) {
.header h1 { font-size: 1.8em; }
.process-card { padding: 25px; }
.nav { gap: 10px; }
.nav a { padding: 10px 15px; font-size: 0.85em; }
}
</style>
</head>
<body>
<div class="container">
<!-- 头部 -->
<div class="header">
<h1>JCDP 教育培训管理系统</h1>
<p class="subtitle">BPMN 2.0 业务流程模型</p>
<div class="meta">
<span class="meta-item">📅 版本: v1.0</span>
<span class="meta-item">🏢 中国电子科技集团第五十四研究所</span>
<span class="meta-item">🔢 软件版本: 54</span>
</div>
</div>
<!-- BPMN图例 -->
<div class="legend">
<div class="legend-item">
<div class="legend-icon">
<svg width="24" height="24" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="#4ade80" stroke="#22c55e" stroke-width="2"/></svg>
</div>
<span>开始事件</span>
</div>
<div class="legend-item">
<div class="legend-icon">
<svg width="24" height="24" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="#fecaca" stroke="#ef4444" stroke-width="2"/><circle cx="12" cy="12" r="6" fill="none" stroke="#ef4444" stroke-width="2"/></svg>
</div>
<span>结束事件</span>
</div>
<div class="legend-item">
<div class="legend-icon">
<svg width="24" height="24" viewBox="0 0 24 24"><rect x="2" y="4" width="20" height="16" rx="3" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/></svg>
</div>
<span>用户任务</span>
</div>
<div class="legend-item">
<div class="legend-icon">
<svg width="24" height="24" viewBox="0 0 24 24"><rect x="2" y="4" width="20" height="16" rx="3" fill="#a78bfa" stroke="#7c3aed" stroke-width="2"/></svg>
</div>
<span>子流程</span>
</div>
<div class="legend-item">
<div class="legend-icon">
<svg width="24" height="24" viewBox="0 0 24 24"><polygon points="12,2 22,12 12,22 2,12" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/></svg>
</div>
<span>排他网关</span>
</div>
<div class="legend-item">
<div class="legend-icon">
<svg width="24" height="24" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="none" stroke="#888" stroke-width="2" stroke-dasharray="4"/><polygon points="12,6 18,12 12,18" fill="#888"/></svg>
</div>
<span>连接线</span>
</div>
</div>
<!-- 导航 -->
<nav class="nav">
<a href="#overview">📊 流程总览</a>
<a href="#plan">📝 培训计划管理</a>
<a href="#implement">🎓 培训实施管理</a>
<a href="#exam">📋 考试管理</a>
<a href="#outtrain">🌐 外派培训</a>
<a href="#approval">✅ 审批流程</a>
<a href="#summary">📈 年度总结</a>
</nav>
<!-- 流程总览 -->
<section id="overview" class="process-card">
<h2><span class="icon">📊</span> 业务流程总览</h2>
<p class="process-desc">JCDP系统核心业务流程一览</p>
<div class="overview-grid">
<div class="overview-card" onclick="document.getElementById('plan').scrollIntoView({behavior: 'smooth'})">
<h4>培训计划管理 <span class="pid">PROC-TRAIN-PLAN</span></h4>
<p>年度培训计划的制定、调研、汇总与审批流程</p>
<div class="tags">
<span class="tag">审批流</span>
<span class="tag">多部门协作</span>
<span class="tag">年度周期</span>
</div>
</div>
<div class="overview-card" onclick="document.getElementById('implement').scrollIntoView({behavior: 'smooth'})">
<h4>培训实施管理 <span class="pid">PROC-TRAIN-IMPLEMENT</span></h4>
<p>培训班级创建、学员管理、授课与效果评估</p>
<div class="tags">
<span class="tag">状态驱动</span>
<span class="tag">班级管理</span>
<span class="tag">效果反馈</span>
</div>
</div>
<div class="overview-card" onclick="document.getElementById('exam').scrollIntoView({behavior: 'smooth'})">
<h4>考试管理 <span class="pid">PROC-EXAM</span></h4>
<p>试卷管理、在线答题、自动/人工判卷</p>
<div class="tags">
<span class="tag">定时触发</span>
<span class="tag">自动判分</span>
<span class="tag">人员限定</span>
</div>
</div>
<div class="overview-card" onclick="document.getElementById('outtrain').scrollIntoView({behavior: 'smooth'})">
<h4>外派培训管理 <span class="pid">PROC-OUTTRAIN</span></h4>
<p>外部培训申请、审批、归来登记与考核</p>
<div class="tags">
<span class="tag">审批流</span>
<span class="tag">外出管理</span>
<span class="tag">经济责任制</span>
</div>
</div>
<div class="overview-card" onclick="document.getElementById('approval').scrollIntoView({behavior: 'smooth'})">
<h4>通用审批流程 <span class="pid">SUB-APPROVAL</span></h4>
<p>被其他流程调用的通用多级审批子流程</p>
<div class="tags">
<span class="tag">子流程</span>
<span class="tag">多级审批</span>
<span class="tag">可复用</span>
</div>
</div>
<div class="overview-card" onclick="document.getElementById('summary').scrollIntoView({behavior: 'smooth'})">
<h4>年度培训总结 <span class="pid">PROC-YEAR-SUMMARY</span></h4>
<p>年度培训数据汇总、报告生成</p>
<div class="tags">
<span class="tag">填报流</span>
<span class="tag">年度周期</span>
<span class="tag">数据汇总</span>
</div>
</div>
</div>
</section>
<!-- 培训计划管理流程 -->
<section id="plan" class="process-card">
<h2><span class="icon">📝</span> 培训计划管理流程 <span class="process-id">PROC-TRAIN-PLAN</span></h2>
<p class="process-desc">年度培训计划的制定、调研、汇总与审批管理</p>
<!-- 流程定义 -->
<div class="process-meta">
<div class="meta-item">
<div class="label">流程ID</div>
<div class="value">PROC-TRAIN-PLAN</div>
</div>
<div class="meta-item">
<div class="label">流程类型</div>
<div class="value">审批流 + 数据填报流</div>
</div>
<div class="meta-item">
<div class="label">触发方式</div>
<div class="value">手工触发(所级管理员)</div>
</div>
<div class="meta-item">
<div class="label">流程周期</div>
<div class="value">年度Q4制定次年计划</div>
</div>
</div>
<!-- 参与者 -->
<div class="participants">
<h3>👥 参与者定义</h3>
<div class="participant-list">
<div class="participant">
<span>🎯</span>
<div>
<div class="role">所级管理员</div>
<div class="duty">发起计划、下发通知、汇总生成、审批</div>
</div>
</div>
<div class="participant">
<span>👤</span>
<div>
<div class="role">部门管理员</div>
<div class="duty">填报课程需求、反馈调研</div>
</div>
</div>
<div class="participant">
<span>📋</span>
<div>
<div class="role">部门领导</div>
<div class="duty">审核部门申报</div>
</div>
</div>
<div class="participant">
<span>🏛️</span>
<div>
<div class="role">所级领导</div>
<div class="duty">最终审批</div>
</div>
</div>
</div>
</div>
<!-- BPMN流程图 -->
<div class="bpmn-container">
<svg class="bpmn-svg" width="1100" height="750" viewBox="0 0 1100 750">
<!-- 背景网格 -->
<defs>
<pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M 20 0 L 0 0 0 20" fill="none" stroke="#f0f0f0" stroke-width="0.5"/>
</pattern>
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#666"/>
</marker>
<marker id="arrowhead-green" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#22c55e"/>
</marker>
<marker id="arrowhead-red" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#ef4444"/>
</marker>
</defs>
<rect width="100%" height="100%" fill="url(#grid)"/>
<!-- 泳道标题 -->
<rect x="0" y="0" width="200" height="750" fill="#e8f4fc" stroke="#b8d4e8" stroke-width="1"/>
<text x="100" y="30" text-anchor="middle" font-weight="bold" fill="#1976d2">所级管理员</text>
<rect x="200" y="0" width="250" height="750" fill="#fff3e0" stroke="#ffcc80" stroke-width="1"/>
<text x="325" y="30" text-anchor="middle" font-weight="bold" fill="#e65100">部门管理员</text>
<rect x="450" y="0" width="650" height="750" fill="#e8f5e9" stroke="#a5d6a7" stroke-width="1"/>
<text x="775" y="30" text-anchor="middle" font-weight="bold" fill="#2e7d32">领导层审批</text>
<!-- 开始事件 -->
<circle cx="100" cy="80" r="25" fill="#4ade80" stroke="#22c55e" stroke-width="3"/>
<text x="100" y="85" text-anchor="middle" fill="#000" font-size="12">开始</text>
<!-- 计划来源选择 -->
<rect x="25" y="130" width="150" height="60" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="100" y="155" text-anchor="middle" fill="#fff" font-size="11">创建培训计划</text>
<text x="100" y="172" text-anchor="middle" fill="#fff" font-size="9">et_train_ip/gip/gop</text>
<line x1="100" y1="105" x2="100" y2="130" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 计划类型网关 -->
<polygon points="100,210 130,235 100,260 70,235" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="100" y="240" text-anchor="middle" fill="#000" font-size="10">计划</text>
<text x="100" y="252" text-anchor="middle" fill="#000" font-size="10">类型?</text>
<line x1="100" y1="190" x2="100" y2="210" stroke="#666" stroke-width="2"/>
<!-- 所级计划分支 -->
<rect x="10" y="285" width="130" height="50" rx="6" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="75" y="310" text-anchor="middle" fill="#fff" font-size="10">所级计划</text>
<text x="75" y="323" text-anchor="middle" fill="#fff" font-size="9">et_train_ip</text>
<text x="75" y="275" text-anchor="middle" fill="#666" font-size="9">jhly='sj'</text>
<!-- 部门计划内分支 -->
<rect x="150" y="285" width="130" height="50" rx="6" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="215" y="310" text-anchor="middle" fill="#fff" font-size="10">部门计划内</text>
<text x="215" y="323" text-anchor="middle" fill="#fff" font-size="9">et_train_gip</text>
<text x="215" y="275" text-anchor="middle" fill="#666" font-size="9">jhly='bmn'</text>
<!-- 部门计划外分支 -->
<rect x="300" y="285" width="130" height="50" rx="6" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="365" y="310" text-anchor="middle" fill="#fff" font-size="10">部门计划外</text>
<text x="365" y="323" text-anchor="middle" fill="#fff" font-size="9">et_train_gop</text>
<text x="365" y="275" text-anchor="middle" fill="#666" font-size="9">jhly='bmw'</text>
<!-- 连接线 -->
<line x1="100" y1="260" x2="75" y2="285" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="130" y1="235" x2="150" y2="260" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="70" y1="235" x2="75" y2="260" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="100" y1="235" x2="75" y2="260" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="130" y1="235" x2="365" y2="260" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 部门填报 -->
<rect x="150" y="360" width="250" height="70" rx="8" fill="#a78bfa" stroke="#7c3aed" stroke-width="2"/>
<text x="275" y="388" text-anchor="middle" fill="#fff" font-size="11">部门管理员填报</text>
<text x="275" y="403" text-anchor="middle" fill="#fff" font-size="9">选择课程、填写需求</text>
<text x="275" y="416" text-anchor="middle" fill="#fff" font-size="9">et_train_gipgroup_kc</text>
<line x1="75" y1="335" x2="75" y2="360" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="215" y1="335" x2="275" y2="360" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="365" y1="335" x2="365" y2="360" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 调研网关 -->
<polygon points="275,455 305,480 275,505 245,480" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="275" y="485" text-anchor="middle" fill="#000" font-size="10">需要</text>
<text x="275" y="497" text-anchor="middle" fill="#000" font-size="10">调研?</text>
<line x1="275" y1="430" x2="275" y2="455" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 调研流程 -->
<rect x="450" y="455" width="180" height="50" rx="6" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="540" y="478" text-anchor="middle" fill="#fff" font-size="10">下发调研问卷</text>
<text x="540" y="493" text-anchor="middle" fill="#fff" font-size="9">et_train_ipdy</text>
<rect x="650" y="455" width="180" height="50" rx="6" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="740" y="478" text-anchor="middle" fill="#fff" font-size="10">部门反馈需求</text>
<text x="740" y="493" text-anchor="middle" fill="#fff" font-size="9">et_train_ipdy_kc</text>
<line x1="305" y1="480" x2="450" y2="480" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="630" y1="480" x2="650" y2="480" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 是/否标签 -->
<text x="315" y="470" fill="#22c55e" font-size="10"></text>
<text x="315" y="495" fill="#ef4444" font-size="10"></text>
<!-- 汇总生成 -->
<rect x="25" y="530" width="150" height="60" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="100" y="555" text-anchor="middle" fill="#fff" font-size="11">所级汇总生成</text>
<text x="100" y="570" text-anchor="middle" fill="#fff" font-size="9">et_train_ipf</text>
<line x1="245" y1="480" x2="100" y2="530" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="740" y1="505" x2="100" y2="505" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 审批子流程 -->
<rect x="200" y="615" width="700" height="80" rx="10" fill="#c8e6c9" stroke="#4caf50" stroke-width="2" stroke-dasharray="5,5"/>
<text x="550" y="645" text-anchor="middle" fill="#2e7d32" font-size="12" font-weight="bold">🔄 通用审批子流程 SUB-APPROVAL</text>
<text x="550" y="665" text-anchor="middle" fill="#666" font-size="10">部门领导审核 → 所级领导审批</text>
<text x="550" y="680" text-anchor="middle" fill="#666" font-size="9">et_train_sp</text>
<line x1="100" y1="590" x2="550" y2="615" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 审批结果网关 -->
<polygon points="550,720 580,745 550,770 520,745" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="550" y="750" text-anchor="middle" fill="#000" font-size="10">审批</text>
<text x="550" y="762" text-anchor="middle" fill="#000" font-size="10">结果?</text>
<line x1="550" y1="695" x2="550" y2="720" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 驳回路径 -->
<rect x="10" y="720" width="100" height="40" rx="6" fill="#fecaca" stroke="#ef4444" stroke-width="2"/>
<text x="60" y="745" text-anchor="middle" fill="#ef4444" font-size="10">驳回重编</text>
<line x1="520" y1="745" x2="110" y2="745" stroke="#ef4444" stroke-width="2" marker-end="url(#arrowhead-red)"/>
<path d="M 110 730 L 110 700 L 75 700" fill="none" stroke="#ef4444" stroke-width="2" marker-end="url(#arrowhead-red)"/>
<line x1="75" y1="700" x2="75" y2="335" stroke="#ef4444" stroke-width="2" marker-end="url(#arrowhead-red)"/>
<line x1="75" y1="335" x2="150" y2="335" stroke="#ef4444" stroke-width="2"/>
<!-- 通过路径 -->
<circle cx="550" cy="80" r="25" fill="#fecaca" stroke="#ef4444" stroke-width="3"/>
<circle cx="550" cy="80" r="15" fill="none" stroke="#ef4444" stroke-width="3"/>
<text x="550" y="85" text-anchor="middle" fill="#000" font-size="11">结束</text>
<line x1="580" y1="745" x2="550" y2="105" stroke="#22c55e" stroke-width="2" marker-end="url(#arrowhead-green)"/>
<path d="M 550 720 L 550 105" fill="none" stroke="#22c55e" stroke-width="2"/>
<text x="595" y="420" fill="#22c55e" font-size="10">通过</text>
</svg>
</div>
<!-- 流程节点详情 -->
<h3 style="margin: 30px 0 15px; color: #00d4ff;">📋 流程节点详情</h3>
<table class="node-table">
<thead>
<tr>
<th>节点ID</th>
<th>节点名称</th>
<th>类型</th>
<th>输入</th>
<th>输出</th>
<th>执行人</th>
</tr>
</thead>
<tbody>
<tr>
<td>PROC-TRAIN-PLAN.START</td>
<td>开始</td>
<td><span class="node-type type-start">开始事件</span></td>
<td>年度计划请求</td>
<td>-</td>
<td>所级管理员</td>
</tr>
<tr>
<td>PROC-TRAIN-PLAN.CREATE</td>
<td>创建计划</td>
<td><span class="node-type type-task">用户任务</span></td>
<td>计划类型</td>
<td>et_train_ip/gip/gop记录</td>
<td>所级管理员</td>
</tr>
<tr>
<td>PROC-TRAIN-PLAN.FILL</td>
<td>部门填报</td>
<td><span class="node-type type-subprocess">子流程</span></td>
<td>通知</td>
<td>et_train_gipgroup_kc</td>
<td>部门管理员</td>
</tr>
<tr>
<td>PROC-TRAIN-PLAN.SURVEY</td>
<td>调研征集</td>
<td><span class="node-type type-gateway">排他网关</span></td>
<td>-</td>
<td>et_train_ipdy</td>
<td>所级管理员</td>
</tr>
<tr>
<td>PROC-TRAIN-PLAN.SUMMARY</td>
<td>汇总生成</td>
<td><span class="node-type type-task">用户任务</span></td>
<td>部门需求</td>
<td>et_train_ipf</td>
<td>所级管理员</td>
</tr>
<tr>
<td>PROC-TRAIN-PLAN.APPROVE</td>
<td>审批流程</td>
<td><span class="node-type type-subprocess">子流程</span></td>
<td>计划ID</td>
<td>审批结果</td>
<td>领导层</td>
</tr>
<tr>
<td>PROC-TRAIN-PLAN.END</td>
<td>计划生效</td>
<td><span class="node-type type-end">结束事件</span></td>
<td>审批通过</td>
<td>状态变更</td>
<td>系统</td>
</tr>
</tbody>
</table>
</section>
<!-- 培训实施管理流程 -->
<section id="implement" class="process-card">
<h2><span class="icon">🎓</span> 培训实施管理流程 <span class="process-id">PROC-TRAIN-IMPLEMENT</span></h2>
<p class="process-desc">培训班级的创建、审核、学员管理、授课与效果评估</p>
<!-- 流程定义 -->
<div class="process-meta">
<div class="meta-item">
<div class="label">流程ID</div>
<div class="value">PROC-TRAIN-IMPLEMENT</div>
</div>
<div class="meta-item">
<div class="label">流程类型</div>
<div class="value">状态驱动流程</div>
</div>
<div class="meta-item">
<div class="label">触发方式</div>
<div class="value">计划批准后自动/手工创建</div>
</div>
<div class="meta-item">
<div class="label">流程周期</div>
<div class="value">单次培训(按班级)</div>
</div>
</div>
<!-- 参与者 -->
<div class="participants">
<h3>👥 参与者定义</h3>
<div class="participant-list">
<div class="participant">
<span>🎯</span>
<div>
<div class="role">所级管理员</div>
<div class="duty">开班审核、下发</div>
</div>
</div>
<div class="participant">
<span>👨‍🏫</span>
<div>
<div class="role">培训管理员</div>
<div class="duty">课程分配、学员管理</div>
</div>
</div>
<div class="participant">
<span>📖</span>
<div>
<div class="role">讲师</div>
<div class="duty">授课、签到</div>
</div>
</div>
<div class="participant">
<span>🎓</span>
<div>
<div class="role">学员</div>
<div class="duty">参训、反馈</div>
</div>
</div>
</div>
</div>
<!-- 状态机 -->
<h3 style="margin: 30px 0 15px; color: #00d4ff;">🔄 培训班级状态机</h3>
<div class="state-machine" style="display: flex; justify-content: center; align-items: center; flex-wrap: wrap; gap: 10px;">
<div class="state-box">
<div class="state-circle state-error">-1</div>
<div class="state-name">被驳回</div>
</div>
<span class="arrow"></span>
<div class="state-box">
<div class="state-circle state-value">0</div>
<div class="state-name">未开班</div>
</div>
<span class="arrow"></span>
<div class="state-box">
<div class="state-circle state-active">1</div>
<div class="state-name">已下发</div>
</div>
<span class="arrow"></span>
<div class="state-box">
<div class="state-circle state-active">2</div>
<div class="state-name">已开班</div>
</div>
<span class="arrow"></span>
<div class="state-box">
<div class="state-circle state-complete">3</div>
<div class="state-name">待审核</div>
</div>
<span class="arrow"></span>
<div class="state-box">
<div style="width:80px;height:80px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:#22c55e;color:#fff;font-weight:bold;"></div>
<div class="state-name">培训完成</div>
</div>
</div>
<!-- BPMN流程图 -->
<div class="bpmn-container">
<svg class="bpmn-svg" width="1100" height="650" viewBox="0 0 1100 650">
<rect width="100%" height="100%" fill="url(#grid)"/>
<!-- 泳道 -->
<rect x="0" y="0" width="180" height="650" fill="#e3f2fd" stroke="#90caf9" stroke-width="1"/>
<text x="90" y="30" text-anchor="middle" font-weight="bold" fill="#1565c0">管理员</text>
<rect x="180" y="0" width="200" height="650" fill="#fff3e0" stroke="#ffcc80" stroke-width="1"/>
<text x="280" y="30" text-anchor="middle" font-weight="bold" fill="#e65100">培训管理员</text>
<rect x="380" y="0" width="200" height="650" fill="#e8f5e9" stroke="#a5d6a7" stroke-width="1"/>
<text x="480" y="30" text-anchor="middle" font-weight="bold" fill="#2e7d32">讲师</text>
<rect x="580" y="0" width="520" height="650" fill="#fce4ec" stroke="#f48fb1" stroke-width="1"/>
<text x="840" y="30" text-anchor="middle" font-weight="bold" fill="#c2185b">学员/系统</text>
<!-- 开始 -->
<circle cx="90" cy="80" r="25" fill="#4ade80" stroke="#22c55e" stroke-width="3"/>
<text x="90" y="85" text-anchor="middle" fill="#000" font-size="12">开始</text>
<!-- 创建班级 -->
<rect x="15" y="130" width="150" height="60" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="90" y="155" text-anchor="middle" fill="#fff" font-size="11">创建培训班级</text>
<text x="90" y="172" text-anchor="middle" fill="#fff" font-size="9">status=0</text>
<line x1="90" y1="105" x2="90" y2="130" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 分配信息 -->
<rect x="195" y="130" width="170" height="80" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="280" y="155" text-anchor="middle" fill="#fff" font-size="10">设置培训信息</text>
<text x="280" y="170" text-anchor="middle" fill="#fff" font-size="9">• 选择讲师</text>
<text x="280" y="183" text-anchor="middle" fill="#fff" font-size="9">• 设置时间</text>
<text x="280" y="196" text-anchor="middle" fill="#fff" font-size="9">• 设置参数</text>
<line x1="165" y1="160" x2="195" y2="160" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 开班审核网关 -->
<polygon points="480,160 510,185 480,210 450,185" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="480" y="190" text-anchor="middle" fill="#000" font-size="10">审核</text>
<text x="480" y="202" text-anchor="middle" fill="#000" font-size="10">通过?</text>
<line x1="365" y1="170" x2="450" y2="170" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 驳回 -->
<rect x="320" y="235" width="100" height="35" rx="6" fill="#fecaca" stroke="#ef4444" stroke-width="2"/>
<text x="370" y="257" text-anchor="middle" fill="#ef4444" font-size="10">驳回修改</text>
<line x1="450" y1="185" x2="370" y2="235" stroke="#ef4444" stroke-width="2" marker-end="url(#arrowhead-red)"/>
<path d="M 370 235 L 370 200 L 165 200" fill="none" stroke="#ef4444" stroke-width="2"/>
<line x1="165" y1="200" x2="165" y2="160" stroke="#ef4444" stroke-width="2"/>
<text x="420" y="210" fill="#ef4444" font-size="9">驳回</text>
<!-- 下发 -->
<rect x="510" y="130" width="150" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="585" y="150" text-anchor="middle" fill="#fff" font-size="11">下发开班通知</text>
<text x="585" y="165" text-anchor="middle" fill="#fff" font-size="9">status=1</text>
<line x1="510" y1="185" x2="585" y2="180" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="520" y="175" fill="#22c55e" font-size="9">通过</text>
<!-- 学员管理 -->
<rect x="195" y="280" width="170" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="280" y="300" text-anchor="middle" fill="#fff" font-size="11">学员管理</text>
<text x="280" y="315" text-anchor="middle" fill="#fff" font-size="9">et_train_pd_cc_user</text>
<line x1="585" y1="155" x2="585" y2="100" stroke="#666" stroke-width="2"/>
<line x1="585" y1="100" x2="280" y2="100" stroke="#666" stroke-width="2"/>
<line x1="280" y1="100" x2="280" y2="280" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 签到网关 -->
<polygon points="480,295 510,320 480,345 450,320" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="480" y="325" text-anchor="middle" fill="#000" font-size="10">需要</text>
<text x="480" y="337" text-anchor="middle" fill="#000" font-size="10">签到?</text>
<line x1="365" y1="305" x2="450" y2="305" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 签到 -->
<rect x="395" y="365" width="170" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="480" y="385" text-anchor="middle" fill="#fff" font-size="11">签到管理</text>
<text x="480" y="400" text-anchor="middle" fill="#fff" font-size="9">et_train_pd_cc_dt</text>
<line x1="480" y1="345" x2="480" y2="365" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="490" y="335" fill="#22c55e" font-size="9"></text>
<!-- 授课 -->
<rect x="395" y="430" width="170" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="480" y="450" text-anchor="middle" fill="#fff" font-size="11">授课管理</text>
<text x="480" y="465" text-anchor="middle" fill="#fff" font-size="9">填写实际讲师</text>
<line x1="450" y1="320" x2="400" y2="400" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="480" y1="415" x2="480" y2="430" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="460" y="410" fill="#ef4444" font-size="9"></text>
<!-- 标记完成 -->
<rect x="590" y="430" width="150" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="665" y="450" text-anchor="middle" fill="#fff" font-size="11">标记开班完成</text>
<text x="665" y="465" text-anchor="middle" fill="#fff" font-size="9">status=2</text>
<line x1="565" y1="455" x2="590" y2="455" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 效果反馈网关 -->
<polygon points="850,455 880,480 850,505 820,480" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="850" y="485" text-anchor="middle" fill="#000" font-size="10">需要</text>
<text x="850" y="497" text-anchor="middle" fill="#000" font-size="10">考核?</text>
<line x1="740" y1="455" x2="820" y2="455" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 发布问卷 -->
<rect x="780" y="525" width="140" height="50" rx="8" fill="#a78bfa" stroke="#7c3aed" stroke-width="2"/>
<text x="850" y="545" text-anchor="middle" fill="#fff" font-size="11">发布评分问卷</text>
<text x="850" y="560" text-anchor="middle" fill="#fff" font-size="9">pgwjxxy.status=2</text>
<line x1="850" y1="505" x2="850" y2="525" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="865" y="495" fill="#22c55e" font-size="9"></text>
<!-- 归档 -->
<rect x="920" y="430" width="150" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="995" y="450" text-anchor="middle" fill="#fff" font-size="11">提交归档</text>
<text x="995" y="465" text-anchor="middle" fill="#fff" font-size="9">status=3</text>
<line x1="880" y1="480" x2="995" y2="480" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="900" y="470" fill="#ef4444" font-size="9"></text>
<!-- 结束 -->
<circle cx="90" cy="580" r="25" fill="#fecaca" stroke="#ef4444" stroke-width="3"/>
<circle cx="90" cy="580" r="15" fill="none" stroke="#ef4444" stroke-width="3"/>
<text x="90" y="585" text-anchor="middle" fill="#000" font-size="11">完成</text>
<!-- 完成连接 -->
<line x1="995" y1="455" x2="995" y2="520" stroke="#666" stroke-width="2"/>
<line x1="995" y1="520" x2="150" y2="520" stroke="#666" stroke-width="2"/>
<line x1="150" y1="520" x2="150" y2="600" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<path d="M 150 600 Q 120 600 115 580" fill="none" stroke="#666" stroke-width="2"/>
<line x1="115" y1="580" x2="90" y2="580" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
</svg>
</div>
<!-- 培训完成判定 -->
<h3 style="margin: 30px 0 15px; color: #00d4ff;">📊 培训完成判定规则</h3>
<div style="background: rgba(255,255,255,0.05); padding: 20px; border-radius: 10px; border-left: 4px solid #00d4ff;">
<p style="margin-bottom: 15px;"><strong>判定逻辑:</strong></p>
<pre style="background: rgba(0,0,0,0.3); padding: 15px; border-radius: 8px; overflow-x: auto; font-family: 'Consolas', monospace;">
IF (nd >= 2023) THEN
完成条件 = et_train_pd_cc_pgwjyxx.status = 2 (问卷/心得状态=已完成)
ELSE
完成条件 = IF(yxx.status IS NOT NULL, yxx.status=2, pg.status=1)
END IF
说明2023年起新增培训效果问卷反馈环节替代原有的评分机制</pre>
</div>
</section>
<!-- 考试管理流程 -->
<section id="exam" class="process-card">
<h2><span class="icon">📋</span> 考试管理流程 <span class="process-id">PROC-EXAM</span></h2>
<p class="process-desc">试卷管理、在线答题、自动/人工判卷全流程</p>
<!-- 流程定义 -->
<div class="process-meta">
<div class="meta-item">
<div class="label">流程ID</div>
<div class="value">PROC-EXAM</div>
</div>
<div class="meta-item">
<div class="label">流程类型</div>
<div class="value">定时触发 + 手工触发</div>
</div>
<div class="meta-item">
<div class="label">触发方式</div>
<div class="value">试卷发布后自动计时/手工</div>
</div>
<div class="meta-item">
<div class="label">流程周期</div>
<div class="value">按试卷设定的考试周期</div>
</div>
</div>
<!-- 参与者 -->
<div class="participants">
<h3>👥 参与者定义</h3>
<div class="participant-list">
<div class="participant">
<span>📝</span>
<div>
<div class="role">考试管理员</div>
<div class="duty">试卷创建、发布、管理</div>
</div>
</div>
<div class="participant">
<span>🎓</span>
<div>
<div class="role">考生</div>
<div class="duty">在线答题</div>
</div>
</div>
<div class="participant">
<span>✏️</span>
<div>
<div class="role">阅卷教师</div>
<div class="duty">主观题判分</div>
</div>
</div>
<div class="participant">
<span>⚙️</span>
<div>
<div class="role">系统</div>
<div class="duty">自动判分、状态切换</div>
</div>
</div>
</div>
</div>
<!-- 状态机 -->
<h3 style="margin: 30px 0 15px; color: #00d4ff;">🔄 考试状态机 (exampaper.state)</h3>
<div class="state-machine" style="display: flex; justify-content: center; align-items: center; flex-wrap: wrap; gap: 10px;">
<div class="state-box">
<div class="state-circle state-error">已撤销</div>
<div class="state-name">已撤销</div>
</div>
<span class="arrow"></span>
<div class="state-box">
<div class="state-circle state-value">未开始</div>
<div class="state-name">未开始</div>
<div style="font-size:0.7em;color:#888">datediff>0</div>
</div>
<span class="arrow"></span>
<div class="state-box">
<div class="state-circle state-active">进行中</div>
<div class="state-name">正在进行</div>
<div style="font-size:0.7em;color:#888">startdate≤0≤enddate</div>
</div>
<span class="arrow"></span>
<div class="state-box">
<div class="state-circle state-complete">已关闭</div>
<div class="state-name">已关闭</div>
<div style="font-size:0.7em;color:#888">datediff<0</div>
</div>
<span class="arrow"></span>
<div class="state-box">
<div class="state-circle state-complete" style="background:#9c27b0;">已归档</div>
<div class="state-name">已归档</div>
</div>
</div>
<!-- 判分规则 -->
<h3 style="margin: 30px 0 15px; color: #00d4ff;">✏️ 判分规则</h3>
<table class="node-table">
<thead>
<tr>
<th>题型</th>
<th>自动判分</th>
<th>人工判分</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>单选题</td>
<td><span style="color:#22c55e;">✅ 支持</span></td>
<td><span style="color:#ef4444;"></span></td>
<td>答案一致得分</td>
</tr>
<tr>
<td>多选题</td>
<td><span style="color:#22c55e;">✅ 支持</span></td>
<td><span style="color:#ef4444;"></span></td>
<td>答案一致得分</td>
</tr>
<tr>
<td>判断题</td>
<td><span style="color:#22c55e;">✅ 支持</span></td>
<td><span style="color:#ef4444;"></span></td>
<td>答案一致得分</td>
</tr>
<tr>
<td>简答题</td>
<td><span style="color:#ef4444;"></span></td>
<td><span style="color:#22c55e;">✅ 支持</span></td>
<td>需阅卷教师评分</td>
</tr>
</tbody>
</table>
<!-- BPMN流程图 -->
<div class="bpmn-container">
<svg class="bpmn-svg" width="1100" height="580" viewBox="0 0 1100 580">
<rect width="100%" height="100%" fill="url(#grid)"/>
<!-- 泳道 -->
<rect x="0" y="0" width="180" height="580" fill="#e3f2fd" stroke="#90caf9" stroke-width="1"/>
<text x="90" y="30" text-anchor="middle" font-weight="bold" fill="#1565c0">考试管理员</text>
<rect x="180" y="0" width="200" height="580" fill="#fce4ec" stroke="#f48fb1" stroke-width="1"/>
<text x="280" y="30" text-anchor="middle" font-weight="bold" fill="#c2185b">考生</text>
<rect x="380" y="0" width="180" height="580" fill="#fff3e0" stroke="#ffcc80" stroke-width="1"/>
<text x="470" y="30" text-anchor="middle" font-weight="bold" fill="#e65100">系统</text>
<rect x="560" y="0" width="180" height="580" fill="#e8f5e9" stroke="#a5d6a7" stroke-width="1"/>
<text x="650" y="30" text-anchor="middle" font-weight="bold" fill="#2e7d32">阅卷教师</text>
<rect x="740" y="0" width="360" height="580" fill="#f3e5f5" stroke="#ce93d8" stroke-width="1"/>
<text x="920" y="30" text-anchor="middle" font-weight="bold" fill="#7b1fa2">归档/发布</text>
<!-- 开始 -->
<circle cx="90" cy="80" r="25" fill="#4ade80" stroke="#22c55e" stroke-width="3"/>
<text x="90" y="85" text-anchor="middle" fill="#000" font-size="12">开始</text>
<!-- 创建试卷 -->
<rect x="15" y="130" width="150" height="60" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="90" y="155" text-anchor="middle" fill="#fff" font-size="11">创建试卷</text>
<text x="90" y="172" text-anchor="middle" fill="#fff" font-size="9">et_exam_exampaper</text>
<line x1="90" y1="105" x2="90" y2="130" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 添加题目 -->
<rect x="195" y="130" width="170" height="70" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="280" y="155" text-anchor="middle" fill="#fff" font-size="11">添加题目</text>
<text x="280" y="170" text-anchor="middle" fill="#fff" font-size="9">et_exam_editexampaper</text>
<text x="280" y="185" text-anchor="middle" fill="#fff" font-size="9">type/score/answer</text>
<line x1="165" y1="160" x2="195" y2="165" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 题型网关 -->
<polygon points="480,155 510,180 480,205 450,180" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="480" y="185" text-anchor="middle" fill="#000" font-size="10">题型?</text>
<line x1="365" y1="165" x2="450" y2="165" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 客观题 -->
<rect x="510" y="130" width="120" height="50" rx="6" fill="#4ade80" stroke="#22c55e" stroke-width="2"/>
<text x="570" y="155" text-anchor="middle" fill="#000" font-size="10">客观题</text>
<text x="570" y="168" text-anchor="middle" fill="#000" font-size="9">设标准答案</text>
<!-- 主观题 -->
<rect x="510" y="190" width="120" height="50" rx="6" fill="#f472b6" stroke="#ec4899" stroke-width="2"/>
<text x="570" y="215" text-anchor="middle" fill="#000" font-size="10">主观题</text>
<text x="570" y="228" text-anchor="middle" fill="#000" font-size="9">待人工判分</text>
<line x1="510" y1="180" x2="530" y2="155" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="510" y1="180" x2="530" y2="215" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="495" y="165" fill="#666" font-size="8">客观</text>
<text x="495" y="220" fill="#666" font-size="8">主观</text>
<!-- 人员限定 -->
<rect x="15" y="230" width="150" height="50" rx="8" fill="#a78bfa" stroke="#7c3aed" stroke-width="2"/>
<text x="90" y="250" text-anchor="middle" fill="#fff" font-size="10">人员限定</text>
<text x="90" y="265" text-anchor="middle" fill="#fff" font-size="9">et_exam_limitation</text>
<line x1="90" y1="190" x2="90" y2="230" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="90" y1="230" x2="165" y2="230" stroke="#666" stroke-width="2"/>
<line x1="165" y1="230" x2="165" y2="165" stroke="#666" stroke-width="2"/>
<line x1="165" y1="165" x2="195" y2="165" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 开始时间判断 -->
<polygon points="380,155 410,180 380,205 350,180" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="380" y="185" text-anchor="middle" fill="#000" font-size="10">开始</text>
<text x="380" y="197" text-anchor="middle" fill="#000" font-size="10">时间?</text>
<line x1="630" y1="180" x2="460" y2="180" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="395" y="170" fill="#22c55e" font-size="9"></text>
<!-- 考试进行中 -->
<rect x="430" y="130" width="120" height="45" rx="8" fill="#3b82f6" stroke="#2563eb" stroke-width="2"/>
<text x="490" y="157" text-anchor="middle" fill="#fff" font-size="11">考试进行中</text>
<!-- 循环等待 -->
<path d="M 430 152 L 410 152 L 410 180 L 380 180" fill="none" stroke="#666" stroke-width="2"/>
<text x="420" y="170" fill="#666" font-size="8"></text>
<!-- 考生答题 -->
<rect x="180" y="280" width="200" height="80" rx="8" fill="#f472b6" stroke="#ec4899" stroke-width="2"/>
<text x="280" y="305" text-anchor="middle" fill="#000" font-size="11">在线答题</text>
<text x="280" y="320" text-anchor="middle" fill="#000" font-size="9">et_exam_usertest</text>
<text x="280" y="335" text-anchor="middle" fill="#000" font-size="9">user_answer</text>
<line x1="490" y1="152" x2="490" y2="80" stroke="#666" stroke-width="2"/>
<line x1="490" y1="80" x2="280" y2="80" stroke="#666" stroke-width="2"/>
<line x1="280" y1="80" x2="280" y2="280" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 题目类型网关 -->
<polygon points="480,310 510,335 480,360 450,335" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="480" y="340" text-anchor="middle" fill="#000" font-size="10">题型?</text>
<line x1="380" y1="320" x2="450" y2="320" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 自动判分 -->
<rect x="430" y="380" width="100" height="45" rx="6" fill="#4ade80" stroke="#22c55e" stroke-width="2"/>
<text x="480" y="407" text-anchor="middle" fill="#000" font-size="10">自动判分</text>
<!-- 人工判分 -->
<rect x="560" y="380" width="100" height="45" rx="6" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="610" y="407" text-anchor="middle" fill="#000" font-size="10">人工判分</text>
<line x1="510" y1="335" x2="530" y2="380" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="510" y1="335" x2="620" y2="380" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="515" y="360" fill="#666" font-size="8">客观</text>
<text x="525" y="365" fill="#666" font-size="8"></text>
<text x="530" y="360" fill="#666" font-size="8">主观</text>
<text x="540" y="365" fill="#666" font-size="8"></text>
<!-- 全部提交判断 -->
<polygon points="850,310 880,335 850,360 820,335" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="850" y="340" text-anchor="middle" fill="#000" font-size="10">全部</text>
<text x="850" y="352" text-anchor="middle" fill="#000" font-size="10">提交?</text>
<line x1="530" y1="402" x2="560" y2="402" stroke="#666" stroke-width="2"/>
<line x1="660" y1="402" x2="750" y2="402" stroke="#666" stroke-width="2"/>
<line x1="750" y1="402" x2="750" y2="320" stroke="#666" stroke-width="2"/>
<line x1="750" y1="320" x2="880" y2="320" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 循环 -->
<path d="M 820 320 L 800 320 L 800 360 L 280 360 L 280 360" fill="none" stroke="#666" stroke-width="2"/>
<line x1="280" y1="360" x2="280" y2="320" stroke="#666" stroke-width="2"/>
<line x1="280" y1="320" x2="300" y2="320" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="600" y="390" fill="#ef4444" font-size="8"></text>
<text x="800" y="315" fill="#22c55e" font-size="8"></text>
<!-- 考试关闭 -->
<rect x="920" y="280" width="150" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="995" y="300" text-anchor="middle" fill="#fff" font-size="11">考试关闭</text>
<text x="995" y="315" text-anchor="middle" fill="#fff" font-size="9">state=已关闭</text>
<line x1="880" y1="335" x2="920" y2="305" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 成绩发布 -->
<rect x="920" y="380" width="150" height="50" rx="8" fill="#a78bfa" stroke="#7c3aed" stroke-width="2"/>
<text x="995" y="400" text-anchor="middle" fill="#fff" font-size="11">成绩发布</text>
<text x="995" y="415" text-anchor="middle" fill="#fff" font-size="9">user_score</text>
<line x1="995" y1="330" x2="995" y2="380" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 结束 -->
<circle cx="90" cy="520" r="25" fill="#fecaca" stroke="#ef4444" stroke-width="3"/>
<circle cx="90" cy="520" r="15" fill="none" stroke="#ef4444" stroke-width="3"/>
<text x="90" y="525" text-anchor="middle" fill="#000" font-size="11">完成</text>
<line x1="995" y1="405" x2="995" y2="480" stroke="#666" stroke-width="2"/>
<line x1="995" y1="480" x2="115" y2="480" stroke="#666" stroke-width="2"/>
<line x1="115" y1="480" x2="115" y2="520" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
</svg>
</div>
</section>
<!-- 外派培训管理流程 -->
<section id="outtrain" class="process-card">
<h2><span class="icon">🌐</span> 外派培训管理流程 <span class="process-id">PROC-OUTTRAIN</span></h2>
<p class="process-desc">外部培训申请、审批、归来登记与考核关联</p>
<!-- 流程定义 -->
<div class="process-meta">
<div class="meta-item">
<div class="label">流程ID</div>
<div class="value">PROC-OUTTRAIN</div>
</div>
<div class="meta-item">
<div class="label">流程类型</div>
<div class="value">审批流</div>
</div>
<div class="meta-item">
<div class="label">触发方式</div>
<div class="value">手工发起</div>
</div>
<div class="meta-item">
<div class="label">流程周期</div>
<div class="value">单次外派</div>
</div>
</div>
<!-- BPMN流程图 -->
<div class="bpmn-container">
<svg class="bpmn-svg" width="1100" height="480" viewBox="0 0 1100 480">
<rect width="100%" height="100%" fill="url(#grid)"/>
<!-- 泳道 -->
<rect x="0" y="0" width="200" height="480" fill="#e8f4fc" stroke="#b8d4e8" stroke-width="1"/>
<text x="100" y="30" text-anchor="middle" font-weight="bold" fill="#1976d2">申请人</text>
<rect x="200" y="0" width="250" height="480" fill="#fff3e0" stroke="#ffcc80" stroke-width="1"/>
<text x="325" y="30" text-anchor="middle" font-weight="bold" fill="#e65100">审批流程</text>
<rect x="450" y="0" width="250" height="480" fill="#e8f5e9" stroke="#a5d6a7" stroke-width="1"/>
<text x="575" y="30" text-anchor="middle" font-weight="bold" fill="#2e7d32">外派执行</text>
<rect x="700" y="0" width="400" height="480" fill="#fce4ec" stroke="#f48fb1" stroke-width="1"/>
<text x="900" y="30" text-anchor="middle" font-weight="bold" fill="#c2185b">归来登记</text>
<!-- 开始 -->
<circle cx="100" cy="80" r="25" fill="#4ade80" stroke="#22c55e" stroke-width="3"/>
<text x="100" y="85" text-anchor="middle" fill="#000" font-size="12">开始</text>
<!-- 填写申请 -->
<rect x="25" y="130" width="150" height="60" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="100" y="155" text-anchor="middle" fill="#fff" font-size="11">填写外派申请</text>
<text x="100" y="172" text-anchor="middle" fill="#fff" font-size="9">et_train_ot</text>
<line x1="100" y1="105" x2="100" y2="130" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 培训对象网关 -->
<polygon points="325,150 355,175 325,200 295,175" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="325" y="180" text-anchor="middle" fill="#000" font-size="10">培训</text>
<text x="325" y="192" text-anchor="middle" fill="#000" font-size="10">对象?</text>
<line x1="175" y1="160" x2="295" y2="160" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 本部门 -->
<rect x="25" y="230" width="150" height="50" rx="6" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="100" y="255" text-anchor="middle" fill="#fff" font-size="10">自动关联</text>
<text x="100" y="268" text-anchor="middle" fill="#fff" font-size="9">pxdjfw='0'</text>
<!-- 指定人员 -->
<rect x="200" y="230" width="150" height="50" rx="6" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="275" y="255" text-anchor="middle" fill="#fff" font-size="10">指定参训人员</text>
<text x="275" y="268" text-anchor="middle" fill="#fff" font-size="9">et_train_ot_xy</text>
<line x1="325" y1="175" x2="100" y2="230" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="355" y1="175" x2="275" y2="230" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="310" y="165" fill="#22c55e" font-size="9">本部门</text>
<text x="345" y="205" fill="#22c55e" font-size="9">指定</text>
<!-- 提交审批 -->
<rect x="200" y="320" width="150" height="50" rx="8" fill="#a78bfa" stroke="#7c3aed" stroke-width="2"/>
<text x="275" y="345" text-anchor="middle" fill="#fff" font-size="11">提交审批</text>
<line x1="100" y1="280" x2="100" y2="320" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="275" y1="280" x2="275" y2="320" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 审批结果网关 -->
<polygon points="575,335 605,360 575,385 545,360" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="575" y="365" text-anchor="middle" fill="#000" font-size="10">审批</text>
<text x="575" y="377" text-anchor="middle" fill="#000" font-size="10">结果?</text>
<line x1="350" y1="345" x2="545" y2="345" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 驳回 -->
<rect x="200" y="390" width="100" height="40" rx="6" fill="#fecaca" stroke="#ef4444" stroke-width="2"/>
<text x="250" y="415" text-anchor="middle" fill="#ef4444" font-size="10">驳回修改</text>
<line x1="545" y1="360" x2="250" y2="390" stroke="#ef4444" stroke-width="2" marker-end="url(#arrowhead-red)"/>
<path d="M 250 390 L 250 200 L 100 200" fill="none" stroke="#ef4444" stroke-width="2"/>
<line x1="100" y1="200" x2="100" y2="160" stroke="#ef4444" stroke-width="2"/>
<text x="400" y="355" fill="#ef4444" font-size="9">驳回</text>
<!-- 等待开始 -->
<rect x="500" y="280" width="150" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="575" y="300" text-anchor="middle" fill="#fff" font-size="11">等待外派开始</text>
<text x="575" y="315" text-anchor="middle" fill="#fff" font-size="9">pxstarttime</text>
<line x1="605" y1="360" x2="575" y2="330" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="600" y="350" fill="#22c55e" font-size="9">通过</text>
<!-- 外派进行中 -->
<rect x="500" y="410" width="150" height="50" rx="8" fill="#3b82f6" stroke="#2563eb" stroke-width="2"/>
<text x="575" y="435" text-anchor="middle" fill="#fff" font-size="11">外派培训中</text>
<!-- 归来 -->
<rect x="700" y="280" width="150" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="775" y="300" text-anchor="middle" fill="#fff" font-size="11">外派归来</text>
<text x="775" y="315" text-anchor="middle" fill="#fff" font-size="9">pxendtime到达</text>
<line x1="575" y1="460" x2="700" y2="460" stroke="#666" stroke-width="2"/>
<line x1="700" y1="460" x2="700" y2="330" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 外派登记 -->
<rect x="700" y="180" width="150" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="775" y="200" text-anchor="middle" fill="#fff" font-size="11">外派登记</text>
<text x="775" y="215" text-anchor="middle" fill="#fff" font-size="9">et_train_ot_pxdj</text>
<line x1="100" y1="160" x2="100" y2="80" stroke="#666" stroke-width="2"/>
<line x1="100" y1="80" x2="875" y2="80" stroke="#666" stroke-width="2"/>
<line x1="875" y1="80" x2="875" y2="180" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 经济责任制网关 -->
<polygon points="950,195 980,220 950,245 920,220" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="950" y="225" text-anchor="middle" fill="#000" font-size="10">单位</text>
<text x="950" y="237" text-anchor="middle" fill="#000" font-size="10">性质?</text>
<line x1="850" y1="205" x2="920" y2="205" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 经济责任制 -->
<rect x="850" y="280" width="150" height="50" rx="6" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="925" y="300" text-anchor="middle" fill="#fff" font-size="10">经济责任制</text>
<text x="925" y="315" text-anchor="middle" fill="#fff" font-size="9">关联考核</text>
<!-- 非经济责任制 -->
<rect x="850" y="360" width="150" height="50" rx="6" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="925" y="380" text-anchor="middle" fill="#fff" font-size="10">非经济责任制</text>
<text x="925" y="395" text-anchor="middle" fill="#fff" font-size="9">关联考核</text>
<line x1="950" y1="220" x2="925" y2="280" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="950" y1="220" x2="925" y2="360" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="960" y="210" fill="#22c55e" font-size="9">经济</text>
<text x="965" y="330" fill="#ef4444" font-size="9">非经济</text>
<!-- 结束 -->
<circle cx="925" cy="80" r="25" fill="#fecaca" stroke="#ef4444" stroke-width="3"/>
<circle cx="925" cy="80" r="15" fill="none" stroke="#ef4444" stroke-width="3"/>
<text x="925" y="85" text-anchor="middle" fill="#000" font-size="11">完成</text>
<line x1="925" y1="130" x2="925" y2="105" stroke="#666" stroke-width="2"/>
<line x1="925" y1="330" x2="925" y2="105" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="925" y1="410" x2="925" y2="105" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
</svg>
</div>
<!-- 关键数据表 -->
<h3 style="margin: 30px 0 15px; color: #00d4ff;">📊 关键数据表</h3>
<table class="node-table">
<thead>
<tr>
<th>表名</th>
<th>说明</th>
<th>关键字段</th>
</tr>
</thead>
<tbody>
<tr>
<td>et_train_ot</td>
<td>外派培训主表</td>
<td>pxmc, pxfy, sld, pxdjfw, status=5</td>
</tr>
<tr>
<td>et_train_ot_xy</td>
<td>外派学员表</td>
<td>usercode, username</td>
</tr>
<tr>
<td>et_train_ot_pxdj</td>
<td>外派登记表</td>
<td>status=4 (已完成登记)</td>
</tr>
</tbody>
</table>
</section>
<!-- 通用审批流程 -->
<section id="approval" class="process-card">
<h2><span class="icon"></span> 通用审批流程 <span class="process-id">SUB-APPROVAL</span></h2>
<p class="process-desc">被其他流程调用的通用多级审批子流程</p>
<!-- 流程定义 -->
<div class="process-meta">
<div class="meta-item">
<div class="label">子流程ID</div>
<div class="value">SUB-APPROVAL</div>
</div>
<div class="meta-item">
<div class="label">调用方式</div>
<div class="value">被主流程调用</div>
</div>
<div class="meta-item">
<div class="label">审批层级</div>
<div class="value">多级(可配置)</div>
</div>
</div>
<!-- BPMN流程图 -->
<div class="bpmn-container">
<svg class="bpmn-svg" width="900" height="400" viewBox="0 0 900 400">
<rect width="100%" height="100%" fill="url(#grid)"/>
<!-- 开始 -->
<circle cx="80" cy="80" r="25" fill="#4ade80" stroke="#22c55e" stroke-width="3"/>
<text x="80" y="85" text-anchor="middle" fill="#000" font-size="12">开始</text>
<!-- 获取审批人 -->
<rect x="20" y="130" width="120" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="80" y="150" text-anchor="middle" fill="#fff" font-size="10">获取审批人</text>
<text x="80" y="165" text-anchor="middle" fill="#fff" font-size="9">sp_person</text>
<line x1="80" y1="105" x2="80" y2="130" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 审批判断 -->
<polygon points="280,145 310,170 280,195 250,170" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="280" y="175" text-anchor="middle" fill="#000" font-size="10">还有未</text>
<text x="280" y="187" text-anchor="middle" fill="#000" font-size="10">审批项?</text>
<line x1="140" y1="155" x2="250" y2="155" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 审批人处理 -->
<rect x="330" y="130" width="120" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="390" y="150" text-anchor="middle" fill="#fff" font-size="10">当前审批人</text>
<text x="390" y="165" text-anchor="middle" fill="#fff" font-size="10">审批</text>
<line x1="310" y1="170" x2="330" y2="155" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 审批结果 -->
<polygon points="570,145 600,170 570,195 540,170" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="570" y="175" text-anchor="middle" fill="#000" font-size="10">审批</text>
<text x="570" y="187" text-anchor="middle" fill="#000" font-size="10">结果?</text>
<line x1="450" y1="155" x2="540" y2="155" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 驳回 -->
<rect x="490" y="230" width="100" height="40" rx="6" fill="#fecaca" stroke="#ef4444" stroke-width="2"/>
<text x="540" y="255" text-anchor="middle" fill="#ef4444" font-size="10">驳回</text>
<line x1="540" y1="195" x2="540" y2="230" stroke="#ef4444" stroke-width="2" marker-end="url(#arrowhead-red)"/>
<text x="550" y="215" fill="#ef4444" font-size="9">驳回</text>
<!-- 驳回结束 -->
<circle cx="540" cy="320" r="25" fill="#fecaca" stroke="#ef4444" stroke-width="3"/>
<circle cx="540" cy="320" r="15" fill="none" stroke="#ef4444" stroke-width="3"/>
<text x="540" y="325" text-anchor="middle" fill="#000" font-size="10">结束</text>
<line x1="540" y1="270" x2="540" y2="295" stroke="#ef4444" stroke-width="2" marker-end="url(#arrowhead-red)"/>
<!-- 下一级判断 -->
<polygon points="720,145 750,170 720,195 690,170" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="720" y="175" text-anchor="middle" fill="#000" font-size="10">还有</text>
<text x="720" y="187" text-anchor="middle" fill="#000" font-size="10">下一级?</text>
<line x1="600" y1="170" x2="690" y2="170" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="610" y="163" fill="#22c55e" font-size="9">通过</text>
<!-- 流转 -->
<rect x="650" y="230" width="100" height="40" rx="6" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="700" y="255" text-anchor="middle" fill="#fff" font-size="10">流转下一级</text>
<line x1="720" y1="195" x2="700" y2="230" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="700" y1="270" x2="310" y2="270" stroke="#666" stroke-width="2"/>
<line x1="310" y1="270" x2="310" y2="195" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="720" y="215" fill="#22c55e" font-size="9"></text>
<!-- 全部通过 -->
<rect x="750" y="230" width="100" height="40" rx="6" fill="#4ade80" stroke="#22c55e" stroke-width="2"/>
<text x="800" y="255" text-anchor="middle" fill="#000" font-size="10">审批通过</text>
<line x1="750" y1="170" x2="800" y2="230" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="755" y="210" fill="#ef4444" font-size="9"></text>
<!-- 通过结束 -->
<circle cx="800" cy="320" r="25" fill="#4ade80" stroke="#22c55e" stroke-width="3"/>
<text x="800" y="325" text-anchor="middle" fill="#000" font-size="10">结束</text>
<line x1="800" y1="270" x2="800" y2="295" stroke="#666" stroke-width="2" marker-end="url(#arrowhead-green)"/>
<!-- 数据存储表 -->
<rect x="100" y="320" width="650" height="60" rx="10" fill="#fff" stroke="#666" stroke-width="1" stroke-dasharray="5,5"/>
<text x="425" y="345" text-anchor="middle" fill="#333" font-size="11" font-weight="bold">et_train_sp 数据存储</text>
<text x="425" y="365" text-anchor="middle" fill="#666" font-size="10">tname(表名) | tid(记录ID) | spusername(审批人) | spdate(审批时间) | yj(意见) | spresult(结果)</text>
</svg>
</div>
<!-- 审批数据表 -->
<h3 style="margin: 30px 0 15px; color: #00d4ff;">📊 审批数据存储 (et_train_sp)</h3>
<table class="node-table">
<thead>
<tr>
<th>字段</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>tname</td>
<td>目标业务表名</td>
</tr>
<tr>
<td>tid</td>
<td>目标业务记录ID</td>
</tr>
<tr>
<td>spusername</td>
<td>审批人姓名</td>
</tr>
<tr>
<td>spdate</td>
<td>审批时间</td>
</tr>
<tr>
<td>yj</td>
<td>审批意见</td>
</tr>
<tr>
<td>spresult</td>
<td>审批结果 (通过/驳回)</td>
</tr>
</tbody>
</table>
</section>
<!-- 年度总结流程 -->
<section id="summary" class="process-card">
<h2><span class="icon">📈</span> 年度培训总结流程 <span class="process-id">PROC-YEAR-SUMMARY</span></h2>
<p class="process-desc">年度培训数据汇总、报告生成流程</p>
<!-- 流程定义 -->
<div class="process-meta">
<div class="meta-item">
<div class="label">流程ID</div>
<div class="value">PROC-YEAR-SUMMARY</div>
</div>
<div class="meta-item">
<div class="label">触发方式</div>
<div class="value">年度结束12月</div>
</div>
<div class="meta-item">
<div class="label">流程周期</div>
<div class="value">年度</div>
</div>
</div>
<!-- BPMN流程图 -->
<div class="bpmn-container">
<svg class="bpmn-svg" width="900" height="380" viewBox="0 0 900 380">
<rect width="100%" height="100%" fill="url(#grid)"/>
<!-- 泳道 -->
<rect x="0" y="0" width="200" height="380" fill="#e8f4fc" stroke="#b8d4e8" stroke-width="1"/>
<text x="100" y="30" text-anchor="middle" font-weight="bold" fill="#1976d2">所级管理员</text>
<rect x="200" y="0" width="250" height="380" fill="#fff3e0" stroke="#ffcc80" stroke-width="1"/>
<text x="325" y="30" text-anchor="middle" font-weight="bold" fill="#e65100">部门管理员</text>
<rect x="450" y="0" width="450" height="380" fill="#e8f5e9" stroke="#a5d6a7" stroke-width="1"/>
<text x="675" y="30" text-anchor="middle" font-weight="bold" fill="#2e7d32">汇总分析</text>
<!-- 开始 -->
<circle cx="100" cy="80" r="25" fill="#4ade80" stroke="#22c55e" stroke-width="3"/>
<text x="100" y="85" text-anchor="middle" fill="#000" font-size="12">开始</text>
<!-- 创建年度总结 -->
<rect x="25" y="130" width="150" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="100" y="155" text-anchor="middle" fill="#fff" font-size="11">创建年度总结</text>
<text x="100" y="170" text-anchor="middle" fill="#fff" font-size="9">et_train_ys</text>
<line x1="100" y1="105" x2="100" y2="130" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 下发通知 -->
<rect x="25" y="210" width="150" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="100" y="235" text-anchor="middle" fill="#fff" font-size="11">下发填报通知</text>
<line x1="100" y1="180" x2="100" y2="210" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 部门填报 -->
<rect x="200" y="130" width="250" height="80" rx="8" fill="#a78bfa" stroke="#7c3aed" stroke-width="2"/>
<text x="325" y="160" text-anchor="middle" fill="#fff" font-size="11">部门填报年度总结</text>
<text x="325" y="178" text-anchor="middle" fill="#fff" font-size="9">et_train_ysgroup</text>
<text x="325" y="193" text-anchor="middle" fill="#fff" font-size="9">status=待填报</text>
<line x1="100" y1="235" x2="200" y2="235" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<line x1="200" y1="170" x2="200" y2="235" stroke="#666" stroke-width="2"/>
<!-- 提交部门总结 -->
<rect x="200" y="280" width="120" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="260" y="305" text-anchor="middle" fill="#fff" font-size="11">提交总结</text>
<line x1="325" y1="210" x2="325" y2="280" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 状态更新 -->
<rect x="340" y="280" width="110" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="395" y="305" text-anchor="middle" fill="#fff" font-size="11">状态更新</text>
<text x="395" y="318" text-anchor="middle" fill="#fff" font-size="9">status=3</text>
<line x1="320" y1="305" x2="340" y2="305" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 所级汇总 -->
<rect x="470" y="130" width="180" height="70" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="560" y="155" text-anchor="middle" fill="#fff" font-size="11">所级管理员汇总</text>
<text x="560" y="173" text-anchor="middle" fill="#fff" font-size="9">合并各部门数据</text>
<text x="560" y="188" text-anchor="middle" fill="#fff" font-size="9">生成统计报表</text>
<line x1="395" y1="280" x2="560" y2="200" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 数据完整判断 -->
<polygon points="770,155 800,180 770,205 740,180" fill="#fbbf24" stroke="#f59e0b" stroke-width="2"/>
<text x="770" y="185" text-anchor="middle" fill="#000" font-size="10">数据</text>
<text x="770" y="197" text-anchor="middle" fill="#000" font-size="10">完整?</text>
<line x1="650" y1="165" x2="740" y2="165" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 返回补充 -->
<rect x="470" y="250" width="100" height="40" rx="6" fill="#fecaca" stroke="#ef4444" stroke-width="2"/>
<text x="520" y="275" text-anchor="middle" fill="#ef4444" font-size="10">返回补充</text>
<line x1="770" y1="180" x2="520" y2="250" stroke="#ef4444" stroke-width="2" marker-end="url(#arrowhead-red)"/>
<path d="M 520 250 L 520 200 L 325 200" fill="none" stroke="#ef4444" stroke-width="2"/>
<line x1="325" y1="200" x2="325" y2="155" stroke="#ef4444" stroke-width="2" marker-end="url(#arrowhead-red)"/>
<text x="620" y="170" fill="#ef4444" font-size="9"></text>
<text x="640" y="215" fill="#22c55e" font-size="9"></text>
<!-- 生成报告 -->
<rect x="800" y="130" width="80" height="50" rx="8" fill="#60a5fa" stroke="#3b82f6" stroke-width="2"/>
<text x="840" y="155" text-anchor="middle" fill="#fff" font-size="10">生成</text>
<text x="840" y="168" text-anchor="middle" fill="#fff" font-size="10">报告</text>
<line x1="800" y1="180" x2="840" y2="180" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- 结束 -->
<circle cx="840" cy="280" r="25" fill="#fecaca" stroke="#ef4444" stroke-width="3"/>
<circle cx="840" cy="280" r="15" fill="none" stroke="#ef4444" stroke-width="3"/>
<text x="840" y="285" text-anchor="middle" fill="#000" font-size="11">完成</text>
<line x1="840" y1="180" x2="840" y2="255" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
</svg>
</div>
</section>
<!-- 流程总览表格 -->
<section class="process-card">
<h2><span class="icon">📊</span> 流程模型总览</h2>
<table class="node-table">
<thead>
<tr>
<th>流程ID</th>
<th>流程名称</th>
<th>类型</th>
<th>触发方式</th>
<th>关联主表</th>
</tr>
</thead>
<tbody>
<tr>
<td>PROC-TRAIN-PLAN</td>
<td>培训计划管理</td>
<td><span class="node-type" style="background:#fbbf24;color:#000;">审批流</span></td>
<td>手工触发</td>
<td>et_train_ip / et_train_gip</td>
</tr>
<tr>
<td>PROC-TRAIN-IMPLEMENT</td>
<td>培训实施管理</td>
<td><span class="node-type" style="background:#3b82f6;color:#fff;">状态流</span></td>
<td>计划批准后</td>
<td>et_train_pd_cc</td>
</tr>
<tr>
<td>PROC-EXAM</td>
<td>考试管理</td>
<td><span class="node-type" style="background:#f97316;color:#fff;">定时流</span></td>
<td>试卷发布</td>
<td>et_exam_exampaper</td>
</tr>
<tr>
<td>PROC-OUTTRAIN</td>
<td>外派培训</td>
<td><span class="node-type" style="background:#fbbf24;color:#000;">审批流</span></td>
<td>手工发起</td>
<td>et_train_ot</td>
</tr>
<tr>
<td>SUB-APPROVAL</td>
<td>通用审批</td>
<td><span class="node-type" style="background:#a78bfa;color:#fff;">子流程</span></td>
<td>被调用</td>
<td>et_train_sp</td>
</tr>
<tr>
<td>PROC-YEAR-SUMMARY</td>
<td>年度总结</td>
<td><span class="node-type" style="background:#22c55e;color:#000;">填报流</span></td>
<td>年度结束</td>
<td>et_train_ys</td>
</tr>
</tbody>
</table>
</section>
<!-- 页脚 -->
<div class="footer">
<p>JCDP 教育培训管理系统 - BPMN业务流程模型</p>
<p>文档版本: v1.0 | 生成时间: 2026-04-16 | 中国电子科技集团第五十四研究所</p>
</div>
</div>
<script>
// 平滑滚动
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// 高亮当前导航
const sections = document.querySelectorAll('section[id]');
const navLinks = document.querySelectorAll('.nav a');
window.addEventListener('scroll', () => {
let current = '';
sections.forEach(section => {
const sectionTop = section.offsetTop;
const sectionHeight = section.clientHeight;
if (scrollY >= sectionTop - 200) {
current = section.getAttribute('id');
}
});
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === '#' + current) {
link.classList.add('active');
}
});
});
</script>
</body>
</html>