#!/usr/bin/env python3 """ 为用户交流技术实现方案.md中的架构图生成SVG并转为JPG """ import os import subprocess OUTPUT_DIR = os.path.join(os.path.dirname(__file__), "images") os.makedirs(OUTPUT_DIR, exist_ok=True) # ─── 颜色方案 ─── C_BG = "#ffffff" C_TITLE = "#1a1a2e" C_LAYER1 = "#e3f2fd" # 浅蓝 C_LAYER1_B = "#1565c0" C_LAYER2 = "#e8f5e9" # 浅绿 C_LAYER2_B = "#2e7d32" C_LAYER3 = "#fff3e0" # 浅橙 C_LAYER3_B = "#e65100" C_LAYER4 = "#f3e5f5" # 浅紫 C_LAYER4_B = "#6a1b9a" C_LAYER5 = "#fce4ec" # 浅粉 C_LAYER5_B = "#c62828" C_LAYER6 = "#e0f7fa" # 浅青 C_LAYER6_B = "#00838f" C_BOX = "#f5f5f5" C_BOX_B = "#616161" C_ARROW = "#424242" C_HIGHLIGHT = "#ffd54f" C_AI = "#e8eaf6" C_AI_B = "#283593" C_VR = "#ede7f6" C_VR_B = "#4527a0" C_SECURITY = "#ffebee" C_SECURITY_B = "#b71c1c" C_DEPLOY = "#e0f2f1" C_DEPLOY_B = "#00695c" FONT = "Microsoft YaHei, PingFang SC, Heiti SC, SimHei, sans-serif" def svg_header(w, h): return f'' def svg_text(x, y, text, size=14, color=C_TITLE, bold=False, anchor="middle", font=FONT): weight = "bold" if bold else "normal" return f'{text}' def svg_rect(x, y, w, h, fill=C_BOX, stroke=C_BOX_B, rx=8, sw=1.5, opacity=1.0): return f'' def svg_box(x, y, w, h, text, fill=C_BOX, stroke=C_BOX_B, ts=13, tc=C_TITLE, bold=False, rx=8): cx = x + w/2 cy = y + h/2 return svg_rect(x, y, w, h, fill, stroke, rx) + svg_text(cx, cy, text, ts, tc, bold) import math as _math def svg_arrow(x1, y1, x2, y2, color=C_ARROW, sw=2, al=14, aw=0.55): """绘制带箭头的线段。箭头在(x2,y2)端。 al: 箭头长度, aw: 箭头半角(弧度) """ angle = _math.atan2(y2-y1, x2-x1) # 箭头三角形的两个底点 bx = x2 - al * _math.cos(angle) by = y2 - al * _math.sin(angle) ax1 = bx + al * _math.sin(angle) * _math.tan(aw) ay1 = by - al * _math.cos(angle) * _math.tan(aw) ax2 = bx - al * _math.sin(angle) * _math.tan(aw) ay2 = by + al * _math.cos(angle) * _math.tan(aw) # 线段缩短到箭头底部 return (f'' f'') def svg_line(x1, y1, x2, y2, color=C_ARROW, sw=1.5, dash=None): d = f' stroke-dasharray="{dash}"' if dash else '' return f'' def svg_arrow_dashed(x1, y1, x2, y2, color=C_ARROW, sw=1.5, dash='6,4', al=12, aw=0.5): """绘制带箭头的虚线段。""" angle = _math.atan2(y2-y1, x2-x1) bx = x2 - al * _math.cos(angle) by = y2 - al * _math.sin(angle) ax1 = bx + al * _math.sin(angle) * _math.tan(aw) ay1 = by - al * _math.cos(angle) * _math.tan(aw) ax2 = bx - al * _math.sin(angle) * _math.tan(aw) ay2 = by + al * _math.cos(angle) * _math.tan(aw) return (f'' f'') def svg_arrow_down(cx, y1, y2, color=C_ARROW, sw=2, al=14): """绘制垂直向下的箭头。""" return svg_arrow(cx, y1, cx, y2, color, sw, al) def svg_h_branch(x1, y1, x2_left, x2_right, y2, color=C_ARROW, sw=2): """从(x1,y1)向下到y2,然后水平分叉到x2_left和x2_right,各带箭头。""" s = f'' s += f'' s += svg_arrow(x2_left, y2, x2_left, y2+18, color, sw) s += svg_arrow(x2_right, y2, x2_right, y2+18, color, sw) return s def save_svg_and_jpg(svg_content, name): svg_path = os.path.join(OUTPUT_DIR, f"{name}.svg") png_path = os.path.join(OUTPUT_DIR, f"{name}.png") jpg_path = os.path.join(OUTPUT_DIR, f"{name}.jpg") if not svg_content.rstrip().endswith(""): svg_content += "\n" with open(svg_path, "w", encoding="utf-8") as f: f.write(svg_content) # SVG → PNG (rsvg-convert支持中文字体) result = subprocess.run( ["/usr/local/bin/rsvg-convert", "-d", "200", "-p", "200", "-f", "png", "-o", png_path, svg_path], capture_output=True, text=True ) if result.returncode != 0: print(f" ✗ {name} rsvg-convert失败: {result.stderr[:200]}") return # PNG → JPG (sips是macOS自带工具) result2 = subprocess.run( ["sips", "-s", "format", "jpeg", "-s", "formatOptions", "95", png_path, "--out", jpg_path], capture_output=True, text=True ) if result2.returncode != 0: print(f" ✗ {name} sips失败: {result2.stderr[:200]}") return os.remove(png_path) print(f" ✓ {name}.jpg") # ═══════════════════════════════════════════════════════════════ # 图1: 六层技术架构 # ═══════════════════════════════════════════════════════════════ def gen_01_six_layer(): W, H = 900, 620 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "六层技术架构", 22, C_TITLE, True) layers = [ ("用户触达层", "线下终端(触屏/VR/环幕/UWB/RFID) | 线上(Web/小程序/H5) | 节点终端", C_LAYER1, C_LAYER1_B), ("应用服务层", "F1自适应叙事 F2情境任务 F3文物数字生命 F4成长护照 F5云上共同体 F6青年共创 F7行动实验室 F8星火节点", C_LAYER2, C_LAYER2_B), ("公共平台层", "X1体验编排引擎 X2成长护照档案 X3内容治理中心 S9节点协同", C_LAYER3, C_LAYER3_B), ("AI能力层", "可信叙事引擎 学习成长引擎 编审助手引擎 策展助手引擎", C_LAYER4, C_LAYER4_B), ("数据资产层", "知识图谱 向量检索库 内容资源仓 业务数据库 时序分析库 实时缓存 消息总线", C_LAYER5, C_LAYER5_B), ("基础设施层", "私有云容器编排 GPU推理集群 5G专网 IoT网关 CDN 安防网络", C_LAYER6, C_LAYER6_B), ] y = 60 lh = 80 for i, (title, content, fill, stroke) in enumerate(layers): s += svg_rect(40, y, W-80, lh-10, fill, stroke, 10, 2) s += svg_text(130, y+22, title, 15, stroke, True) s += svg_text(W/2, y+50, content, 12, "#333") if i < len(layers) - 1: s += svg_arrow_down(W/2, y+lh-12, y+lh, "#bbb", 1.5, 8) y += lh save_svg_and_jpg(s, "01_six_layer_architecture") # ═══════════════════════════════════════════════════════════════ # 图2: 系统部署拓扑 # ═══════════════════════════════════════════════════════════════ def gen_02_deployment(): W, H = 880, 560 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "系统部署拓扑", 22, C_TITLE, True) # 公网入口 s += svg_box(300, 60, 280, 50, "公网入口 WAF + 负载均衡", C_SECURITY, C_SECURITY_B, 13, C_SECURITY_B, True) # 分叉到两个区域 — 用h_branch s += svg_h_branch(W/2, 110, 180, 700, 155, C_ARROW, 2) # 线上云区 s += svg_box(60, 175, 240, 160, "", C_LAYER1, C_LAYER1_B, 13, C_LAYER1_B, True, 10) s += svg_text(180, 200, "线上云区 (公有云)", 14, C_LAYER1_B, True) s += svg_text(180, 230, "Web/小程序", 12, "#333") s += svg_text(180, 255, "API网关", 12, "#333") s += svg_text(180, 280, "CDN节点", 12, "#333") s += svg_text(180, 305, "港澳加速", 12, "#333") # 线下场馆区 s += svg_box(580, 175, 240, 160, "", C_LAYER2, C_LAYER2_B, 13, C_LAYER2_B, True, 10) s += svg_text(700, 200, "线下场馆区 (私有云)", 14, C_LAYER2_B, True) s += svg_text(700, 230, "AI推理GPU集群", 12, "#333") s += svg_text(700, 255, "容器集群", 12, "#333") s += svg_text(700, 280, "数据库集群", 12, "#333") s += svg_text(700, 305, "知识图谱+向量库", 12, "#333") # VPN连线 — 双向虚线箭头 s += svg_arrow_dashed(300, 255, 580, 255, "#888", 1.5, "6,4") s += svg_arrow_dashed(580, 255, 300, 255, "#888", 1.5, "6,4") s += svg_text(440, 245, "VPN专线互联", 11, "#888") # 设备区 — 从线下场馆区底部出发 s += svg_box(350, 380, 200, 60, "IoT/安防/VR\n设备网络 (VLAN隔离)", C_LAYER6, C_LAYER6_B, 12, C_LAYER6_B, True) s += svg_arrow(700, 335, 550, 380, C_ARROW, 2) # 全国节点 — 从线上云区底部出发 s += svg_box(60, 380, 240, 60, "全国星火节点\n(远程组件包分发)", C_LAYER3, C_LAYER3_B, 12, C_LAYER3_B, True) s += svg_arrow(180, 335, 180, 380, C_ARROW, 2) s += svg_text(W/2, 490, "AI推理+核心数据部署在场馆私有云,保证安全与低延迟", 12, "#666") s += svg_text(W/2, 515, "Web/小程序/云展馆部署在公有云,CDN加速港澳访问", 12, "#666") s += svg_text(W/2, 540, "全国节点通过S9节点协同系统远程部署,断网不失能", 12, "#666") save_svg_and_jpg(s, "02_deployment_topology") # ═══════════════════════════════════════════════════════════════ # 图3: AI可信知识引擎架构 # ═══════════════════════════════════════════════════════════════ def gen_03_ai_engine(): W, H = 860, 580 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "AI可信知识引擎架构", 22, C_TITLE, True) # 外框 s += svg_rect(30, 55, W-60, 490, "#fafafa", C_AI_B, 12, 2) # 三列 cols = [ ("知识图谱", "事件/人物/文物/\n概念/地点及关系\n\n史实锚点\n\n交叉验证", C_LAYER4, C_LAYER4_B), ("RAG检索增强", "用户提问\n → 语义检索\n → 召回史料\n → 生成回答\n\n读史料后回答\n非凭记忆回答", C_LAYER1, C_LAYER1_B), ("大模型微调", "延安精神\n专属语料\n → LoRA微调\n → 人群适配\n\n懂延安·懂党史·懂教育", C_LAYER3, C_LAYER3_B), ] cw = 230 gap = 20 x0 = 50 for i, (title, content, fill, stroke) in enumerate(cols): x = x0 + i * (cw + gap) s += svg_rect(x, 80, cw, 280, fill, stroke, 10, 2) s += svg_text(x + cw/2, 110, title, 16, stroke, True) for j, line in enumerate(content.split("\n")): s += svg_text(x + cw/2, 145 + j*22, line, 12, "#333") if i < 2: s += svg_arrow(x + cw, 220, x + cw + gap, 220, "#999", 2, 12) # 汇聚箭头 s += svg_arrow_down(W/2, 360, 380, "#999", 2) # 安全护栏 s += svg_rect(150, 380, W-300, 140, C_SECURITY, C_SECURITY_B, 10, 2) s += svg_text(W/2, 410, "安全护栏层", 15, C_SECURITY_B, True) steps = ["输入过滤", "事实校验", "输出过滤", "审计追溯"] for i, step in enumerate(steps): sx = 200 + i * 130 s += svg_rect(sx, 430, 110, 35, "#fff", C_SECURITY_B, 6, 1.5) s += svg_text(sx + 55, 448, step, 12, C_SECURITY_B, True) if i < 3: s += svg_arrow(sx + 110, 448, sx + 130, 448, C_SECURITY_B, 2, 10) save_svg_and_jpg(s, "03_ai_knowledge_engine") # ═══════════════════════════════════════════════════════════════ # 图4: 可信叙事引擎 # ═══════════════════════════════════════════════════════════════ def gen_04_narrative_engine(): W, H = 860, 480 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "可信叙事引擎", 22, C_TITLE, True) s += svg_rect(30, 55, W-60, 400, "#fafafa", C_LAYER3_B, 12, 2) # 内容组件仓库 s += svg_rect(50, 80, 320, 220, C_LAYER3, C_LAYER3_B, 10, 2) s += svg_text(210, 110, "内容组件仓库", 15, C_LAYER3_B, True) items = ["已审核的文字片段", "影像素材", "3D模型", "互动任务", "AI讲解词", "每个组件标注: 适用人群/时长/审核状态"] for i, item in enumerate(items): s += svg_text(210, 140 + i*25, item, 12, "#333") # 箭头 — 从内容仓库到叙事算法 s += svg_arrow(370, 190, 440, 190, C_ARROW, 2, 14) # 叙事路线算法 s += svg_rect(440, 80, 360, 220, C_LAYER1, C_LAYER1_B, 10, 2) s += svg_text(620, 110, "叙事路线算法", 15, C_LAYER1_B, True) inputs = ["输入: 人群类型 + 学习问题", " 可用时长 + 语言偏好", " 实时客流状态"] s += svg_text(620, 145, inputs[0], 12, "#333") s += svg_text(620, 170, inputs[1], 12, "#333") s += svg_text(620, 195, inputs[2], 12, "#333") s += svg_text(620, 225, "输出: 节点序列 + 每节点内容", 12, C_LAYER1_B, True) s += svg_text(620, 250, " 适配方案 + 时长估算", 12, C_LAYER1_B, True) # 底部原则 s += svg_rect(50, 330, W-100, 50, C_HIGHLIGHT, "#f57f17", 8, 2) s += svg_text(W/2, 355, "关键原则: 不生成新内容,只编排已审核组件 — 像乐高积木一样编排", 13, "#e65100", True) s += svg_text(W/2, 420, "同一空间千人千面: 小学生看动画+游戏 | 党员干部看文献+分析 | 港澳青年看繁体+湾区视角", 12, "#666") save_svg_and_jpg(s, "04_narrative_engine") # ═══════════════════════════════════════════════════════════════ # 图5: 学习成长引擎 # ═══════════════════════════════════════════════════════════════ def gen_05_growth_engine(): W, H = 860, 420 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "学习成长引擎", 22, C_TITLE, True) # 三个阶段 stages = [ ("参观前导学", ["人群选择", "问题选择", "路线生成", "导学推送"], C_LAYER1, C_LAYER1_B), ("参观中记录", ["UWB自动记录位置", "任务完成记录", "AI问答记录", "理解表达记录"], C_LAYER2, C_LAYER2_B), ("离馆后回访", ["第7天回顾推送", "第30天进展反馈", "第90天成果提交", "行动评估+案例入库"], C_LAYER3, C_LAYER3_B), ] sw = 240 gap = 20 x0 = 40 for i, (title, items, fill, stroke) in enumerate(stages): x = x0 + i * (sw + gap) s += svg_rect(x, 60, sw, 220, fill, stroke, 10, 2) s += svg_text(x + sw/2, 90, title, 15, stroke, True) for j, item in enumerate(items): s += svg_text(x + sw/2, 125 + j*30, item, 12, "#333") if i < 2: s += svg_arrow(x + sw, 170, x + sw + gap, 170, "#999", 2, 14) # 统一档案 s += svg_arrow_down(W/2, 280, 310, "#999", 2) s += svg_rect(120, 310, W-240, 60, C_LAYER4, C_LAYER4_B, 10, 2) s += svg_text(W/2, 332, "统一成长档案 (X2护照)", 15, C_LAYER4_B, True) s += svg_text(W/2, 352, "跨系统同步 · 全程陪伴 · 闭环追踪 · 北极星指标可计算", 12, "#333") save_svg_and_jpg(s, "05_growth_engine") # ═══════════════════════════════════════════════════════════════ # 图6: 复制运营引擎 # ═══════════════════════════════════════════════════════════════ def gen_06_replication_engine(): W, H = 860, 520 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "复制运营引擎", 22, C_TITLE, True) # 旗舰中心 s += svg_rect(180, 60, 500, 100, C_LAYER5, C_LAYER5_B, 10, 2) s += svg_text(W/2, 90, "L4 旗舰中心 (13000㎡)", 15, C_LAYER5_B, True) s += svg_text(W/2, 115, "权威内容生产 → 组件包打包 → 版本发布", 12, "#333") s += svg_text(W/2, 138, "全国节点调度 → 远程监控 → 数据回收", 12, "#333") # 分发线 — 从旗舰中心向下到水平分发线 s += svg_line(W/2, 160, W/2, 180, C_ARROW, 2) s += svg_text(W/2 + 55, 175, "组件包分发", 10, "#999") s += svg_line(130, 180, 730, 180, C_ARROW, 2) # 四级节点 nodes = [ ("L1 微节点", "一体机\n即开即用\n定期WiFi同步", C_LAYER6, C_LAYER6_B), ("L2 标准节点", "7天部署\n本地AI推理\nVR串流", C_LAYER1, C_LAYER1_B), ("L3 城市节点", "独立运营\n本地服务器\n内容本地化", C_LAYER2, C_LAYER2_B), ("L4 旗舰中心", "全量系统\n内容生产\n全国调度", C_LAYER5, C_LAYER5_B), ] nw = 180 gap = 20 x0 = 40 for i, (title, desc, fill, stroke) in enumerate(nodes): x = x0 + i * (nw + gap) s += svg_arrow(x + nw/2, 180, x + nw/2, 200) s += svg_rect(x, 200, nw, 130, fill, stroke, 10, 2) s += svg_text(x + nw/2, 225, title, 13, stroke, True) for j, line in enumerate(desc.split("\n")): s += svg_text(x + nw/2, 250 + j*22, line, 11, "#333") # 组件包内容 s += svg_rect(50, 370, W-100, 50, C_HIGHLIGHT, "#f57f17", 8, 2) s += svg_text(W/2, 395, "组件包: 知识图谱子集 + 史料向量 + 课程 + 任务剧本 + VR场景 + 运营SOP", 12, "#e65100", True) s += svg_text(W/2, 460, "断网不失能: 各节点本地有AI推理和内容缓存,网络恢复后自动同步", 12, "#666") s += svg_text(W/2, 485, "内容可回流: 各节点优秀作品可提交旗舰中心审核后全国共享", 12, "#666") save_svg_and_jpg(s, "06_replication_engine") # ═══════════════════════════════════════════════════════════════ # 图7: F1自适应叙事空间 + X1编排引擎 # ═══════════════════════════════════════════════════════════════ def gen_07_f1_x1(): W, H = 900, 620 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "F1自适应叙事空间 + X1体验编排引擎", 20, C_TITLE, True) # F1三模块 s += svg_rect(30, 55, W-60, 180, "#fafafa", C_LAYER1_B, 10, 2) s += svg_text(W/2, 80, "F1 自适应叙事空间系统", 14, C_LAYER1_B, True) modules = [ ("入馆选择终端", "人群类型/学习问题\n可用时长/语言"), ("空间联动控制", "屏幕/灯光/音频\nAI/互动设备"), ("学习脉络生成", "路线节点/文物\n任务/AI问答/报告"), ] mw = 250 for i, (title, desc) in enumerate(modules): x = 50 + i * (mw + 15) s += svg_rect(x, 95, mw, 120, C_LAYER1, C_LAYER1_B, 8, 1.5) s += svg_text(x + mw/2, 120, title, 13, C_LAYER1_B, True) for j, line in enumerate(desc.split("\n")): s += svg_text(x + mw/2, 150 + j*22, line, 11, "#333") # X1编排引擎 s += svg_arrow_down(W/2, 240, 275, C_LAYER3_B, 2, 14) s += svg_text(W/2, 258, "X1全场景体验编排引擎", 14, C_LAYER3_B, True) s += svg_rect(30, 275, W-60, 280, "#fafafa", C_LAYER3_B, 10, 2) # 输入 s += svg_rect(50, 295, 200, 120, C_LAYER3, C_LAYER3_B, 8, 1.5) s += svg_text(150, 320, "输入", 13, C_LAYER3_B, True) inputs = ["用户路线", "UWB实时位置(10Hz)", "实时客流", "设备状态"] for i, inp in enumerate(inputs): s += svg_text(150, 345 + i*22, inp, 11, "#333") # 箭头 — 输入到处理 s += svg_arrow(250, 355, 320, 355, C_ARROW, 2, 14) # 处理 s += svg_rect(320, 295, 260, 120, C_HIGHLIGHT, "#f57f17", 8, 2) s += svg_text(450, 320, "实时流式计算 (CEP)", 13, "#e65100", True) s += svg_text(450, 350, "复杂事件处理引擎", 12, "#333") s += svg_text(450, 375, "毫秒级复合条件判断", 12, "#333") s += svg_text(450, 400, "规则 + AI编排决策", 12, "#333") # 箭头 — 处理到输出 s += svg_arrow(580, 355, 650, 355, C_ARROW, 2, 14) # 输出 s += svg_rect(650, 295, 200, 120, C_LAYER2, C_LAYER2_B, 8, 1.5) s += svg_text(750, 320, "输出", 13, C_LAYER2_B, True) outputs = ["设备控制指令", "用户学习记录", "客流调度信号"] for i, out in enumerate(outputs): s += svg_text(750, 345 + i*22, out, 11, "#333") # 设备控制 s += svg_text(W/2, 445, "六类设备统一编排", 13, C_TITLE, True) devices = ["LED屏幕", "灯光系统", "音频系统", "VR设备", "互动终端", "AI数字人"] dw = 120 for i, dev in enumerate(devices): x = 60 + i * (dw + 10) s += svg_rect(x, 460, dw, 35, C_LAYER6, C_LAYER6_B, 6, 1.5) s += svg_text(x + dw/2, 478, dev, 11, C_LAYER6_B, True) s += svg_text(W/2, 530, "UWB厘米级室内定位 + 复杂事件处理 + 像指挥家指挥交响乐", 12, "#666") s += svg_text(W/2, 555, "同一物理空间,数字内容随人而变", 12, C_LAYER3_B, True) save_svg_and_jpg(s, "07_f1_x1_orchestration") # ═══════════════════════════════════════════════════════════════ # 图8: F2情境任务剧场 # ═══════════════════════════════════════════════════════════════ def gen_08_f2_task(): W, H = 860, 400 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "F2 情境任务剧场系统", 22, C_TITLE, True) modules = [ ("任务引擎", "任务定义: 历史问题\n角色分配/资源约束\n证据集/历史事实\n评价维度\n状态机驱动(9状态)"), ("团队协作终端", "主屏: 情境展示\n分屏: 证据查看\n个人终端: 决策\n团队屏: 方案汇总\nVR模式: 虚拟窑洞讨论"), ("AI复盘引擎", "团队方案 vs 历史\nAI追问(史料引用)\n证据使用分析\n现实连接问题\n像历史导师一对一"), ] mw = 250 for i, (title, desc) in enumerate(modules): x = 30 + i * (mw + 15) fill = [C_LAYER2, C_LAYER1, C_LAYER4][i] stroke = [C_LAYER2_B, C_LAYER1_B, C_LAYER4_B][i] s += svg_rect(x, 55, mw, 240, fill, stroke, 10, 2) s += svg_text(x + mw/2, 82, title, 14, stroke, True) for j, line in enumerate(desc.split("\n")): s += svg_text(x + mw/2, 110 + j*22, line, 11, "#333") if i < 2: s += svg_arrow(x + mw, 175, x + mw + 15, 175, "#999", 2, 12) # 底部 s += svg_rect(30, 320, W-60, 50, C_HIGHLIGHT, "#f57f17", 8, 2) s += svg_text(W/2, 345, "VR与非VR双模式共享同一剧本: 同一任务定义/证据集/历史揭示/AI复盘/护照记录", 12, "#e65100", True) save_svg_and_jpg(s, "08_f2_task_theater") # ═══════════════════════════════════════════════════════════════ # 图9: F3文物数字生命 # ═══════════════════════════════════════════════════════════════ def gen_09_f3_artifact(): W, H = 860, 400 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "F3 文物数字生命系统", 22, C_TITLE, True) modules = [ ("数字采集管理", "3D扫描任务\n摄影测量任务\n质量检测\n元数据录入"), ("五层内容管理", "L1看见: 图像/3D\nL2知道: 元数据\nL3理解: 关联网络\nL4研究: 档案\nL5连接: 课程/任务"), ("关系星图引擎", "力导向图渲染\n交互式星图\n时间轴\n点击节点展开"), ] mw = 250 for i, (title, desc) in enumerate(modules): x = 30 + i * (mw + 15) fill = [C_LAYER3, C_LAYER4, C_LAYER1][i] stroke = [C_LAYER3_B, C_LAYER4_B, C_LAYER1_B][i] s += svg_rect(x, 55, mw, 200, fill, stroke, 10, 2) s += svg_text(x + mw/2, 82, title, 14, stroke, True) for j, line in enumerate(desc.split("\n")): s += svg_text(x + mw/2, 110 + j*22, line, 11, "#333") if i < 2: s += svg_arrow(x + mw, 155, x + mw + 15, 155, "#999", 2, 12) # 五层递进 s += svg_text(W/2, 290, "一件文物 = 一个知识宇宙", 14, C_TITLE, True) levels = ["看见", "知道", "理解", "研究", "连接"] lw = 140 for i, lv in enumerate(levels): x = 50 + i * (lw + 10) fill = [C_LAYER6, C_LAYER1, C_LAYER2, C_LAYER3, C_LAYER4][i] stroke = [C_LAYER6_B, C_LAYER1_B, C_LAYER2_B, C_LAYER3_B, C_LAYER4_B][i] s += svg_rect(x, 305, lw, 35, fill, stroke, 6, 1.5) s += svg_text(x + lw/2, 323, lv, 12, stroke, True) if i < 4: s += svg_arrow(x + lw, 323, x + lw + 10, 323, "#999", 1.5, 10) s += svg_text(W/2, 370, "推测性复原标识: 有争议部分用不同颜色边框区分「史实确认」和「推测复原」", 11, "#666") save_svg_and_jpg(s, "09_f3_artifact_life") # ═══════════════════════════════════════════════════════════════ # 图10: F4成长护照 # ═══════════════════════════════════════════════════════════════ def gen_10_f4_passport(): W, H = 860, 380 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "F4 成长护照系统", 22, C_TITLE, True) stages = [ ("参观前导学", ["人群/问题选择", "团队目标创建", "参观建议生成", "导学材料推送"]), ("参观中记录", ["文物查看记录", "任务完成记录", "AI问答记录", "理解表达记录", "行动选择记录"]), ("离馆后回访", ["第7天推送回顾", "第30天进展反馈", "第90天成果提交", "后续课程推荐"]), ] sw = 250 for i, (title, items) in enumerate(stages): x = 30 + i * (sw + 10) fill = [C_LAYER1, C_LAYER2, C_LAYER3][i] stroke = [C_LAYER1_B, C_LAYER2_B, C_LAYER3_B][i] s += svg_rect(x, 55, sw, 200, fill, stroke, 10, 2) s += svg_text(x + sw/2, 82, title, 14, stroke, True) for j, item in enumerate(items): s += svg_text(x + sw/2, 110 + j*25, item, 11, "#333") if i < 2: s += svg_arrow(x + sw, 155, x + sw + 10, 155, "#999", 2, 12) # X2统一档案 s += svg_arrow_down(W/2, 255, 275, "#999", 2) s += svg_rect(100, 275, W-200, 50, C_LAYER4, C_LAYER4_B, 10, 2) s += svg_text(W/2, 300, "X2 统一成长档案 — 跨系统数据同步 · GraphQL统一查询", 13, C_LAYER4_B, True) s += svg_text(W/2, 350, "隐私保护是设计底线: 禁止采集人脸特征/情绪识别/政治倾向推断", 11, C_SECURITY_B) save_svg_and_jpg(s, "10_f4_growth_passport") # ═══════════════════════════════════════════════════════════════ # 图11: F5云上学习共同体 # ═══════════════════════════════════════════════════════════════ def gen_11_f5_cloud(): W, H = 860, 400 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "F5 云上学习共同体", 22, C_TITLE, True) modules = [ ("Web3D云展馆", "3D渲染引擎\n虚拟漫游\nAI导览\n文物3D展示"), ("云端课程平台", "视频点播/直播\n课程管理\n学时记录\n证书发放"), ("协作任务平台", "实时音视频协作\n多人同堂任务\n粤港澳三地同步\n在线研讨室"), ] mw = 250 for i, (title, desc) in enumerate(modules): x = 30 + i * (mw + 15) fill = [C_LAYER1, C_LAYER2, C_LAYER3][i] stroke = [C_LAYER1_B, C_LAYER2_B, C_LAYER3_B][i] s += svg_rect(x, 55, mw, 160, fill, stroke, 10, 2) s += svg_text(x + mw/2, 82, title, 14, stroke, True) for j, line in enumerate(desc.split("\n")): s += svg_text(x + mw/2, 110 + j*22, line, 11, "#333") # 四种模式 s += svg_text(W/2, 245, "四种访问模式", 13, C_TITLE, True) modes = [("8分钟精华\n轻量H5", C_LAYER6, C_LAYER6_B), ("一节课模式\n视频+互动", C_LAYER1, C_LAYER1_B), ("协作任务模式\n实时协作+白板", C_LAYER3, C_LAYER3_B), ("深度研究模式\n文献检索+图谱", C_LAYER4, C_LAYER4_B)] mw2 = 190 for i, (title, fill, stroke) in enumerate(modes): x = 30 + i * (mw2 + 10) s += svg_rect(x, 265, mw2, 55, fill, stroke, 8, 1.5) for j, line in enumerate(title.split("\n")): s += svg_text(x + mw2/2, 283 + j*18, line, 11, stroke, j==0) s += svg_text(W/2, 365, "三档渲染自适应: 高端(WebGPU+PBR) → 轻量(WebGL+减面) → 极简(全景图片热点)", 11, "#666") save_svg_and_jpg(s, "11_f5_cloud_community") # ═══════════════════════════════════════════════════════════════ # 图12: F6湾区青年共创 # ═══════════════════════════════════════════════════════════════ def gen_12_f6_cocreation(): W, H = 860, 350 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "F6 湾区青年共创平台", 22, C_TITLE, True) modules = [ ("共创项目管理", "年度主题发布\n混合小组组建\n专家工作坊预约\n进度跟踪\n资源库访问"), ("AI辅助创作工具集", "AI辅助写作(标注)\nAI辅助绘画\n短视频编辑\n声音档案录制\n互动网页制作"), ("三级审核与展示", "AI编审自动检查\n编辑复审(人工)\n专家终审\n线上专区展示\n优秀作品入临展"), ] mw = 250 for i, (title, desc) in enumerate(modules): x = 30 + i * (mw + 15) fill = [C_LAYER2, C_LAYER4, C_LAYER3][i] stroke = [C_LAYER2_B, C_LAYER4_B, C_LAYER3_B][i] s += svg_rect(x, 55, mw, 200, fill, stroke, 10, 2) s += svg_text(x + mw/2, 82, title, 14, stroke, True) for j, line in enumerate(desc.split("\n")): s += svg_text(x + mw/2, 110 + j*22, line, 11, "#333") if i < 2: s += svg_arrow(x + mw, 155, x + mw + 15, 155, "#999", 2, 12) s += svg_rect(30, 280, W-60, 40, C_HIGHLIGHT, "#f57f17", 8, 2) s += svg_text(W/2, 300, "AI编审四项自动检查: 史实校验 + 来源完整性 + 版权合规 + 政治合规", 12, "#e65100", True) s += svg_text(W/2, 335, "AI是工具不是作者,人的创造力是核心 — 所有AI生成内容强制标注", 11, "#666") save_svg_and_jpg(s, "12_f6_cocreation") # ═══════════════════════════════════════════════════════════════ # 图13: F7行动实验室 # ═══════════════════════════════════════════════════════════════ def gen_13_f7_action(): W, H = 860, 350 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "F7 现实行动实验室", 22, C_TITLE, True) modules = [ ("行动选择终端", "行动方向展示\n智能推荐(基于参观记录)\n行动模板选择\n自定义行动\n团队行动创建"), ("行动跟踪系统", "行动卡片生成\n7/30/90天跟踪\n进展提醒推送\n反馈表单"), ("成果回流系统", "成果提交入口\n成果墙展示\n课程案例转化\n年度优秀评选"), ] mw = 250 for i, (title, desc) in enumerate(modules): x = 30 + i * (mw + 15) fill = [C_LAYER3, C_LAYER1, C_LAYER2][i] stroke = [C_LAYER3_B, C_LAYER1_B, C_LAYER2_B][i] s += svg_rect(x, 55, mw, 200, fill, stroke, 10, 2) s += svg_text(x + mw/2, 82, title, 14, stroke, True) for j, line in enumerate(desc.split("\n")): s += svg_text(x + mw/2, 110 + j*22, line, 11, "#333") if i < 2: s += svg_arrow(x + mw, 155, x + mw + 15, 155, "#999", 2, 12) s += svg_rect(30, 280, W-60, 40, C_HIGHLIGHT, "#f57f17", 8, 2) s += svg_text(W/2, 300, "把「一次性参观」变成「持续性行动」 — 优秀成果成为系统内容资产", 12, "#e65100", True) s += svg_text(W/2, 335, "三类行动: 个人7天(实事求是调查员) | 团队30天(南泥湾式创新) | 湾区90天(红色故事传播者)", 11, "#666") save_svg_and_jpg(s, "13_f7_action_lab") # ═══════════════════════════════════════════════════════════════ # 图14: F8星火节点网络 # ═══════════════════════════════════════════════════════════════ def gen_14_f8_nodes(): W, H = 860, 520 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "F8 星火节点全国复制网络", 22, C_TITLE, True) nodes = [ ("L4 旗舰中心", "13000㎡", "完整私有云 + GPU集群\n完整知识图谱+向量库+内容仓\n全国节点调度中心\n权威内容生产与发布", C_LAYER5, C_LAYER5_B), ("L3 城市节点", "院校/区县基地", "本地服务器 + 完整展陈\n知识图谱子集 + 向量库子集\n独立运营 + 数据上报\n云端连线能力", C_LAYER2, C_LAYER2_B), ("L2 标准节点", "高校/企事业单位", "触屏终端 + 边缘AI + VR\n本地内容缓存 + 云端AI增强\n成长护照接入\n7天标准化部署", C_LAYER1, C_LAYER1_B), ("L1 微节点", "一体机", "一块触屏交互一体机\n离线内容包 + AI轻量版\n定期WiFi/4G同步更新", C_LAYER6, C_LAYER6_B), ] nh = 90 for i, (title, scale, desc, fill, stroke) in enumerate(nodes): y = 55 + i * (nh + 10) s += svg_rect(40, y, W-80, nh, fill, stroke, 10, 2) s += svg_text(160, y + 25, title, 14, stroke, True) s += svg_text(160, y + 48, scale, 11, "#666") for j, line in enumerate(desc.split("\n")): s += svg_text(450, y + 20 + j*18, line, 11, "#333") if i < 3: s += svg_arrow_down(W/2, y + nh, y + nh + 10, "#999", 2, 10) s += svg_text(W/2, 490, "组件包标准化分发 — 像App Store更新一样简单", 12, C_LAYER3_B, True) save_svg_and_jpg(s, "14_f8_spark_nodes") # ═══════════════════════════════════════════════════════════════ # 图15: VR/XR整体架构 # ═══════════════════════════════════════════════════════════════ def gen_15_vr_architecture(): W, H = 900, 420 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "VR/XR 沉浸体验系统架构", 22, C_TITLE, True) layers = [ ("内容生产层", ["Unity场景工程", "3D资产管线", "交互逻辑脚本", "AI NPC驱动", "场景烘焙渲染"], C_VR, C_VR_B), ("运行时引擎", ["场景管理器", "多人同步引擎", "编排对接层", "安全监控守护", "性能监控"], C_LAYER4, C_LAYER4_B), ("设备与体感层", ["VR头显(Pico/Meta)", "6DOF动态座椅", "手部追踪", "触觉反馈背心", "风效/热效/气味"], C_LAYER3, C_LAYER3_B), ] lh = 100 for i, (title, items, fill, stroke) in enumerate(layers): y = 55 + i * (lh + 10) s += svg_rect(30, y, W-60, lh, fill, stroke, 10, 2) s += svg_text(130, y + 25, title, 14, stroke, True) iw = 140 for j, item in enumerate(items): x = 240 + j * (iw + 10) s += svg_rect(x, y + 45, iw, 35, "#fff", stroke, 6, 1) s += svg_text(x + iw/2, y + 63, item, 10, "#333") if i < 2: s += svg_arrow_down(W/2, y + lh, y + lh + 10, "#999", 2, 10) s += svg_text(W/2, 390, "Unity + XR Interaction Toolkit — 一次开发多设备运行 | 6DOF体感+五感同步沉浸", 12, C_VR_B, True) save_svg_and_jpg(s, "15_vr_xr_architecture") # ═══════════════════════════════════════════════════════════════ # 图16: 多人协同VR架构 # ═══════════════════════════════════════════════════════════════ def gen_16_vr_multiplayer(): W, H = 700, 520 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "多人协同VR架构", 22, C_TITLE, True) # 4个VR座位 seats = ["VR座位1\n(队长)", "VR座位2\n(队员)", "VR座位3\n(队员)", "VR座位4\n(队员)"] for i, label in enumerate(seats): x = 60 + i * 150 s += svg_rect(x, 60, 130, 60, C_VR, C_VR_B, 8, 2) for j, line in enumerate(label.split("\n")): s += svg_text(x + 65, 78 + j*18, line, 11, C_VR_B, j==0) # 从座位底部到状态同步服务器顶部,用箭头 s += svg_arrow(x + 65, 120, 350, 170, C_ARROW, 1.5, 10) # 状态同步服务器 s += svg_rect(200, 170, 300, 60, C_LAYER4, C_LAYER4_B, 10, 2) s += svg_text(W/2, 195, "状态同步服务器", 14, C_LAYER4_B, True) s += svg_text(W/2, 215, "Photon Fusion — 头像/手部/任务进度实时同步", 11, "#333") s += svg_arrow_down(W/2, 230, 250, C_ARROW, 2, 12) # 房间管理 s += svg_rect(200, 250, 300, 50, C_LAYER3, C_LAYER3_B, 10, 2) s += svg_text(W/2, 275, "房间管理服务 — 4人同场,场次调度", 12, C_LAYER3_B, True) s += svg_arrow_down(W/2, 300, 320, C_ARROW, 2, 12) # X1编排 s += svg_rect(200, 320, 300, 50, C_LAYER1, C_LAYER1_B, 10, 2) s += svg_text(W/2, 345, "X1编排引擎 — 任务剧本推送", 12, C_LAYER1_B, True) # 底部说明 s += svg_rect(50, 400, W-100, 90, C_HIGHLIGHT, "#f57f17", 8, 2) s += svg_text(W/2, 425, "技术亮点", 13, "#e65100", True) s += svg_text(W/2, 448, "• Photon Fusion状态同步: 4人虚拟化身和手势实时可见", 11, "#333") s += svg_text(W/2, 468, "• 角色与F2任务对应: 各有专属资源和约束,真正的团队协作", 11, "#333") s += svg_text(W/2, 488, "• VR内AI NPC: 由AI可信知识引擎驱动,可对话的AI角色", 11, "#333") save_svg_and_jpg(s, "16_vr_multiplayer") # ═══════════════════════════════════════════════════════════════ # 图17: 云端VR串流 # ═══════════════════════════════════════════════════════════════ def gen_17_vr_cloud_streaming(): W, H = 860, 400 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "云端VR串流方案", 22, C_TITLE, True) # 左侧: 节点 s += svg_rect(40, 70, 300, 200, C_LAYER1, C_LAYER1_B, 10, 2) s += svg_text(190, 100, "L2/L3节点 (轻量硬件)", 14, C_LAYER1_B, True) items_l = ["VR头显", "WiFi/5G传输", "解码显示", "手柄/头显数据"] for i, item in enumerate(items_l): s += svg_text(190, 130 + i*30, item, 12, "#333") if i < 3: s += svg_arrow_down(190, 140 + i*30, 150 + i*30, "#bbb", 1.5, 8) # 中间: 数据流 — 双向箭头 s += svg_arrow(340, 130, 460, 130, C_VR_B, 2, 12) s += svg_arrow(460, 130, 340, 130, C_VR_B, 2, 12) s += svg_text(400, 118, "视频流", 10, C_VR_B, True) s += svg_arrow(340, 160, 460, 160, C_VR_B, 2, 12) s += svg_arrow(460, 160, 340, 160, C_VR_B, 2, 12) s += svg_text(400, 148, "音频流", 10, C_VR_B, True) s += svg_arrow(340, 190, 460, 190, C_VR_B, 2, 12) s += svg_text(400, 178, "输入流", 10, C_VR_B, True) s += svg_text(400, 220, "H.265超低延迟传输", 11, "#999") # 右侧: 云端 s += svg_rect(520, 70, 300, 200, C_LAYER5, C_LAYER5_B, 10, 2) s += svg_text(670, 100, "旗舰中心/区域云端 (GPU集群)", 14, C_LAYER5_B, True) items_r = ["云端渲染服务器", "Unity应用实例", "串流编码H.265", "超低延迟传输"] for i, item in enumerate(items_r): s += svg_text(670, 130 + i*30, item, 12, "#333") # 方案表 s += svg_text(W/2, 310, "四种方案对比", 13, C_TITLE, True) schemes = [("CloudXR\n15-30ms\nL3城市节点", C_LAYER2, C_LAYER2_B), ("ALVR开源\n20-40ms\nL2标准节点", C_LAYER1, C_LAYER1_B), ("本地渲染\n<10ms\nL4旗舰中心", C_LAYER5, C_LAYER5_B), ("WebXR\n30-80ms\nF5云展馆", C_LAYER6, C_LAYER6_B)] sw = 190 for i, (label, fill, stroke) in enumerate(schemes): x = 30 + i * (sw + 10) s += svg_rect(x, 325, sw, 55, fill, stroke, 8, 1.5) for j, line in enumerate(label.split("\n")): s += svg_text(x + sw/2, 343 + j*16, line, 10, stroke, j==0) save_svg_and_jpg(s, "17_vr_cloud_streaming") # ═══════════════════════════════════════════════════════════════ # 图18: X1编排数据流 # ═══════════════════════════════════════════════════════════════ def gen_18_x1_dataflow(): W, H = 860, 320 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "X1体验编排引擎 — 数据流", 22, C_TITLE, True) # 事件源 sources = ["UWB位置流\n(10Hz)", "客流计数\n(实时)", "设备状态\n(实时)", "用户路线\n(API)", "任务状态\n(API)"] s += svg_text(120, 75, "事件源", 13, C_TITLE, True) for i, src in enumerate(sources): y = 90 + i * 38 s += svg_rect(40, y, 160, 32, C_LAYER1, C_LAYER1_B, 6, 1.5) s += svg_text(120, y + 16, src.replace("\n", " "), 10, C_LAYER1_B, True) # 从每个事件源到处理引擎的箭头 s += svg_arrow(200, y + 16, 280, 175, C_ARROW, 1.5, 10) # 处理引擎 s += svg_rect(280, 130, 260, 90, C_HIGHLIGHT, "#f57f17", 10, 2) s += svg_text(410, 160, "实时流式计算", 14, "#e65100", True) s += svg_text(410, 185, "复杂事件处理(CEP)", 12, "#333") s += svg_text(410, 205, "规则 + AI编排决策", 12, "#333") s += svg_arrow(540, 175, 620, 175) # 输出 s += svg_text(700, 75, "输出目标", 13, C_TITLE, True) outputs = ["设备控制指令\n(实时消息推送)", "用户学习记录\n(写入成长护照)", "客流调度信号\n(反馈智慧场馆)"] for i, out in enumerate(outputs): y = 90 + i * 55 s += svg_rect(620, y, 200, 42, C_LAYER2, C_LAYER2_B, 6, 1.5) for j, line in enumerate(out.split("\n")): s += svg_text(720, y + 14 + j*16, line, 10, C_LAYER2_B, True) # 从处理引擎到每个输出目标的箭头 s += svg_arrow(540, 175, 620, y + 21, C_ARROW, 1.5, 10) s += svg_text(W/2, 290, "五路数据流实时汇入 — 系统对全馆状态有「上帝视角」", 12, "#666") save_svg_and_jpg(s, "18_x1_dataflow") # ═══════════════════════════════════════════════════════════════ # 图19: X2跨系统同步 # ═══════════════════════════════════════════════════════════════ def gen_19_x2_sync(): W, H = 700, 380 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "X2 成长护照 — 跨系统同步", 22, C_TITLE, True) # 数据源 sources = ["票务系统", "教研系统", "港澳专项", "数据中台", "线下终端"] for i, src in enumerate(sources): y = 70 + i * 45 s += svg_rect(40, y, 160, 35, C_LAYER1, C_LAYER1_B, 8, 1.5) s += svg_text(120, y + 18, src, 12, C_LAYER1_B, True) # 从数据源到中心API的箭头 s += svg_arrow(200, y + 17, 280, 200, C_ARROW, 1.5, 10) # 中心 s += svg_rect(280, 165, 200, 70, C_LAYER4, C_LAYER4_B, 10, 2) s += svg_text(380, 190, "X2成长护照统一API", 13, C_LAYER4_B, True) s += svg_text(380, 215, "GraphQL统一查询", 12, "#333") # 输出 s += svg_rect(520, 165, 140, 70, C_LAYER2, C_LAYER2_B, 10, 2) s += svg_text(590, 190, "统一学习档案", 13, C_LAYER2_B, True) s += svg_text(590, 215, "全生命周期", 12, "#333") s += svg_arrow(480, 200, 520, 200, C_ARROW, 2, 14) # 底部 s += svg_text(W/2, 300, "从第一次预约到第90天行动成果,一个人的完整学习旅程在一本护照里", 12, "#666") s += svg_text(W/2, 325, "对前端来说,所有数据来自一个「虚拟数据库」", 12, C_LAYER4_B, True) s += svg_text(W/2, 355, "北极星指标可计算: 完成核心学习路径+理解验证+形成行动+产生反馈的完整闭环人数", 11, "#e65100") save_svg_and_jpg(s, "19_x2_sync") # ═══════════════════════════════════════════════════════════════ # 图20: X3审核工作流 # ═══════════════════════════════════════════════════════════════ def gen_20_x3_review(): W, H = 700, 480 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "X3 权威内容治理中心 — 审核工作流", 20, C_TITLE, True) steps = [ ("内容创建/修改", C_LAYER6, C_LAYER6_B), ("AI编审助手自动检查\n事实校验·来源检查·合规检查·版权检查", C_LAYER4, C_LAYER4_B), ("编辑复审 (人工)", C_LAYER3, C_LAYER3_B), ("专家终审 (关键内容)", C_SECURITY, C_SECURITY_B), ("版本发布 (带版本号,可回滚)", C_LAYER2, C_LAYER2_B), ("同步到: 展陈/云展馆/课程平台/全国节点", C_LAYER1, C_LAYER1_B), ] for i, (step, fill, stroke) in enumerate(steps): y = 65 + i * 60 s += svg_rect(100, y, W-200, 45, fill, stroke, 8, 2) s += svg_text(W/2, y + 23, step, 12, stroke, True) if i < len(steps) - 1: s += svg_arrow_down(W/2, y + 45, y + 60, "#999", 2, 12) # 底部 s += svg_rect(50, 440, W-100, 30, C_HIGHLIGHT, "#f57f17", 6, 1.5) s += svg_text(W/2, 456, "AI初审自动化把审核效率提升10倍,人工只做最关键的终审", 11, "#e65100", True) save_svg_and_jpg(s, "20_x3_review_workflow") # ═══════════════════════════════════════════════════════════════ # 图21: 网络安全架构 # ═══════════════════════════════════════════════════════════════ def gen_21_security(): W, H = 700, 420 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "网络安全架构", 22, C_TITLE, True) zones = [ ("互联网", "WAF (Web应用防火墙)", C_SECURITY, C_SECURITY_B), ("DMZ区", "负载均衡 + API网关", C_LAYER3, C_LAYER3_B), ("应用区 (容器集群)", "微服务集群 (服务网格 + 自动扩缩容)", C_LAYER1, C_LAYER1_B), ("数据区 (隔离)", "业务数据库 | 知识图谱 | 向量库 | 内容仓 | GPU推理集群", C_LAYER4, C_LAYER4_B), ("设备区 (VLAN隔离)", "IoT/安防/VR/灯光音频 (独立VLAN)", C_LAYER6, C_LAYER6_B), ] for i, (zone, content, fill, stroke) in enumerate(zones): y = 60 + i * 65 s += svg_rect(50, y, W-100, 55, fill, stroke, 10, 2) s += svg_text(180, y + 20, zone, 13, stroke, True) s += svg_text(W/2, y + 40, content, 11, "#333") if i < len(zones) - 1: s += svg_arrow_down(W/2, y + 55, y + 65, "#999", 2, 12) save_svg_and_jpg(s, "21_security_architecture") # ═══════════════════════════════════════════════════════════════ # 图22: AI安全三层护栏 # ═══════════════════════════════════════════════════════════════ def gen_22_ai_guardrail(): W, H = 600, 480 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "AI安全三层护栏", 22, C_TITLE, True) # 用户输入 s += svg_rect(200, 60, 200, 40, C_LAYER6, C_LAYER6_B, 8, 2) s += svg_text(W/2, 80, "用户输入", 14, C_LAYER6_B, True) s += svg_arrow_down(W/2, 100, 125, "#999", 2, 12) # 第一层 s += svg_rect(150, 125, 300, 50, C_SECURITY, C_SECURITY_B, 10, 2) s += svg_text(W/2, 145, "第一层: 输入过滤", 13, C_SECURITY_B, True) s += svg_text(W/2, 162, "拦截不当提问", 11, "#333") s += svg_arrow_down(W/2, 175, 195, "#999", 2, 12) # 第二层 s += svg_rect(150, 195, 300, 50, C_SECURITY, C_SECURITY_B, 10, 2) s += svg_text(W/2, 215, "第二层: 事实校验", 13, C_SECURITY_B, True) s += svg_text(W/2, 232, "AI回答与知识图谱比对,发现错误则拦截", 11, "#333") s += svg_arrow_down(W/2, 245, 265, "#999", 2, 12) # 第三层 s += svg_rect(150, 265, 300, 50, C_SECURITY, C_SECURITY_B, 10, 2) s += svg_text(W/2, 285, "第三层: 输出过滤", 13, C_SECURITY_B, True) s += svg_text(W/2, 302, "拦截不当表述", 11, "#333") s += svg_arrow_down(W/2, 315, 335, "#999", 2, 12) # 输出 s += svg_rect(100, 335, 400, 50, C_LAYER2, C_LAYER2_B, 10, 2) s += svg_text(W/2, 355, "安全回答 + 史料来源 + 审计日志", 13, C_LAYER2_B, True) s += svg_text(W/2, 372, "100%不当内容拦截率", 11, "#333") # 底部 s += svg_text(W/2, 420, "NPC禁止模拟革命领袖发表新言论,仅复述已审核史料", 11, "#666") s += svg_text(W/2, 445, "全部对话可审计追溯,支持质量回查", 11, "#666") save_svg_and_jpg(s, "22_ai_guardrail") # ═══════════════════════════════════════════════════════════════ # 图23: 多语言与多人群适配流程 # ═══════════════════════════════════════════════════════════════ def gen_23_multilang_flow(): W, H = 520, 620 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "多语言与多人群适配流程", 20, C_TITLE, True) steps = [ ("用户提问(繁体中文)", C_LAYER6, C_LAYER6_B), ("意图识别 + 人群类型判断(港澳中学生)", C_LAYER1, C_LAYER1_B), ("RAG检索(史料库语义检索,召回相关文献)", C_LAYER4, C_LAYER4_B), ("大模型生成(适配港澳中学生理解水平,繁体中文输出)", C_LAYER3, C_LAYER3_B), ("安全护栏(事实校验 + 输出过滤)", C_SECURITY, C_SECURITY_B), ("TTS语音合成(粤语发音可选)", C_LAYER2, C_LAYER2_B), ("回答 + 史料来源 + 追问建议", C_LAYER5, C_LAYER5_B), ] bw = 420 bh = 50 x0 = (W - bw) // 2 y0 = 55 gap = 22 for i, (step, fill, stroke) in enumerate(steps): y = y0 + i * (bh + gap) s += svg_rect(x0, y, bw, bh, fill, stroke, 10, 2) s += svg_text(W/2, y + bh/2 + 5, step, 12, stroke, True) if i < len(steps) - 1: s += svg_arrow_down(W/2, y + bh, y + bh + gap, "#999", 2, 14) s += svg_text(W/2, H - 20, "同一问题 · 不同人群 · 不同语言 · 不同深度", 11, "#666") save_svg_and_jpg(s, "23_multilang_flow") # ═══════════════════════════════════════════════════════════════ # 图24: X1体验编排引擎详细架构 # ═══════════════════════════════════════════════════════════════ def gen_24_x1_detail(): W, H = 860, 680 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "X1 体验编排引擎 — 详细架构", 20, C_TITLE, True) # 外框 s += svg_rect(30, 50, W-60, H-70, "#fafafa", C_LAYER3_B, 12, 2) # ── 输入区 ── s += svg_text(60, 78, "输入", 14, C_LAYER3_B, True) inputs = [ ("用户路线", "来自可信叙事引擎"), ("实时位置", "UWB定位 10Hz更新"), ("实时客流", "摄像头+IoT传感器"), ("设备状态", "监控系统"), ] iw = 180 ih = 55 ix0 = 50 for i, (title, desc) in enumerate(inputs): x = ix0 + i * (iw + 15) s += svg_rect(x, 88, iw, ih, C_LAYER3, C_LAYER3_B, 8, 1.5) s += svg_text(x + iw/2, 108, title, 12, C_LAYER3_B, True) s += svg_text(x + iw/2, 128, desc, 10, "#666") # 汇聚箭头 → 编排逻辑 for i in range(4): x = ix0 + i * (iw + 15) + iw/2 s += svg_arrow(x, 143, W/2, 175, C_ARROW, 1.5, 10) # ── 编排逻辑区 ── s += svg_text(W/2, 168, "编排逻辑 (实时流式计算)", 14, "#e65100", True) s += svg_rect(50, 175, W-100, 250, C_HIGHLIGHT, "#f57f17", 10, 2) steps = [ ("1. 用户进入区域", "匹配路线节点"), ("2. 查询内容组件", "该节点对应的内容组件"), ("3. 下发指令到设备", "屏幕/灯光/音频/AI终端/互动设备"), ("4. 客流拥挤", "切换备选节点 → 重新下发指令"), ] sy = 190 for i, (title, desc) in enumerate(steps): y = sy + i * 55 s += svg_rect(70, y, W-140, 42, "#fff", "#f57f17", 8, 1.5) s += svg_text(90, y + 26, title, 12, "#e65100", True) s += svg_text(280, y + 26, desc, 11, "#333") if i < 3: s += svg_arrow_down(W/2, y + 42, y + 55, "#f57f17", 1.5, 10) # 设备指令细分 (第3步展开) dev_cmds = ["屏幕: 播放对应内容", "灯光: 切换场景灯光", "音频: 播放对应导览", "AI终端: 加载讲解上下文", "互动设备: 激活对应任务"] s += svg_text(W/2, 415, "第3步设备指令明细", 11, "#e65100", True) dcw = 150 for i, cmd in enumerate(dev_cmds): x = 55 + i * (dcw + 5) s += svg_rect(x, 425, dcw, 30, "#fff", "#f57f17", 6, 1) s += svg_text(x + dcw/2, 444, cmd, 9, "#333") # ── 输出区 ── s += svg_arrow_down(W/2, 460, 475, C_ARROW, 2, 14) s += svg_text(W/2, 470, "输出", 14, C_LAYER2_B, True) outputs = [ ("设备控制指令", "实时消息推送"), ("用户学习记录", "写入成长护照"), ("客流调度信号", "反馈智慧场馆"), ] ow = 220 ox0 = (W - 3*ow - 2*20) // 2 for i, (title, desc) in enumerate(outputs): x = ox0 + i * (ow + 20) s += svg_rect(x, 480, ow, 55, C_LAYER2, C_LAYER2_B, 8, 2) s += svg_text(x + ow/2, 500, title, 12, C_LAYER2_B, True) s += svg_text(x + ow/2, 520, desc, 10, "#666") s += svg_text(W/2, H - 25, "实时事件驱动 · 毫秒级响应 · 同一空间千人千面", 12, C_LAYER3_B, True) save_svg_and_jpg(s, "24_x1_detail") # ═══════════════════════════════════════════════════════════════ # 图25: F3文物扫码体验流程 # ═══════════════════════════════════════════════════════════════ def gen_25_f3_scan_flow(): W, H = 540, 660 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "F3 文物扫码体验流程", 20, C_TITLE, True) steps = [ ("展柜前扫描二维码", C_LAYER6, C_LAYER6_B), ("手机加载文物星图H5", C_LAYER1, C_LAYER1_B), ("L1 看见: 3D模型 + 基本信息", C_LAYER6, C_LAYER6_B), ("上滑 → L2 知道: 元数据卡片", C_LAYER1, C_LAYER1_B), ("点击星图节点 → L3 理解: 关联网络可视化", C_LAYER2, C_LAYER2_B), ('点击"深度研究" → L4 研究: 档案文献', C_LAYER3, C_LAYER3_B), ('点击"相关课程" → L5 连接: 课程推荐', C_LAYER4, C_LAYER4_B), ('点击"做一做" → 跳转F7行动选择', C_LAYER5, C_LAYER5_B), ] bw = 440 bh = 48 x0 = (W - bw) // 2 y0 = 55 gap = 26 for i, (step, fill, stroke) in enumerate(steps): y = y0 + i * (bh + gap) s += svg_rect(x0, y, bw, bh, fill, stroke, 10, 2) s += svg_text(W/2, y + bh/2 + 5, step, 12, stroke, True) if i < len(steps) - 1: s += svg_arrow_down(W/2, y + bh, y + bh + gap, "#999", 2, 14) s += svg_text(W/2, H - 20, "一件文物 = 一个知识宇宙 · 从看见到行动", 11, "#666") save_svg_and_jpg(s, "25_f3_scan_flow") # ═══════════════════════════════════════════════════════════════ # 图26: F2情境任务剧场 VR/非VR双模式共享架构 # ═══════════════════════════════════════════════════════════════ def gen_26_f2_vr_share(): W, H = 720, 560 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "F2 情境任务剧场 — VR/非VR双模式共享架构", 18, C_TITLE, True) # 顶部: F2 s += svg_rect(W/2-130, 50, 260, 45, C_LAYER3, C_LAYER3_B, 10, 2) s += svg_text(W/2, 78, "F2 情境任务剧场", 15, C_LAYER3_B, True) # 分叉箭头到两个模式 s += svg_arrow(W/2, 95, W/2-160, 130, C_ARROW, 2, 12) s += svg_arrow(W/2, 95, W/2+160, 130, C_ARROW, 2, 12) # 左: 非VR模式 s += svg_rect(60, 130, 280, 160, C_LAYER1, C_LAYER1_B, 10, 2) s += svg_text(200, 155, "非VR模式", 14, C_LAYER1_B, True) non_vr = ["多屏互动终端", "AI复盘"] for i, item in enumerate(non_vr): s += svg_rect(90, 170+i*50, 220, 38, "#fff", C_LAYER1_B, 8, 1.5) s += svg_text(200, 193+i*50, item, 12, "#333") # 右: VR模式 s += svg_rect(380, 130, 280, 160, C_VR, C_VR_B, 10, 2) s += svg_text(520, 155, "VR模式", 14, C_VR_B, True) vr_items = ["沉浸场景", "体感设备", "多人协同", "AI复盘"] for i, item in enumerate(vr_items): s += svg_rect(410, 170+i*32, 220, 26, "#fff", C_VR_B, 6, 1.2) s += svg_text(520, 188+i*32, item, 11, "#333") # 汇聚箭头到共享层 s += svg_arrow(200, 290, W/2, 330, C_ARROW, 2, 12) s += svg_arrow(520, 290, W/2, 330, C_ARROW, 2, 12) # 共享层 s += svg_rect(80, 330, W-160, 200, C_LAYER5, C_LAYER5_B, 10, 2) s += svg_text(W/2, 358, "共享层", 14, C_LAYER5_B, True) shared = [ "同一任务定义", "同一证据集(从知识图谱检索)", "同一历史事实揭示", "同一AI学习教练复盘", "同一成长护照记录", ] for i, item in enumerate(shared): y = 375 + i * 28 s += svg_rect(120, y, W-240, 22, "#fff", C_LAYER5_B, 6, 1) s += svg_text(W/2, y+15, item, 11, "#333") s += svg_text(W/2, H - 20, "不同体验通道 · 同一学习内核", 12, C_LAYER5_B, True) save_svg_and_jpg(s, "26_f2_vr_share") # ═══════════════════════════════════════════════════════════════ # 图27: VR体验全流程 # ═══════════════════════════════════════════════════════════════ def gen_27_vr_experience_flow(): W, H = 720, 780 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "VR 体验全流程", 20, C_TITLE, True) phases = [ ("排队区(3分钟)", C_LAYER6, C_LAYER6_B, [ "观看历史背景视频", "查看分配到的角色和资源约束", "学习VR手柄操作和交互方式", "了解安全须知和紧急退出方法", "查看排队位置和预计等待时间", ]), ("进入VR工位", C_LAYER1, C_LAYER1_B, [ "佩戴VR头显 + 触觉背心", "系统加载场景(按人群类型适配内容)", "4人同步进入同一历史场景", ]), ("沉浸体验(8-15分钟)", C_VR, C_VR_B, [ "在虚拟场景中执行任务", "抓取文物、查看证据", "与AI NPC对话(可提问,NPC用史料回答)", "4人语音讨论 + 手势交互", "体感设备同步场景事件", "团队做出决策", ]), ("退出VR", C_LAYER5, C_LAYER5_B, [ "AI复盘(学习教练分析方案vs历史)", "现实连接问题", "学习记录写入成长护照", "设备复位 + 消毒(3分钟)", ]), ] pw = 560 x0 = (W - pw) // 2 y = 55 for pi, (title, fill, stroke, items) in enumerate(phases): ph = 40 + len(items) * 26 + 10 s += svg_rect(x0, y, pw, ph, fill, stroke, 10, 2) s += svg_rect(x0, y, pw, 32, fill, stroke, 10, 2) s += svg_text(W/2, y + 21, title, 14, stroke, True) for i, item in enumerate(items): iy = y + 42 + i * 26 s += svg_text(x0 + 20, iy + 16, "• " + item, 11, "#333") y += ph if pi < len(phases) - 1: s += svg_arrow_down(W/2, y, y + 20, C_ARROW, 2, 14) y += 20 s += svg_text(W/2, H - 18, "从排队到离场 · 全流程数据记录 · 无缝衔接成长护照", 11, "#666") save_svg_and_jpg(s, "27_vr_experience_flow") # ═══════════════════════════════════════════════════════════════ # 图28: 最小可行原型组成 # ═══════════════════════════════════════════════════════════════ def gen_28_mvp(): W, H = 860, 420 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "最小可行原型 (MVP)", 20, C_TITLE, True) # 左侧: 最小原型标签 s += svg_rect(40, 140, 130, 140, C_LAYER3, C_LAYER3_B, 10, 2) s += svg_text(105, 195, "最小原型", 16, C_LAYER3_B, True) s += svg_text(105, 220, "MVP", 13, C_LAYER3_B) s += svg_text(105, 250, "6个核心模块", 10, "#666") # 等号 s += svg_text(195, 210, "=", 28, C_LAYER3_B, True) # 6个组件 (2行×3列) comps = [ ("文物3D展示", "1件", C_LAYER6, C_LAYER6_B), ("情境任务", "1个", C_LAYER1, C_LAYER1_B), ("AI问答入口", "1个", C_LAYER4, C_LAYER4_B), ("成长护照H5", "1个", C_LAYER2, C_LAYER2_B), ("行动选择页", "1个", C_LAYER5, C_LAYER5_B), ("30天回访推送", "1个", C_VR, C_VR_B), ] cw = 175 ch = 80 cx0 = 235 cy0 = 100 gap_x = 20 gap_y = 30 for i, (title, qty, fill, stroke) in enumerate(comps): col = i % 3 row = i // 3 x = cx0 + col * (cw + gap_x) y = cy0 + row * (ch + gap_y) s += svg_rect(x, y, cw, ch, fill, stroke, 10, 2) s += svg_text(x + cw/2, y + 28, qty, 12, stroke, True) s += svg_text(x + cw/2, y + 55, title, 14, stroke, True) # + 号连接 (同行内) if col < 2: s += svg_text(x + cw + gap_x/2 - 5, y + ch/2 + 5, "+", 20, "#999", True) # 第一行末到第二行首的连接箭头 if i == 2: s += svg_arrow(x + cw/2, y + ch, x + cw/2, y + ch + 10, "#999", 1.5, 10) s += svg_arrow(x + cw/2, y + ch + 10, cx0 + cw/2, y + ch + gap_y, "#999", 1.5, 10) s += svg_text(x + cw/2 + 15, y + ch + 12, "+", 16, "#999", True) # 底部说明 s += svg_text(W/2, H - 25, "6个模块 = 1条完整体验链路 · 从看到文物到行动反馈", 12, "#666") save_svg_and_jpg(s, "28_mvp") # ═══════════════════════════════════════════════════════════════ # 图29: MVP用户体验流程 # ═══════════════════════════════════════════════════════════════ def gen_29_mvp_flow(): W, H = 860, 580 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "MVP 用户体验流程", 20, C_TITLE, True) steps = [ ("触屏终端开始", "用户入场", C_LAYER6, C_LAYER6_B), ("查看文物3D模型", "可旋转缩放", C_LAYER1, C_LAYER1_B), ("参与情境任务", "阅读证据 → 团队讨论 → 提交方案 → 历史揭示 → AI复盘", C_LAYER4, C_LAYER4_B), ("向AI提问", "获得带史料引用的回答", C_LAYER3, C_LAYER3_B), ("打开手机H5查看成长护照", "离馆后继续", C_LAYER2, C_LAYER2_B), ("选择一个行动方向", "F7现实行动", C_LAYER5, C_LAYER5_B), ("30天后收到微信推送", "提交行动反馈", C_VR, C_VR_B), ] bw = 680 bh = 52 x0 = (W - bw) // 2 y0 = 55 gap = 22 for i, (title, desc, fill, stroke) in enumerate(steps): y = y0 + i * (bh + gap) s += svg_rect(x0, y, bw, bh, fill, stroke, 10, 2) s += svg_text(x0 + 30, y + bh/2 + 5, title, 13, stroke, True) s += svg_text(x0 + bw - 20, y + bh/2 + 5, desc, 11, "#666") if i < len(steps) - 1: s += svg_arrow_down(W/2, y + bh, y + bh + gap, C_ARROW, 2, 14) s += svg_text(W/2, H - 18, "从入场到离馆后30天 · 一条完整的体验闭环", 11, "#666") save_svg_and_jpg(s, "29_mvp_flow") # ═══════════════════════════════════════════════════════════════ # 图30: MVP原型部署方案 # ═══════════════════════════════════════════════════════════════ def gen_30_mvp_deploy(): W, H = 760, 460 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "MVP 原型部署方案", 20, C_TITLE, True) s += svg_text(W/2, 55, "单服务器部署(原型阶段)", 13, "#666") # 外框 s += svg_rect(40, 75, W-80, 340, "#fafafa", C_LAYER6_B, 12, 2) servers = [ ("GPU服务器", "×1台", "AI推理 + 向量检索", C_LAYER3, C_LAYER3_B), ("应用服务器", "×1台", "业务服务 + 缓存", C_LAYER1, C_LAYER1_B), ("前端服务器", "×1台", "3D展示 + 小程序后端", C_LAYER4, C_LAYER4_B), ("互动终端", "×1台", "情境任务 + AI问答界面", C_LAYER2, C_LAYER2_B), ] bw = 300 bh = 60 x0 = (W - bw) // 2 y0 = 95 gap = 20 for i, (name, qty, desc, fill, stroke) in enumerate(servers): y = y0 + i * (bh + gap) s += svg_rect(x0, y, bw, bh, fill, stroke, 10, 2) s += svg_text(x0 + 20, y + 25, name, 14, stroke, True) s += svg_text(x0 + bw - 20, y + 25, qty, 12, stroke, True) s += svg_text(x0 + 20, y + 48, desc, 11, "#333") if i < len(servers) - 1: s += svg_arrow_down(W/2, y + bh, y + bh + gap, "#bbb", 1.5, 10) s += svg_text(W/2, H - 20, "4台设备 · 最小成本验证完整体验闭环", 12, C_LAYER6_B, True) save_svg_and_jpg(s, "30_mvp_deploy") # ═══════════════════════════════════════════════════════════════ # 图31: 核心体验闭环 # ═══════════════════════════════════════════════════════════════ def gen_31_core_loop(): import math as _m W, H = 760, 560 s = svg_header(W, H) s += f'' s += svg_text(W/2, 30, "核心体验闭环", 20, C_TITLE, True) stages = [ ("提问", "参观前选择学习问题\nAI全程可问答", C_LAYER3, C_LAYER3_B), ("体验", "自适应路线 + 沉浸VR\n情境任务 + 文物星图", C_VR, C_VR_B), ("理解", "AI复盘 + 理解表达\n离馆报告", C_LAYER4, C_LAYER4_B), ("行动", "行动选择\n7/30/90天跟踪", C_LAYER2, C_LAYER2_B), ("反馈", "进展提交 + 成果回流\n优秀案例入库", C_LAYER5, C_LAYER5_B), ("再传播", "青年共创 + 云展馆\n全国节点复制", C_LAYER1, C_LAYER1_B), ] n = len(stages) cx, cy = W/2, 310 r = 180 bw, bh = 130, 60 # 计算每个节点的位置 pts = [] for i in range(n): angle = -_m.pi/2 + i * 2 * _m.pi / n # 从顶部开始顺时针 x = cx + r * _m.cos(angle) y = cy + r * _m.sin(angle) pts.append((x, y, angle)) # 先画弧形箭头连接 (相邻节点之间) for i in range(n): x1, y1, a1 = pts[i] x2, y2, a2 = pts[(i+1) % n] # 在圆弧上取中点偏移,画弧线 mid_angle = (a1 + a2) / 2 if i < n-1 else (a1 + a2 + 2*_m.pi) / 2 arc_r = r - 5 mx = cx + arc_r * _m.cos(mid_angle) my = cy + arc_r * _m.sin(mid_angle) # 画曲线箭头 s += f'' # 箭头头在终点 da = mid_angle - a2 if i < n-1 else mid_angle - a2 + 2*_m.pi bx = x2 - 12 * _m.cos(a2 + _m.pi/2) by = y2 - 12 * _m.sin(a2 + _m.pi/2) s += svg_arrow(bx, by, x2, y2, C_ARROW, 2, 12) # 画节点框和文字 (覆盖在线之上) for i, (title, desc, fill, stroke) in enumerate(stages): x, y, angle = pts[i] rx = x - bw/2 ry = y - bh/2 s += svg_rect(rx, ry, bw, bh, fill, stroke, 10, 2) s += svg_text(x, y - 5, title, 15, stroke, True) # desc 多行 lines = desc.split("\\n") for j, line in enumerate(lines): s += svg_text(x, y + 15 + j*14, line, 9, "#333") # 中心文字 s += svg_text(cx, cy - 5, "核心体验", 16, C_TITLE, True) s += svg_text(cx, cy + 15, "闭环", 16, C_TITLE, True) s += svg_text(cx, cy + 35, "一件文物 → 一次行动", 10, "#999") save_svg_and_jpg(s, "31_core_loop") # ═══════════════════════════════════════════════════════════════ # 主程序 # ═══════════════════════════════════════════════════════════════ if __name__ == "__main__": print("开始生成SVG → JPG...") gen_01_six_layer() gen_02_deployment() gen_03_ai_engine() gen_04_narrative_engine() gen_05_growth_engine() gen_06_replication_engine() gen_07_f1_x1() gen_08_f2_task() gen_09_f3_artifact() gen_10_f4_passport() gen_11_f5_cloud() gen_12_f6_cocreation() gen_13_f7_action() gen_14_f8_nodes() gen_15_vr_architecture() gen_16_vr_multiplayer() gen_17_vr_cloud_streaming() gen_18_x1_dataflow() gen_19_x2_sync() gen_20_x3_review() gen_21_security() gen_22_ai_guardrail() gen_23_multilang_flow() gen_24_x1_detail() gen_25_f3_scan_flow() gen_26_f2_vr_share() gen_27_vr_experience_flow() gen_28_mvp() gen_29_mvp_flow() gen_30_mvp_deploy() gen_31_core_loop() print(f"\n全部完成! 共生成31张JPG,保存在: {OUTPUT_DIR}")