mirror of
https://github.com/lobehub/lobe-chat.git
synced 2025-12-20 01:12:52 +08:00
♻️ refactor: add badge and improve document (#8528)
* update readme * 📝 docs: Update readme * 💄 style: Update PlanIcon * improve tooltip placement * improve tray --------- Co-authored-by: canisminor1990 <i@canisminor.cc>
This commit is contained in:
@@ -1,67 +1,353 @@
|
||||
# LobeHub Desktop Application
|
||||
# 🤯 LobeHub Desktop Application
|
||||
|
||||
LobeHub Desktop 是 [LobeChat](https://github.com/lobehub/lobe-chat) 的跨平台桌面应用程序,使用 Electron 构建,提供了更加原生的桌面体验和功能。
|
||||
LobeHub Desktop is a cross-platform desktop application for [LobeChat](https://github.com/lobehub/lobe-chat), built with Electron, providing a more native desktop experience and functionality.
|
||||
|
||||
## 功能特点
|
||||
## ✨ Features
|
||||
|
||||
- **跨平台支持**:支持 macOS (Intel/Apple Silicon)、Windows 和 Linux 系统
|
||||
- **自动更新**:内置更新机制,确保您始终使用最新版本
|
||||
- **多语言支持**:完整的国际化支持,包括中文、英文等多种语言
|
||||
- **原生集成**:与操作系统深度集成,提供原生菜单、快捷键和通知
|
||||
- **安全可靠**:macOS 版本经过公证,确保安全性
|
||||
- **多渠道发布**:提供稳定版、测试版和每日构建版本
|
||||
- **🌍 Cross-platform Support**: Supports macOS (Intel/Apple Silicon), Windows, and Linux systems
|
||||
- **🔄 Auto Updates**: Built-in update mechanism ensures you always have the latest version
|
||||
- **🌐 Multi-language Support**: Complete i18n support for 18+ languages with lazy loading
|
||||
- **🎨 Native Integration**: Deep OS integration with native menus, shortcuts, and notifications
|
||||
- **🔒 Secure & Reliable**: macOS notarized, encrypted token storage, secure OAuth flow
|
||||
- **📦 Multiple Release Channels**: Stable, beta, and nightly build versions
|
||||
- **⚡ Advanced Window Management**: Multi-window architecture with theme synchronization
|
||||
- **🔗 Remote Server Sync**: Secure data synchronization with remote LobeChat instances
|
||||
- **🎯 Developer Tools**: Built-in development panel and comprehensive debugging tools
|
||||
|
||||
## 开发环境设置
|
||||
## 🚀 Development Setup
|
||||
|
||||
### 前提条件
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 22+
|
||||
- pnpm 10+
|
||||
- **Node.js** 22+
|
||||
- **pnpm** 10+
|
||||
- **Electron** compatible development environment
|
||||
|
||||
### 安装依赖
|
||||
### Quick Start
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
pnpm install-isolated
|
||||
```
|
||||
|
||||
### 配置环境变量
|
||||
|
||||
复制 `.env.desktop` 到 `.env`。
|
||||
|
||||
> [!WARNING]
|
||||
> 注意提前备份好 `.env` 文件,避免丢失配置。
|
||||
|
||||
### 开发模式运行
|
||||
|
||||
```bash
|
||||
# Start development server
|
||||
pnpm electron:dev
|
||||
|
||||
# Type checking
|
||||
pnpm typecheck
|
||||
|
||||
# Run tests
|
||||
pnpm test
|
||||
```
|
||||
|
||||
### 构建应用
|
||||
### Environment Configuration
|
||||
|
||||
构建所有平台:
|
||||
Copy `.env.desktop` to `.env` and configure as needed:
|
||||
|
||||
```bash
|
||||
pnpm build
|
||||
cp .env.desktop .env
|
||||
```
|
||||
|
||||
构建特定平台:
|
||||
> \[!WARNING]
|
||||
> Backup your `.env` file before making changes to avoid losing configurations.
|
||||
|
||||
### Build Commands
|
||||
|
||||
| Command | Description |
|
||||
| ------------------ | --------------------------------------- |
|
||||
| `pnpm build` | Build for all platforms |
|
||||
| `pnpm build:mac` | Build for macOS (Intel + Apple Silicon) |
|
||||
| `pnpm build:win` | Build for Windows |
|
||||
| `pnpm build:linux` | Build for Linux |
|
||||
| `pnpm build-local` | Local development build |
|
||||
|
||||
### Development Workflow
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
pnpm build:mac
|
||||
# 1. Development
|
||||
pnpm electron:dev # Start with hot reload
|
||||
|
||||
# Windows
|
||||
pnpm build:win
|
||||
# 2. Code Quality
|
||||
pnpm lint # ESLint checking
|
||||
pnpm format # Prettier formatting
|
||||
pnpm typecheck # TypeScript validation
|
||||
|
||||
# Linux
|
||||
pnpm build:linux
|
||||
# 3. Testing
|
||||
pnpm test # Run Vitest tests
|
||||
|
||||
# 4. Build & Package
|
||||
pnpm build # Production build
|
||||
pnpm build-local # Local testing build
|
||||
```
|
||||
|
||||
## 发布渠道
|
||||
## 🎯 Release Channels
|
||||
|
||||
应用提供三个发布渠道:
|
||||
| Channel | Description | Stability | Auto-Updates |
|
||||
| ----------- | -------------------------------- | --------- | ------------ |
|
||||
| **Stable** | Thoroughly tested releases | 🟢 High | ✅ Yes |
|
||||
| **Beta** | Pre-release with new features | 🟡 Medium | ✅ Yes |
|
||||
| **Nightly** | Daily builds with latest changes | 🟠 Low | ✅ Yes |
|
||||
|
||||
- **稳定版**:经过充分测试的正式版本
|
||||
- **测试版 (Beta)**:预发布版本,包含即将发布的新功能
|
||||
- **每日构建版 (Nightly)**:包含最新开发进展的构建版本
|
||||
## 🛠 Technology Stack
|
||||
|
||||
### Core Framework
|
||||
|
||||
- **Electron** `37.1.0` - Cross-platform desktop framework
|
||||
- **Node.js** `22+` - Backend runtime
|
||||
- **TypeScript** `5.7+` - Type-safe development
|
||||
- **Vite** `6.2+` - Build tooling
|
||||
|
||||
### Architecture & Patterns
|
||||
|
||||
- **Dependency Injection** - IoC container with decorator-based registration
|
||||
- **Event-Driven Architecture** - IPC communication between processes
|
||||
- **Module Federation** - Dynamic controller and service loading
|
||||
- **Observer Pattern** - State management and UI synchronization
|
||||
|
||||
### Development Tools
|
||||
|
||||
- **Vitest** - Unit testing framework
|
||||
- **ESLint** - Code linting
|
||||
- **Prettier** - Code formatting
|
||||
- **electron-builder** - Application packaging
|
||||
- **electron-updater** - Auto-update mechanism
|
||||
|
||||
### Security & Storage
|
||||
|
||||
- **Electron Safe Storage** - Encrypted token storage
|
||||
- **OAuth 2.0 + PKCE** - Secure authentication flow
|
||||
- **electron-store** - Persistent configuration
|
||||
- **Custom Protocol Handler** - Secure callback handling
|
||||
|
||||
## 🏗 Architecture
|
||||
|
||||
The desktop application uses a sophisticated dependency injection and event-driven architecture:
|
||||
|
||||
### 📁 Core Structure
|
||||
|
||||
```
|
||||
src/main/core/
|
||||
├── App.ts # 🎯 Main application orchestrator
|
||||
├── IoCContainer.ts # 🔌 Dependency injection container
|
||||
├── window/ # 🪟 Window management modules
|
||||
│ ├── WindowThemeManager.ts # 🎨 Theme synchronization
|
||||
│ ├── WindowPositionManager.ts # 📐 Position persistence
|
||||
│ ├── WindowErrorHandler.ts # ⚠️ Error boundaries
|
||||
│ └── WindowConfigBuilder.ts # ⚙️ Configuration builder
|
||||
├── browser/ # 🌐 Browser management modules
|
||||
│ ├── Browser.ts # 🪟 Individual window instances
|
||||
│ └── BrowserManager.ts # 👥 Multi-window coordinator
|
||||
├── ui/ # 🎨 UI system modules
|
||||
│ ├── Tray.ts # 📍 System tray integration
|
||||
│ ├── TrayManager.ts # 🔧 Tray management
|
||||
│ ├── MenuManager.ts # 📋 Native menu system
|
||||
│ └── ShortcutManager.ts # ⌨️ Global shortcuts
|
||||
└── infrastructure/ # 🔧 Infrastructure services
|
||||
├── StoreManager.ts # 💾 Configuration storage
|
||||
├── I18nManager.ts # 🌍 Internationalization
|
||||
├── UpdaterManager.ts # 📦 Auto-update system
|
||||
└── StaticFileServerManager.ts # 🗂️ Local file serving
|
||||
```
|
||||
|
||||
### 🔄 Application Lifecycle
|
||||
|
||||
The `App.ts` class orchestrates the entire application lifecycle through key phases:
|
||||
|
||||
#### 1. 🚀 Initialization Phase
|
||||
|
||||
- **System Information Logging** - Captures OS, CPU, RAM, and locale details
|
||||
- **Store Manager Setup** - Initializes persistent configuration storage
|
||||
- **Dynamic Module Loading** - Auto-discovers controllers and services via glob imports
|
||||
- **IPC Event Registration** - Sets up inter-process communication channels
|
||||
|
||||
#### 2. 🏃 Bootstrap Phase
|
||||
|
||||
- **Single Instance Check** - Ensures only one application instance runs
|
||||
- **IPC Server Launch** - Starts the communication server
|
||||
- **Core Manager Initialization** - Sequential initialization of all managers:
|
||||
- 🌍 I18n for internationalization
|
||||
- 📋 Menu system for native menus
|
||||
- 🗂️ Static file server for local assets
|
||||
- ⌨️ Global shortcuts registration
|
||||
- 🪟 Browser window management
|
||||
- 📍 System tray (Windows only)
|
||||
- 📦 Auto-updater system
|
||||
|
||||
### 🔧 Core Components Deep Dive
|
||||
|
||||
#### 🌐 Browser Management System
|
||||
|
||||
- **Multi-Window Architecture** - Supports chat, settings, and devtools windows
|
||||
- **Window State Management** - Handles positioning, theming, and lifecycle
|
||||
- **WebContents Mapping** - Bidirectional mapping between WebContents and identifiers
|
||||
- **Event Broadcasting** - Centralized event distribution to all or specific windows
|
||||
|
||||
#### 🔌 Dependency Injection & Event System
|
||||
|
||||
- **IoC Container** - WeakMap-based container for decorated controller methods
|
||||
- **Decorator Registration** - `@ipcClientEvent` and `@ipcServerEvent` decorators
|
||||
- **Automatic Event Mapping** - Events registered during controller loading
|
||||
- **Service Locator** - Type-safe service and controller retrieval
|
||||
|
||||
#### 🪟 Window Management
|
||||
|
||||
- **Theme-Aware Windows** - Automatic adaptation to system dark/light mode
|
||||
- **Platform-Specific Styling** - Windows title bar and overlay customization
|
||||
- **Position Persistence** - Save and restore window positions across sessions
|
||||
- **Error Boundaries** - Centralized error handling for window operations
|
||||
|
||||
#### 🔧 Infrastructure Services
|
||||
|
||||
##### 🌍 I18n Manager
|
||||
|
||||
- **18+ Language Support** with lazy loading and namespace organization
|
||||
- **System Integration** with Electron's locale detection
|
||||
- **Dynamic UI Refresh** on language changes
|
||||
- **Resource Management** with efficient loading strategies
|
||||
|
||||
##### 📦 Update Manager
|
||||
|
||||
- **Multi-Channel Support** (stable, beta, nightly) with configurable intervals
|
||||
- **Background Downloads** with progress tracking and user notifications
|
||||
- **Rollback Protection** with error handling and recovery mechanisms
|
||||
- **Channel Management** with automatic channel switching
|
||||
|
||||
##### 💾 Store Manager
|
||||
|
||||
- **Type-Safe Storage** using electron-store with TypeScript interfaces
|
||||
- **Encrypted Secrets** via Electron's Safe Storage API
|
||||
- **Configuration Validation** with default value management
|
||||
- **File System Integration** with automatic directory creation
|
||||
|
||||
##### 🗂️ Static File Server
|
||||
|
||||
- **Local HTTP Server** for serving application assets and user files
|
||||
- **Security Controls** with request filtering and access validation
|
||||
- **File Management** with upload, download, and deletion capabilities
|
||||
- **Path Resolution** with intelligent routing between storage locations
|
||||
|
||||
#### 🎨 UI System Integration
|
||||
|
||||
- **Global Shortcuts** - Platform-aware keyboard shortcut registration with conflict detection
|
||||
- **System Tray** - Native integration with context menus and notifications
|
||||
- **Native Menus** - Platform-specific application and context menus with i18n
|
||||
- **Theme Synchronization** - Automatic theme updates across all UI components
|
||||
|
||||
### 🏛 Controller & Service Architecture
|
||||
|
||||
#### 🎮 Controller Pattern
|
||||
|
||||
- **IPC Event Handling** - Processes events from renderer with decorator-based registration
|
||||
- **Lifecycle Hooks** - `beforeAppReady` and `afterAppReady` for initialization phases
|
||||
- **Type-Safe Communication** - Strong typing for all IPC events and responses
|
||||
- **Error Boundaries** - Comprehensive error handling with proper propagation
|
||||
|
||||
#### 🔧 Service Pattern
|
||||
|
||||
- **Business Logic Encapsulation** - Clean separation of concerns
|
||||
- **Dependency Management** - Managed through IoC container
|
||||
- **Cross-Controller Sharing** - Services accessible via service locator pattern
|
||||
- **Resource Management** - Proper initialization and cleanup
|
||||
|
||||
### 🔗 Inter-Process Communication
|
||||
|
||||
#### 📡 IPC System Features
|
||||
|
||||
- **Bidirectional Communication** - Main↔Renderer and Main↔Next.js server
|
||||
- **Type-Safe Events** - TypeScript interfaces for all event parameters
|
||||
- **Context Awareness** - Events include sender context for window-specific operations
|
||||
- **Error Propagation** - Centralized error handling with proper status codes
|
||||
|
||||
#### 🛡️ Security Features
|
||||
|
||||
- **OAuth 2.0 + PKCE** - Secure authentication with state parameter validation
|
||||
- **Encrypted Token Storage** - Using Electron's Safe Storage API when available
|
||||
- **Custom Protocol Handler** - Secure callback handling for OAuth flows
|
||||
- **Request Filtering** - Security controls for web requests and external links
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
### Test Structure
|
||||
|
||||
```bash
|
||||
apps/desktop/src/main/controllers/__tests__/ # Controller unit tests
|
||||
tests/ # Integration tests
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
pnpm test # Run all tests
|
||||
pnpm test:watch # Watch mode
|
||||
pnpm typecheck # Type validation
|
||||
```
|
||||
|
||||
### Test Coverage
|
||||
|
||||
- **Controller Tests** - IPC event handling validation
|
||||
- **Service Tests** - Business logic verification
|
||||
- **Integration Tests** - End-to-end workflow testing
|
||||
- **Type Tests** - TypeScript interface validation
|
||||
|
||||
## 🔒 Security Features
|
||||
|
||||
### Authentication & Authorization
|
||||
|
||||
- **OAuth 2.0 Flow** with PKCE for secure token exchange
|
||||
- **State Parameter Validation** to prevent CSRF attacks
|
||||
- **Encrypted Token Storage** using platform-native secure storage
|
||||
- **Automatic Token Refresh** with fallback to re-authentication
|
||||
|
||||
### Application Security
|
||||
|
||||
- **Code Signing** - macOS notarization for enhanced security
|
||||
- **Sandboxing** - Controlled access to system resources
|
||||
- **CSP Controls** - Content Security Policy management
|
||||
- **Request Filtering** - Security controls for external requests
|
||||
|
||||
### Data Protection
|
||||
|
||||
- **Encrypted Configuration** - Sensitive data encrypted at rest
|
||||
- **Secure IPC** - Type-safe communication channels
|
||||
- **Path Validation** - Secure file system access controls
|
||||
- **Network Security** - HTTPS enforcement and proxy support
|
||||
|
||||
## 🤝 Contribution
|
||||
|
||||
Desktop application development involves complex cross-platform considerations and native integrations. We welcome community contributions to improve functionality, performance, and user experience. You can participate in improvements through:
|
||||
|
||||
### How to Contribute
|
||||
|
||||
1. **Platform Support**: Enhance cross-platform compatibility and native integrations
|
||||
2. **Performance Optimization**: Improve application startup time, memory usage, and responsiveness
|
||||
3. **Feature Development**: Add new desktop-specific features and capabilities
|
||||
4. **Bug Fixes**: Fix platform-specific issues and edge cases
|
||||
5. **Security Improvements**: Enhance security measures and authentication flows
|
||||
6. **UI/UX Enhancements**: Improve desktop user interface and experience
|
||||
|
||||
### Contribution Process
|
||||
|
||||
1. Fork the [LobeChat repository](https://github.com/lobehub/lobe-chat)
|
||||
2. Set up the desktop development environment following our setup guide
|
||||
3. Make your changes to the desktop application
|
||||
4. Submit a Pull Request describing:
|
||||
|
||||
- Platform compatibility testing results
|
||||
- Performance impact analysis
|
||||
- Security considerations
|
||||
- User experience improvements
|
||||
- Breaking changes (if any)
|
||||
|
||||
### Development Areas
|
||||
|
||||
- **Core Architecture**: Dependency injection, event system, and lifecycle management
|
||||
- **Window Management**: Multi-window support, theme synchronization, and state persistence
|
||||
- **IPC Communication**: Type-safe inter-process communication between main and renderer
|
||||
- **Platform Integration**: Native menus, shortcuts, notifications, and system tray
|
||||
- **Security Features**: OAuth flows, token encryption, and secure storage
|
||||
- **Auto-Update System**: Multi-channel updates and rollback mechanisms
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
- **Development Guide**: [`Development.md`](./Development.md) - Comprehensive development documentation
|
||||
- **Architecture Docs**: [`/docs`](../../docs/) - Detailed technical specifications
|
||||
- **Contributing**: [`CONTRIBUTING.md`](../../CONTRIBUTING.md) - Contribution guidelines
|
||||
- **Issues & Support**: [GitHub Issues](https://github.com/lobehub/lobe-chat/issues)
|
||||
|
||||
353
apps/desktop/README.zh-CN.md
Normal file
353
apps/desktop/README.zh-CN.md
Normal file
@@ -0,0 +1,353 @@
|
||||
# 🤯 LobeHub 桌面应用程序
|
||||
|
||||
LobeHub Desktop 是 [LobeChat](https://github.com/lobehub/lobe-chat) 的跨平台桌面应用程序,使用 Electron 构建,提供了更加原生的桌面体验和功能。
|
||||
|
||||
## ✨ 功能特点
|
||||
|
||||
- **🌍 跨平台支持**:支持 macOS (Intel/Apple Silicon)、Windows 和 Linux 系统
|
||||
- **🔄 自动更新**:内置更新机制,确保您始终使用最新版本
|
||||
- **🌐 多语言支持**:完整的 i18n 支持,包含 18+ 种语言的懒加载
|
||||
- **🎨 原生集成**:与操作系统深度集成,提供原生菜单、快捷键和通知
|
||||
- **🔒 安全可靠**:macOS 公证认证,加密令牌存储,安全的 OAuth 流程
|
||||
- **📦 多渠道发布**:提供稳定版、测试版和每日构建版本
|
||||
- **⚡ 高级窗口管理**:多窗口架构,支持主题同步
|
||||
- **🔗 远程服务器同步**:与远程 LobeChat 实例的安全数据同步
|
||||
- **🎯 开发者工具**:内置开发面板和全面的调试工具
|
||||
|
||||
## 🚀 开发环境设置
|
||||
|
||||
### 前提条件
|
||||
|
||||
- **Node.js** 22+
|
||||
- **pnpm** 10+
|
||||
- **Electron** 兼容的开发环境
|
||||
|
||||
### 快速开始
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
pnpm install-isolated
|
||||
|
||||
# 启动开发服务器
|
||||
pnpm electron:dev
|
||||
|
||||
# 类型检查
|
||||
pnpm typecheck
|
||||
|
||||
# 运行测试
|
||||
pnpm test
|
||||
```
|
||||
|
||||
### 环境变量配置
|
||||
|
||||
复制 `.env.desktop` 到 `.env` 并根据需要配置:
|
||||
|
||||
```bash
|
||||
cp .env.desktop .env
|
||||
```
|
||||
|
||||
> \[!WARNING]
|
||||
> 在进行更改之前请备份您的 `.env` 文件,避免丢失配置。
|
||||
|
||||
### 构建命令
|
||||
|
||||
| 命令 | 描述 |
|
||||
| ------------------ | ---------------------------------- |
|
||||
| `pnpm build` | 构建所有平台 |
|
||||
| `pnpm build:mac` | 构建 macOS (Intel + Apple Silicon) |
|
||||
| `pnpm build:win` | 构建 Windows |
|
||||
| `pnpm build:linux` | 构建 Linux |
|
||||
| `pnpm build-local` | 本地开发构建 |
|
||||
|
||||
### 开发工作流
|
||||
|
||||
```bash
|
||||
# 1. 开发
|
||||
pnpm electron:dev # 启动热重载开发服务器
|
||||
|
||||
# 2. 代码质量
|
||||
pnpm lint # ESLint 检查
|
||||
pnpm format # Prettier 格式化
|
||||
pnpm typecheck # TypeScript 验证
|
||||
|
||||
# 3. 测试
|
||||
pnpm test # 运行 Vitest 测试
|
||||
|
||||
# 4. 构建和打包
|
||||
pnpm build # 生产构建
|
||||
pnpm build-local # 本地测试构建
|
||||
```
|
||||
|
||||
## 🎯 发布渠道
|
||||
|
||||
| 渠道 | 描述 | 稳定性 | 自动更新 |
|
||||
| ------------------------ | ---------------------- | ------ | -------- |
|
||||
| **稳定版** | 经过充分测试的正式版本 | 🟢 高 | ✅ 是 |
|
||||
| **测试版 (Beta)** | 包含新功能的预发布版本 | 🟡 中 | ✅ 是 |
|
||||
| **每日构建版 (Nightly)** | 包含最新更改的每日构建 | 🟠 低 | ✅ 是 |
|
||||
|
||||
## 🛠 技术栈
|
||||
|
||||
### 核心框架
|
||||
|
||||
- **Electron** `37.1.0` - 跨平台桌面框架
|
||||
- **Node.js** `22+` - 后端运行时
|
||||
- **TypeScript** `5.7+` - 类型安全开发
|
||||
- **Vite** `6.2+` - 构建工具
|
||||
|
||||
### 架构和模式
|
||||
|
||||
- **依赖注入** - 基于装饰器注册的 IoC 容器
|
||||
- **事件驱动架构** - 进程间 IPC 通信
|
||||
- **模块联邦** - 动态控制器和服务加载
|
||||
- **观察者模式** - 状态管理和 UI 同步
|
||||
|
||||
### 开发工具
|
||||
|
||||
- **Vitest** - 单元测试框架
|
||||
- **ESLint** - 代码检查
|
||||
- **Prettier** - 代码格式化
|
||||
- **electron-builder** - 应用程序打包
|
||||
- **electron-updater** - 自动更新机制
|
||||
|
||||
### 安全和存储
|
||||
|
||||
- **Electron Safe Storage** - 加密令牌存储
|
||||
- **OAuth 2.0 + PKCE** - 安全认证流程
|
||||
- **electron-store** - 持久化配置
|
||||
- **自定义协议处理器** - 安全回调处理
|
||||
|
||||
## 🏗 架构设计
|
||||
|
||||
桌面应用程序采用了复杂的依赖注入和事件驱动架构:
|
||||
|
||||
### 📁 核心结构
|
||||
|
||||
```
|
||||
src/main/core/
|
||||
├── App.ts # 🎯 主应用程序协调器
|
||||
├── IoCContainer.ts # 🔌 依赖注入容器
|
||||
├── window/ # 🪟 窗口管理模块
|
||||
│ ├── WindowThemeManager.ts # 🎨 主题同步
|
||||
│ ├── WindowPositionManager.ts # 📐 位置持久化
|
||||
│ ├── WindowErrorHandler.ts # ⚠️ 错误边界
|
||||
│ └── WindowConfigBuilder.ts # ⚙️ 配置构建器
|
||||
├── browser/ # 🌐 浏览器管理模块
|
||||
│ ├── Browser.ts # 🪟 单个窗口实例
|
||||
│ └── BrowserManager.ts # 👥 多窗口协调器
|
||||
├── ui/ # 🎨 UI 系统模块
|
||||
│ ├── Tray.ts # 📍 系统托盘集成
|
||||
│ ├── TrayManager.ts # 🔧 托盘管理
|
||||
│ ├── MenuManager.ts # 📋 原生菜单系统
|
||||
│ └── ShortcutManager.ts # ⌨️ 全局快捷键
|
||||
└── infrastructure/ # 🔧 基础设施服务
|
||||
├── StoreManager.ts # 💾 配置存储
|
||||
├── I18nManager.ts # 🌍 国际化
|
||||
├── UpdaterManager.ts # 📦 自动更新系统
|
||||
└── StaticFileServerManager.ts # 🗂️ 本地文件服务
|
||||
```
|
||||
|
||||
### 🔄 应用程序生命周期
|
||||
|
||||
`App.ts` 类通过几个关键阶段协调整个应用程序的生命周期:
|
||||
|
||||
#### 1. 🚀 初始化阶段
|
||||
|
||||
- **系统信息记录** - 捕获操作系统、CPU、内存和区域设置详细信息
|
||||
- **存储管理器设置** - 初始化持久配置存储
|
||||
- **动态模块加载** - 通过 glob 导入自动发现控制器和服务
|
||||
- **IPC 事件注册** - 设置进程间通信通道
|
||||
|
||||
#### 2. 🏃 引导阶段
|
||||
|
||||
- **单实例检查** - 确保只运行一个应用程序实例
|
||||
- **IPC 服务器启动** - 启动通信服务器
|
||||
- **核心管理器初始化** - 按顺序初始化所有管理器:
|
||||
- 🌍 国际化管理器
|
||||
- 📋 原生菜单系统
|
||||
- 🗂️ 本地资源服务器
|
||||
- ⌨️ 全局快捷键注册
|
||||
- 🪟 浏览器窗口管理
|
||||
- 📍 系统托盘(仅 Windows)
|
||||
- 📦 自动更新系统
|
||||
|
||||
### 🔧 核心组件深度解析
|
||||
|
||||
#### 🌐 浏览器管理系统
|
||||
|
||||
- **多窗口架构** - 支持聊天、设置和开发工具窗口
|
||||
- **窗口状态管理** - 处理定位、主题和生命周期
|
||||
- **WebContents 映射** - WebContents 和标识符之间的双向映射
|
||||
- **事件广播** - 向所有或特定窗口的集中事件分发
|
||||
|
||||
#### 🔌 依赖注入和事件系统
|
||||
|
||||
- **IoC 容器** - 基于 WeakMap 的装饰控制器方法容器
|
||||
- **装饰器注册** - `@ipcClientEvent` 和 `@ipcServerEvent` 装饰器
|
||||
- **自动事件映射** - 控制器加载期间注册的事件
|
||||
- **服务定位器** - 类型安全的服务和控制器检索
|
||||
|
||||
#### 🪟 窗口管理
|
||||
|
||||
- **主题感知窗口** - 自动适应系统深色 / 浅色模式
|
||||
- **平台特定样式** - Windows 标题栏和覆盖自定义
|
||||
- **位置持久化** - 跨会话保存和恢复窗口位置
|
||||
- **错误边界** - 窗口操作的集中错误处理
|
||||
|
||||
#### 🔧 基础设施服务
|
||||
|
||||
##### 🌍 国际化管理器
|
||||
|
||||
- **18+ 语言支持** 懒加载和命名空间组织
|
||||
- **系统集成** 与 Electron 的区域检测集成
|
||||
- **动态 UI 刷新** 语言更改时的 UI 更新
|
||||
- **资源管理** 高效的加载策略
|
||||
|
||||
##### 📦 更新管理器
|
||||
|
||||
- **多渠道支持** (稳定版、测试版、每日构建)可配置间隔
|
||||
- **后台下载** 进度跟踪和用户通知
|
||||
- **回滚保护** 错误处理和恢复机制
|
||||
- **渠道管理** 自动渠道切换
|
||||
|
||||
##### 💾 存储管理器
|
||||
|
||||
- **类型安全存储** 使用带有 TypeScript 接口的 electron-store
|
||||
- **加密机密** 通过 Electron 的安全存储 API
|
||||
- **配置验证** 默认值管理
|
||||
- **文件系统集成** 自动目录创建
|
||||
|
||||
##### 🗂️ 静态文件服务器
|
||||
|
||||
- **本地 HTTP 服务器** 用于提供应用程序资源和用户文件
|
||||
- **安全控制** 请求过滤和访问验证
|
||||
- **文件管理** 上传、下载和删除功能
|
||||
- **路径解析** 存储位置之间的智能路由
|
||||
|
||||
#### 🎨 UI 系统集成
|
||||
|
||||
- **全局快捷键** - 平台感知的键盘快捷键注册与冲突检测
|
||||
- **系统托盘** - 带有上下文菜单和通知的原生集成
|
||||
- **原生菜单** - 带有 i18n 的平台特定应用程序和上下文菜单
|
||||
- **主题同步** - 所有 UI 组件的自动主题更新
|
||||
|
||||
### 🏛 控制器和服务架构
|
||||
|
||||
#### 🎮 控制器模式
|
||||
|
||||
- **IPC 事件处理** - 通过基于装饰器的注册处理来自渲染器的事件
|
||||
- **生命周期钩子** - 初始化阶段的 `beforeAppReady` 和 `afterAppReady`
|
||||
- **类型安全通信** - 所有 IPC 事件和响应的强类型
|
||||
- **错误边界** - 具有适当传播的全面错误处理
|
||||
|
||||
#### 🔧 服务模式
|
||||
|
||||
- **业务逻辑封装** - 关注点的清晰分离
|
||||
- **依赖管理** - 通过 IoC 容器管理
|
||||
- **跨控制器共享** - 通过服务定位器模式访问的服务
|
||||
- **资源管理** - 适当的初始化和清理
|
||||
|
||||
### 🔗 进程间通信
|
||||
|
||||
#### 📡 IPC 系统功能
|
||||
|
||||
- **双向通信** - Main↔Renderer 和 Main↔Next.js 服务器
|
||||
- **类型安全事件** - 所有事件参数的 TypeScript 接口
|
||||
- **上下文感知** - 事件包含用于窗口特定操作的发送者上下文
|
||||
- **错误传播** - 具有适当状态码的集中错误处理
|
||||
|
||||
#### 🛡️ 安全功能
|
||||
|
||||
- **OAuth 2.0 + PKCE** - 具有状态参数验证的安全认证
|
||||
- **加密令牌存储** - 在可用时使用 Electron 的安全存储 API
|
||||
- **自定义协议处理器** - OAuth 流程的安全回调处理
|
||||
- **请求过滤** - 网络请求和外部链接的安全控制
|
||||
|
||||
## 🧪 测试
|
||||
|
||||
### 测试结构
|
||||
|
||||
```bash
|
||||
apps/desktop/src/main/controllers/__tests__/ # 控制器单元测试
|
||||
tests/ # 集成测试
|
||||
```
|
||||
|
||||
### 运行测试
|
||||
|
||||
```bash
|
||||
pnpm test # 运行所有测试
|
||||
pnpm test:watch # 监视模式
|
||||
pnpm typecheck # 类型验证
|
||||
```
|
||||
|
||||
### 测试覆盖
|
||||
|
||||
- **控制器测试** - IPC 事件处理验证
|
||||
- **服务测试** - 业务逻辑验证
|
||||
- **集成测试** - 端到端工作流测试
|
||||
- **类型测试** - TypeScript 接口验证
|
||||
|
||||
## 🔒 安全功能
|
||||
|
||||
### 认证和授权
|
||||
|
||||
- **OAuth 2.0 流程** 使用 PKCE 进行安全令牌交换
|
||||
- **状态参数验证** 防止 CSRF 攻击
|
||||
- **加密令牌存储** 使用平台原生安全存储
|
||||
- **自动令牌刷新** 在失败时回退到重新认证
|
||||
|
||||
### 应用程序安全
|
||||
|
||||
- **代码签名** - macOS 公证认证以增强安全性
|
||||
- **沙盒** - 对系统资源的受控访问
|
||||
- **CSP 控制** - 内容安全策略管理
|
||||
- **请求过滤** - 外部请求的安全控制
|
||||
|
||||
### 数据保护
|
||||
|
||||
- **加密配置** - 敏感数据静态加密
|
||||
- **安全 IPC** - 类型安全的通信通道
|
||||
- **路径验证** - 安全的文件系统访问控制
|
||||
- **网络安全** - HTTPS 强制和代理支持
|
||||
|
||||
## 🤝 参与贡献
|
||||
|
||||
桌面应用程序开发涉及复杂的跨平台考虑和原生集成。我们欢迎社区贡献来改进功能、性能和用户体验。您可以通过以下方式参与改进:
|
||||
|
||||
### 如何贡献
|
||||
|
||||
1. **平台支持**:增强跨平台兼容性和原生集成
|
||||
2. **性能优化**:改进应用程序启动时间、内存使用和响应性
|
||||
3. **功能开发**:添加新的桌面特定功能和能力
|
||||
4. **错误修复**:修复平台特定问题和边缘情况
|
||||
5. **安全改进**:增强安全措施和认证流程
|
||||
6. **UI/UX 增强**:改进桌面用户界面和体验
|
||||
|
||||
### 贡献流程
|
||||
|
||||
1. Fork [LobeChat 仓库](https://github.com/lobehub/lobe-chat)
|
||||
2. 按照我们的设置指南建立桌面开发环境
|
||||
3. 对桌面应用程序进行修改
|
||||
4. 提交 Pull Request 并描述:
|
||||
|
||||
- 平台兼容性测试结果
|
||||
- 性能影响分析
|
||||
- 安全考虑
|
||||
- 用户体验改进
|
||||
- 破坏性更改(如有)
|
||||
|
||||
### 开发领域
|
||||
|
||||
- **核心架构**:依赖注入、事件系统和生命周期管理
|
||||
- **窗口管理**:多窗口支持、主题同步和状态持久化
|
||||
- **IPC 通信**:主进程和渲染进程之间的类型安全进程间通信
|
||||
- **平台集成**:原生菜单、快捷键、通知和系统托盘
|
||||
- **安全功能**:OAuth 流程、令牌加密和安全存储
|
||||
- **自动更新系统**:多渠道更新和回滚机制
|
||||
|
||||
## 📚 其他资源
|
||||
|
||||
- **开发指南**:[`Development.md`](./Development.md) - 全面的开发文档
|
||||
- **架构文档**:[`/docs`](../../docs/) - 详细的技术规范
|
||||
- **贡献指南**:[`CONTRIBUTING.md`](../../CONTRIBUTING.md) - 贡献指导
|
||||
- **问题和支持**:[GitHub Issues](https://github.com/lobehub/lobe-chat/issues)
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "lobehub-desktop-dev",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"description": "LobeHub Desktop Application",
|
||||
"homepage": "https://lobehub.com",
|
||||
"repository": {
|
||||
|
||||
BIN
apps/desktop/resources/tray-dark.png
Normal file
BIN
apps/desktop/resources/tray-dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 896 B |
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB |
BIN
apps/desktop/resources/tray-light.png
Normal file
BIN
apps/desktop/resources/tray-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 963 B |
BIN
apps/desktop/resources/tray.png
Normal file
BIN
apps/desktop/resources/tray.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
@@ -1,3 +1,28 @@
|
||||
import os from 'node:os';
|
||||
|
||||
export const isDev = process.env.NODE_ENV === 'development';
|
||||
|
||||
export const OFFICIAL_CLOUD_SERVER = process.env.OFFICIAL_CLOUD_SERVER || 'https://lobechat.com';
|
||||
|
||||
export const isMac = process.platform === 'darwin';
|
||||
export const isWindows = process.platform === 'win32';
|
||||
export const isLinux = process.platform === 'linux';
|
||||
|
||||
function getIsWindows11() {
|
||||
if (!isWindows) return false;
|
||||
// 获取操作系统版本(如 "10.0.22621")
|
||||
const release = os.release();
|
||||
const parts = release.split('.');
|
||||
|
||||
// 主版本和次版本
|
||||
const majorVersion = parseInt(parts[0], 10);
|
||||
const minorVersion = parseInt(parts[1], 10);
|
||||
|
||||
// 构建号是第三部分
|
||||
const buildNumber = parseInt(parts[2], 10);
|
||||
|
||||
// Windows 11 的构建号从 22000 开始
|
||||
return majorVersion === 10 && minorVersion === 0 && buildNumber >= 22_000;
|
||||
}
|
||||
|
||||
export const isWindows11 = getIsWindows11();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { MainBroadcastEventKey, MainBroadcastParams } from '@lobechat/electron-client-ipc';
|
||||
import { nativeTheme } from 'electron';
|
||||
|
||||
import { name } from '@/../../package.json';
|
||||
import { isMac } from '@/const/env';
|
||||
import { createLogger } from '@/utils/logger';
|
||||
|
||||
import type { App } from './App';
|
||||
@@ -54,7 +56,11 @@ export default class TrayManager {
|
||||
initializeMainTray() {
|
||||
logger.debug('初始化主托盘');
|
||||
return this.retrieveOrInitialize({
|
||||
iconPath: 'tray-icon.png',
|
||||
iconPath: isMac
|
||||
? nativeTheme.shouldUseDarkColors
|
||||
? 'tray-light.png'
|
||||
: 'tray-dark.png'
|
||||
: 'tray.png',
|
||||
identifier: 'main', // 使用应用图标,需要确保资源目录中有此文件
|
||||
tooltip: name, // 可以使用 app.getName() 或本地化字符串
|
||||
});
|
||||
|
||||
24
locales/ar/subscription.json
Normal file
24
locales/ar/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "النسخة التجارية"
|
||||
},
|
||||
"free": {
|
||||
"title": "النسخة المجانية"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "نسخة الخدمة الذاتية"
|
||||
},
|
||||
"premium": {
|
||||
"title": "النسخة المتقدمة"
|
||||
},
|
||||
"starter": {
|
||||
"title": "النسخة الأساسية"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "النسخة الاحترافية"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/bg-BG/subscription.json
Normal file
24
locales/bg-BG/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Корпоративна версия"
|
||||
},
|
||||
"free": {
|
||||
"title": "Безплатна версия"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Самостоятелен вариант"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Напреднал"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Основна версия"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Професионален"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/de-DE/subscription.json
Normal file
24
locales/de-DE/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Unternehmensversion"
|
||||
},
|
||||
"free": {
|
||||
"title": "Kostenlose Version"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Selbstbedienungs-Version"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Premium"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Grundversion"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Ultimate"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/en-US/subscription.json
Normal file
24
locales/en-US/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Enterprise"
|
||||
},
|
||||
"free": {
|
||||
"title": "Free"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Hobby"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Premium"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Starter"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Ultimate"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/es-ES/subscription.json
Normal file
24
locales/es-ES/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Versión empresarial"
|
||||
},
|
||||
"free": {
|
||||
"title": "Versión gratuita"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Versión de autoservicio"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Premium"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Versión básica"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Ultimate"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/fa-IR/subscription.json
Normal file
24
locales/fa-IR/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "نسخه سازمانی"
|
||||
},
|
||||
"free": {
|
||||
"title": "نسخه رایگان"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "نسخه خودکار"
|
||||
},
|
||||
"premium": {
|
||||
"title": "نسخه پیشرفته"
|
||||
},
|
||||
"starter": {
|
||||
"title": "نسخه پایه"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "نسخه حرفهای"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/fr-FR/subscription.json
Normal file
24
locales/fr-FR/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Version entreprise"
|
||||
},
|
||||
"free": {
|
||||
"title": "Version gratuite"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Version autonome"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Premium"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Version de base"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Ultimate"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/it-IT/subscription.json
Normal file
24
locales/it-IT/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Versione enterprise"
|
||||
},
|
||||
"free": {
|
||||
"title": "Versione gratuita"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Versione autonoma"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Premium"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Versione base"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Ultimate"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/ja-JP/subscription.json
Normal file
24
locales/ja-JP/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "エンタープライズ版"
|
||||
},
|
||||
"free": {
|
||||
"title": "無料版"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "セルフサービス版"
|
||||
},
|
||||
"premium": {
|
||||
"title": "アドバンス版"
|
||||
},
|
||||
"starter": {
|
||||
"title": "基本版"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "プロ版"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/ko-KR/subscription.json
Normal file
24
locales/ko-KR/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "기업용"
|
||||
},
|
||||
"free": {
|
||||
"title": "무료 버전"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "셀프 서비스 버전"
|
||||
},
|
||||
"premium": {
|
||||
"title": "프리미엄"
|
||||
},
|
||||
"starter": {
|
||||
"title": "스타터 버전"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "얼티메이트"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/nl-NL/subscription.json
Normal file
24
locales/nl-NL/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Onderneming"
|
||||
},
|
||||
"free": {
|
||||
"title": "Gratis"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Zelfbediening versie"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Premium"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Basis"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Ultimate"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/pl-PL/subscription.json
Normal file
24
locales/pl-PL/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Przedsiębiorstwo"
|
||||
},
|
||||
"free": {
|
||||
"title": "Darmowy"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Wersja samodzielna"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Premium"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Podstawowy"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Ultimate"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/pt-BR/subscription.json
Normal file
24
locales/pt-BR/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Versão Empresarial"
|
||||
},
|
||||
"free": {
|
||||
"title": "Versão Gratuita"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Versão Autônoma"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Premium"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Versão Básica"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Ultimate"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/ru-RU/subscription.json
Normal file
24
locales/ru-RU/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Предприятие"
|
||||
},
|
||||
"free": {
|
||||
"title": "Бесплатно"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Самостоятельная версия"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Продвинутый"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Базовый"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Профессиональный"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/tr-TR/subscription.json
Normal file
24
locales/tr-TR/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Kurumsal"
|
||||
},
|
||||
"free": {
|
||||
"title": "Ücretsiz"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Kendi Kendine Hizmet Versiyonu"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Gelişmiş"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Temel"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Profesyonel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/vi-VN/subscription.json
Normal file
24
locales/vi-VN/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "Phiên bản doanh nghiệp"
|
||||
},
|
||||
"free": {
|
||||
"title": "Phiên bản miễn phí"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "Phiên bản tự phục vụ"
|
||||
},
|
||||
"premium": {
|
||||
"title": "Phiên bản Nâng cao"
|
||||
},
|
||||
"starter": {
|
||||
"title": "Phiên bản cơ bản"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "Phiên bản Chuyên nghiệp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/zh-CN/subscription.json
Normal file
24
locales/zh-CN/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "企业版"
|
||||
},
|
||||
"free": {
|
||||
"title": "免费版"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "自助版"
|
||||
},
|
||||
"premium": {
|
||||
"title": "进阶版"
|
||||
},
|
||||
"starter": {
|
||||
"title": "基础版"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "专业版"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
locales/zh-TW/subscription.json
Normal file
24
locales/zh-TW/subscription.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"plans": {
|
||||
"plan": {
|
||||
"enterprise": {
|
||||
"title": "企業版"
|
||||
},
|
||||
"free": {
|
||||
"title": "免費版"
|
||||
},
|
||||
"hobby": {
|
||||
"title": "自助版"
|
||||
},
|
||||
"premium": {
|
||||
"title": "進階版"
|
||||
},
|
||||
"starter": {
|
||||
"title": "基礎版"
|
||||
},
|
||||
"ultimate": {
|
||||
"title": "專業版"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +1,73 @@
|
||||
# @lobechat/electron-client-ipc
|
||||
|
||||
这个包是 LobeChat 在 Electron 环境中用于处理 IPC(进程间通信)的客户端工具包。
|
||||
This package is a client-side toolkit for handling IPC (Inter-Process Communication) in LobeChat's Electron environment.
|
||||
|
||||
## 介绍
|
||||
## Introduction
|
||||
|
||||
在 Electron 应用中,IPC(进程间通信)是连接主进程(Main Process)、渲染进程(Renderer Process)以及 NextJS 进程的桥梁。为了更好地组织和管理这些通信,我们将 IPC 相关的代码分成了两个包:
|
||||
In Electron applications, IPC (Inter-Process Communication) serves as a bridge connecting the Main Process, Renderer Process, and NextJS Process. To better organize and manage these communications, we have split the IPC-related code into two packages:
|
||||
|
||||
- `@lobechat/electron-client-ipc`:**客户端 IPC 包**
|
||||
- `@lobechat/electron-server-ipc`:**服务端 IPC 包**
|
||||
- `@lobechat/electron-client-ipc`: **Client-side IPC package**
|
||||
- `@lobechat/electron-server-ipc`: **Server-side IPC package**
|
||||
|
||||
## 主要区别
|
||||
## Key Differences
|
||||
|
||||
### electron-client-ipc(本包)
|
||||
### electron-client-ipc (This Package)
|
||||
|
||||
- 运行环境:在渲染进程(Renderer Process)中运行
|
||||
- 主要职责:
|
||||
- 提供渲染进程调用主进程方法的接口定义
|
||||
- 封装 `ipcRenderer.invoke` 相关方法
|
||||
- 处理与主进程的通信请求
|
||||
- Runtime Environment: Runs in the Renderer Process
|
||||
- Main Responsibilities:
|
||||
- Provides interface definitions for renderer process to call main process methods
|
||||
- Encapsulates `ipcRenderer.invoke` related methods
|
||||
- Handles communication requests with the main process
|
||||
|
||||
### electron-server-ipc
|
||||
|
||||
- 运行环境:在 Electron 主进程和 Next.js 服务端进程中运行
|
||||
- 主要职责:
|
||||
- 提供基于 Socket 的 IPC 通信机制
|
||||
- 实现服务端(ElectronIPCServer)和客户端(ElectronIpcClient)通信组件
|
||||
- 处理跨进程的请求和响应
|
||||
- 提供自动重连和错误处理机制
|
||||
- 确保类型安全的 API 调用
|
||||
- Runtime Environment: Runs in both Electron main process and Next.js server process
|
||||
- Main Responsibilities:
|
||||
- Provides Socket-based IPC communication mechanism
|
||||
- Implements server-side (ElectronIPCServer) and client-side (ElectronIpcClient) communication components
|
||||
- Handles cross-process requests and responses
|
||||
- Provides automatic reconnection and error handling mechanisms
|
||||
- Ensures type-safe API calls
|
||||
|
||||
## 使用场景
|
||||
## Use Cases
|
||||
|
||||
当渲染进程需要:
|
||||
When the renderer process needs to:
|
||||
|
||||
- 访问系统 API
|
||||
- 进行文件操作
|
||||
- 调用主进程特定功能
|
||||
- Access system APIs
|
||||
- Perform file operations
|
||||
- Call main process specific functions
|
||||
|
||||
时,都需要通过 `electron-client-ipc` 包提供的方法来发起请求。
|
||||
All such operations need to be initiated through the methods provided by the `electron-client-ipc` package.
|
||||
|
||||
## 技术说明
|
||||
## Technical Notes
|
||||
|
||||
这种分包设计遵循了关注点分离原则,使得:
|
||||
This separated package design follows the principle of separation of concerns, ensuring that:
|
||||
|
||||
- IPC 通信接口清晰可维护
|
||||
- 客户端和服务端代码解耦
|
||||
- TypeScript 类型定义共享,确保类型安全
|
||||
- IPC communication interfaces are clear and maintainable
|
||||
- Client-side and server-side code are decoupled
|
||||
- TypeScript type definitions are shared, ensuring type safety
|
||||
|
||||
## 🤝 Contribution
|
||||
|
||||
IPC communication needs vary across different use cases and platforms. We welcome community contributions to improve and extend the IPC functionality. You can participate in improvements through:
|
||||
|
||||
### How to Contribute
|
||||
|
||||
1. **Bug Reports**: Report issues with IPC communication or type definitions
|
||||
2. **Feature Requests**: Suggest new IPC methods or improvements to existing interfaces
|
||||
3. **Code Contributions**: Submit pull requests for bug fixes or new features
|
||||
|
||||
### Contribution Process
|
||||
|
||||
1. Fork the [LobeChat repository](https://github.com/lobehub/lobe-chat)
|
||||
2. Make your changes to the IPC client package
|
||||
3. Submit a Pull Request describing:
|
||||
|
||||
- The problem being solved
|
||||
- Implementation details
|
||||
- Test cases or usage examples
|
||||
- Impact on existing functionality
|
||||
|
||||
## 📌 Note
|
||||
|
||||
This is an internal module of LobeHub (`"private": true`), designed specifically for LobeChat and not published as a standalone package.
|
||||
|
||||
73
packages/electron-client-ipc/README.zh-CN.md
Normal file
73
packages/electron-client-ipc/README.zh-CN.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# @lobechat/electron-client-ipc
|
||||
|
||||
这个包是 LobeChat 在 Electron 环境中用于处理 IPC(进程间通信)的客户端工具包。
|
||||
|
||||
## 介绍
|
||||
|
||||
在 Electron 应用中,IPC(进程间通信)是连接主进程(Main Process)、渲染进程(Renderer Process)以及 NextJS 进程的桥梁。为了更好地组织和管理这些通信,我们将 IPC 相关的代码分成了两个包:
|
||||
|
||||
- `@lobechat/electron-client-ipc`:**客户端 IPC 包**
|
||||
- `@lobechat/electron-server-ipc`:**服务端 IPC 包**
|
||||
|
||||
## 主要区别
|
||||
|
||||
### electron-client-ipc(本包)
|
||||
|
||||
- 运行环境:在渲染进程(Renderer Process)中运行
|
||||
- 主要职责:
|
||||
- 提供渲染进程调用主进程方法的接口定义
|
||||
- 封装 `ipcRenderer.invoke` 相关方法
|
||||
- 处理与主进程的通信请求
|
||||
|
||||
### electron-server-ipc
|
||||
|
||||
- 运行环境:在 Electron 主进程和 Next.js 服务端进程中运行
|
||||
- 主要职责:
|
||||
- 提供基于 Socket 的 IPC 通信机制
|
||||
- 实现服务端(ElectronIPCServer)和客户端(ElectronIpcClient)通信组件
|
||||
- 处理跨进程的请求和响应
|
||||
- 提供自动重连和错误处理机制
|
||||
- 确保类型安全的 API 调用
|
||||
|
||||
## 使用场景
|
||||
|
||||
当渲染进程需要:
|
||||
|
||||
- 访问系统 API
|
||||
- 进行文件操作
|
||||
- 调用主进程特定功能
|
||||
|
||||
时,都需要通过 `electron-client-ipc` 包提供的方法来发起请求。
|
||||
|
||||
## 技术说明
|
||||
|
||||
这种分包设计遵循了关注点分离原则,使得:
|
||||
|
||||
- IPC 通信接口清晰可维护
|
||||
- 客户端和服务端代码解耦
|
||||
- TypeScript 类型定义共享,确保类型安全
|
||||
|
||||
## 🤝 参与贡献
|
||||
|
||||
不同用例和平台的 IPC 通信需求各异。我们欢迎社区贡献来改进和扩展 IPC 功能。您可以通过以下方式参与改进:
|
||||
|
||||
### 如何贡献
|
||||
|
||||
1. **错误报告**:报告 IPC 通信或类型定义的问题
|
||||
2. **功能请求**:建议新的 IPC 方法或改进现有接口
|
||||
3. **代码贡献**:提交错误修复或新功能的拉取请求
|
||||
|
||||
### 贡献流程
|
||||
|
||||
1. Fork [LobeChat 仓库](https://github.com/lobehub/lobe-chat)
|
||||
2. 对 IPC 客户端包进行修改
|
||||
3. 提交 Pull Request 并描述:
|
||||
|
||||
- 解决的问题
|
||||
- 实现细节
|
||||
- 测试用例或使用示例
|
||||
- 对现有功能的影响
|
||||
|
||||
## 📌 说明
|
||||
|
||||
这是 LobeHub 的内部模块(`"private": true`),专为 LobeChat 设计,不作为独立包发布。
|
||||
@@ -1,54 +1,76 @@
|
||||
# @lobechat/electron-server-ipc
|
||||
|
||||
LobeHub 的 Electron 应用与服务端之间的 IPC(进程间通信)模块,提供可靠的跨进程通信能力。
|
||||
IPC (Inter-Process Communication) module between LobeHub's Electron application and server, providing reliable cross-process communication capabilities.
|
||||
|
||||
## 📝 简介
|
||||
## 📝 Introduction
|
||||
|
||||
`@lobechat/electron-server-ipc` 是 LobeHub 桌面应用的核心组件,负责处理 Electron 主进程与 nextjs 服务端之间的通信。它提供了一套简单而健壮的 API,用于在不同进程间传递数据和执行远程方法调用。
|
||||
`@lobechat/electron-server-ipc` is a core component of LobeHub's desktop application, responsible for handling communication between the Electron main process and Next.js server. It provides a simple yet robust API for passing data and executing remote method calls across different processes.
|
||||
|
||||
## 🛠️ 核心功能
|
||||
## 🛠️ Core Features
|
||||
|
||||
- **可靠的 IPC 通信**: 基于 Socket 的通信机制,确保跨进程通信的稳定性和可靠性
|
||||
- **自动重连机制**: 客户端具备断线重连功能,提高应用稳定性
|
||||
- **类型安全**: 使用 TypeScript 提供完整的类型定义,确保 API 调用的类型安全
|
||||
- **跨平台支持**: 同时支持 Windows、macOS 和 Linux 平台
|
||||
- **Reliable IPC Communication**: Socket-based communication mechanism ensuring stability and reliability of cross-process communication
|
||||
- **Automatic Reconnection**: Client features automatic reconnection functionality to improve application stability
|
||||
- **Type Safety**: Uses TypeScript to provide complete type definitions, ensuring type safety for API calls
|
||||
- **Cross-Platform Support**: Supports Windows, macOS, and Linux platforms
|
||||
|
||||
## 🧩 核心组件
|
||||
## 🧩 Core Components
|
||||
|
||||
### IPC 服务端 (ElectronIPCServer)
|
||||
### IPC Server (ElectronIPCServer)
|
||||
|
||||
负责监听客户端请求并响应,通常运行在 Electron 的主进程中:
|
||||
Responsible for listening to client requests and responding, typically runs in Electron's main process:
|
||||
|
||||
```typescript
|
||||
import { ElectronIPCEventHandler, ElectronIPCServer } from '@lobechat/electron-server-ipc';
|
||||
|
||||
// 定义处理函数
|
||||
// Define handler functions
|
||||
const eventHandler: ElectronIPCEventHandler = {
|
||||
getDatabasePath: async () => {
|
||||
return '/path/to/database';
|
||||
},
|
||||
// 其他处理函数...
|
||||
// Other handler functions...
|
||||
};
|
||||
|
||||
// 创建并启动服务器
|
||||
// Create and start server
|
||||
const server = new ElectronIPCServer(eventHandler);
|
||||
server.start();
|
||||
```
|
||||
|
||||
### IPC 客户端 (ElectronIpcClient)
|
||||
### IPC Client (ElectronIpcClient)
|
||||
|
||||
负责连接到服务端并发送请求,通常在服务端(如 Next.js 服务)中使用:
|
||||
Responsible for connecting to the server and sending requests, typically used in the server (such as Next.js service):
|
||||
|
||||
```typescript
|
||||
import { ElectronIPCMethods, ElectronIpcClient } from '@lobechat/electron-server-ipc';
|
||||
|
||||
// 创建客户端
|
||||
// Create client
|
||||
const client = new ElectronIpcClient();
|
||||
|
||||
// 发送请求
|
||||
// Send request
|
||||
const dbPath = await client.sendRequest(ElectronIPCMethods.getDatabasePath);
|
||||
```
|
||||
|
||||
## 📌 说明
|
||||
## 🤝 Contribution
|
||||
|
||||
这是 LobeHub 的内部模块 (`"private": true`),专为 LobeHub 桌面应用设计,不作为独立包发布。
|
||||
IPC server implementations need to handle various communication scenarios and edge cases. We welcome community contributions to enhance reliability and functionality. You can participate in improvements through:
|
||||
|
||||
### How to Contribute
|
||||
|
||||
1. **Performance Optimization**: Improve IPC communication speed and reliability
|
||||
2. **Error Handling**: Enhance error recovery and reconnection mechanisms
|
||||
3. **New Features**: Add support for new IPC methods or communication patterns
|
||||
4. **Documentation**: Improve code documentation and usage examples
|
||||
|
||||
### Contribution Process
|
||||
|
||||
1. Fork the [LobeChat repository](https://github.com/lobehub/lobe-chat)
|
||||
2. Implement your improvements to the IPC server package
|
||||
3. Submit a Pull Request describing:
|
||||
|
||||
- Performance improvements or new features
|
||||
- Testing methodology and results
|
||||
- Compatibility considerations
|
||||
- Usage examples
|
||||
|
||||
## 📌 Note
|
||||
|
||||
This is an internal module of LobeHub (`"private": true`), designed specifically for LobeHub desktop applications and not published as a standalone package.
|
||||
|
||||
76
packages/electron-server-ipc/README.zh-CN.md
Normal file
76
packages/electron-server-ipc/README.zh-CN.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# @lobechat/electron-server-ipc
|
||||
|
||||
LobeHub 的 Electron 应用与服务端之间的 IPC(进程间通信)模块,提供可靠的跨进程通信能力。
|
||||
|
||||
## 📝 简介
|
||||
|
||||
`@lobechat/electron-server-ipc` 是 LobeHub 桌面应用的核心组件,负责处理 Electron 主进程与 nextjs 服务端之间的通信。它提供了一套简单而健壮的 API,用于在不同进程间传递数据和执行远程方法调用。
|
||||
|
||||
## 🛠️ 核心功能
|
||||
|
||||
- **可靠的 IPC 通信**: 基于 Socket 的通信机制,确保跨进程通信的稳定性和可靠性
|
||||
- **自动重连机制**: 客户端具备断线重连功能,提高应用稳定性
|
||||
- **类型安全**: 使用 TypeScript 提供完整的类型定义,确保 API 调用的类型安全
|
||||
- **跨平台支持**: 同时支持 Windows、macOS 和 Linux 平台
|
||||
|
||||
## 🧩 核心组件
|
||||
|
||||
### IPC 服务端 (ElectronIPCServer)
|
||||
|
||||
负责监听客户端请求并响应,通常运行在 Electron 的主进程中:
|
||||
|
||||
```typescript
|
||||
import { ElectronIPCEventHandler, ElectronIPCServer } from '@lobechat/electron-server-ipc';
|
||||
|
||||
// 定义处理函数
|
||||
const eventHandler: ElectronIPCEventHandler = {
|
||||
getDatabasePath: async () => {
|
||||
return '/path/to/database';
|
||||
},
|
||||
// 其他处理函数...
|
||||
};
|
||||
|
||||
// 创建并启动服务器
|
||||
const server = new ElectronIPCServer(eventHandler);
|
||||
server.start();
|
||||
```
|
||||
|
||||
### IPC 客户端 (ElectronIpcClient)
|
||||
|
||||
负责连接到服务端并发送请求,通常在服务端(如 Next.js 服务)中使用:
|
||||
|
||||
```typescript
|
||||
import { ElectronIPCMethods, ElectronIpcClient } from '@lobechat/electron-server-ipc';
|
||||
|
||||
// 创建客户端
|
||||
const client = new ElectronIpcClient();
|
||||
|
||||
// 发送请求
|
||||
const dbPath = await client.sendRequest(ElectronIPCMethods.getDatabasePath);
|
||||
```
|
||||
|
||||
## 🤝 参与贡献
|
||||
|
||||
IPC 服务端实现需要处理各种通信场景和边缘情况。我们欢迎社区贡献来增强可靠性和功能性。您可以通过以下方式参与改进:
|
||||
|
||||
### 如何贡献
|
||||
|
||||
1. **性能优化**:提高 IPC 通信速度和可靠性
|
||||
2. **错误处理**:增强错误恢复和重连机制
|
||||
3. **新功能**:添加新的 IPC 方法或通信模式支持
|
||||
4. **文档改进**:改进代码文档和使用示例
|
||||
|
||||
### 贡献流程
|
||||
|
||||
1. Fork [LobeChat 仓库](https://github.com/lobehub/lobe-chat)
|
||||
2. 对 IPC 服务端包实施改进
|
||||
3. 提交 Pull Request 并描述:
|
||||
|
||||
- 性能改进或新功能
|
||||
- 测试方法和结果
|
||||
- 兼容性考虑
|
||||
- 使用示例
|
||||
|
||||
## 📌 说明
|
||||
|
||||
这是 LobeHub 的内部模块 (`"private": true`),专为 LobeHub 桌面应用设计,不作为独立包发布。
|
||||
@@ -1,63 +1,89 @@
|
||||
# @lobehub/file-loaders
|
||||
# @lobechat/file-loaders
|
||||
|
||||
`@lobehub/file-loaders` 是 LobeChat 项目中的一个工具包,专门用于从本地文件路径加载各种类型的文件,并将其内容转换为标准化的 `Document` 对象数组。
|
||||
`@lobechat/file-loaders` is a toolkit within the LobeChat project, specifically designed for loading various types of files from local file paths and converting their content into standardized `Document` object arrays.
|
||||
|
||||
它的主要目的是提供一个统一的接口来读取不同的文件格式,提取其核心文本内容,并为后续处理(例如在 LobeChat 中进行文件预览、内容提取或将其作为知识库数据源)做好准备。
|
||||
Its primary purpose is to provide a unified interface for reading different file formats, extracting their core text content, and preparing them for subsequent processing (such as file preview, content extraction, or serving as knowledge base data sources in LobeChat).
|
||||
|
||||
## ✨ 功能特性
|
||||
## ✨ Features
|
||||
|
||||
- **统一接口**: 提供 `loadFile(filePath: string)` 函数作为核心入口点。
|
||||
- **自动类型检测**: 根据文件扩展名自动选择合适的加载方式。
|
||||
- **广泛的格式支持**:
|
||||
- **纯文本类**: `.txt`, `.csv`, `.md`, `.json`, `.xml`, `.yaml`, `.html` 以及多种代码和配置文件格式。
|
||||
- **PDF**: `.pdf` 文件。
|
||||
- **Word**: `.docx` 文件。
|
||||
- **Excel**: `.xlsx`, `.xls` 文件,每个工作表作为一个 `Page`。
|
||||
- **PowerPoint**: `.pptx` 文件,每个幻灯片作为一个 `Page`。
|
||||
- **标准化输出**: 始终返回 `Promise<Document>`。 `Document` 对象代表一个加载的文件,其内部包含一个 `Page` 数组,代表文件的各个逻辑单元(页、幻灯片、工作表、文本块等)。
|
||||
- **层级结构**: 采用 `Document` 包含 `Page[]` 的结构,更好地反映文件原始组织方式。
|
||||
- **丰富的元数据**: 在 `Document` 和 `Page` 层面提供详细的元数据,包括文件信息、内容统计和结构信息。
|
||||
- **Unified Interface**: Provides `loadFile(filePath: string)` function as the core entry point.
|
||||
- **Automatic Type Detection**: Automatically selects appropriate loading methods based on file extensions.
|
||||
- **Extensive Format Support**:
|
||||
- **Plain Text**: `.txt`, `.csv`, `.md`, `.json`, `.xml`, `.yaml`, `.html` and various code and configuration file formats.
|
||||
- **PDF**: `.pdf` files.
|
||||
- **Word**: `.docx` files.
|
||||
- **Excel**: `.xlsx`, `.xls` files, with each worksheet as a `Page`.
|
||||
- **PowerPoint**: `.pptx` files, with each slide as a `Page`.
|
||||
- **Standardized Output**: Always returns `Promise<Document>`. A `Document` object represents a loaded file, containing an array of `Page` objects that represent the logical units of the file (pages, slides, worksheets, text blocks, etc.).
|
||||
- **Hierarchical Structure**: Uses a structure where `Document` contains `Page[]`, better reflecting the original organization of the file.
|
||||
- **Rich Metadata**: Provides detailed metadata at both `Document` and `Page` levels, including file information, content statistics, and structural information.
|
||||
|
||||
## 核心数据结构
|
||||
## Core Data Structures
|
||||
|
||||
`loadFile` 函数返回一个 `FileDocument` 对象,包含文件级信息和其所有逻辑页面 / 块 (`DocumentPage`)。
|
||||
The `loadFile` function returns a `FileDocument` object containing file-level information and all its logical pages/blocks (`DocumentPage`).
|
||||
|
||||
### `FileDocument` Interface
|
||||
|
||||
| 字段 | 类型 | 描述 |
|
||||
| :---------------- | :---------------- | :------------------------------------------------------------- |
|
||||
| `content` | `string` | 文件内容 (聚合后的内容) |
|
||||
| `createdTime` | `Date` | 文件创建时间戳。 |
|
||||
| `fileType` | `string` | 文件类型或扩展名。 |
|
||||
| `filename` | `string` | 原始文件名。 |
|
||||
| `metadata` | `object` | 文件级别的元数据。 |
|
||||
| `metadata.author` | `string?` | 文档作者 (如果可用)。 |
|
||||
| `metadata.error` | `string?` | 如果整个文件加载失败,记录错误信息。 |
|
||||
| `metadata.title` | `string?` | 文档标题 (如果可用)。 |
|
||||
| `...` | `any` | 其他文件级别的元数据。 |
|
||||
| `modifiedTime` | `Date` | 文件最后修改时间戳。 |
|
||||
| `pages` | `DocumentPage[]?` | 包含文档中所有逻辑页面 / 块的数组 (可选)。 |
|
||||
| `source` | `string` | 原始文件的完整路径。 |
|
||||
| `totalCharCount` | `number` | 整个文档的总字符数 (所有 `DocumentPage` 的 `charCount` 之和)。 |
|
||||
| `totalLineCount` | `number` | 整个文档的总行数 (所有 `DocumentPage` 的 `lineCount` 之和)。 |
|
||||
| Field | Type | Description |
|
||||
| :---------------- | :---------------- | :------------------------------------------------------------------------------------ |
|
||||
| `content` | `string` | File content (aggregated content) |
|
||||
| `createdTime` | `Date` | File creation timestamp. |
|
||||
| `fileType` | `string` | File type or extension. |
|
||||
| `filename` | `string` | Original filename. |
|
||||
| `metadata` | `object` | File-level metadata. |
|
||||
| `metadata.author` | `string?` | Document author (if available). |
|
||||
| `metadata.error` | `string?` | Error information if the entire file loading failed. |
|
||||
| `metadata.title` | `string?` | Document title (if available). |
|
||||
| `...` | `any` | Other file-level metadata. |
|
||||
| `modifiedTime` | `Date` | File last modified timestamp. |
|
||||
| `pages` | `DocumentPage[]?` | Array containing all logical pages/blocks in the document (optional). |
|
||||
| `source` | `string` | Full path of the original file. |
|
||||
| `totalCharCount` | `number` | Total character count of the entire document (sum of all `DocumentPage` `charCount`). |
|
||||
| `totalLineCount` | `number` | Total line count of the entire document (sum of all `DocumentPage` `lineCount`). |
|
||||
|
||||
### `DocumentPage` Interface
|
||||
|
||||
| 字段 | 类型 | 描述 |
|
||||
| :------------------------- | :-------- | :--------------------------- |
|
||||
| `charCount` | `number` | 此页 / 块内容的字符数。 |
|
||||
| `lineCount` | `number` | 此页 / 块内容的行数。 |
|
||||
| `metadata` | `object` | 与此页 / 块相关的元数据。 |
|
||||
| `metadata.chunkIndex` | `number?` | 如果分割成块,当前块的索引。 |
|
||||
| `metadata.error` | `string?` | 处理此页 / 块时发生的错误。 |
|
||||
| `metadata.lineNumberEnd` | `number?` | 在原始文件中的结束行号。 |
|
||||
| `metadata.lineNumberStart` | `number?` | 在原始文件中的起始行号。 |
|
||||
| `metadata.pageNumber` | `number?` | 页码 (适用于 PDF, DOCX)。 |
|
||||
| `metadata.sectionTitle` | `string?` | 相关的章节标题。 |
|
||||
| `metadata.sheetName` | `string?` | 工作表名称 (适用于 XLSX)。 |
|
||||
| `metadata.slideNumber` | `number?` | 幻灯片编号 (适用于 PPTX)。 |
|
||||
| `metadata.totalChunks` | `number?` | 如果分割成块,总块数。 |
|
||||
| `...` | `any` | 其他特定于页 / 块的元数据。 |
|
||||
| `pageContent` | `string` | 此页 / 块的核心文本内容。 |
|
||||
| Field | Type | Description |
|
||||
| :------------------------- | :-------- | :---------------------------------------------- |
|
||||
| `charCount` | `number` | Character count of this page/block content. |
|
||||
| `lineCount` | `number` | Line count of this page/block content. |
|
||||
| `metadata` | `object` | Metadata related to this page/block. |
|
||||
| `metadata.chunkIndex` | `number?` | Current chunk index if split into chunks. |
|
||||
| `metadata.error` | `string?` | Error occurred when processing this page/block. |
|
||||
| `metadata.lineNumberEnd` | `number?` | End line number in the original file. |
|
||||
| `metadata.lineNumberStart` | `number?` | Start line number in the original file. |
|
||||
| `metadata.pageNumber` | `number?` | Page number (applicable to PDF, DOCX). |
|
||||
| `metadata.sectionTitle` | `string?` | Related section title. |
|
||||
| `metadata.sheetName` | `string?` | Worksheet name (applicable to XLSX). |
|
||||
| `metadata.slideNumber` | `number?` | Slide number (applicable to PPTX). |
|
||||
| `metadata.totalChunks` | `number?` | Total chunks if split into chunks. |
|
||||
| `...` | `any` | Other page/block-specific metadata. |
|
||||
| `pageContent` | `string` | Core text content of this page/block. |
|
||||
|
||||
如果你对我们的项目感兴趣,欢迎在 [GitHub](https://github.com/lobehub/lobe-chat) 上查看、点赞或贡献代码!
|
||||
## 🤝 Contribution
|
||||
|
||||
File formats and parsing requirements are constantly evolving. We welcome community contributions to expand format support and improve parsing accuracy. You can participate in improvements through:
|
||||
|
||||
### How to Contribute
|
||||
|
||||
1. **New File Format Support**: Add support for additional file types
|
||||
2. **Parser Improvements**: Enhance existing parsers for better content extraction
|
||||
3. **Metadata Enhancement**: Improve metadata extraction capabilities
|
||||
4. **Performance Optimization**: Optimize file loading and processing performance
|
||||
|
||||
### Contribution Process
|
||||
|
||||
1. Fork the [LobeChat repository](https://github.com/lobehub/lobe-chat)
|
||||
2. Add new format support or improve existing parsers
|
||||
3. Submit a Pull Request describing:
|
||||
|
||||
- New file formats supported or improvements made
|
||||
- Testing with various file samples
|
||||
- Performance impact analysis
|
||||
- Documentation updates
|
||||
|
||||
## 📌 Note
|
||||
|
||||
This is an internal module of LobeHub (`"private": true`), designed specifically for LobeChat and not published as a standalone package.
|
||||
|
||||
If you're interested in our project, feel free to check it out, star it, or contribute code on [GitHub](https://github.com/lobehub/lobe-chat)!
|
||||
|
||||
89
packages/file-loaders/README.zh-CN.md
Normal file
89
packages/file-loaders/README.zh-CN.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# @lobechat/file-loaders
|
||||
|
||||
`@lobechat/file-loaders` 是 LobeChat 项目中的一个工具包,专门用于从本地文件路径加载各种类型的文件,并将其内容转换为标准化的 `Document` 对象数组。
|
||||
|
||||
它的主要目的是提供一个统一的接口来读取不同的文件格式,提取其核心文本内容,并为后续处理(例如在 LobeChat 中进行文件预览、内容提取或将其作为知识库数据源)做好准备。
|
||||
|
||||
## ✨ 功能特性
|
||||
|
||||
- **统一接口**: 提供 `loadFile(filePath: string)` 函数作为核心入口点。
|
||||
- **自动类型检测**: 根据文件扩展名自动选择合适的加载方式。
|
||||
- **广泛的格式支持**:
|
||||
- **纯文本类**: `.txt`, `.csv`, `.md`, `.json`, `.xml`, `.yaml`, `.html` 以及多种代码和配置文件格式。
|
||||
- **PDF**: `.pdf` 文件。
|
||||
- **Word**: `.docx` 文件。
|
||||
- **Excel**: `.xlsx`, `.xls` 文件,每个工作表作为一个 `Page`。
|
||||
- **PowerPoint**: `.pptx` 文件,每个幻灯片作为一个 `Page`。
|
||||
- **标准化输出**: 始终返回 `Promise<Document>`。 `Document` 对象代表一个加载的文件,其内部包含一个 `Page` 数组,代表文件的各个逻辑单元(页、幻灯片、工作表、文本块等)。
|
||||
- **层级结构**: 采用 `Document` 包含 `Page[]` 的结构,更好地反映文件原始组织方式。
|
||||
- **丰富的元数据**: 在 `Document` 和 `Page` 层面提供详细的元数据,包括文件信息、内容统计和结构信息。
|
||||
|
||||
## 核心数据结构
|
||||
|
||||
`loadFile` 函数返回一个 `FileDocument` 对象,包含文件级信息和其所有逻辑页面 / 块 (`DocumentPage`)。
|
||||
|
||||
### `FileDocument` Interface
|
||||
|
||||
| 字段 | 类型 | 描述 |
|
||||
| :---------------- | :---------------- | :------------------------------------------------------------- |
|
||||
| `content` | `string` | 文件内容 (聚合后的内容) |
|
||||
| `createdTime` | `Date` | 文件创建时间戳。 |
|
||||
| `fileType` | `string` | 文件类型或扩展名。 |
|
||||
| `filename` | `string` | 原始文件名。 |
|
||||
| `metadata` | `object` | 文件级别的元数据。 |
|
||||
| `metadata.author` | `string?` | 文档作者 (如果可用)。 |
|
||||
| `metadata.error` | `string?` | 如果整个文件加载失败,记录错误信息。 |
|
||||
| `metadata.title` | `string?` | 文档标题 (如果可用)。 |
|
||||
| `...` | `any` | 其他文件级别的元数据。 |
|
||||
| `modifiedTime` | `Date` | 文件最后修改时间戳。 |
|
||||
| `pages` | `DocumentPage[]?` | 包含文档中所有逻辑页面 / 块的数组 (可选)。 |
|
||||
| `source` | `string` | 原始文件的完整路径。 |
|
||||
| `totalCharCount` | `number` | 整个文档的总字符数 (所有 `DocumentPage` 的 `charCount` 之和)。 |
|
||||
| `totalLineCount` | `number` | 整个文档的总行数 (所有 `DocumentPage` 的 `lineCount` 之和)。 |
|
||||
|
||||
### `DocumentPage` Interface
|
||||
|
||||
| 字段 | 类型 | 描述 |
|
||||
| :------------------------- | :-------- | :--------------------------- |
|
||||
| `charCount` | `number` | 此页 / 块内容的字符数。 |
|
||||
| `lineCount` | `number` | 此页 / 块内容的行数。 |
|
||||
| `metadata` | `object` | 与此页 / 块相关的元数据。 |
|
||||
| `metadata.chunkIndex` | `number?` | 如果分割成块,当前块的索引。 |
|
||||
| `metadata.error` | `string?` | 处理此页 / 块时发生的错误。 |
|
||||
| `metadata.lineNumberEnd` | `number?` | 在原始文件中的结束行号。 |
|
||||
| `metadata.lineNumberStart` | `number?` | 在原始文件中的起始行号。 |
|
||||
| `metadata.pageNumber` | `number?` | 页码 (适用于 PDF, DOCX)。 |
|
||||
| `metadata.sectionTitle` | `string?` | 相关的章节标题。 |
|
||||
| `metadata.sheetName` | `string?` | 工作表名称 (适用于 XLSX)。 |
|
||||
| `metadata.slideNumber` | `number?` | 幻灯片编号 (适用于 PPTX)。 |
|
||||
| `metadata.totalChunks` | `number?` | 如果分割成块,总块数。 |
|
||||
| `...` | `any` | 其他特定于页 / 块的元数据。 |
|
||||
| `pageContent` | `string` | 此页 / 块的核心文本内容。 |
|
||||
|
||||
## 🤝 参与贡献
|
||||
|
||||
文件格式和解析需求在不断发展。我们欢迎社区贡献来扩展格式支持和提高解析准确性。您可以通过以下方式参与改进:
|
||||
|
||||
### 如何贡献
|
||||
|
||||
1. **新文件格式支持**:添加对其他文件类型的支持
|
||||
2. **解析器改进**:增强现有解析器以更好地提取内容
|
||||
3. **元数据增强**:改进元数据提取能力
|
||||
4. **性能优化**:优化文件加载和处理性能
|
||||
|
||||
### 贡献流程
|
||||
|
||||
1. Fork [LobeChat 仓库](https://github.com/lobehub/lobe-chat)
|
||||
2. 添加新格式支持或改进现有解析器
|
||||
3. 提交 Pull Request 并描述:
|
||||
|
||||
- 支持的新文件格式或所做的改进
|
||||
- 使用各种文件样本进行测试
|
||||
- 性能影响分析
|
||||
- 文档更新
|
||||
|
||||
## 📌 说明
|
||||
|
||||
这是 LobeHub 的内部模块(`"private": true`),专为 LobeChat 设计,不作为独立包发布。
|
||||
|
||||
如果你对我们的项目感兴趣,欢迎在 [GitHub](https://github.com/lobehub/lobe-chat) 上查看、点赞或贡献代码!
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { ActionIcon, Tooltip } from '@lobehub/ui';
|
||||
import { ActionIcon } from '@lobehub/ui';
|
||||
import { PanelRightClose, PanelRightOpen } from 'lucide-react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -30,13 +30,16 @@ const HeaderAction = memo<{ className?: string }>(({ className }) => {
|
||||
return (
|
||||
<Flexbox className={className} gap={4} horizontal>
|
||||
<ShareButton />
|
||||
<Tooltip hotkey={hotkey} title={t('toggleRightPanel.title', { ns: 'hotkey' })}>
|
||||
<ActionIcon
|
||||
icon={showAgentSettings ? PanelRightClose : PanelRightOpen}
|
||||
onClick={() => toggleConfig()}
|
||||
size={DESKTOP_HEADER_ICON_SIZE}
|
||||
/>
|
||||
</Tooltip>
|
||||
<ActionIcon
|
||||
icon={showAgentSettings ? PanelRightClose : PanelRightOpen}
|
||||
onClick={() => toggleConfig()}
|
||||
size={DESKTOP_HEADER_ICON_SIZE}
|
||||
title={t('toggleRightPanel.title', { ns: 'hotkey' })}
|
||||
tooltipProps={{
|
||||
hotkey,
|
||||
placement: 'bottom',
|
||||
}}
|
||||
/>
|
||||
{isAgentEditable && <SettingButton />}
|
||||
</Flexbox>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { ActionIcon, Tooltip } from '@lobehub/ui';
|
||||
import { ActionIcon } from '@lobehub/ui';
|
||||
import { AlignJustify } from 'lucide-react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { memo } from 'react';
|
||||
@@ -25,13 +25,16 @@ const SettingButton = memo<{ mobile?: boolean }>(({ mobile }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip hotkey={hotkey} title={t('openChatSettings.title', { ns: 'hotkey' })}>
|
||||
<ActionIcon
|
||||
icon={AlignJustify}
|
||||
onClick={() => openChatSettings()}
|
||||
size={mobile ? MOBILE_HEADER_ICON_SIZE : DESKTOP_HEADER_ICON_SIZE}
|
||||
/>
|
||||
</Tooltip>
|
||||
<ActionIcon
|
||||
icon={AlignJustify}
|
||||
onClick={() => openChatSettings()}
|
||||
size={mobile ? MOBILE_HEADER_ICON_SIZE : DESKTOP_HEADER_ICON_SIZE}
|
||||
title={t('openChatSettings.title', { ns: 'hotkey' })}
|
||||
tooltipProps={{
|
||||
hotkey,
|
||||
placement: 'bottom',
|
||||
}}
|
||||
/>
|
||||
<AgentSettings key={id} />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -31,6 +31,9 @@ const ShareButton = memo<ShareButtonProps>(({ mobile, setOpen, open }) => {
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
size={mobile ? MOBILE_HEADER_ICON_SIZE : DESKTOP_HEADER_ICON_SIZE}
|
||||
title={t('share')}
|
||||
tooltipProps={{
|
||||
placement: 'bottom',
|
||||
}}
|
||||
/>
|
||||
<ShareModal onCancel={() => setIsModalOpen(false)} open={isModalOpen} />
|
||||
</>
|
||||
|
||||
@@ -62,6 +62,9 @@ const Header = memo(() => {
|
||||
size={DESKTOP_HEADER_ICON_SIZE}
|
||||
style={{ flex: 'none' }}
|
||||
title={t('newAgent')}
|
||||
tooltipProps={{
|
||||
placement: 'bottom',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Flexbox>
|
||||
|
||||
126
src/features/PlanIcon/index.tsx
Normal file
126
src/features/PlanIcon/index.tsx
Normal file
@@ -0,0 +1,126 @@
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { Tag } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { Atom, Box, CircleSlash, Sparkle, Zap } from 'lucide-react';
|
||||
import { CSSProperties, MouseEvent, memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Center, Flexbox } from 'react-layout-kit';
|
||||
|
||||
import { Plans } from '@/types/subscription';
|
||||
|
||||
export const themes = {
|
||||
[Plans.Free]: {
|
||||
icon: CircleSlash,
|
||||
theme: {
|
||||
background: undefined,
|
||||
color: undefined,
|
||||
},
|
||||
},
|
||||
[Plans.Hobby]: {
|
||||
icon: Box,
|
||||
theme: {
|
||||
background: 'linear-gradient(45deg, #21B2EE, #2271ED)',
|
||||
color: '#E5F8FF',
|
||||
},
|
||||
},
|
||||
[Plans.Starter]: {
|
||||
icon: Sparkle,
|
||||
theme: {
|
||||
background: 'linear-gradient(45deg, #C57948, #803718)',
|
||||
color: '#FFC385',
|
||||
},
|
||||
},
|
||||
[Plans.Premium]: {
|
||||
icon: Zap,
|
||||
theme: {
|
||||
background: 'linear-gradient(45deg, #A5B4C2, #606E7B)',
|
||||
color: '#FCFDFF',
|
||||
},
|
||||
},
|
||||
[Plans.Ultimate]: {
|
||||
icon: Atom,
|
||||
theme: {
|
||||
background: 'linear-gradient(45deg, #F7A82F, #BB7227)',
|
||||
color: '#FCFA6E',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
icon: css`
|
||||
flex: none;
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
box-shadow: 0 0 0 1px ${token.colorFillSecondary};
|
||||
`,
|
||||
}));
|
||||
|
||||
interface PlanIconProps {
|
||||
className?: string;
|
||||
mono?: boolean;
|
||||
onClick?: (e: MouseEvent) => void;
|
||||
plan: Plans;
|
||||
size?: number;
|
||||
style?: CSSProperties;
|
||||
type?: 'icon' | 'tag' | 'combine';
|
||||
}
|
||||
|
||||
const PlanIcon = memo<PlanIconProps>(
|
||||
({ type = 'icon', plan, size = 36, mono, style, className, onClick }) => {
|
||||
const { icon, theme } = themes[plan];
|
||||
const { cx, styles, theme: token } = useStyles();
|
||||
const { t } = useTranslation('subscription');
|
||||
const isTag = type === 'tag';
|
||||
const isCombine = type === 'combine';
|
||||
const isFree = plan === Plans.Free;
|
||||
|
||||
if (isTag) {
|
||||
return (
|
||||
<Tag
|
||||
bordered={false}
|
||||
className={className}
|
||||
onClick={onClick}
|
||||
style={{
|
||||
...(theme || { background: token.colorFillSecondary, color: token.colorText }),
|
||||
border: 'none',
|
||||
borderRadius: 12,
|
||||
cursor: 'pointer',
|
||||
flex: 'none',
|
||||
margin: 0,
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
{t(`plans.plan.${plan}.title`)}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
|
||||
const iconContent = (
|
||||
<Center
|
||||
className={cx(styles.icon, className)}
|
||||
height={size}
|
||||
onClick={onClick}
|
||||
style={
|
||||
mono
|
||||
? style
|
||||
: { ...theme, border: isFree ? undefined : `2px solid ${theme.color}`, ...style }
|
||||
}
|
||||
width={size}
|
||||
>
|
||||
<Icon color={mono ? undefined : theme.color} icon={icon} size={size / 2} />
|
||||
</Center>
|
||||
);
|
||||
|
||||
if (isCombine) {
|
||||
return (
|
||||
<Flexbox align={'center'} gap={8} horizontal>
|
||||
{iconContent}
|
||||
<span>{t(`plans.plan.${plan}.title`)}</span>
|
||||
</Flexbox>
|
||||
);
|
||||
}
|
||||
|
||||
return iconContent;
|
||||
},
|
||||
);
|
||||
|
||||
export default PlanIcon;
|
||||
@@ -1,43 +1,51 @@
|
||||
import { Tag, Tooltip } from '@lobehub/ui';
|
||||
import { Tag } from '@lobehub/ui';
|
||||
import { useTheme } from 'antd-style';
|
||||
import { CSSProperties, memo, useMemo } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import urlJoin from 'url-join';
|
||||
|
||||
import { OFFICIAL_URL } from '@/const/url';
|
||||
import { isDesktop } from '@/const/version';
|
||||
import PlanIcon from '@/features/PlanIcon';
|
||||
import { Plans } from '@/types/subscription';
|
||||
|
||||
export enum PlanType {
|
||||
Preview = 'preview',
|
||||
}
|
||||
|
||||
export interface PlanTagProps {
|
||||
type?: PlanType;
|
||||
type?: PlanType | Plans;
|
||||
}
|
||||
|
||||
const PlanTag = memo<PlanTagProps>(({ type = PlanType.Preview }) => {
|
||||
const { t } = useTranslation('common');
|
||||
const theme = useTheme();
|
||||
const tag: {
|
||||
desc: string;
|
||||
style: CSSProperties;
|
||||
title: string;
|
||||
} = useMemo(() => {
|
||||
switch (type) {
|
||||
case PlanType.Preview: {
|
||||
return {
|
||||
desc: t('userPanel.community'),
|
||||
style: {
|
||||
background: theme.colorFill,
|
||||
},
|
||||
title: 'Community',
|
||||
};
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (type === PlanType.Preview) {
|
||||
return (
|
||||
<Tag
|
||||
bordered={false}
|
||||
style={{ background: theme.colorFill, borderRadius: 12, cursor: 'pointer' }}
|
||||
>
|
||||
{t('userPanel.community')}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
|
||||
const isFree = type === Plans.Free;
|
||||
|
||||
return (
|
||||
<Tooltip title={tag.desc}>
|
||||
<Tag bordered={false} style={{ ...tag.style, borderRadius: 12, cursor: 'pointer' }}>
|
||||
{tag.title}
|
||||
</Tag>
|
||||
</Tooltip>
|
||||
<Link
|
||||
href={urlJoin(
|
||||
isDesktop ? OFFICIAL_URL : '/',
|
||||
isFree ? '/subscription/plans' : '/subscription/usage',
|
||||
)}
|
||||
style={{ cursor: 'pointer' }}
|
||||
target={isDesktop ? '_blank' : undefined}
|
||||
>
|
||||
<PlanIcon plan={type} size={22} type={'tag'} />
|
||||
</Link>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import portal from './portal';
|
||||
import providers from './providers';
|
||||
import ragEval from './ragEval';
|
||||
import setting from './setting';
|
||||
import subscription from './subscription';
|
||||
import thread from './thread';
|
||||
import tool from './tool';
|
||||
import topic from './topic';
|
||||
@@ -52,6 +53,7 @@ const resources = {
|
||||
providers,
|
||||
ragEval,
|
||||
setting,
|
||||
subscription,
|
||||
thread,
|
||||
tool,
|
||||
topic,
|
||||
|
||||
24
src/locales/default/subscription.ts
Normal file
24
src/locales/default/subscription.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export default {
|
||||
plans: {
|
||||
plan: {
|
||||
enterprise: {
|
||||
title: '企业版',
|
||||
},
|
||||
free: {
|
||||
title: '免费版',
|
||||
},
|
||||
hobby: {
|
||||
title: '自助版',
|
||||
},
|
||||
premium: {
|
||||
title: '进阶版',
|
||||
},
|
||||
starter: {
|
||||
title: '基础版',
|
||||
},
|
||||
ultimate: {
|
||||
title: '专业版',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
7
src/types/subscription.ts
Normal file
7
src/types/subscription.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export enum Plans {
|
||||
Free = 'free',
|
||||
Hobby = 'hobby',
|
||||
Premium = 'premium',
|
||||
Starter = 'starter',
|
||||
Ultimate = 'ultimate',
|
||||
}
|
||||
Reference in New Issue
Block a user