diff --git a/README.md b/README.md index 5e53668..03df162 100644 --- a/README.md +++ b/README.md @@ -1,121 +1,318 @@ # Interactive Mindmap -基于 Next.js、FastAPI 和 SQLite 的交互式思维导图应用,支持通过腾讯云 AI Agent 对话生成思维导图。 +基于 `Next.js 14`、`FastAPI` 和 `SQLite` 的思维导图项目。 + +当前项目的实际使用方式是: + +- 腾讯云智能体工作流生成思维导图 JSON +- 后端 `POST /api/mindmaps` 保存脑图并返回访问链接 +- 前端通过 `/mindmap/[id]` 展示脑图 +- 在脑图详情页中,双击节点可打开右侧聊天面板,继续通过腾讯云智能体进行对话 + +## 当前功能 + +- 保存思维导图 JSON,并生成可访问链接 +- 展示思维导图详情页 +- 支持节点展开/收缩 +- 支持在详情页中对节点发起对话 +- 后端代理腾讯云智能体 SSE 接口 ## 项目结构 -``` +```text mindmap/ -├── backend/ # FastAPI 后端 +├── backend/ │ ├── app/ -│ │ ├── main.py # 应用入口 -│ │ ├── config.py # 配置 -│ │ ├── database.py # 数据库 -│ │ ├── models.py # 数据模型 -│ │ ├── schemas.py # Pydantic schemas +│ │ ├── main.py +│ │ ├── config.py +│ │ ├── database.py +│ │ ├── models.py +│ │ ├── schemas.py │ │ └── routers/ -│ │ ├── mindmaps.py # 思维导图 CRUD API -│ │ └── chat.py # AI 对话代理 (SSE) -│ ├── data/ # SQLite 数据库文件 +│ │ ├── chat.py +│ │ └── mindmaps.py +│ ├── data/ │ ├── requirements.txt │ └── .env.example -├── frontend/ # Next.js 前端 +├── frontend/ │ ├── app/ -│ │ ├── page.tsx # 首页 +│ │ ├── page.tsx │ │ └── mindmap/ -│ │ ├── [id]/page.tsx # 思维导图详情页 -│ │ └── chat/page.tsx # AI 对话 + 思维导图页 +│ │ └── [id]/page.tsx │ ├── components/ -│ │ ├── MindmapCanvas.tsx # 思维导图画布 -│ │ ├── MindmapNodeCard.tsx # 节点卡片 -│ │ ├── ChatPanel.tsx # 聊天面板 -│ │ └── CreateMindmapForm.tsx # 创建表单 +│ │ ├── ChatPanel.tsx +│ │ ├── MarkdownMessage.tsx +│ │ ├── MindmapCanvas.tsx +│ │ └── MindmapNodeCard.tsx │ ├── lib/ -│ │ ├── api.ts # API 调用 -│ │ └── treeToGraph.ts # 树转图布局 -│ └── types/ -│ └── mindmap.ts # TypeScript 类型 -└── mind_prompt.md # AI Agent 系统提示词 -``` - -## 环境配置 - -### 后端 - -1. 安装依赖: - -```bash -cd backend -pip install -r requirements.txt -``` - -2. 配置环境变量: - -```bash -# 复制示例配置 -cp .env.example .env - -# 编辑 .env,填入腾讯云 AI Agent 的 bot_app_key -TENCENT_BOT_APP_KEY=your-key-here -``` - -3. 启动后端: - -```bash -TENCENT_BOT_APP_KEY=your-key-here uvicorn app.main:app --reload -``` - -### 前端 - -1. 安装依赖: - -```bash -cd frontend -npm install -``` - -2. 启动开发服务器: - -```bash -npm run dev +│ │ ├── api.ts +│ │ ├── tencentSse.ts +│ │ └── treeToGraph.ts +│ ├── types/ +│ │ └── mindmap.ts +│ └── package.json +├── mind_prompt.md +├── 宝塔面板部署指南.md +└── 腾讯云工作流说明.md ``` ## 页面说明 ### 首页 `/` -输入主题创建思维导图(使用 mock 数据)。 +当前首页是项目说明页,不负责直接创建脑图。 -### 思维导图详情 `/mindmap/[id]` +### 思维导图详情页 `/mindmap/[id]` -查看已保存的思维导图,支持节点展开/收缩。 +该页面会: -### AI 对话生成 `/mindmap/chat?sessionId=xxx` +- 从后端读取指定 `unique_id` 的脑图数据 +- 渲染交互式脑图 +- 双击节点后打开右侧聊天面板 +- 聊天面板通过 `/api/chat` 与腾讯云智能体交互 -通过与腾讯云 AI Agent 对话生成思维导图: +## 后端接口 -- **左侧**: 思维导图画布,初始为空,AI 返回有效数据后自动渲染 -- **右侧**: 聊天面板,支持实时 SSE 流式响应 +### `GET /` -URL 参数: -- `sessionId` (必填): 会话 ID,用于标识对话会话 +健康检查接口。 -## 数据流 +返回: -``` -用户输入 → ChatPanel → POST /api/chat → 后端代理 → 腾讯云 SSE API - ↓ -画布更新 ← onMindmapUpdate ← JSON 解析 ← SSE 流式响应 ←─┘ +```json +{"message":"Interactive Mindmap API is running"} ``` -1. 用户在聊天面板输入消息 -2. 前端发送 POST 请求到后端 `/api/chat` -3. 后端将请求代理到腾讯云 AI Agent SSE 接口 -4. SSE 流式响应逐步返回到前端 -5. 前端解析 SSE 事件,逐步显示 AI 回复 -6. 当 AI 回复完成后,尝试从回复中提取思维导图 JSON -7. 如果提取成功,更新左侧画布 +### `POST /api/mindmaps` -## AI Agent 配置 +创建并保存思维导图。 -参见 [mind_prompt.md](./mind_prompt.md) 获取 AI Agent 的系统提示词配置。 +请求体: + +```json +{ + "session_id": "session_001", + "mindmap_json": { + "id": "node_0", + "label": "主题", + "parent_id": null, + "level": 0, + "is_leaf": false, + "children": [] + } +} +``` + +返回中会包含: + +- `unique_id` +- `title` +- `url` +- `tree` + +### `GET /api/mindmaps/{unique_id}` + +读取指定脑图详情。 + +### `POST /api/chat` + +后端代理腾讯云智能体 SSE 接口。 + +请求体: + +```json +{ + "session_id": "session_001", + "content": "帮我解释一下这个节点", + "visitor_biz_id": "default_visitor" +} +``` + +返回: + +- `text/event-stream` + +## 环境变量 + +## 后端 `backend/.env` + +复制: + +```bash +cp backend/.env.example backend/.env +``` + +实际使用的变量名是: + +```env +BOT_APP_KEY=your-app-key +FRONTEND_BASE_URL=http://localhost:3000 +``` + +说明: + +- `BOT_APP_KEY`:腾讯云智能体平台 AppKey +- `FRONTEND_BASE_URL`:后端返回脑图链接时使用的前端基地址 + +注意:当前代码读取的是 `BOT_APP_KEY`,不是 `TENCENT_BOT_APP_KEY`。 + +## 前端 `frontend/.env.production` + +如果前后端分端口直连,推荐写成: + +```env +NEXT_PUBLIC_API_BASE_URL=http://你的公网IP:8000 +``` + +如果后面切到统一入口反向代理,可以改成: + +```env +NEXT_PUBLIC_API_BASE_URL= +``` + +## 本地开发 + +## 启动后端 + +```bash +cd backend +python -m venv venv +source venv/bin/activate +pip install -r requirements.txt +uvicorn app.main:app --reload +``` + +默认地址: + +```text +http://127.0.0.1:8000 +``` + +## 启动前端 + +```bash +cd frontend +npm install +npm run dev +``` + +默认地址: + +```text +http://127.0.0.1:3000 +``` + +## 生产构建 + +```bash +cd frontend +npm ci +rm -rf .next +npm run build +npm run start -- -p 3000 +``` + +## 测试一条脑图创建链路 + +后端启动后,可以直接调用: + +```bash +curl -X POST http://127.0.0.1:8000/api/mindmaps \ + -H "Content-Type: application/json" \ + -d '{ + "session_id": "test-session", + "mindmap_json": { + "id": "node_0", + "label": "测试主题", + "parent_id": null, + "level": 0, + "is_leaf": false, + "children": [ + { + "id": "node_1", + "label": "测试子节点", + "parent_id": "node_0", + "level": 1, + "is_leaf": true, + "children": [] + } + ] + } + }' +``` + +成功后会返回一个 `url`,打开即可查看脑图详情页。 + +## 腾讯云智能体接入说明 + +当前项目更适合由腾讯云工作流或插件来创建脑图,而不是由前端首页直接生成。 + +建议查看: + +- [mind_prompt.md](E:/code/mindmap/mind_prompt.md) +- [腾讯云工作流说明.md](E:/code/mindmap/腾讯云工作流说明.md) + +如果你走当前工作流方案,关键链路是: + +```text +开始 +-> 大模型生成内容 +-> 大模型整理 JSON +-> 大模型检查 JSON +-> 变量转换(JSON 反序列化) +-> 插件调用 /api/mindmaps +-> 回复脑图链接 +``` + +## 部署说明 + +当前实际部署文档见: + +- [宝塔面板部署指南.md](E:/code/mindmap/宝塔面板部署指南.md) + +当前推荐部署方式与实际落地一致: + +- 前端放在宝塔 `Node 项目` +- 后端放在宝塔 `Python 项目` +- 通过公网 IP + `3000/8000` 直接访问 + +## 已知注意事项 + +### 1. `frontend/lib` 不能被 `.gitignore` 误伤 + +根目录 `.gitignore` 如果写成: + +```gitignore +lib/ +``` + +会把 `frontend/lib/` 一起忽略掉,导致服务器缺少: + +- `frontend/lib/api.ts` +- `frontend/lib/tencentSse.ts` +- `frontend/lib/treeToGraph.ts` + +正确写法应该是: + +```gitignore +/lib/ +/lib64/ +``` + +### 2. 前端接口地址改动后必须重建 + +只要改了: + +- `NEXT_PUBLIC_API_BASE_URL` + +就必须重新执行: + +```bash +cd frontend +rm -rf .next +npm run build +``` + +### 3. 后端返回链接依赖 `FRONTEND_BASE_URL` + +如果这个值不对,后端返回的 `url` 就会不对。 diff --git a/宝塔面板部署指南.md b/宝塔面板部署指南.md index 65dcdf5..87e9284 100644 --- a/宝塔面板部署指南.md +++ b/宝塔面板部署指南.md @@ -1,177 +1,157 @@ -# Interactive Mindmap 宝塔面板部署指南 +# Interactive Mindmap 宝塔部署指南 -## 1. 部署原则 +## 1. 当前部署形态 -这份文档按“尽可能使用宝塔面板现成功能”的思路编写: +这份文档按当前实际部署方式整理: -- 前端优先使用宝塔的 `网站 -> Node 项目` -- 后端优先使用宝塔的 `Python 项目` -- 如果你的面板版本里没有合适的 Python 项目入口,再退回 `进程守护` -- 如果你不想改访问端口,可以直接保留 `3000/8000` -- 如果你后续想统一入口,再用宝塔 `网站 + 反向代理` +- 前端放在宝塔 `Node 项目` +- 后端放在宝塔 `Python 项目` +- 当前直接通过公网 IP + 原始端口访问 +- 前端地址:`http://公网IP:3000` +- 后端地址:`http://公网IP:8000` -对这个项目来说,最省事的顺序是: +以下示例以当前服务器目录为例: -1. 先用宝塔把前端跑在 `3000` -2. 再把后端跑在 `8000` -3. 先直接通过 `公网IP:端口` 验证 -4. 跑通后,再决定要不要加网站反向代理 +```bash +/mindmap/minimap +``` -## 2. 先确认项目的真实配置 +如果你的实际目录不同,把文档里的路径替换成你的真实路径即可。 -这个仓库里有几个关键点,部署时必须按代码真实行为来: +## 2. 当前推荐结构 + +### 前端 + +- 项目目录:`/mindmap/minimap/frontend` +- 运行方式:宝塔 `Node 项目` +- 运行端口:`3000` +- Node 版本:建议 `20` +- 启动命令:`npm run start -- -p 3000` + +### 后端 + +- 项目目录:`/mindmap/minimap/backend` +- 运行方式:宝塔 `Python 项目` +- Python 版本:建议 `3.11` +- 运行端口:`8000` +- 启动命令:`uvicorn app.main:app --host 0.0.0.0 --port 8000 --proxy-headers` + +### 数据库 + +- 使用 SQLite +- 数据文件:`/mindmap/minimap/backend/data/mindmap.db` + +## 3. 部署前需要确认的代码行为 + +这个项目里有几个配置不能写错: - 后端环境变量名是 `BOT_APP_KEY` -- 后端还要配置 `FRONTEND_BASE_URL` -- 前端环境变量名是 `NEXT_PUBLIC_API_BASE_URL` -- 前端主要页面是 `/` 和 `/mindmap/[id]` -- 后端接口前缀是 `/api` -- `/api/chat` 是 SSE 流式接口 +- 后端返回脑图链接依赖 `FRONTEND_BASE_URL` +- 前端请求后端依赖 `NEXT_PUBLIC_API_BASE_URL` +- 前端详情页路径是 `/mindmap/[id]` +- 后端创建脑图接口是 `POST /api/mindmaps` +- 后端对话接口是 `POST /api/chat` -对应文件: +对应代码文件: - [config.py](E:/code/mindmap/backend/app/config.py) - [mindmaps.py](E:/code/mindmap/backend/app/routers/mindmaps.py) - [api.ts](E:/code/mindmap/frontend/lib/api.ts) -## 3. 宝塔里建议安装的软件 +## 4. 前端部署到宝塔 Node 项目 -在宝塔 `软件商店` 里优先安装: +## 4.1 前端目录 -- `Node.js` -- `PM2 管理器` -- `Python 3.11` -- `Nginx` - -按你的面板版本,下面二选一: - -- 如果有 `Python 项目` 或 `Python 项目管理器`,优先用它 -- 如果没有,就安装或使用 `进程守护 / Supervisor` - -建议版本: - -- `Node.js 20` -- `Python 3.11` - -## 4. 上传项目 - -建议上传到: +前端目录: ```bash -/www/wwwroot/mindmap +/mindmap/minimap/frontend ``` -推荐做法: +## 4.2 前端环境变量 -1. 宝塔 `文件` 里上传项目压缩包 -2. 在宝塔里解压到 `/www/wwwroot/mindmap` - -如果你是从本地 Windows 机器直接传上来的,先在宝塔终端执行: - -```bash -cd /www/wwwroot/mindmap/frontend -rm -rf node_modules .next -``` - -这是为了避免把 Windows 的前端依赖直接拿到 Linux 里运行。 - -## 5. 推荐方案:先保留原始端口跑通 - -这是当前最推荐你的做法,因为最少折腾。 - -最终访问方式: - -- 前端:`http://公网IP:3000` -- 后端:`http://公网IP:8000` - -这一步不需要先配网站反向代理。 - -## 6. 前端:优先使用宝塔 `网站 -> Node 项目` - -### 6.1 先准备前端环境变量 - -在宝塔 `文件` 里进入: - -```bash -/www/wwwroot/mindmap/frontend -``` - -新建文件 `.env.production`,内容写成: +在前端目录创建或修改 `.env.production`: ```env NEXT_PUBLIC_API_BASE_URL=http://你的公网IP:8000 ``` -这里必须写公网 IP + `8000`,因为你当前是让前端直接访问后端原始端口。 +说明: -### 6.2 安装依赖并构建 +- 当前前端直接访问后端 `8000` 端口,所以这里不能留空 +- 只要改过这个值,就必须重新构建前端 + +## 4.3 安装依赖和构建 宝塔终端执行: ```bash -cd /www/wwwroot/mindmap/frontend +cd /mindmap/minimap/frontend npm ci +rm -rf .next npm run build ``` -### 6.3 在宝塔里创建 Node 项目 +如果构建失败,先看本文末尾的“常见问题”。 + +## 4.4 在宝塔中配置 Node 项目 进入宝塔: - `网站` - `Node 项目` -- `添加 Node 项目` +- 找到或新建前端项目 -建议填写: +建议配置: - 项目名称:`mindmap-frontend` -- 项目目录:`/www/wwwroot/mindmap/frontend` +- 项目目录:`/mindmap/minimap/frontend` - Node 版本:`20` +- 运行端口:`3000` - 启动方式:`PM2` -- 端口:`3000` -- 启动命令:`start -p 3000` -如果界面要求你选择启动文件,按 Next.js 方式选择项目启动即可;面板不同版本字段名称会略有区别,但核心是让它执行 `next start -p 3000`。 - -### 6.4 是否开启外网映射 - -如果你想直接通过公网访问: - -- 开启 `外网映射` -- 确认映射端口是 `3000` - -这样前端就可以直接通过: - -```text -http://公网IP:3000 -``` - -访问。 - -### 6.5 检查前端是否正常 - -在宝塔里查看: - -- `Node 项目` 状态是否为运行中 -- `PM2 管理器` 里是否有 `mindmap-frontend` - -也可以访问: - -```text -http://公网IP:3000 -``` - -## 7. 后端:优先使用宝塔 `Python 项目` - -### 7.1 先准备后端环境变量 - -在宝塔 `文件` 里进入: +如果界面需要填写启动命令,建议使用: ```bash -/www/wwwroot/mindmap/backend +npm run start -- -p 3000 ``` -复制 `.env.example` 为 `.env`,并写成: +如果界面要求先执行构建,请先完成: + +```bash +npm run build +``` + +## 4.5 前端验证 + +浏览器访问: + +```text +http://公网IP:3000 +``` + +如果首页能打开,说明 Node 项目启动正常。 + +## 5. 后端部署到宝塔 Python 项目 + +## 5.1 后端目录 + +后端目录: + +```bash +/mindmap/minimap/backend +``` + +## 5.2 后端环境变量 + +复制配置文件: + +```bash +cd /mindmap/minimap/backend +cp .env.example .env +``` + +然后将 `.env` 改成类似这样: ```env BOT_APP_KEY=你的腾讯云智能体AppKey @@ -180,70 +160,50 @@ FRONTEND_BASE_URL=http://你的公网IP:3000 说明: -- `BOT_APP_KEY`:腾讯云智能体平台 AppKey -- `FRONTEND_BASE_URL`:因为你前端直接跑在 `3000`,所以这里必须写 `:3000` +- `BOT_APP_KEY` 是腾讯云智能体平台 AppKey +- `FRONTEND_BASE_URL` 必须指向前端真实访问地址 +- 当前前端在 `3000` 端口,所以这里必须带 `:3000` -### 7.2 如果你的宝塔有 `Python 项目` +## 5.3 在宝塔中配置 Python 项目 -优先这样做: +进入宝塔: -- 打开 `Python 项目` -- `添加项目` -- 选择 Python 版本:`3.11` -- 项目目录:`/www/wwwroot/mindmap/backend` +- `Python 项目` +- 找到或新建后端项目 + +建议配置: + +- 项目名称:`mindmap-backend` +- 项目目录:`/mindmap/minimap/backend` +- Python 版本:`3.11` - 监听地址:`0.0.0.0` - 监听端口:`8000` -如果界面支持自定义启动命令,建议填: +如果界面支持自定义启动命令,建议填写: ```bash uvicorn app.main:app --host 0.0.0.0 --port 8000 --proxy-headers ``` -如果界面要求你选择虚拟环境,就让它在项目目录里创建并使用虚拟环境,然后安装: +如果宝塔 Python 项目需要先准备虚拟环境和依赖,执行: ```bash -pip install -r requirements.txt -``` - -### 7.3 如果你的宝塔没有合适的 `Python 项目` 入口 - -就用宝塔的 `进程守护` 或 `Supervisor 管理器`,不要自己后台挂命令。 - -先在宝塔终端执行: - -```bash -cd /www/wwwroot/mindmap/backend +cd /mindmap/minimap/backend python3.11 -m venv venv source venv/bin/activate pip install --upgrade pip pip install -r requirements.txt ``` -然后进入: +## 5.4 后端验证 -- `进程守护` -- 或 `Supervisor 管理器` -- `添加守护进程` - -建议填写: - -- 名称:`mindmap-backend` -- 运行目录:`/www/wwwroot/mindmap/backend` -- 启动用户:`www` -- 启动命令:`/www/wwwroot/mindmap/backend/venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8000 --proxy-headers` -- 自启动:开启 -- 自动重启:开启 - -### 7.4 检查后端是否正常 - -访问: +浏览器访问: ```text http://公网IP:8000 ``` -或: +或在终端执行: ```bash curl http://公网IP:8000/ @@ -255,34 +215,37 @@ curl http://公网IP:8000/ {"message":"Interactive Mindmap API is running"} ``` -## 8. 防火墙与安全组 +## 6. 宝塔防火墙与云安全组 -如果你现在采用“保留原始端口”的方案,必须在宝塔防火墙和云安全组中放行: +当前部署方式需要对公网放行: - `3000` - `8000` -否则面板里虽然显示运行中,但公网访问不到。 +必须同时检查两层: -## 9. 先做一次完整验证 +- 宝塔防火墙 +- 云服务器安全组 -### 9.1 打开首页 +只放行其中一层是不够的。 -浏览器访问: +## 7. 当前部署方式下的验证步骤 + +## 7.1 验证首页 ```text http://公网IP:3000 ``` -### 9.2 验证接口 +## 7.2 验证后端接口 ```bash curl http://公网IP:8000/api/mindmaps/not-found ``` -正常结果应该是后端返回的 `404 JSON`,而不是超时或 HTML 页面。 +这里预期是后端返回 `404` JSON,而不是超时或 HTML 页面。 -### 9.3 创建一条测试思维导图 +## 7.3 创建一条测试思维导图 ```bash curl -X POST http://公网IP:8000/api/mindmaps \ @@ -317,85 +280,50 @@ curl -X POST http://公网IP:8000/api/mindmaps \ }' ``` -成功后会返回 `url`,类似: +成功后返回的 `url` 应类似: ```text http://公网IP:3000/mindmap/xxxxxx ``` -直接访问这个地址,能看到脑图页就说明前后端链路已经通了。 +直接打开该链接,能正常看到脑图页,说明前后端都通了。 -## 10. 如果你后面想用宝塔 `添加网站` +## 8. 后续如果想切到宝塔网站统一入口 -等你先跑通后,再考虑这一步。 +你当前不需要这一步,但后续可以这样演进: -### 10.1 什么时候需要 `添加网站` +1. 前端 Node 项目改为监听 `127.0.0.1:3000` +2. 后端 Python 项目改为监听 `127.0.0.1:8000` +3. 再使用宝塔 `网站 -> 添加站点` +4. 用站点反向代理把 `/` 转到前端,把 `/api/` 转到后端 -只有在你想把访问地址收敛成一个入口时,才建议加网站: +如果切到这种模式: -- 例如从 `http://公网IP:3000` -- 改成 `http://公网IP` -- 或 `http://公网IP:8080` +- 前端 `.env.production` 应改为 `NEXT_PUBLIC_API_BASE_URL=` +- 后端 `.env` 中 `FRONTEND_BASE_URL` 应改成统一入口地址 +- 前端需要重新构建 -### 10.2 这种情况下怎么用宝塔 +## 9. 常见问题 -推荐做法: +## 9.1 前端能打开,但接口请求错地址 -1. 前端 Node 项目继续跑在 `127.0.0.1:3000` -2. 后端 Python 项目继续跑在 `127.0.0.1:8000` -3. 再去宝塔 `网站 -> 添加站点` -4. 用站点的 `反向代理` 把 `/` 转给前端,把 `/api/` 转给后端 - -也就是说: - -- `网站` 负责对外入口 -- `Node 项目` 负责前端运行 -- `Python 项目` 负责后端运行 - -这是更符合宝塔使用习惯的结构。 - -### 10.3 如果要切换到统一入口,环境变量也要改 - -如果外部地址改成: - -```text -http://公网IP -``` - -那么后端 `.env` 要改成: - -```env -FRONTEND_BASE_URL=http://你的公网IP -``` - -前端 `.env.production` 要改成: - -```env -NEXT_PUBLIC_API_BASE_URL= -``` - -改完后要重新构建前端,并重启前后端项目。 - -## 11. 常见问题 - -### 11.1 前端能打开,但接口请求错地址 - -先看前端环境变量: +检查: ```env NEXT_PUBLIC_API_BASE_URL=http://你的公网IP:8000 ``` -只要改过这个值,就必须重新执行: +只要这个值改过,就重新执行: ```bash -cd /www/wwwroot/mindmap/frontend +cd /mindmap/minimap/frontend +rm -rf .next npm run build ``` -然后在宝塔里重启 Node 项目或 PM2。 +然后在宝塔里重启 Node 项目。 -### 11.2 后端能运行,但返回链接不对 +## 9.2 后端返回的脑图链接不对 检查: @@ -403,41 +331,63 @@ npm run build FRONTEND_BASE_URL=http://你的公网IP:3000 ``` -如果这里没写对,接口返回的 `url` 就会不对。 +如果这里错了,API 返回的 `url` 就会错。 -### 11.3 SSE 对话接口不稳定 +## 9.3 前端构建时报 `Can't resolve ../lib/api` -`/api/chat` 是 SSE。 -如果你当前还没上反向代理,先直接用原始端口跑通最稳。 -等后面加网站代理时,再专门处理 `/api/chat` 的代理缓冲设置。 +这通常不是 Next.js 本身问题,而是服务器代码不完整。 -### 11.4 公网访问不到 +先确认这些文件在服务器上存在: + +```text +/mindmap/minimap/frontend/lib/api.ts +/mindmap/minimap/frontend/lib/tencentSse.ts +/mindmap/minimap/frontend/lib/treeToGraph.ts +/mindmap/minimap/frontend/types/mindmap.ts +``` + +如果缺文件,优先检查 Git 同步是否完整。 + +## 9.4 Git push 后服务器代码不完整 + +这个项目之前踩过一个典型问题: + +- 根目录 `.gitignore` 中如果写了 `lib/` +- 会把 `frontend/lib/` 一起忽略掉 + +正确写法应该是: + +```gitignore +/lib/ +/lib64/ +``` + +这样只忽略仓库根目录的 `lib`,不会误伤 `frontend/lib`。 + +## 9.5 公网访问不到 优先检查: -- 宝塔防火墙是否放行了 `3000` 和 `8000` -- 云安全组是否放行了 `3000` 和 `8000` -- 前端是否真的监听在 `3000` -- 后端是否真的监听在 `8000` +- 宝塔防火墙是否放行 `3000` 和 `8000` +- 云安全组是否放行 `3000` 和 `8000` +- Node 项目是否运行中 +- Python 项目是否运行中 -### 11.5 浏览器提示不安全 +## 9.6 浏览器提示不安全 -如果你现在使用的是: +当前是: - 公网 IP - HTTP -- 非 80/443 标准端口 +- 非 80/443 端口 -浏览器提示“不安全”是正常现象,不代表项目没跑起来。 +浏览器提示“不安全”是正常现象,不代表服务没有跑起来。 -## 12. 你现在最该怎么做 +## 10. 当前最稳的运维方式 -按下面顺序走最稳: +按你现在的实际情况,最稳的方式就是保持: -1. 用宝塔 `Node 项目` 跑前端到 `3000` -2. 用宝塔 `Python 项目` 或 `进程守护` 跑后端到 `8000` -3. 放行 `3000/8000` -4. 先通过 `http://公网IP:3000` 和 `http://公网IP:8000` 验证 -5. 等功能确认无误后,再决定要不要加 `网站 + 反向代理` - -这样基本不需要先折腾复杂的 Nginx 配置,也最符合你现在“原端口能跑就不改”的目标。 +1. 前端继续放在宝塔 `Node 项目` +2. 后端继续放在宝塔 `Python 项目` +3. 继续用 `3000/8000` 直接验证 +4. 等功能稳定后,再考虑加宝塔网站做统一入口 diff --git a/腾讯云工作流说明.md b/腾讯云工作流说明.md new file mode 100644 index 0000000..9365717 --- /dev/null +++ b/腾讯云工作流说明.md @@ -0,0 +1,383 @@ +# 腾讯云思维导图工作流说明 + +## 1. 工作流目标 + +当前工作流的目标是: + +1. 接收用户主题与会话 ID +2. 通过大模型生成思维导图内容 +3. 将内容整理为合法 JSON 字符串 +4. 对 JSON 做校验和修复 +5. 将 JSON 字符串反序列化为对象 +6. 调用后端工具保存脑图 +7. 将生成后的访问链接回复给用户 + +这条链路的关键点是: + +- 大模型节点输出保持为 `string` +- 插件节点接收的 `mindmap_json` 必须是 `object` +- 所以中间必须经过一次 `变量转换节点 -> JSON 反序列化` + +## 2. 当前工作流节点 + +根据当前画布,节点顺序为: + +1. `开始` +2. `生成思维导图内容` +3. `生成思维导图内容json` +4. `检查json` +5. `变量转换1` +6. `生成前端页面` +7. `回复1` +8. `结束` + +## 3. 节点职责说明 + +## 3.1 开始 + +作用: + +- 接收工作流启动输入 + +建议输入变量: + +- `topic` +- `session_id` + +说明: + +- `topic` 用于告诉大模型本次脑图主题 +- `session_id` 用于插件调用时传给后端接口 + +## 3.2 生成思维导图内容 + +节点类型: + +- 大模型节点 + +作用: + +- 根据用户主题先生成一版结构化脑图内容 + +建议输出: + +- `Output.Content`:文本内容 + +建议: + +- 这一层可以先输出脑图提纲或中间描述 +- 不要求它直接输出最终可落库的 JSON + +## 3.3 生成思维导图内容json + +节点类型: + +- 大模型节点 + +作用: + +- 将上一节点的内容转换成思维导图 JSON 字符串 + +建议输出: + +- `Output.Content`:JSON 字符串 + +这一节点必须满足: + +- 只输出纯 JSON +- 不要输出解释文字 +- 不要输出 markdown 代码块 +- 不要输出前后缀说明 + +建议要求它输出的格式为: + +```json +{ + "id": "node_0", + "label": "主题", + "parent_id": null, + "level": 0, + "is_leaf": false, + "children": [] +} +``` + +## 3.4 检查json + +节点类型: + +- 大模型节点 + +作用: + +- 对上一节点生成的 JSON 字符串做检查和修复 + +建议输出: + +- `Output.Content`:修复后的 JSON 字符串 + +建议规则: + +1. 如果 JSON 合法且结构正确,原样返回 +2. 如果不合法,修复后返回 +3. 始终只输出 JSON 字符串 +4. 不输出解释文字 + +这一节点输出仍然应该是 `string`,不要直接改成 `JSON` 类型输出。 + +## 3.5 变量转换1 + +节点类型: + +- 变量转换节点 + +当前建议配置: + +- 转换类型:`JSON` +- 转换方式:`JSON 反序列化` +- 转换变量:`检查json.Output.Content` + +作用: + +- 将 `检查json` 节点输出的 JSON 字符串反序列化为对象 + +为什么必须有这一步: + +- 大模型节点输出的是字符串 +- 插件节点里的 `mindmap_json` 入参需要的是 `object` + +该节点默认输出: + +- `Output` +- `Error` + +后续插件节点应引用: + +- `变量转换1.Output` + +不要引用: + +- `变量转换1.Error` + +## 3.6 生成前端页面 + +节点类型: + +- 插件节点 + +作用: + +- 调用后端 API 创建并保存思维导图 +- 返回脑图访问链接 + +当前插件接口建议: + +- 调用地址:`http://公网IP:8000/api/mindmaps` +- 请求方式:`POST` +- Content-Type:`application/json` + +插件输入参数应配置为: + +- `session_id` +- `mindmap_json` + +工作流内的输入映射建议如下: + +### 输入参数 `session_id` + +来源建议: + +- `开始.session_id` + +如果你是通过应用 API 调工作流,也可以使用: + +- `API.session_id` + +### 输入参数 `mindmap_json` + +来源必须是: + +- `变量转换1.Output` + +也就是反序列化后的对象,而不是大模型输出的字符串。 + +## 3.7 回复1 + +节点类型: + +- 回复节点 + +作用: + +- 将生成后的脑图链接返回给用户 + +当前文案可以写成: + +```text +思维导图已生成!请打开以下链接查看:{{url}} +``` + +如果你在插件节点里直接暴露的是完整路径变量,也可以写成: + +```text +思维导图已生成!请打开以下链接查看:{{生成前端页面.Output.Body.url}} +``` + +如果还想带标题,可以改成: + +```text +思维导图已生成! +标题:{{生成前端页面.Output.Body.title}} +链接:{{生成前端页面.Output.Body.url}} +``` + +## 3.8 结束 + +作用: + +- 标记工作流结束 + +## 4. 当前工作流的数据流 + +可以理解为: + +```text +开始 + -> 生成思维导图内容 + -> 生成思维导图内容json + -> 检查json + -> 变量转换1(JSON反序列化) + -> 生成前端页面(插件/API落库) + -> 回复1 + -> 结束 +``` + +其中最关键的一段是: + +```text +检查json.Output.Content (string) + -> 变量转换1.Output (object) + -> 生成前端页面.mindmap_json +``` + +## 5. 插件节点推荐配置 + +如果你使用当前项目现有后端接口,插件建议如下: + +### 工具基础信息 + +- 工具名称:`create_mindmap` +- 调用地址:`http://公网IP:8000/api/mindmaps` +- 请求方法:`POST` +- 请求体格式:`JSON` + +### 输入参数 + +- `body.session_id`:`string` +- `body.mindmap_json`:`object` + +### 输出参数 + +- `url`:`string` +- `title`:`string` +- `unique_id`:`string` + +如果平台输出变量是以返回体路径显示,也可以直接使用: + +- `Output.Body.url` +- `Output.Body.title` +- `Output.Body.unique_id` + +## 6. 当前工作流下各节点变量关系 + +| 节点 | 关键输入 | 关键输出 | 备注 | +|---|---|---|---| +| 开始 | `topic`、`session_id` | 输入变量本身 | 作为整条链路源头 | +| 生成思维导图内容 | `topic` | `Output.Content` | 生成脑图内容 | +| 生成思维导图内容json | 上一节点内容 | `Output.Content` | 输出 JSON 字符串 | +| 检查json | 上一节点 JSON 字符串 | `Output.Content` | 修复后的 JSON 字符串 | +| 变量转换1 | `检查json.Output.Content` | `Output`、`Error` | `Output` 为 object | +| 生成前端页面 | `session_id`、`mindmap_json` | `Output.Body.url` 等 | 调用插件/API | +| 回复1 | `url` | 文本回复 | 回复用户链接 | + +## 7. 当前工作流的关键注意点 + +## 7.1 不要让大模型节点直接输出 object 给插件 + +当前这条链里,最稳的方式仍然是: + +- 大模型输出 `string` +- 变量转换节点做 `JSON 反序列化` +- 插件节点接收 `object` + +## 7.2 插件节点的 `mindmap_json` 必须吃反序列化后的结果 + +正确: + +- `变量转换1.Output` + +错误: + +- `检查json.Output.Content` +- `生成思维导图内容json.Output.Content` + +因为这两者还是字符串。 + +## 7.3 插件节点的 `session_id` 不要写死 + +建议引用: + +- `开始.session_id` +- 或 `API.session_id` + +这样才能保证每次生成的脑图都能和对应会话关联。 + +## 7.4 当前工作流还缺少显式异常分支 + +建议后续补一个条件判断: + +1. 如果 `变量转换1.Error` 不为空,直接回复“JSON 解析失败” +2. 如果 `生成前端页面.Error` 不为空,直接回复“脑图保存失败” + +当前不加也能跑,但可维护性会差一些。 + +## 8. 建议的后续优化 + +如果你后面想继续提升稳定性,优先做这几件事: + +1. 在 `检查json` 节点里进一步收紧输出约束,只允许返回纯 JSON 字符串 +2. 在工作流里增加错误分支,处理反序列化失败和插件调用失败 +3. 插件输出中除了 `url` 外,再将 `title` 一并回复给用户 +4. 如果后面模型经常输出不稳定,可以增加代码节点做 schema 校验 + +## 9. 当前工作流与项目接口的对应关系 + +当前插件节点 `生成前端页面` 对应后端接口: + +- [mindmaps.py](E:/code/mindmap/backend/app/routers/mindmaps.py) + +接口实际请求体结构为: + +```json +{ + "session_id": "string", + "mindmap_json": { + "id": "node_0", + "label": "主题", + "parent_id": null, + "level": 0, + "is_leaf": false, + "children": [] + } +} +``` + +接口实际返回中至少会包含: + +```json +{ + "unique_id": "string", + "title": "string", + "url": "string" +} +```