docs: 更新README文档内容与结构
refactor(useThinkFlow): 改进节点布局算法以支持动态尺寸计算 style(i18n): 修改"deepDive"翻译为"回答"以更准确表达功能
This commit is contained in:
203
README.md
203
README.md
@@ -2,164 +2,115 @@
|
||||
|
||||
English | [中文](./README.zh-CN.md)
|
||||
|
||||
ThinkFlow AI is a lightweight, local-first idea-to-structure workspace. You type a core idea, and the app expands it into a navigable knowledge graph (modules/submodules). Each node supports follow-up expansion, deep-dive details, and optional image generation.
|
||||
ThinkFlow AI is a lightweight, local-first, AI-driven mind mapping workspace. It automatically transforms a simple idea into a structured and highly visual mind map using the divergent thinking power of AI.
|
||||
|
||||
This repository currently uses the package name `thinkflow` (historical) while the product name is **ThinkFlow AI**.
|
||||
This project aims to provide a smooth, zero-backend-config thinking assistant that offers deep analytical capabilities, supporting users during brainstorming, knowledge organization, and creative expansion.
|
||||
|
||||
## Highlights
|
||||
---
|
||||
|
||||
- **Idea expansion to graph**: generate a root node and expand into structured child nodes.
|
||||
- **Context-aware follow-up**: expand a selected node with an additional requirement (follow-up input).
|
||||
- **Deep dive**: generate detailed explanations for a node and show them inline.
|
||||
- **Image generation (per node)**: generate/regenerate a visual for a node and preview it fullscreen.
|
||||
- **Export to Markdown**: export the current graph as a Markdown outline (including deep-dive content).
|
||||
- **Local-first settings**: API mode and endpoints are stored in `localStorage` (no backend needed).
|
||||
- **Bilingual UI**: built-in English/Chinese UI with a one-click toggle.
|
||||
## 🌟 Key Highlights
|
||||
|
||||
## Tech Stack
|
||||
- **🚀 Idea to Graph**: Just enter a core concept, and the AI will automatically generate a root node and expand into multiple insightful child nodes.
|
||||
- **🧠 Context-Aware Follow-up**: Support for follow-up questions on any node. The AI considers the "thinking path" from root to the current node to ensure logical consistency.
|
||||
- **📖 Deep Answer (Deep Dive)**: More than just keywords—click "Answer" to have the AI generate detailed analysis, background, and applications for a node, rendered in Markdown.
|
||||
- **🎨 Intelligent Visual Aid**: Integrated AI image generation creates realistic visuals based on node content, enhancing the visual impact and memory retention of your mind map.
|
||||
- **📊 Session Summary**: One-click summary of the entire canvas, extracting core logic, main dimensions, and final insights.
|
||||
- **📂 Structured Export**: Export the entire mind map as a standard Markdown outline, including node descriptions, answers, and hierarchical structure.
|
||||
- **🔐 Local-First Configuration**: All API configurations (Key, Base URL, etc.) and language preferences are stored in the browser's `localStorage`, ensuring privacy and security.
|
||||
|
||||
- **Vue 3** (Composition API)
|
||||
- **Vite 5**
|
||||
- **TypeScript**
|
||||
- **Tailwind CSS**
|
||||
- **VueFlow** (`@vue-flow/core`, `background`, `controls`, `minimap`)
|
||||
- **vue-i18n**
|
||||
- **lucide-vue-next** (icons)
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
## 🛠️ Tech Stack
|
||||
|
||||
Key files you will touch most often:
|
||||
- **Framework**: [Vue 3](https://vuejs.org/) (Composition API)
|
||||
- **Build Tool**: [Vite 5](https://vitejs.dev/)
|
||||
- **Language**: [TypeScript](https://www.typescriptlang.org/)
|
||||
- **Styling**: [Tailwind CSS](https://tailwindcss.com/)
|
||||
- **Graph Engine**: [@vue-flow/core](https://vueflow.dev/)
|
||||
- **I18n**: [vue-i18n](https://vue-i18n.intlify.dev/)
|
||||
- **Icon Library**: [lucide-vue-next](https://lucide.dev/)
|
||||
- **Markdown Rendering**: [markdown-it](https://github.com/markdown-it/markdown-it)
|
||||
|
||||
- `src/App.vue`: app shell, composes the layout and wires UI to business actions.
|
||||
- `src/composables/useThinkFlow.ts`: core business logic (graph operations, API calls, persistence).
|
||||
- `src/components/TopNav.vue`: top toolbar (layout, export, summary, settings, language toggle).
|
||||
- `src/components/BottomBar.vue`: bottom input bar (core idea input + execute).
|
||||
- `src/components/WindowNode.vue`: custom VueFlow node UI (expand/deep-dive/image/follow-up).
|
||||
- `src/components/SettingsModal.vue`: API mode and custom endpoints configuration UI.
|
||||
- `src/i18n/index.ts`: i18n bootstrap (default English; persists language in `localStorage`).
|
||||
---
|
||||
|
||||
## How It Works (High-Level)
|
||||
## 📂 Code Structure Guide
|
||||
|
||||
ThinkFlow AI is built around a single composable:
|
||||
```text
|
||||
src/
|
||||
├── components/ # UI Components
|
||||
│ ├── TopNav.vue # Top toolbar: Handles fit, layout, export, summary, and language toggle.
|
||||
│ ├── SideNav.vue # Left side nav: Controls MiniMap, edge styles, background, and settings entry.
|
||||
│ ├── BottomBar.vue # Bottom input bar: Initial entry for core ideas.
|
||||
│ ├── WindowNode.vue # Custom Node: Core UI for expanding, answers, image generation, and follow-ups.
|
||||
│ ├── SettingsModal.vue # API Settings: Configuration for Text and Image generation endpoints.
|
||||
│ ├── SummaryModal.vue # Modal for displaying the session summary.
|
||||
│ ├── ImagePreviewModal.vue # Modal for fullscreen node image preview.
|
||||
│ └── ResetConfirmModal.vue # Confirmation modal for canvas reset.
|
||||
├── composables/ # Core Logic Layer
|
||||
│ └── useThinkFlow.ts # Core Business Hook: Manages node state, API calls, layout algorithms, and persistence.
|
||||
├── i18n/ # Internationalization
|
||||
│ ├── locales/ # Language packs (zh.json, en.json)
|
||||
│ └── index.ts # I18n initialization
|
||||
├── App.vue # App Entry: Composes components and configures the VueFlow environment.
|
||||
└── main.ts # Program Entry Point
|
||||
```
|
||||
|
||||
- `useThinkFlow` owns all reactive state for nodes/edges and UI flags.
|
||||
- UI components are “thin”: they render and forward events (expand, deep-dive, image, export).
|
||||
- The graph is rendered with VueFlow using a custom node type (`window`).
|
||||
- Settings are stored in `localStorage`:
|
||||
- language (`language`)
|
||||
- API mode + chat/image endpoints/models/keys
|
||||
### Core Design Principles
|
||||
|
||||
## Getting Started
|
||||
- **State Management**: Uses `useThinkFlow` composable to centralize management of nodes, edges, and UI states, distributed to child components via `App.vue`.
|
||||
- **Layout Algorithm**: Implements a horizontal tree layout algorithm based on dynamic subtree height calculations, automatically adapting to node size changes.
|
||||
- **API Communication**: Compatible with OpenAI-style endpoints, supporting custom model names and Base URLs.
|
||||
|
||||
### Prerequisites
|
||||
---
|
||||
|
||||
- Node.js **18+** (required by Vite 5)
|
||||
- npm (or pnpm/yarn; examples use npm)
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Install
|
||||
### 1. Prerequisites
|
||||
|
||||
- Node.js 18+
|
||||
- npm or pnpm
|
||||
|
||||
### 2. Install Dependencies
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### Run Dev Server
|
||||
### 3. Run Development Server
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Then open the URL printed by Vite (usually `http://localhost:5173`).
|
||||
Access `http://localhost:5173` to start.
|
||||
|
||||
### Build
|
||||
---
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
## ⚙️ Configuration
|
||||
|
||||
### Preview Production Build
|
||||
This project does not provide a backend; users must configure their own API endpoints:
|
||||
|
||||
```bash
|
||||
npm run preview
|
||||
```
|
||||
1. Click the **Settings** icon at the bottom of the left sidebar.
|
||||
2. **Default Mode**: Uses pre-configured trial endpoints (subject to rate limits).
|
||||
3. **Custom Mode**:
|
||||
- **Text Gen**: Enter OpenAI-compatible `Base URL`, `Model Name`, and `API Key`.
|
||||
- **Image Gen**: Enter configuration for `dall-e` or other image generation APIs.
|
||||
|
||||
## Configuration
|
||||
---
|
||||
|
||||
### Custom Mode (Bring Your Own Endpoint)
|
||||
## 📖 Usage Manual
|
||||
|
||||
Open **Settings** in the UI:
|
||||
1. **Start a Session**: Enter your idea in the bottom input (e.g., "Future of Urban Transportation") and press Enter.
|
||||
2. **Node Actions**:
|
||||
- **Expand**: Click the `+` on a node or enter a follow-up requirement to generate child nodes.
|
||||
- **Answer**: Click the book icon for a deep analysis of that node.
|
||||
- **Image**: Click the image icon to generate a visual reference for the idea.
|
||||
3. **Organize Canvas**:
|
||||
- **Layout**: Click the "Layout" button at the top to automatically organize all nodes.
|
||||
- **Export**: Click the "Export" button at the top to get a Markdown copy of your work.
|
||||
|
||||
- Switch to **Custom**
|
||||
- Configure **Text Generation** (chat completion)
|
||||
- `baseUrl` (POST endpoint)
|
||||
- `model`
|
||||
- `apiKey`
|
||||
- Configure **Image Generation**
|
||||
- `baseUrl` (POST endpoint)
|
||||
- `model`
|
||||
- `apiKey`
|
||||
---
|
||||
|
||||
These fields are saved into `localStorage` automatically.
|
||||
## 📄 License
|
||||
|
||||
## Features Guide
|
||||
|
||||
### 1) Expand From a Core Idea
|
||||
|
||||
1. Type a core idea in the bottom input.
|
||||
2. Press Enter or click **Execute**.
|
||||
3. A root node appears and the app generates child nodes.
|
||||
|
||||
### 2) Expand a Specific Node (Follow-Up)
|
||||
|
||||
1. Click into a node’s follow-up input.
|
||||
2. Type an additional requirement.
|
||||
3. Press Enter to expand using the context path (root → current node).
|
||||
|
||||
### 3) Deep Dive a Node
|
||||
|
||||
Click **Deep Dive** on a node to generate a detailed explanation. The content will be stored on the node and can be reopened without re-requesting (unless you expand further).
|
||||
|
||||
### 4) Generate/Preview Node Image
|
||||
|
||||
- Click **IMG** to generate an image for a node.
|
||||
- Click the image to open fullscreen preview.
|
||||
- Use the regenerate action to request a new image.
|
||||
|
||||
### 5) Export Markdown
|
||||
|
||||
Use **Export** in the top toolbar:
|
||||
|
||||
- Root becomes the Markdown title
|
||||
- Child nodes become an indented list
|
||||
- Deep-dive text is exported as blockquote content under the node
|
||||
|
||||
## Third-Party Integrations
|
||||
|
||||
- **Microsoft Clarity**: included in `index.html` for analytics.
|
||||
- **VueFlow plugins**:
|
||||
- Background (Dots/Lines)
|
||||
- Controls (zoom/fit)
|
||||
- MiniMap (overview)
|
||||
|
||||
## Internationalization (i18n)
|
||||
|
||||
- Default locale: **English**
|
||||
- Supported: `en`, `zh`
|
||||
- Language choice is stored in `localStorage` key `language`
|
||||
|
||||
To add a new language:
|
||||
|
||||
1. Add a JSON file in `src/i18n/locales/`
|
||||
2. Register it in `src/i18n/index.ts`
|
||||
3. Add a toggle option in the UI (currently a simple EN/ZH switch)
|
||||
|
||||
## Common Troubleshooting
|
||||
|
||||
- **CORS / Failed to fetch**: if you use a custom endpoint, ensure it allows browser requests and supports proper CORS headers.
|
||||
- **401/403**: verify the API key and `Authorization: Bearer ...` format.
|
||||
- **429**: rate limited by the provider; retry later.
|
||||
|
||||
## Scripts
|
||||
|
||||
- `npm run dev`: start Vite dev server
|
||||
- `npm run build`: production build
|
||||
- `npm run preview`: preview the build output locally
|
||||
MIT License
|
||||
|
||||
206
README.zh-CN.md
206
README.zh-CN.md
@@ -2,165 +2,115 @@
|
||||
|
||||
[English](./README.md) | 中文
|
||||
|
||||
ThinkFlow AI 是一个轻量、偏本地化(Local-first)的“从想法到结构化图谱”的工作台:输入一个核心想法,应用会把它扩展为可浏览的知识图谱(模块/子模块)。每个节点支持继续追问扩展、深挖详情,以及可选的配图生成。
|
||||
ThinkFlow AI 是一个轻量级、Local-first(本地优先)的 AI 驱动思维导图工作台。它能够将你的一个简单想法,通过 AI 的发散性思维,自动化地扩展为结构清晰、可视化程度高的思维图谱。
|
||||
|
||||
## 亮点功能
|
||||
本项目旨在提供一个极致流畅、无需复杂后端配置、且具备深度解析能力的思维助手,帮助用户在头脑风暴、知识梳理和创意发散时获得持续的灵感支持。
|
||||
|
||||
- **想法扩展为图谱**:生成根节点并扩展出结构化子节点。
|
||||
- **上下文追问扩展**:对选中节点追加需求(follow-up 输入)并基于路径上下文扩展。
|
||||
- **深挖详情**:为节点生成更详细的解释/补充内容并在节点内展开展示。
|
||||
- **节点配图(可重试)**:为单个节点生成/重新生成图片,并支持全屏预览。
|
||||
- **导出 Markdown**:将当前图谱导出为 Markdown 大纲(包含深挖内容)。
|
||||
- **本地配置**:API 模式与配置保存到 `localStorage`,无需额外后端。
|
||||
- **中英双语**:内置英文/中文 UI,一键切换。
|
||||
---
|
||||
|
||||
## 技术栈
|
||||
## 🌟 核心亮点
|
||||
|
||||
- **Vue 3**(Composition API)
|
||||
- **Vite 5**
|
||||
- **TypeScript**
|
||||
- **Tailwind CSS**
|
||||
- **VueFlow**(`@vue-flow/core` + background/controls/minimap)
|
||||
- **vue-i18n**
|
||||
- **lucide-vue-next**(图标)
|
||||
- **🚀 从想法到图谱**:只需输入一个核心概念,AI 会自动生成根节点并向外发散多个具有深度的子节点。
|
||||
- **🧠 上下文关联追问**:支持针对任意节点进行追问,AI 在生成时会参考“从根到当前节点”的思考路径,确保生成的逻辑一致性。
|
||||
- **📖 深度回答(Deep Dive)**:不再仅仅是关键词,点击“回答”即可让 AI 针对该节点生成详尽的解析、背景及应用场景,支持 Markdown 渲染。
|
||||
- **🎨 智能视觉辅助**:集成 AI 生图能力,可根据节点内容生成写实风格的配图,提升思维导图的视觉冲击力与记忆点。
|
||||
- **📊 全篇智能总结**:一键梳理整张画布的所有想法,提取核心逻辑、主要维度和最终洞察,生成精炼的全局总结。
|
||||
- **📂 结构化导出**:支持将整个思维图谱导出为标准的 Markdown 大纲,包含节点描述、回答内容及层级结构。
|
||||
- **🔐 本地化配置**:所有的 API 配置(Key、Base URL 等)和语言偏好均保存在浏览器 `localStorage` 中,隐私且安全。
|
||||
|
||||
## 项目结构
|
||||
---
|
||||
|
||||
你最常关注的文件:
|
||||
## 🛠️ 技术栈
|
||||
|
||||
- `src/App.vue`:应用壳层,组合布局与事件转发。
|
||||
- `src/composables/useThinkFlow.ts`:核心业务逻辑(节点/边操作、API 调用、持久化)。
|
||||
- `src/components/TopNav.vue`:顶部工具栏(布局、导出、总结、设置、语言切换)。
|
||||
- `src/components/BottomBar.vue`:底部输入条(核心想法输入 + 执行)。
|
||||
- `src/components/WindowNode.vue`:自定义节点 UI(扩展/深挖/配图/follow-up)。
|
||||
- `src/components/SettingsModal.vue`:API 模式与自定义端点配置 UI。
|
||||
- `src/i18n/index.ts`:i18n 初始化(默认英文;语言写入 `localStorage`)。
|
||||
- **框架**: [Vue 3](https://vuejs.org/) (Composition API)
|
||||
- **构建工具**: [Vite 5](https://vitejs.dev/)
|
||||
- **语言**: [TypeScript](https://www.typescriptlang.org/)
|
||||
- **样式**: [Tailwind CSS](https://tailwindcss.com/)
|
||||
- **画布引擎**: [@vue-flow/core](https://vueflow.dev/)
|
||||
- **国际化**: [vue-i18n](https://vue-i18n.intlify.dev/)
|
||||
- **图标库**: [lucide-vue-next](https://lucide.dev/)
|
||||
- **Markdown 渲染**: [markdown-it](https://github.com/markdown-it/markdown-it)
|
||||
|
||||
## 核心原理(高层)
|
||||
---
|
||||
|
||||
应用围绕一个 composable 构建:
|
||||
## 📂 代码结构指南
|
||||
|
||||
- `useThinkFlow` 统一持有:节点/边数据、UI 状态、网络请求、错误处理、导出能力。
|
||||
- 组件尽量“轻”:负责渲染与事件转发(expand、deep-dive、image、export 等)。
|
||||
- 画布由 VueFlow 渲染,节点使用自定义类型 `window`。
|
||||
- 配置持久化到 `localStorage`:
|
||||
- 语言:`language`
|
||||
- API 模式与 chat/image 的 baseUrl/model/apiKey
|
||||
```text
|
||||
src/
|
||||
├── components/ # UI 组件库
|
||||
│ ├── TopNav.vue # 顶部工具栏:处理适配、布局、导出、总结、语言切换等全局动作
|
||||
│ ├── SideNav.vue # 左侧配置栏:控制小地图、连线样式、背景网格及 API 设置入口
|
||||
│ ├── BottomBar.vue # 底部输入框:核心想法的初始入口
|
||||
│ ├── WindowNode.vue # 自定义节点:核心 UI,包含扩展、回答、生图及追问逻辑
|
||||
│ ├── SettingsModal.vue # API 配置弹窗:支持文本/图片生成的 Base URL 和 Key 设置
|
||||
│ ├── SummaryModal.vue # 全篇总结展示弹窗
|
||||
│ ├── ImagePreviewModal.vue # 节点配图全屏预览弹窗
|
||||
│ └── ResetConfirmModal.vue # 画布重置确认弹窗
|
||||
├── composables/ # 核心逻辑层
|
||||
│ └── useThinkFlow.ts # 核心业务 Hook:管理节点状态、API 调用、布局算法、持久化逻辑等
|
||||
├── i18n/ # 国际化
|
||||
│ ├── locales/ # 语言包 (zh.json, en.json)
|
||||
│ └── index.ts # i18n 初始化
|
||||
├── App.vue # 应用入口:组合各组件并配置 VueFlow 画布环境
|
||||
└── main.ts # 程序起点
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
### 核心逻辑设计
|
||||
|
||||
### 环境要求
|
||||
- **状态管理**: 采用 `useThinkFlow` 组合式函数统一管理画布节点、连线及 UI 状态。通过解构方式在 `App.vue` 中分发给各子组件。
|
||||
- **布局算法**: 实现了基于子树高度动态计算的“横向树形”排版算法,能够自动适配节点展开后的尺寸变化,确保图谱整齐。
|
||||
- **API 通信**: 适配 OpenAI 格式接口,支持自定义模型名称及 Base URL。
|
||||
|
||||
- Node.js **18+**(Vite 5 要求)
|
||||
- npm(也可以用 pnpm/yarn;示例使用 npm)
|
||||
---
|
||||
|
||||
### 安装依赖
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 环境准备
|
||||
|
||||
- Node.js 18+
|
||||
- npm 或 pnpm
|
||||
|
||||
### 2. 安装依赖
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### 启动开发环境
|
||||
### 3. 启动开发服务器
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
打开 Vite 输出的地址(通常是 `http://localhost:5173`)。
|
||||
访问 `http://localhost:5173` 即可开始使用。
|
||||
|
||||
### 构建
|
||||
---
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
## ⚙️ 配置说明
|
||||
|
||||
### 预览构建产物
|
||||
本项目不提供后端服务,需用户自行配置 API 接口:
|
||||
|
||||
```bash
|
||||
npm run preview
|
||||
```
|
||||
1. 点击左侧工具栏底部的 **设置** 图标。
|
||||
2. **默认模式**: 预设了部分体验接口(可能有请求限制)。
|
||||
3. **自定义模式**:
|
||||
- **文本生成**: 填入 OpenAI 兼容格式的 `Base URL`、`Model Name` 和 `API Key`。
|
||||
- **图片生成**: 填入支持 `dall-e` 格式或其他生图 API 的配置。
|
||||
|
||||
## 配置说明
|
||||
---
|
||||
|
||||
### 自定义模式:自带端点(BYO Endpoint)
|
||||
## 📖 功能使用手册
|
||||
|
||||
在界面里打开 **Settings**:
|
||||
1. **开启新会话**: 在底部输入框输入您的想法(如“未来城市的交通方式”),按回车。
|
||||
2. **节点操作**:
|
||||
- **扩展**: 点击节点右侧的 `+` 或输入后续要求,AI 会继续在该分支下生成子节点。
|
||||
- **回答**: 点击书本图标,获取该节点的深度解析。
|
||||
- **生图**: 点击图片图标,为该想法生成视觉参考。
|
||||
3. **整理画布**:
|
||||
- **布局**: 点击顶部“布局”按钮,自动按层级整理所有节点。
|
||||
- **导出**: 点击顶部“导出”按钮,获取 Markdown 格式的内容副本。
|
||||
|
||||
- 切换到 **Custom**
|
||||
- 配置 **文本生成(chat completion)**
|
||||
- `baseUrl`(POST 接口地址)
|
||||
- `model`
|
||||
- `apiKey`
|
||||
- 配置 **图片生成**
|
||||
- `baseUrl`(POST 接口地址)
|
||||
- `model`
|
||||
- `apiKey`
|
||||
---
|
||||
|
||||
这些字段会自动保存到 `localStorage`。
|
||||
## 📄 开源协议
|
||||
|
||||
## 功能使用说明
|
||||
|
||||
### 1)从核心想法生成图谱
|
||||
|
||||
1. 在底部输入框输入核心想法
|
||||
2. 回车或点击 **Execute**
|
||||
3. 生成根节点并自动扩展出子节点
|
||||
|
||||
### 2)对某个节点继续扩展(Follow-Up)
|
||||
|
||||
1. 在节点的 follow-up 输入框填写“追加需求”
|
||||
2. 回车触发扩展
|
||||
3. 扩展时会携带“从根到当前节点”的上下文路径,保证更贴合当前分支
|
||||
|
||||
### 3)深挖节点详情
|
||||
|
||||
点击节点上的 **Deep Dive**:
|
||||
|
||||
- 生成更长的解释/拓展内容
|
||||
- 内容会写回节点并可重复打开(不必每次都重新请求)
|
||||
|
||||
### 4)节点配图与预览
|
||||
|
||||
- 点击节点上的 **IMG** 生成配图
|
||||
- 点击图片打开全屏预览
|
||||
- 支持在预览层或节点上进行重新生成
|
||||
|
||||
### 5)导出 Markdown
|
||||
|
||||
顶部工具栏点击 **Export**:
|
||||
|
||||
- 根节点作为一级标题
|
||||
- 子节点按缩进列表输出
|
||||
- 深挖内容作为引用块输出到对应节点下方
|
||||
|
||||
## 第三方集成与插件
|
||||
|
||||
- **Microsoft Clarity**:在 `index.html` 中引入,用于分析与统计。
|
||||
- **VueFlow 插件**:
|
||||
- Background(Dots/Lines)
|
||||
- Controls(缩放/适配)
|
||||
- MiniMap(总览)
|
||||
|
||||
## 国际化(i18n)
|
||||
|
||||
- 默认语言:**英文**
|
||||
- 已支持:`en`、`zh`
|
||||
- 语言选择写入 `localStorage` 的 `language`
|
||||
|
||||
新增语言建议步骤:
|
||||
|
||||
1. 在 `src/i18n/locales/` 添加对应 JSON
|
||||
2. 在 `src/i18n/index.ts` 注册 messages
|
||||
3. 在 UI 中扩展语言切换逻辑(目前为 EN/ZH 双向切换)
|
||||
|
||||
## 常见问题排查
|
||||
|
||||
- **CORS / Failed to fetch**:使用自定义端点时,确保支持浏览器跨域请求并正确返回 CORS 响应头。
|
||||
- **401/403**:检查 API Key 是否正确,以及是否使用 `Authorization: Bearer ...`。
|
||||
- **429**:触发限流,稍后重试。
|
||||
|
||||
## Scripts
|
||||
|
||||
- `npm run dev`:启动开发服务器
|
||||
- `npm run build`:构建生产包
|
||||
- `npm run preview`:本地预览构建产物
|
||||
MIT License
|
||||
|
||||
@@ -510,35 +510,112 @@ export function useThinkFlow({ t, locale }: { t: Translate; locale: Ref<string>
|
||||
|
||||
/**
|
||||
* 布局:从根节点开始按“横向树形”重新排布节点位置
|
||||
* - 主要用于整理节点过多导致的视觉拥挤
|
||||
* - 动态计算节点宽高与子树高度,确保在节点展开(回答/生图)后仍能整齐排布
|
||||
*/
|
||||
const resetLayout = () => {
|
||||
const rootNode = flowNodes.value.find(n => n.data.type === 'root')
|
||||
if (!rootNode) return
|
||||
|
||||
const nodeGapX = 150 // 节点层级间的横向间距
|
||||
const nodeGapY = 40 // 同级节点间的纵向间距
|
||||
|
||||
/**
|
||||
* 获取节点的实际尺寸,优先使用已测量尺寸,否则使用默认值
|
||||
*/
|
||||
const getNodeSize = (node: any) => ({
|
||||
width: node.dimensions?.width ?? node.measured?.width ?? 280,
|
||||
height: node.dimensions?.height ?? node.measured?.height ?? 180
|
||||
})
|
||||
|
||||
// 存储每个节点及其子树所需的总高度
|
||||
const subtreeHeights = new Map<string, number>()
|
||||
|
||||
/**
|
||||
* 第一遍遍历:递归计算每个节点及其子树占用的总高度
|
||||
*/
|
||||
const calculateSubtreeHeight = (nodeId: string): number => {
|
||||
const node = flowNodes.value.find(n => n.id === nodeId)
|
||||
if (!node || node.hidden) return 0
|
||||
|
||||
const size = getNodeSize(node)
|
||||
const children = flowEdges.value
|
||||
.filter(e => e.source === nodeId)
|
||||
.map(e => e.target)
|
||||
.filter(id => {
|
||||
const childNode = flowNodes.value.find(n => n.id === id)
|
||||
return childNode && !childNode.hidden
|
||||
})
|
||||
|
||||
if (children.length === 0) {
|
||||
subtreeHeights.set(nodeId, size.height)
|
||||
return size.height
|
||||
}
|
||||
|
||||
let childrenTotalHeight = 0
|
||||
children.forEach((childId, index) => {
|
||||
childrenTotalHeight += calculateSubtreeHeight(childId)
|
||||
if (index < children.length - 1) {
|
||||
childrenTotalHeight += nodeGapY
|
||||
}
|
||||
})
|
||||
|
||||
// 节点自身高度与子树高度取较大值
|
||||
const totalHeight = Math.max(size.height, childrenTotalHeight)
|
||||
subtreeHeights.set(nodeId, totalHeight)
|
||||
return totalHeight
|
||||
}
|
||||
|
||||
// 开始计算
|
||||
calculateSubtreeHeight(rootNode.id)
|
||||
|
||||
const visited = new Set<string>()
|
||||
const layoutNode = (nodeId: string, x: number, y: number) => {
|
||||
|
||||
/**
|
||||
* 第二遍遍历:根据计算出的子树高度,递归设置节点位置
|
||||
* @param nodeId 当前节点 ID
|
||||
* @param x 当前起始 X 坐标
|
||||
* @param ySubtreeTop 当前子树顶部的 Y 坐标
|
||||
*/
|
||||
const layoutNode = (nodeId: string, x: number, ySubtreeTop: number) => {
|
||||
if (visited.has(nodeId)) return
|
||||
visited.add(nodeId)
|
||||
|
||||
const node = flowNodes.value.find(n => n.id === nodeId)
|
||||
if (node) {
|
||||
node.position = { x, y }
|
||||
if (!node || node.hidden) return
|
||||
|
||||
const childEdges = flowEdges.value.filter(e => e.source === nodeId)
|
||||
childEdges.forEach((edge, index) => {
|
||||
const offsetX = 450
|
||||
const totalHeight = (childEdges.length - 1) * 280
|
||||
const startY = y - totalHeight / 2
|
||||
const offsetY = index * 280
|
||||
const size = getNodeSize(node)
|
||||
const subtreeHeight = subtreeHeights.get(nodeId) || size.height
|
||||
|
||||
layoutNode(edge.target, x + offsetX, startY + offsetY)
|
||||
// 将节点放置在子树区域的垂直中心
|
||||
node.position = {
|
||||
x,
|
||||
y: ySubtreeTop + (subtreeHeight - size.height) / 2
|
||||
}
|
||||
|
||||
const children = flowEdges.value
|
||||
.filter(e => e.source === nodeId)
|
||||
.map(e => e.target)
|
||||
.filter(id => {
|
||||
const childNode = flowNodes.value.find(n => n.id === id)
|
||||
return childNode && !childNode.hidden
|
||||
})
|
||||
|
||||
if (children.length > 0) {
|
||||
const nextX = x + size.width + nodeGapX
|
||||
let currentY = ySubtreeTop
|
||||
|
||||
children.forEach(childId => {
|
||||
const childSubtreeHeight = subtreeHeights.get(childId) || 0
|
||||
layoutNode(childId, nextX, currentY)
|
||||
currentY += childSubtreeHeight + nodeGapY
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
layoutNode(rootNode.id, 50, 300)
|
||||
// 从根节点开始排版
|
||||
layoutNode(rootNode.id, 50, 100)
|
||||
|
||||
// 延迟执行 fitView 确保位置更新已应用
|
||||
setTimeout(() => {
|
||||
fitView({ padding: 0.2, duration: 800 })
|
||||
}, 100)
|
||||
@@ -990,4 +1067,3 @@ export function useThinkFlow({ t, locale }: { t: Translate; locale: Ref<string>
|
||||
expandIdea
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"coreIdea": "Core Idea",
|
||||
"followUp": "Ask a follow-up...",
|
||||
"imgAction": "IMG",
|
||||
"deepDive": "Detail",
|
||||
"deepDive": "Answer",
|
||||
"view": "View",
|
||||
"regenerate": "Regenerate",
|
||||
"mainTitle": "Root Node",
|
||||
|
||||
@@ -72,14 +72,14 @@
|
||||
"coreIdea": "核心想法",
|
||||
"followUp": "输入后续问题...",
|
||||
"imgAction": "生图",
|
||||
"deepDive": "详情",
|
||||
"deepDive": "回答",
|
||||
"view": "查看",
|
||||
"regenerate": "重新生成",
|
||||
"mainTitle": "主节点",
|
||||
"moduleTitle": "子节点"
|
||||
},
|
||||
"prompts": {
|
||||
"system": "你是一个思维发散助手,帮助用户将想法逐层展开,构建思维树。\n\n工作流程:\n1. 用户给出一个初始想法(或选择一个已有节点继续追问)。\n2. 你需要根据【思考上下文路径】(即从根节点到当前节点的思考链路)来理解用户的意图。\n3. 生成 3-5 个更深层或相关维度的子想法。\n4. 每个子想法包含简短名称和极简描述。\n\n返回格式必须为严格 JSON:\n{'{'}\n \"nodes\": [\n {'{'} \"text\": \"子想法1名称\", \"description\": \"一句话描述\" {'}'},\n {'{'} \"text\": \"子想法2名称\", \"description\": \"一句话描述\" {'}'}\n ]\n{'}'}\n\n注意:只返回 JSON,不附加解释。",
|
||||
"system": "你是一个思维发散助手,帮助用户将想法逐层展开,构建思维树。\n\n工作流程:\n1. 用户给出一个初始想法(或选择一个已有节点继续追问)。\n2. 你需要根据【思考上下文路径】(即从根节点到当前节点的思考链路)来理解用户的意图。\n3. 生成 3-5 个更深层或相关维度的子想法。\n4. 每个子想法包含简短名称和简单描述。\n\n返回格式必须为严格 JSON:\n{'{'}\n \"nodes\": [\n {'{'} \"text\": \"子想法1名称\", \"description\": \"一句话描述\" {'}'},\n {'{'} \"text\": \"子想法2名称\", \"description\": \"一句话描述\" {'}'}\n ]\n{'}'}\n\n注意:只返回 JSON,不附加解释。",
|
||||
"image": "这是一张高质量写实摄影风格的图片。上下文(从根到当前的概念链路):{context}。主体/概念:{topic}。详情/特征:{detail}。画面要求:真实材质与细节、准确透视与比例、自然光或电影级布光、干净背景与高级构图、色彩克制,适合作为思维导图的视觉核心。质量:超清、锐利、噪点控制自然、层次分明的景深。严禁:任何文字/水印/Logo;卡通、插画、绘本、手绘、漫画、动漫、3D 渲染感、过度滤镜、变形、模糊、低清。",
|
||||
"continue": "请继续深入发散",
|
||||
"coreIdeaPrefix": "核心想法",
|
||||
@@ -89,4 +89,4 @@
|
||||
"deepDivePrompt": "请针对【{topic}】提供一个深度且详细的解析。要求:\n1. 结构清晰,包含背景、核心原理、关键要素和实际应用。\n2. 语言专业且易懂。\n3. 总字数控制在 300-500 字左右。\n4. 直接输出正文内容,不要包含 JSON 格式,也不要包含任何开场白或结束语。",
|
||||
"summaryPrompt": "你是一个思维总结专家。请根据以下提供的思维导图节点信息(包含核心想法及其发散出的所有子想法),生成一份结构化的全篇总结。\n\n节点数据如下:\n{nodes}\n\n要求:\n1. 提炼出核心主题及其背后的核心逻辑。\n2. 归纳出几个主要的维度或分支方向。\n3. 总结最终达成的洞察或结论。\n4. 语言要精炼、专业,富有启发性。\n5. 直接输出总结内容,不要包含 JSON 格式,不要有任何开场白。"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user