基于 React、Three.js 和 FastAPI 的 3D 可视化拖拽编辑器 MVP,提供项目中心、组件库、三维场景画布、属性面板和场景编排能力。
当前实现覆盖最终需求规格说明书中的核心开发链路:
- 默认进入项目列表页(
#/):项目卡片展示图标、名称、描述、对象数与更新时间 - 内置 6 个实际使用场景示例,开箱即可体验编辑、预览与发布全流程:
- 🏙️ 智慧楼宇与园区安防:BIM 楼宇、园区 GIS、门禁视频与消防感知
- 🏭 智能工厂产线监控:数控加工、机器人作业、输送与厂内物流
- 🛍️ 3D 数字化展厅:沉浸式展销、热点讲解与商品虚拟定制
- 📦 智慧仓储 WMS 中心:库位、托盘、AGV、叉车与出入库协同
- ⚡ 智慧城市与能源基建:城市建筑、交通桥梁、风光电网与态势感知
- 🗄️ 数据中心 DCIM 运维:服务器机柜、制冷、UPS 配电与动环监控
- 点击卡片进入项目编辑器(
#/project/:id),面包屑可返回项目中心 - 新建项目(名称必填、描述可选)与删除项目(带确认,示例项目不可删除)
- 项目列表支持按名称/描述搜索
- 多项目草稿、发布记录、运行错误相互隔离;旧版单项目 localStorage 数据自动迁移到「智慧楼宇与园区安防」
- 组件库搜索、分类、点击添加和拖拽添加
- 建筑/交通/安防/工业/仓储/能源/展陈/机房组件:园区建筑、办公楼、厂房、仓库、道路、车辆、摄像机、门禁、机器人、数控机床、输送线、货架、托盘、AGV、桥梁、输电塔、风机、光伏、数字展台、展示屏、服务器机柜、精密空调和 UPS
- Three.js 三维画布、网格、坐标轴、节点选择和基础对象渲染
- 画布 Gizmo:对象移动、旋转、缩放,支持 0.5 单位移动吸附和 15 度旋转吸附
- 鼠标拖拽落点:按画布射线计算地面坐标,组件不会再固定出现在默认位置
- 真实资源库:上传 GLB、单文件 GLTF、PNG、JPG、WebP;图片显示缩略图,资源通过点击加入场景并可安全删除
- 资源上传前同步校验文件签名与 GLTF/GLB 结构,外部
.bin/纹理依赖的多文件 GLTF 会明确拒绝并提示改用自包含 GLB - 场景树:选择、折叠/展开、点击眼睛图标切换对象可见性和层级展示
- 属性编辑:名称、位置、旋转、缩放、颜色、透明度、文本、数值、可见和锁定;锁定对象不可删除并给出提示
- 运行态预览:隐藏编辑器工具栏,展示只读 3D 场景;标题、副标题与指标卡跟随项目配置(指标为示例数据)
- 场景编排与对象事件分层:顶部「场景编排」管理整个画布的场景时间轴和场景事件,右侧「对象事件」只管理当前选中建筑/设备的点击、双击和悬停交互
- 事件规则闭环:支持相机聚焦、显示弹窗、设置颜色、显示/隐藏;场景级规则和对象级规则均随草稿、发布版本和回滚持久化
- 六个内置示例项目均已配置业务事件,可在预览模式中点击关键对象验证交互效果
- 数据源绑定:支持静态 JSON、REST GET/POST 和 WebSocket,可绑定数值、文字、颜色、透明度和显隐;柱图、折线图、仪表盘会随数值实时更新
- 发布版本、发布记录(本地模式下持久化到 localStorage,刷新不丢失)、回滚和基础运行错误列表
- 可用的撤销/重做(保留 50 步历史,撤销后保持当前选择)、网格开关、场景 JSON 导出以及 W/E/R 模式快捷键
- 返回项目中心时若有未保存变更,自动补一次保存,避免切换页面丢数据
- 使用
:root语义化设计令牌(背景、边框、主色、圆角和滚动条等),后续换肤只需覆盖变量 - 全局细滚动条:WebKit 圆角拇指 + Firefox
scrollbar-width/scrollbar-color,透明轨道不挤占版面 - 键盘可达性:统一的
:focus-visible焦点环,鼠标点击不触发 - 对话框/发布抽屉进出场动效、按钮与输入框统一过渡、文本选区配色
- 属性面板数字输入隐藏原生步进箭头
- 尊重系统「减弱动态效果」偏好(
prefers-reduced-motion) - 最低支持 1280px 宽桌面屏;编辑器三栏按
clamp()流式收缩,不做移动端适配
当前版本为可运行的单机 MVP。真实模型通过 GLTFLoader 加载;项目索引、草稿、发布版本、资源元数据和运行错误持久化到 DATA_DIR。数据源凭证使用 Fernet 独立加密保存,不会出现在草稿、发布产物或运行态响应中。当前持久化方案面向单个 FastAPI 进程,多实例部署仍需 PostgreSQL/Redis。
前端使用哈希路由,无需服务端路由配置:
| 路由 | 页面 | 说明 |
|---|---|---|
#/ |
项目中心 | 项目列表(默认页)、搜索、新建、删除 |
#/project/:id |
项目编辑器 | 场景编辑、预览、发布、回滚(页内切换) |
3dvision/
├── src/ # React + Three.js 前端
│ ├── App.tsx # 哈希路由入口(项目中心 / 编辑器)
│ ├── ProjectsPage.tsx # 项目中心:列表、搜索、新建、删除
│ ├── EditorPage.tsx # 场景编辑器状态编排与工作台布局
│ ├── editor/ # 侧栏、属性、数据、事件、时间轴、预览与发布组件
│ ├── demos.ts # 内置示例项目场景与运行态指标配置
│ ├── SceneCanvas.tsx # Three.js 场景生命周期与交互
│ ├── sceneObjects.ts # Three.js 内置对象工厂与资源释放
│ ├── threeText.ts # 中文 3D 文字与贴图回退
│ ├── api.ts # 项目/草稿/发布接口与本地降级
│ ├── types.ts # 场景、组件、事件与项目类型
│ └── styles.css # 深色工作台样式(设计令牌 + 细滚动条 + 自适应)
├── backend/ # FastAPI 后端
│ ├── main.py # FastAPI 应用与 CORS 装配
│ ├── models.py # API 请求模型
│ ├── store.py # DATA_DIR 项目索引与示例初始化
│ ├── storage.py # 资源与发布产物的磁盘存储
│ ├── security.py # 数据源凭证加密仓
│ ├── asset_validation.py # GLTF/GLB/图片同步校验
│ ├── common.py # 统一响应结构
│ ├── routes/ # 项目版本、资源、运行态与数据源路由
│ ├── requirements.txt
├── public/fonts/ # 浏览器运行时使用的 Three.js 字体与许可证
├── scripts/fonts/ # 字体子集生成和验证脚本,不放运行时文件
├── scripts/backup.ps1 # 单机 DATA_DIR 备份脚本
├── 3D可视化拖拽系统-最终需求规格说明书.md
└── README.md
- Node.js 20 或更高版本
- npm 10 或更高版本
- Python 3.11 或更高版本(启动 FastAPI 时需要)
- 支持 WebGL 的现代 Chrome 或 Edge(最低支持 1280px 宽桌面屏)
后端未启动时,前端会自动使用 localStorage 保存项目、草稿和发布版本,并预置 6 个示例项目,可以直接体验完整流程。
npm install
npm run dev浏览器打开:http://localhost:5173(默认进入项目中心)
终端一启动 FastAPI:
cd backend
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
uvicorn main:app --reload --port 8000终端二启动前端:
npm install
$env:VITE_API_BASE="/api"
npm run dev不设置 VITE_API_BASE 时,前端使用浏览器 localStorage,不会请求未启动的后端;设置为 /api 后,Vite 会把 API 请求代理到 127.0.0.1:8000(同源代理场景无需额外 CORS 配置)。
后端默认不启用 CORS。仅当前端与 API 跨域部署时,需在启动 API 前设置允许的前端来源:
$env:ALLOWED_ORIGINS = "http://localhost:5173"
uvicorn main:app --reload --port 8000API 健康检查:http://localhost:8000/api/health
| 环境变量 | 默认值 | 说明 |
|---|---|---|
DATA_DIR |
项目根目录下的 data/ |
项目索引、资源、发布产物、任务和加密凭证目录 |
APP_SECRET_KEY |
自动生成 DATA_DIR/.secret-key |
数据源凭证加密主密钥;生产环境应固定配置并妥善备份 |
DATA_SOURCE_ALLOW_PRIVATE |
0 |
默认拒绝本机、私网和保留地址;仅在明确可信的内网数据源环境设为 1 |
ALLOWED_ORIGINS |
空 | 跨域部署时允许访问 API 的前端来源,多个值用逗号分隔 |
资源上传接口已经同步完成校验,正常使用不依赖单独启动 Worker。backend/worker.py 仅保留文件任务队列的维护入口;目录初始化、发布文件检查和资源重验可执行:
python -m backend.migrate
python -m backend.migrate --rechecknpm run build
npm run preview构建产物位于 dist/。生产环境建议由 Nginx 托管 dist/,并将 /api 反向代理到 FastAPI。
Windows 开发环境可执行:
.\scripts\backup.ps1脚本会读取 DATA_DIR(未配置时使用项目根目录的 data/),一起压缩 assets、releases、projects.json、secrets.json 和 .secret-key。.secret-key 必须与 secrets.json 成组恢复,否则历史凭证无法解密。备份完成后应把压缩包复制到项目目录之外的本地电脑、NAS 或对象存储。
public/fonts/noto-sans-sc-subset.typeface.json是浏览器运行时资源,src/threeText.ts会直接加载,因此需要提交。scripts/fonts/*.py、*.mjs是字体子集生成与验证工具。scripts/fonts/*.ttf和scripts/fonts/chars.txt是本地输入/中间产物,已加入.gitignore,不需要提交。public/fonts/OFL.txt是随运行时字体保留的 SIL Open Font License。
需要重新生成字体时,在本地准备 scripts/fonts/NotoSansSC-VF.ttf,然后执行:
python scripts/fonts/make_subset.py
node scripts/fonts/ttf_to_typeface.mjs
node scripts/fonts/verify_font.mjs标注“前端已接入”的接口由页面实际调用;其余为后端可用、前端暂未消费的能力。
| 方法 | 路径 | 说明 | 前端 |
|---|---|---|---|
| GET | /api/health |
健康检查 | — |
| GET | /api/projects |
项目列表(含示例项目元信息) | ✅ 已接入 |
| POST | /api/projects |
创建项目 | ✅ 已接入 |
| DELETE | /api/projects/{id} |
删除项目 | ✅ 已接入 |
| GET/PUT | /api/projects/{id}/draft |
读取/保存草稿(409 表示版本冲突) | ✅ 已接入 |
| POST | /api/projects/{id}/releases |
创建发布版本 | ✅ 已接入 |
| GET | /api/projects/{id}/releases |
查询历史版本 | ✅ 已接入 |
| GET/POST | /api/projects/{id}/assets |
查询/上传项目资源 | ✅ 已接入 |
| GET/DELETE | /api/assets/{id} |
查询/删除资源元数据 | ✅ 已接入 |
| GET | /api/assets/{id}/content |
读取资源内容 | ✅ 已接入 |
| POST | /api/data-sources/test |
测试数据源并提取字段 | ✅ 已接入 |
| POST | /api/data-sources/fetch |
运行态代理拉取数据 | ✅ 已接入 |
| POST | /api/runtime/errors |
上报运行错误(按 projectId 归属) | ✅ 已接入 |
| POST | /api/releases/{id}/rollback |
回滚版本 | 暂未接入(前端本地回滚) |
| GET | /api/runtime/{id} |
获取运行态场景 | 暂未接入(预览使用当前场景) |
| GET/DELETE | /api/projects/{id}/errors |
查询/清理运行错误列表 | ✅ 已接入 |
| WS | /api/runtime/{id}/ws |
实时数据通道(回声占位) | 暂未接入 |
说明:后端已预置 6 个示例项目的元信息(草稿内容为空);前端打开未保存过草稿的示例项目时,会使用 src/demos.ts 中的内置场景作为编辑起点,首次自动保存后即持久化到后端。
- 点击顶部「场景编排」,打开底部「场景时间轴」。时间轴属于整个画布,关键帧可以分别绑定到场景中的建筑、设备或其他对象。
- 选中一个对象,在属性面板修改位置、旋转、缩放、颜色、透明度或显隐状态,然后在底部选择对应属性并点击「在当前时间添加关键帧」。同一对象、同一属性、同一时间重复添加会覆盖原关键帧。
- 拖动时间轴播放头或点击播放按钮,可在编辑器画布中实时预览。修改场景时长(1 至 3600 秒)和「循环播放」后,编辑器会在停止操作 10 秒后自动保存草稿,离开编辑器时也会补保存。
- 点击「预览」进入运行态后,时间轴会自动播放;循环开启时从头循环,关闭时播放到末尾停止。发布版本、访问链接和版本回滚都会携带时间轴及关键帧数据。
- 关键帧之间的位置、旋转、缩放、颜色和透明度采用线性插值;显隐属性采用离散切换。六个内置 Demo 还带有场景相机关键帧,会自动完成全景、推进、局部环绕和回景镜头;没有关键帧的对象保持静态,不影响原有场景交互事件。
- 点击顶部「场景编排」,在底部切换「场景时间轴」或「场景事件」。场景事件不依赖当前选中对象,适合场景加载、全局触发和跨对象动作。
- 选中一个建筑或设备,在右侧切换「对象事件」,点击「添加对象事件」。对象事件归属于当前选中对象,触发对象自动固定为该对象。
- 配置触发方式、触发对象、执行动作和动作对象:
- 相机聚焦:运行态点击对象后视角移动到目标对象。
- 显示弹窗:运行态弹出业务说明卡片。
- 设置颜色:运行态临时改变目标对象颜色。
- 显示/隐藏:运行态临时切换目标对象可见性。
- 点击顶部「预览」,在运行态验证场景加载规则和对象交互规则。
- 草稿保存和发布版本都会携带
scene.events;事件规则包含scope(scene/node)和ownerNodeId,回滚后两类规则都会恢复。
npm test -- --run
npm run build
python -m unittest tests_backend.test_backend -v
python -m compileall backend当前验证基线:前端共 5 个测试文件、42 项测试通过(包含 Schema 字段、边界校验、 嵌套更新与发布阻断专项覆盖);生产构建通过。Vite 仍会报告约 1.1 MB 主包体积警告, 属于后续按路由拆包的性能优化项,不影响当前功能运行。
仓库已配置保存时自动格式化。使用 VS Code 或 Cursor 打开项目后,安装工作区推荐的 Prettier 和 Black Formatter 扩展;保存 TypeScript、TSX、CSS、JavaScript、JSON 或 Python 文件时会自动使用项目规则格式化。
手动格式化全部前后端代码:
npm run format仅检查格式但不修改文件:
npm run format:check后端格式化命令通过 uvx 运行 Black,因此需要本机安装 uv。执行 npm install 会安装
项目固定版本的 Prettier。
- 当前文件仓储支持单进程重启恢复,不支持多个 FastAPI Worker 并发写入;多实例生产环境需接入 PostgreSQL/Redis。
- 当前上传支持 GLB 和自包含单文件 GLTF,不支持多文件 GLTF、分片上传、模型压缩和自动 LOD。
- 预览运行态渲染的是当前编辑场景而非服务端已发布版本;回滚在前端完成后保存为新草稿。
- 场景时间轴和事件动作已支持排序、条件与数据源触发;更复杂的脚本动作仍不开放。
- 后端 WebSocket 为回声占位,实时数据推送需要按需求规格接入。
- 用户认证、RBAC、资源访问鉴权和完整审计日志仍属于生产化增强。
- 前端生产包包含 Three.js 和字体资源,当前 JavaScript 主包约 1.1 MB,后续需要按路由拆包。
- 界面按 1280px 及以上桌面屏设计,未适配移动端。

