3.1架构总览
架构的核心不是"层数多",而是边界清楚:业务不碰算法、算法不碰业务库、三维不碰业务逻辑、集成层承担所有外部不确定性。
一期团队 ≤ 15 人,不上微服务。按领域分模块、单库单事务,M4 后按压力拆 2–3 个服务即可。
算法、GIM、PMS、存储、鉴权全部走接口。外部变更只改适配器,不改业务代码。
工作台通过 `SceneAPI` 与业务通信:加载图层、拾取、量测、截图。业务不知道 Cesium 的存在。
3.2技术栈全表
选型优先考虑:内网可离线部署、国产化兼容、团队可招、许可证干净。版本号指一期基线。
| 层 | 技术点 | 选型 | 接入 / 使用方式 | 为什么 |
|---|---|---|---|---|
| 前端 | Web 框架 | Vue 3.5 + TS 5.6 + Vite 6 | SPA,按模块懒加载;Pinia 管状态;Vue Router 管路由与权限守卫。 | 国内团队熟悉、生态稳、招人容易 |
| 前端 | 组件库 | Element Plus 2.9 | 按需引入;通过 CSS Token 覆盖为平台设计语言。 | 表格/表单/树场景成熟 |
| 三维 | GIS 底座 | CesiumJS 1.124 | 仅使用 Viewer / Camera / 坐标 / 3D Tiles 加载;关闭不用的控件与地形服务。 | 地理坐标与瓦片标准成熟,轻量可控 |
| 三维 | 点云渲染 | Potree 2.0 / 3D Tiles pnts | PotreeConverter 转 octree;或直接 pnts 瓦片;统一由 `PointCloudLayer` 封装。 | 亿级点云 LOD 成熟 |
| 三维 | 3DGS 渲染 | 自研 WebGL2 Splat Renderer | 加载 .splat / .ply / SOG / SSOG;GPU 排序 + SH 颜色;与 Cesium 相机同步。 | 避免研究许可;可控性能 |
| 仿真 | OpenUSD / SimReady | USD 24.x + SimReady 1.0 | GIM → USD 转换;输出 .usda/.usdc/USDZ;碰撞、质量、摩擦、关节、语义标签;GUID ↔ Prim 映射。 | 机器人训练主资产(Isaac Sim / Omniverse) |
| 三维 | 3DGS 交付格式 | SOG / Streamed SOG | PLY 作源文件与归档;Web 发布转 SOG(压缩 15–20×);大场景用 lod-meta.json 空间树流式加载。 | 显存与带宽数量级下降(参考 MipMap3D) |
| 三维 | 瓦片加载 | 3d-tiles-renderer 0.4 | Three.js 场景内加载 3D Tiles;与 Cesium 共用相机矩阵。 | 弥补 Cesium 对点云/自定义材质不足 |
| 三维 | GIM 线框 | glTF / 自定义 BufferGeometry | GIM 解析后转 glTF + 构件 ID 映射表;按构件拾取。 | 浏览器原生高效 |
| 前端 | 图表 | ECharts 5.5 | 按需引入;报告页复用同一套 option。 | 国内工程图表适配好 |
| 桌面 | 桌面壳 | Electron 33 | 主进程管窗口/文件/更新;渲染进程加载同一 Web Bundle;本地 sidecar 提供 GPU 任务。 | 交付快、Node 生态成熟 |
| 后端 | 业务服务 | Java 21 + Spring Boot 3.3 | 模块化单体:project / task / indicator / defect / archive / system。 | 强类型、事务、国网生态兼容 |
| 后端 | ORM / 迁移 | MyBatis-Plus + Flyway | 复杂空间查询写 XML;表结构版本化迁移。 | SQL 可控、审计友好 |
| 算法 | 算法网关 | Python 3.11 + FastAPI | 独立服务,暴露任务提交/查询/取消/回调;Celery 执行长任务。 | 贴近算法生态、胶水能力强 |
| 算法 | 几何计算 | NumPy / SciPy / Open3D | 圆柱拟合、平面拟合、悬链线、最短距离;以纯函数封装,可单测。 | 算法团队可复用、可验证 |
| 数据 | 业务库 | PostgreSQL 16 + PostGIS 3.4 | 主数据、指标、缺陷强关系;空间字段用 geometry/geography。 | 事务 + 空间一体 |
| 数据 | 对象存储 | MinIO (S3) | 预签名上传/下载;分片、断点续传、版本控制、Object Lock。 | 私有化、S3 兼容、可换云 |
| 数据 | 消息队列 | RabbitMQ 3.13 | 任务下发、状态事件、通知;DLQ + 重试队列。 | 长任务解耦、可靠投递 |
| 数据 | 缓存 | Redis 7 | 会话、字典、分布式锁、任务进度。 | 简单够用 |
| 集成 | 鉴权 | Keycloak 26 (OIDC) | 对接 LDAP/AD;前端 Authorization Code + PKCE;后端 resource server。 | 标准协议、可接国网 4A |
| 集成 | 接口文档 | OpenAPI 3.1 + AsyncAPI | 代码生成 TS 客户端;Mock Server 供前端联调。 | 契约先行落地手段 |
| 运维 | 容器与编排 | Docker + Compose / K8s | 一期 Compose 单机;多项目并发或 HA 时上 K8s。 | 降低一期运维复杂度 |
| 运维 | 可观测 | OTel + Prometheus + Grafana + Loki | Java/Python/前端统一 OTLP 上报;traceId 全链路透传。 | 排障刚需 |
| 质量 | CI/CD | GitLab CE + Harbor | 内网流水线:lint → test → SAST → image scan → 部署。 | 离线、可控 |
3.3前端与三维架构
三维工作台是整个平台技术难度最高的地方。它不是"嵌一个 Cesium",而是"三个渲染通道 + 一套坐标 + 一套拾取 + 一套量测"。
前端分层
应用层 · App Shell
路由、权限、布局、主题、国际化、错误边界、埋点。
业务模块层 · Features
project / task / indicator / defect / archive / report / admin,按路由懒加载。
领域组件层 · Components
指标表格、三级判定标签、缺陷时间线、资产校验卡、量测结果面板。
三维适配层 · SceneAPI
唯一允许 import Cesium / Three.js 的地方。对外只暴露 loadLayer / pick / measure / screenshot。
平台适配层 · Platform
DataPathProvider / ComputeProvider / ShellBridge,隔离 B/S 与 C/S 差异。
基础设施层 · Core
HTTP 客户端、鉴权、错误码、埋点、缓存、工具函数。
SceneAPI:三维与业务的唯一接口
TS Interface// 业务层只依赖这个接口,不依赖 Cesium interface SceneAPI { load(layer: LayerSpec): Promise<LayerHandle> setCamera(view: ViewPreset | CameraPose): void setLayerVisible(id: string, v: boolean): void setOpacity(id: string, v: number): void pick(screen: Vec2): PickResult | null measure(tool: MeasureTool, points: Vec3[]): MeasureResult snap(screen: Vec2, radius: number): Vec3 | null screenshot(opt?: ShotOpt): Promise<Blob> on(event: SceneEvent, cb: Function): Unsubscribe }
这一层做对,未来换 Cesium 版本、换渲染库、甚至换 WebGPU,都不影响业务代码。
三通道渲染与坐标统一
SOG / SSOG 优先,.splat / .ply 兼容 → GPU 排序 → 球谐颜色 → 与相机同步。支持分层 LOD、裁剪框、透明度。
Potree octree / 3D Tiles pnts;按屏幕空间误差加载;支持按分类、强度、高程着色。
解析为 glTF + 构件映射;线框模式 + 半透明实体;按设备编码拾取。
坐标转换链:一次说清
最容易出错性能预算(1 亿点 / 单工程 20 GB)
| 指标 | 目标 | 手段 | 降级策略 |
|---|---|---|---|
| 首屏可交互 | ≤ 8 s | 瓦片预加载 + 首屏 LOD + Web Worker 解析 | 先加载低精度,再渐进 |
| 帧率 | ≥ 30 FPS | 点预算控制、实例化、GPU 排序 | 关闭 3DGS / 降低点密度 |
| 拾取延迟 | ≤ 50 ms | GPU picking + 空间索引 | 退回屏幕空间近似 |
| 内存占用 | ≤ 2.5 GB | LRU 卸载、分块加载 | 限制同屏图层数 |
| 量测精度 | ≤ 10 mm | float64 本地坐标 + 拟合算法 | — |
3.4后端架构
一期采用"模块化单体 + 一个独立算法网关",而不是一上来拆 10 个微服务。理由很现实:团队规模、事务一致性、运维成本。
业务服务模块划分
| 模块 | 职责 | 关键表 |
|---|---|---|
| project | 工程、标段、单位工程、参与方 | prj_project / prj_unit |
| dataset | 数据登记、版本、成果、CRS | ds_asset / ds_version |
| task | 算法任务、状态机、回调 | tsk_task / tsk_event |
| indicator | 规则库、量测、判定、证据 | ind_rule / ind_result |
| defect | 缺陷、整改单、复验 | dfc_defect / dfc_flow |
| archive | 资产包、哈希、签署、WORM | arc_package / arc_file |
| report | 模板、快照、导出 | rpt_template / rpt_job |
| system | 用户、角色、字典、审计 | sys_user / sys_audit |
为什么不是微服务
团队规模不匹配
一期 6–8 名研发。微服务的部署、链路、配置、联调成本会吃掉 30% 产能。
强事务场景多
指标判定 + 缺陷生成 + 证据写入必须在一个事务里。跨服务分布式事务是自找麻烦。
部署环境受限
国网内网、等保、离线升级。一个 compose 栈比 10 个服务好运维得多。
但保留拆分缝
模块间只通过应用服务接口调用,不跨模块查表。未来按 task / indicator 拆出即可。
核心事务:一次指标判定写入什么
// IndicatorService.verify() 单事务 1. select ind_rule for update // 锁定规则版本,防止并发改规则 2. 计算 design / model / sample / deviation // 纯函数,可单测 3. 三级判定 verdict + reasonCode // pass / watch / fail / pending 4. insert ind_result(含 ruleVersion、algoVersion) 5. insert ind_evidence × N(文件 ID + 哈希 + 截图 + 量测点) 6. if fail → insert dfc_defect + 初始化状态机 7. insert sys_audit(who / when / before / after) 8. 发事件 indicator.verified → 报告/看板异步刷新
ind_result 版本,旧版本保留。否则无法解释"为什么上周是合格,这周是超限"。3.5集成层与接入方式
这一节是交底重点:每个外部系统到底怎么接、用什么协议、失败怎么处理、谁负责。
| 外部系统 | 接入方式 | 接口约定 | 失败处理 | 负责人 |
|---|---|---|---|---|
| 算法平台 重建/配准/分割 |
HTTP REST Webhook S3 | 平台 POST 任务单(含输入清单、参数、回调地址);算法侧返回 taskId;进度通过 webhook 或 GET 轮询;成果写回预签名 S3 路径;完成回调携带 manifest。 | 超时 30s;失败重试 3 次指数退避;回调签名校验;重复回调幂等。 | 算法接口人 |
| 算法平台 大规模异步 |
RabbitMQ(可选) | topic: algo.task.submit / algo.task.progress / algo.task.done;消息体同 HTTP schema;DLQ 保存 7 天。 |
消费幂等、死信告警、人工重放。 | 算法接口人 |
| GIM 解析工具 | CLI / 容器 | 挂载工作目录,执行 gim-parser --in /work/in --out /work/out --crs EPSG:4547;stdout 输出 JSON 摘要;退出码 0/2/3 定义成功/数据错/内部错。 |
超时 10 min;沙箱无网络;输出目录只读校验;失败保留现场。 | 工具提供方 |
| PMS / EAM | REST / ESB | OAuth2 client credentials;设备台账查询、资产编码映射、转资回写;字段映射表可配置。 | 夜间全量 + 变更增量;失败进入补偿队列;不阻塞主流程。 | 业主信息中心 |
| 设计院 DMS / 协同平台 | REST / 工单 | 设计复核单、现场澄清、设计变更、GIM 版本回写;工单双向同步,外部单号对账。 | 超时重试 + 人工催办;设计变更触发重新配准与指标复算。 | 设计接口人 |
| 统一身份 / 4A | OIDC / LDAP | Authorization Code + PKCE;token 15 min;refresh 8 h;角色从 LDAP 组映射。 | 降级到本地账号(仅管理员),强制审计。 | 业主信息中心 |
| 时间戳服务 | RFC 3161 | 归档时对包哈希申请 TSA 时间戳;无外网时使用内网 TSA 或哈希链 + 可信时钟。 | 失败则挂起归档,不允许"先归档后补"。 | 安全管理员 |
| 电子签章 | SM2 / PAdES | PDF 签署接口;证书由业主 CA 颁发;签章位置模板化。 | 签章失败保留待签状态,可重试。 | 安全管理员 |
算法交接时序(必须按这个顺序联调)
3.6数据与存储架构
业务数据用关系库,成果数据用对象存储,空间数据用 PostGIS,归档数据用 WORM。四类数据四种策略,不要混。
对象存储目录规范
s3://verif-prod/ ├── projects/{projectId}/ │ ├── raw/{datasetVersion}/images|las|control/ │ ├── recon/{taskId}/splat|pointcloud|tiles/ │ ├── gim/{gimVersion}/source|gltf|props/ │ ├── evidence/{indicatorId}/{resultId}/ │ ├── defects/{defectId}/photos/ │ └── reports/{reportId}/ ├── archive/{projectId}/{packageVersion}/ │ └── manifest.json + 9 类成果 + signatures/ └── tmp/{taskId}/ // 7 天生命周期
- 桶策略:业务桶私有,归档桶开启 Object Lock(Compliance 模式)。
- 上传:前端分片直传预签名 URL,后端只发凭证,不中转大文件。
- 下载:短时效预签名(≤ 5 min),审计记录。
- 版本:同名文件不允许覆盖,路径带版本号。
核心数据模型(简版 ER)
ind_result(project_id, category, verdict) 组合索引支撑 408 项看板;tsk_task(status, created_at) 支撑任务队列;审计表按月分区。3.7B/S + C/S 双形态
这不是"做两个版本",而是"一套业务代码 + 三个适配点"。架构必须让差异收敛到可枚举的接口。
B/S 主端
- 运行时
- 浏览器(Chrome / Edge 100+)
- 数据面
- 平台对象存储
- 算力
- 平台集群 / GPU 队列
- 优势
- 免安装、易升级、跨地域
- 限制
- 涉敏数据不作为默认通道
C/S 桌面端
- 运行时
- Electron 33(Win 10/11)
- 数据面
- 本地盘 / 工程内网盘
- 算力
- 本地 GPU + sidecar
- 优势
- 数据不出内网、可离线
- 限制
- 安装包、升级、驱动兼容
铁律:业务代码零分支
if (isDesktop) 出现在业务组件、页面、store 中。platform/ 目录下的三个 Provider 实现。PlatformProvider。| 差异点 | 抽象接口 | B/S 实现 | C/S 实现 | 注意 |
|---|---|---|---|---|
| 数据路径 | DataPathProvider | S3 预签名 URL | 本地文件协议 + 内网盘映射 | 统一返回可读流,不暴露路径 |
| 算力调度 | ComputeProvider | 提交到集群队列 | 调用本地 sidecar(GPU) | 任务状态机保持一致 |
| 文件系统 | FileBridge | 浏览器下载 / File System Access API | 原生保存对话框 / 批量导出 | 大文件分片与断点 |
| 外壳能力 | ShellBridge | 无(降级) | 窗口、托盘、离线缓存、自动更新 | 能力探测,不可用则隐藏入口 |
| 打印 / 截图 | ExportBridge | Canvas → Blob → 下载 | 原生打印 / 高分辨率导出 | DPI 与色彩一致 |
3.8部署拓扑
典型国网内网部署:办公区访问、应用区计算、数据区存储、GPU 区渲染、算法区隔离、备份区兜底。
3.9安全与等保
等保三级不是"上线前补材料",而是架构里就要有的东西。以下条目建议逐项落到设计与代码评审清单。
| 领域 | 措施 | 落地位置 |
|---|---|---|
| 身份 | OIDC + MFA;账号锁定;会话超时 30 min | Keycloak / 网关 |
| 授权 | RBAC + ABAC;接口级 + 数据行级 | Spring Security |
| 传输 | TLS 1.2+;国密 SM2/SM4 可选 | Nginx / 服务间 mTLS |
| 存储 | 敏感字段加密;对象存储 SSE | PG / MinIO |
| 审计 | 登录、导出、判定、签署全留痕;不可删 | sys_audit + WORM |
| 备份 | 数据库 PITR;对象存储跨节点;异地副本 | 运维平台 |
| 漏洞 | 镜像扫描、依赖扫描、SAST、渗透测试 | CI + 上线前 |
| 供应链 | SBOM、许可证扫描、制品签名 | Harbor / Cosign |
L1 公开 / L2 内部 / L3 敏感(原始影像、点云、坐标)/ L4 核心(涉密)。L3 以上禁止出内网;C/S 本地处理;导出需审批与水印。
文件 SHA-256 → 包哈希 → TSA 时间戳 → 电子签章。四步缺一不可,且必须可离线验证。哈希算法变更需版本化。
独立 Service Account;仅任务前缀读写;禁止列举桶;禁止访问业务库;所有调用带 traceId 与签名。
3.10可观测性与运维
接口 P95/P99、任务队列长度、GPU 利用率、渲染帧率、对象存储吞吐、判定耗时。
结构化 JSON;traceId / projectId / taskId 三键可查;敏感字段脱敏;保留 180 天。
前端 → 网关 → 业务 → 算法 → 存储全链路;慢调用自动采样。
| 告警项 | 阈值 | 级别 | 动作 |
|---|---|---|---|
| 算法任务积压 | > 10 个 / 30 min | P2 | 扩容 worker / 通知算法团队 |
| 任务失败率 | > 5% / 1 h | P1 | 暂停自动重试,人工介入 |
| 接口 P99 | > 2 s | P2 | 排查慢 SQL / 锁 |
| 对象存储错误率 | > 1% | P1 | 检查 MinIO 节点 / 磁盘 |
| 归档校验失败 | > 0 | P1 | 阻断移交,定位文件 |
| 证书到期 | < 30 天 | P2 | 自动续期 / 人工更换 |
| 备份失败 | > 0 | P1 | 立即补备并排查 |
3.11选型取舍与备选方案
| 决策点 | 首选 | 备选 | 取舍理由 | 切换成本 |
|---|---|---|---|---|
| 桌面壳 | Electron 33 | Tauri 2 | 团队 Node 经验足;生态成熟;包体大但内网可接受 | 中(外壳重写,业务不变) |
| 三维底座 | CesiumJS | Three.js 纯自研 | Cesium 解决地理坐标与 3D Tiles;Three 补渲染 | 高 |
| 点云 | Potree | 3D Tiles pnts | Potree 生态成熟;pnts 与 Cesium 更紧 | 中 |
| 业务后端 | Java / Spring Boot | Python / FastAPI | 事务、权限、国网生态;算法侧仍用 Python | 高 |
| 数据库 | PostgreSQL + PostGIS | 达梦 / 人大金仓 | 空间能力成熟;信创适配留到二期 | 中 |
| 消息 | RabbitMQ | Kafka | 任务型场景 Rabbit 更简单;Kafka 适合事件流 | 低 |
| 编排 | Docker Compose | K8s | 一期单机房、少服务;K8s 运维成本高 | 低 |
| 鉴权 | Keycloak | 自研 / 4A 直连 | 标准协议、可联邦、可离线 | 中 |