- Added core Tree component (BimTree, BimTreeNode) - Added TreeManager for lifecycle management - Added ModelTreeManager for business logic encapsulation (Tree + Dialog) - Integrated into BimEngine and updated demos - Added internationalization support
1358 lines
43 KiB
Markdown
1358 lines
43 KiB
Markdown
# BIM Engine SDK - AI 协作文档
|
||
|
||
> 本文档用于向 AI 助手传递项目信息,帮助 AI 更好地理解和维护本项目。**每次代码改动后,请务必更新本文档的相关部分。**
|
||
|
||
---
|
||
|
||
## 📋 目录
|
||
|
||
1. [项目基本信息](#1-项目基本信息)
|
||
2. [架构设计思想](#2-架构设计思想)
|
||
3. [文件结构说明](#3-文件结构说明)
|
||
4. [组件和事件清单](#4-组件和事件清单)
|
||
5. [AI 工作规则](#5-ai-工作规则)
|
||
|
||
---
|
||
|
||
## 1. 项目基本信息
|
||
|
||
### 1.1 项目描述
|
||
|
||
**BIM Engine SDK** 是一个通用的 3D BIM 引擎 SDK 开发框架,旨在通过一次编码,同时支持 Vue 2、Vue 3、React 和纯 HTML 环境。
|
||
|
||
### 1.2 技术栈
|
||
|
||
- **语言**: TypeScript
|
||
- **构建工具**: Vite (Library Mode)
|
||
- **类型生成**: vite-plugin-dts
|
||
- **CSS 注入**: vite-plugin-css-injected-by-js
|
||
- **3D 引擎**: 基于第三方 SDK (bim-engine-sdk.es.js)
|
||
|
||
### 1.3 项目结构
|
||
|
||
```
|
||
engine/
|
||
├── src/ # SDK 源代码
|
||
│ ├── core/ # 核心基础类
|
||
│ ├── components/ # UI 组件
|
||
│ ├── managers/ # 管理器类
|
||
│ ├── services/ # 服务类(主题、语言)
|
||
│ ├── themes/ # 主题配置
|
||
│ ├── locales/ # 国际化配置
|
||
│ ├── types/ # 类型定义
|
||
│ ├── bim-engine.ts # 主引擎类
|
||
│ └── index.ts # 入口文件
|
||
├── dist/ # 构建产物 (ESM + UMD + .d.ts)
|
||
├── demo/ # HTML 示例
|
||
├── demo-vue/ # Vue 示例
|
||
├── docs/ # 文档目录
|
||
│ └── components/ # 组件详细文档(每个组件一份)
|
||
├── .recycle/ # 回收文件夹(按日期 YYYY-MM-DD 组织,存放被删除的文件)
|
||
├── vite.config.ts # Vite 构建配置
|
||
├── tsconfig.json # TypeScript 配置
|
||
└── package.json # 项目元数据
|
||
```
|
||
|
||
### 1.4 构建和运行
|
||
|
||
#### 构建 SDK
|
||
```bash
|
||
npm run build
|
||
# 生成 dist/ 目录,包含:
|
||
# - bim-engine-sdk.es.js (ESM 格式)
|
||
# - bim-engine-sdk.umd.js (UMD 格式)
|
||
# - index.d.ts (TypeScript 类型定义)
|
||
# - *.map (Source Map 文件)
|
||
```
|
||
|
||
#### 运行 Demo
|
||
|
||
**运行 HTML Demo (纯 JS):**
|
||
```bash
|
||
npm run dev:demo
|
||
# 自动执行:构建 SDK -> 复制 SDK 到 demo/lib -> 启动服务器
|
||
# 开发服务器运行在 http://localhost:3000
|
||
# 自动打开 /demo/index.html
|
||
```
|
||
|
||
**运行 Vue Demo:**
|
||
```bash
|
||
npm run dev:demo-vue
|
||
# 自动执行:构建 SDK -> 复制 SDK 到 demo-vue/public/lib -> 启动服务器
|
||
# 开发服务器运行在 http://localhost:3000
|
||
# 自动打开 Vue 示例页面
|
||
```
|
||
|
||
**同时运行两个 Demo:**
|
||
```bash
|
||
npm run dev:all
|
||
# 同时启动 HTML Demo 和 Vue Demo
|
||
```
|
||
|
||
**注意**:
|
||
- 现在的 `npm run dev:demo` 和 `npm run dev:demo-vue` 命令已包含自动化构建流程,无需手动运行 `npm run build`。
|
||
- Demo 会自动从本地复制的 SDK 副本加载。
|
||
|
||
### 1.5 发布配置
|
||
|
||
`package.json` 配置了 `exports` 字段,确保不同环境自动加载正确的文件:
|
||
|
||
```json
|
||
"exports": {
|
||
".": {
|
||
"types": "./dist/index.d.ts",
|
||
"import": "./dist/bim-engine-sdk.es.js",
|
||
"require": "./dist/bim-engine-sdk.umd.js"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 架构设计思想
|
||
|
||
### 2.1 核心架构模式
|
||
|
||
#### Manager 模式
|
||
项目采用 **Manager 模式** 来管理不同类型的组件:
|
||
|
||
- **BimEngine**: 总控制器,组合各个 Manager
|
||
- **DialogManager**: 管理所有弹窗实例
|
||
- **ToolbarManager**: 管理底部工具栏
|
||
- **ButtonGroupManager**: 管理通用按钮组
|
||
- **EngineManager**: 管理 3D 引擎(延迟初始化)
|
||
|
||
#### 事件总线模式
|
||
项目采用 **混合通信模式**,根据场景选择最合适的方式:
|
||
|
||
- **BimEngine** 继承 `EventEmitter`,作为全局事件总线
|
||
- **BimComponent** 基类提供 `emit()` 和 `on()` 辅助方法
|
||
- 所有 Manager 继承 `BimComponent`,可方便地发送和监听事件
|
||
- 事件类型通过 `EngineEvents` 接口进行类型约束
|
||
|
||
**使用场景选择原则**:
|
||
|
||
1. **简单场景 → 直接调用方法**
|
||
- 一对一调用,调用链简单
|
||
- 需要立即得到返回值
|
||
- 性能要求高的场景
|
||
- **示例**:
|
||
```typescript
|
||
// 直接调用 Manager 方法
|
||
engine.dialog.create({ title: '测试' });
|
||
engine.toolbar.addButton({ id: 'btn1', ... });
|
||
```
|
||
|
||
2. **复杂场景 → 使用事件总线(发布订阅)**
|
||
- 需要多个组件监听同一事件(一对多)
|
||
- 调用链复杂,需要跨多层传递
|
||
- 需要解耦,降低组件间依赖
|
||
- 异步通知场景
|
||
- **示例**:
|
||
```typescript
|
||
// 发送事件,多个组件可以监听
|
||
this.emit('ui:open-dialog', { id: 'info' });
|
||
|
||
// 多个组件可以同时监听
|
||
this.on('engine:model-loaded', (payload) => {
|
||
// 处理模型加载完成
|
||
});
|
||
```
|
||
|
||
#### 依赖注入模式
|
||
**EngineManager** 采用依赖注入模式,不直接依赖具体的 3D 引擎实现:
|
||
|
||
- `Engine` 组件通过参数接收 `createEngine` 函数
|
||
- 可以在运行时决定使用哪个引擎实现
|
||
- 便于测试和切换不同的 3D 引擎
|
||
|
||
### 2.2 组件设计原则
|
||
|
||
#### IBimComponent 接口
|
||
所有 UI 组件必须实现 `IBimComponent` 接口:
|
||
|
||
```typescript
|
||
interface IBimComponent {
|
||
init(): void | Promise<void>; // 初始化组件
|
||
setTheme(theme: ThemeConfig): void; // 设置主题
|
||
setLocales(): void; // 设置语言
|
||
destroy(): void; // 销毁组件
|
||
}
|
||
```
|
||
|
||
#### BimComponent 基类
|
||
所有 Manager 类继承 `BimComponent` 基类:
|
||
|
||
- 自动注入 `BimEngine` 实例
|
||
- 提供 `emit()` 和 `on()` 方法访问事件总线
|
||
- 必须实现 `destroy()` 方法
|
||
|
||
#### 组件生命周期
|
||
1. **构造阶段**: 创建实例,设置配置
|
||
2. **初始化阶段**: 调用 `init()` 创建 DOM、绑定事件
|
||
3. **运行阶段**: 响应主题/语言变更,处理用户交互
|
||
4. **销毁阶段**: 调用 `destroy()` 清理资源
|
||
|
||
### 2.3 代码组织规范
|
||
|
||
#### 目录结构约定
|
||
- `core/`: 核心基础类(EventEmitter、BimComponent)
|
||
- `components/`: UI 组件(Dialog、ButtonGroup、Engine)
|
||
- `managers/`: 管理器类(统一管理组件实例)
|
||
- `services/`: 服务类(单例模式,如 ThemeManager、LocaleManager)
|
||
- `themes/`: 主题配置(预设主题和类型定义)
|
||
- `locales/`: 国际化配置(多语言翻译)
|
||
- `types/`: 类型定义(接口、类型别名)
|
||
|
||
#### 命名规范
|
||
- **类名**: 大驼峰,如 `BimDialog`、`DialogManager`
|
||
- **接口名**: 大驼峰,以 `I` 开头表示接口,如 `IBimComponent`
|
||
- **类型名**: 大驼峰,如 `ThemeConfig`、`DialogOptions`
|
||
- **文件名**: 小写短横线或直接小写,如 `event-emitter.ts`、`index.ts`
|
||
- **CSS 类名**: 小写短横线,以 `bim-` 开头,如 `bim-dialog`、`bim-btn-group`
|
||
|
||
#### 导入顺序
|
||
1. 第三方库
|
||
2. 项目内部类型定义
|
||
3. 项目内部组件/类
|
||
4. 项目内部服务/工具
|
||
5. CSS 文件(使用 `import './index.css'`)
|
||
|
||
### 2.4 重要设计决策
|
||
|
||
#### 延迟初始化
|
||
- **3D 引擎**: 采用延迟初始化,用户需主动调用 `initEngine()` 方法
|
||
- **原因**: 3D 引擎资源消耗大,延迟初始化可以优化性能
|
||
|
||
#### 单例服务
|
||
- **ThemeManager**: 全局单例,所有组件共享同一主题状态
|
||
- **LocaleManager**: 全局单例,所有组件共享同一语言状态
|
||
- **原因**: 主题和语言是全局状态,单例模式确保一致性
|
||
|
||
#### CSS 变量
|
||
- 组件使用 CSS 变量来应用主题颜色
|
||
- 主题变更时,只需更新 CSS 变量值
|
||
- **优势**: 性能好,无需重新渲染 DOM
|
||
|
||
#### 事件拦截
|
||
- Dialog 组件会拦截所有鼠标/触摸事件,防止传递给 3D 引擎
|
||
- 使用 `stopPropagation()` 阻止事件冒泡
|
||
- **原因**: 确保弹窗交互不影响 3D 场景操作
|
||
|
||
---
|
||
|
||
## 3. 文件结构说明
|
||
|
||
### 3.1 核心文件 (`src/core/`)
|
||
|
||
#### `event-emitter.ts`
|
||
- **作用**: 事件总线基础类
|
||
- **功能**:
|
||
- `on(event, listener)`: 订阅事件
|
||
- `off(event, listener)`: 取消订阅
|
||
- `emit(event, payload)`: 发送事件
|
||
- `clear()`: 清空所有事件监听
|
||
- **使用**: `BimEngine` 继承此类,作为全局事件总线
|
||
|
||
#### `component.ts`
|
||
- **作用**: 组件基类
|
||
- **功能**:
|
||
- 注入 `BimEngine` 实例
|
||
- 提供 `emit()` 和 `on()` 辅助方法
|
||
- 定义抽象 `destroy()` 方法
|
||
- **使用**: 所有 Manager 类继承此类
|
||
|
||
### 3.2 主引擎文件
|
||
|
||
#### `bim-engine.ts`
|
||
- **作用**: SDK 主入口类
|
||
- **功能**:
|
||
- 初始化所有 Manager
|
||
- 管理主题和语言
|
||
- 提供事件总线功能
|
||
- 暴露公共 API
|
||
- **依赖**: EventEmitter、所有 Manager、Service
|
||
|
||
#### `index.ts`
|
||
- **作用**: SDK 入口文件
|
||
- **功能**: 导出所有公共 API
|
||
- **导出内容**:
|
||
- `BimEngine` 主类
|
||
- `BimButtonGroup`、`Toolbar` 组件
|
||
- 类型定义 (`EngineOptions`、`ModelLoadOptions` 等)
|
||
- `createEngine` 函数(从第三方 SDK 重新导出)
|
||
|
||
### 3.3 组件目录 (`src/components/`)
|
||
|
||
#### `dialog/`
|
||
- **`index.ts`**: `BimDialog` 类 - 通用弹窗组件
|
||
- 支持拖拽、缩放
|
||
- 支持自定义内容和样式
|
||
- 实现 `IBimComponent` 接口
|
||
- **`index.type.ts`**: 弹窗类型定义 (`DialogOptions`、`DialogPosition` 等)
|
||
- **`index.css`**: 弹窗样式
|
||
- **`bimInfoDialog/index.ts`**: `BimInfoDialog` 类 - 信息弹窗(继承 `BimDialog`)
|
||
|
||
#### `button-group/`
|
||
- **`index.ts`**: `BimButtonGroup` 类 - 通用按钮组组件
|
||
- 支持按钮、菜单类型
|
||
- 支持分组、嵌套菜单
|
||
- 支持主题和国际化
|
||
- **`index.type.ts`**: 按钮组类型定义 (`ButtonConfig`、`ButtonGroupOptions` 等)
|
||
- **`index.css`**: 按钮组样式
|
||
- **`toolbar/index.ts`**: `Toolbar` 类 - 底部工具栏(继承 `BimButtonGroup`)
|
||
- **`toolbar/buttons/`**: 工具栏按钮配置
|
||
- `home/`: 首页按钮
|
||
- `info/`: 信息按钮
|
||
- `location/`: 定位按钮
|
||
- `setting/`: 设置按钮
|
||
- `walk/`: 漫游相关按钮(菜单、人物、鸟瞰)
|
||
|
||
#### `engine/`
|
||
- **`index.ts`**: `Engine` 类 - 3D 引擎组件
|
||
- 封装第三方 3D 引擎 SDK
|
||
- 实现延迟初始化
|
||
- 管理引擎生命周期
|
||
- **`types.ts`**: 引擎类型定义 (`EngineOptions`、`ModelLoadOptions`)
|
||
|
||
### 3.4 管理器目录 (`src/managers/`)
|
||
|
||
#### `dialog-manager.ts`
|
||
- **作用**: 弹窗管理器
|
||
- **功能**:
|
||
- 创建和管理弹窗实例
|
||
- 监听 `ui:open-dialog` 事件
|
||
- 统一应用主题
|
||
- **继承**: `BimComponent`
|
||
|
||
#### `toolbar-manager.ts`
|
||
- **作用**: 底部工具栏管理器
|
||
- **功能**:
|
||
- 创建和管理工具栏实例
|
||
- 提供工具栏操作 API(添加按钮、设置可见性等)
|
||
- **继承**: `BimComponent`
|
||
|
||
#### `button-group-manager.ts`
|
||
- **作用**: 通用按钮组管理器
|
||
- **功能**:
|
||
- 创建和管理通用按钮组实例
|
||
- 支持多个按钮组并存
|
||
- **继承**: `BimComponent`
|
||
|
||
#### `engine-manager.ts`
|
||
- **作用**: 3D 引擎管理器
|
||
- **功能**:
|
||
- 管理 3D 引擎生命周期
|
||
- 提供引擎操作 API(初始化、加载模型等)
|
||
- 延迟初始化模式
|
||
- **继承**: `BimComponent`
|
||
|
||
### 3.5 服务目录 (`src/services/`)
|
||
|
||
#### `theme.ts`
|
||
- **作用**: 主题管理器(单例)
|
||
- **功能**:
|
||
- 管理当前主题配置
|
||
- 提供主题切换 API
|
||
- 支持主题变更订阅
|
||
- **导出**: `themeManager` 单例实例
|
||
|
||
#### `locale.ts`
|
||
- **作用**: 语言管理器(单例)
|
||
- **功能**:
|
||
- 管理当前语言配置
|
||
- 提供语言切换 API
|
||
- 提供翻译函数 `t(key)`
|
||
- 支持语言变更订阅
|
||
- **导出**: `localeManager` 单例实例、`t()` 翻译函数
|
||
|
||
### 3.6 主题目录 (`src/themes/`)
|
||
|
||
#### `types.ts`
|
||
- **作用**: 主题类型定义
|
||
- **内容**: `ThemeConfig` 接口、`ThemeType` 类型
|
||
|
||
#### `presets.ts`
|
||
- **作用**: 预设主题配置
|
||
- **内容**: `darkTheme`、`lightTheme` 预设配置对象
|
||
|
||
### 3.7 国际化目录 (`src/locales/`)
|
||
|
||
#### `types.ts`
|
||
- **作用**: 国际化类型定义
|
||
- **内容**:
|
||
- `LocaleType`: 支持的语言类型(`'zh-CN' | 'en-US'`)
|
||
- `TranslationDictionary`: 翻译字典接口,定义所有翻译键的结构
|
||
|
||
#### `zh-CN.ts`
|
||
- **作用**: 中文翻译字典
|
||
- **内容**: 所有中文翻译文本,结构必须与 `TranslationDictionary` 接口一致
|
||
|
||
#### `en-US.ts`
|
||
- **作用**: 英文翻译字典
|
||
- **内容**: 所有英文翻译文本,结构必须与 `TranslationDictionary` 接口一致
|
||
|
||
### 3.8 类型定义目录 (`src/types/`)
|
||
|
||
#### `component.ts`
|
||
- **作用**: 组件接口定义
|
||
- **内容**: `IBimComponent` 接口
|
||
|
||
#### `events.ts`
|
||
- **作用**: 事件类型定义
|
||
- **内容**: `EngineEvents` 接口,定义所有事件类型和 payload 结构
|
||
|
||
### 3.9 样式文件
|
||
|
||
#### `bim-engine.css`
|
||
- **作用**: 全局样式
|
||
- **位置**: `src/bim-engine.css`
|
||
- **内容**: 基础样式、CSS 变量定义
|
||
|
||
### 3.10 组件详细文档目录 (`docs/components/`)
|
||
|
||
#### 文档说明
|
||
- **作用**: 存放每个组件的详细文档
|
||
- **用途**: 供 AI 根据文档重现组件,包含完整的实现细节
|
||
- **维护规则**: 组件有更改时,必须同步更新对应的组件文档
|
||
|
||
#### 文档列表
|
||
- `dialog.md` - Dialog 组件详细文档
|
||
- `button-group.md` - ButtonGroup 组件详细文档
|
||
- `engine.md` - Engine 组件详细文档
|
||
|
||
#### 文档内容结构
|
||
每个组件文档包含以下部分:
|
||
1. 组件概述(基本信息、在 SDK 中的位置)
|
||
2. 组件类 API 文档(所有公共方法、参数、返回值)
|
||
3. 分化组件说明(如 Toolbar 继承自 ButtonGroup)
|
||
4. Manager API 文档(Manager 的所有公共方法)
|
||
5. UI 详细描述(DOM 结构、CSS 类名、交互行为)
|
||
6. 逻辑流程详细描述(初始化、生命周期、事件处理)
|
||
7. 国际化支持(使用的翻译键、语言变更处理)
|
||
8. 主题支持(使用的主题变量、主题变更处理)
|
||
9. 使用示例(基本使用、高级使用)
|
||
10. 实现细节(关键算法、性能优化、注意事项)
|
||
11. 类型定义
|
||
12. 文件清单
|
||
|
||
**重要**: 组件文档必须非常详细,详细到其他 AI 可以直接根据文档重现组件。
|
||
|
||
---
|
||
|
||
## 4. 组件和事件清单
|
||
|
||
### 4.0 组件与 Manager 的关系(重要)
|
||
|
||
#### 核心原则
|
||
**组件是独立的实现,但使用组件必须通过 Manager,不允许直接使用组件类。**
|
||
|
||
#### 设计理念
|
||
- **组件 (`components/`)**: 独立的 UI 组件实现,负责具体的功能逻辑
|
||
- **Manager (`managers/`)**: 组件管理器,负责创建、管理和协调组件实例
|
||
- **BimEngine**: 总控制器,通过 Manager 统一管理所有组件
|
||
|
||
#### 为什么必须通过 Manager?
|
||
1. **统一管理**: Manager 负责组件的生命周期管理,确保资源正确释放
|
||
2. **主题和语言**: Manager 统一应用主题和国际化,保证一致性
|
||
3. **事件总线**: Manager 可以监听和发送事件,实现组件间解耦通信
|
||
- 简单场景:直接调用 Manager 方法
|
||
- 复杂场景:通过事件总线进行发布订阅
|
||
4. **容器管理**: Manager 管理组件的挂载容器,避免冲突
|
||
5. **API 封装**: Manager 提供统一的公共 API,隐藏组件实现细节
|
||
|
||
#### 使用示例
|
||
|
||
**❌ 错误方式 - 直接使用组件:**
|
||
```typescript
|
||
// 错误:直接创建和使用组件
|
||
import { BimDialog } from 'bim-engine-sdk';
|
||
|
||
const dialog = new BimDialog({
|
||
container: document.getElementById('container'),
|
||
title: '测试弹窗',
|
||
content: '这是内容'
|
||
});
|
||
dialog.init();
|
||
// 问题:没有通过 Manager 管理,无法统一应用主题、语言等
|
||
```
|
||
|
||
**✅ 正确方式 - 通过 Manager 使用:**
|
||
```typescript
|
||
// 正确:通过 BimEngine 的 Manager 使用组件
|
||
import { BimEngine } from 'bim-engine-sdk';
|
||
|
||
const engine = new BimEngine('container', {
|
||
locale: 'zh-CN',
|
||
theme: 'dark'
|
||
});
|
||
|
||
// 通过 DialogManager 创建弹窗
|
||
const dialog = engine.dialog.create({
|
||
title: '测试弹窗',
|
||
content: '这是内容'
|
||
});
|
||
// 优势:
|
||
// 1. 自动应用当前主题
|
||
// 2. 自动应用当前语言
|
||
// 3. 统一管理弹窗实例
|
||
// 4. 可以监听事件总线
|
||
```
|
||
|
||
**✅ 另一个正确示例 - 工具栏按钮:**
|
||
```typescript
|
||
// 正确:通过 ToolbarManager 操作工具栏
|
||
import { BimEngine } from 'bim-engine-sdk';
|
||
|
||
const engine = new BimEngine('container');
|
||
|
||
// 通过 ToolbarManager 添加按钮
|
||
engine.toolbar.addButton({
|
||
id: 'my-button',
|
||
groupId: 'group-1',
|
||
type: 'button',
|
||
label: 'toolbar.myButton',
|
||
icon: '<svg>...</svg>',
|
||
onClick: (button) => {
|
||
console.log('按钮被点击');
|
||
}
|
||
});
|
||
|
||
// 通过 ToolbarManager 控制可见性
|
||
engine.toolbar.setButtonVisibility('my-button', false);
|
||
```
|
||
|
||
#### 组件导出说明
|
||
虽然 `src/index.ts` 中导出了 `BimButtonGroup` 和 `Toolbar` 组件,但这是为了:
|
||
- 高级用户需要完全自定义的场景
|
||
- 内部 Manager 的实现需要
|
||
- **不推荐** 外部用户直接使用,应该通过 Manager
|
||
|
||
### 4.1 Manager 类清单
|
||
|
||
| 类名 | 文件路径 | 功能 | 继承关系 |
|
||
|------|---------|------|---------|
|
||
| `DialogManager` | `src/managers/dialog-manager.ts` | 管理弹窗实例 | `BimComponent` |
|
||
| `ToolbarManager` | `src/managers/toolbar-manager.ts` | 管理底部工具栏 | `BimComponent` |
|
||
| `ButtonGroupManager` | `src/managers/button-group-manager.ts` | 管理通用按钮组 | `BimComponent` |
|
||
| `EngineManager` | `src/managers/engine-manager.ts` | 管理 3D 引擎 | `BimComponent` |
|
||
| `RightKeyManager` | `src/managers/right-key-manager.ts` | 管理右键菜单 (Context Menu) | `BimComponent` |
|
||
| `TreeManager` | `src/managers/tree-manager.ts` | 管理树组件实例 | `BimComponent` |
|
||
| `ModelTreeManager` | `src/managers/model-tree-manager.ts` | 模型树业务管理器 (组合 Dialog 和 Tree) | `BimComponent` |
|
||
|
||
### 4.2 组件类清单
|
||
|
||
| 类名 | 文件路径 | 功能 | 实现接口 |
|
||
|------|---------|------|---------|
|
||
| `BimDialog` | `src/components/dialog/index.ts` | 通用弹窗组件 | `IBimComponent` |
|
||
| `BimInfoDialog` | `src/components/dialog/bimInfoDialog/index.ts` | 信息弹窗组件 | 继承 `BimDialog` |
|
||
| `BimButtonGroup` | `src/components/button-group/index.ts` | 通用按钮组组件 | `IBimComponent` |
|
||
| `Toolbar` | `src/components/button-group/toolbar/index.ts` | 底部工具栏组件 | 继承 `BimButtonGroup` |
|
||
| `Engine` | `src/components/engine/index.ts` | 3D 引擎组件 | `IBimComponent` |
|
||
| `BimRightKey` | `src/components/right-key/index.ts` | 右键浮层容器 | `IBimComponent` |
|
||
| `BimMenu` | `src/components/menu/index.ts` | 通用菜单列表 | `IBimComponent` |
|
||
| `BimTree` | `src/components/tree/index.ts` | 通用树形组件 | `IBimComponent` |
|
||
|
||
### 4.3 服务类清单
|
||
|
||
| 类名 | 文件路径 | 功能 | 模式 |
|
||
|------|---------|------|------|
|
||
| `ThemeManager` | `src/services/theme.ts` | 主题管理 | 单例 |
|
||
| `LocaleManager` | `src/services/locale.ts` | 语言管理 | 单例 |
|
||
|
||
### 4.4 事件总线定义
|
||
|
||
#### 事件类型 (`EngineEvents`)
|
||
|
||
定义在 `src/types/events.ts`:
|
||
|
||
```typescript
|
||
interface EngineEvents {
|
||
// UI 事件
|
||
'ui:open-dialog': { id: string; data?: any };
|
||
'ui:close-dialog': { id: string };
|
||
|
||
// 引擎事件
|
||
'engine:model-loaded': { url: string };
|
||
'engine:object-clicked': { objectId: string; position: { x: number, y: number, z: number } };
|
||
|
||
// 树组件事件
|
||
'ui:tree-node-check': { id: string; checked: boolean; node: any };
|
||
'ui:tree-node-select': { id: string; selected: boolean; node: any };
|
||
'ui:tree-node-expand': { id: string; expanded: boolean };
|
||
|
||
// 系统事件
|
||
'sys:theme-changed': { theme: string };
|
||
'sys:locale-changed': { locale: string };
|
||
}
|
||
```
|
||
|
||
#### 事件命名规范
|
||
- **UI 事件**: `ui:` 前缀,如 `ui:open-dialog`
|
||
- **引擎事件**: `engine:` 前缀,如 `engine:model-loaded`
|
||
- **系统事件**: `sys:` 前缀,如 `sys:theme-changed`
|
||
|
||
#### 事件使用方式
|
||
|
||
**发送事件**:
|
||
```typescript
|
||
// 在 BimComponent 子类中
|
||
this.emit('ui:open-dialog', { id: 'info' });
|
||
```
|
||
|
||
**监听事件**:
|
||
```typescript
|
||
// 在 BimComponent 子类中
|
||
// 返回取消订阅函数
|
||
const unsubscribe = this.on('ui:open-dialog', (payload) => {
|
||
console.log('收到事件:', payload);
|
||
});
|
||
|
||
// 组件销毁时取消订阅
|
||
unsubscribe();
|
||
```
|
||
|
||
#### 使用场景判断
|
||
|
||
**✅ 使用直接调用方法的场景**:
|
||
- 简单的 API 调用,如 `engine.dialog.create()`
|
||
- 需要立即得到结果的操作
|
||
- 单一调用者,不需要多个监听者
|
||
- 性能敏感的操作
|
||
|
||
**✅ 使用事件总线的场景**:
|
||
- 需要多个组件同时响应的事件(如模型加载完成)
|
||
- 跨多层组件传递信息
|
||
- 解耦需求,降低组件间直接依赖
|
||
- 异步通知场景
|
||
- 需要动态添加/移除监听者的场景
|
||
|
||
**示例对比**:
|
||
|
||
```typescript
|
||
// 场景 1: 简单操作 - 使用直接调用
|
||
// 用户代码直接调用,简单直接
|
||
engine.dialog.create({
|
||
title: t('dialog.title'),
|
||
content: 'Hello'
|
||
});
|
||
|
||
// 场景 2: 复杂场景 - 使用事件总线
|
||
// 按钮点击后,需要通知多个组件(弹窗、日志、统计等)
|
||
this.emit('ui:open-dialog', { id: 'info', data: { source: 'toolbar' } });
|
||
|
||
// 多个组件可以同时监听
|
||
// DialogManager 监听并打开弹窗
|
||
this.on('ui:open-dialog', (payload) => {
|
||
if (payload.id === 'info') {
|
||
this.showInfoDialog();
|
||
}
|
||
});
|
||
|
||
// AnalyticsManager 监听并记录统计
|
||
this.on('ui:open-dialog', (payload) => {
|
||
this.trackEvent('dialog_opened', payload);
|
||
});
|
||
```
|
||
|
||
### 4.5 核心基类
|
||
|
||
| 类名 | 文件路径 | 功能 | 继承/实现 |
|
||
|------|---------|------|----------|
|
||
| `EventEmitter` | `src/core/event-emitter.ts` | 事件总线基础类 | - |
|
||
| `BimComponent` | `src/core/component.ts` | 组件基类 | 抽象类 |
|
||
| `BimEngine` | `src/bim-engine.ts` | 主引擎类 | 继承 `EventEmitter` |
|
||
|
||
---
|
||
|
||
## 4.6 国际化实现指南
|
||
|
||
### 4.6.1 国际化的重要性
|
||
|
||
**所有用户可见的文本都必须支持国际化,这是强制要求。**
|
||
|
||
- 项目支持多语言(目前:中文、英文)
|
||
- 所有 UI 文本必须通过翻译函数获取
|
||
- 严禁在代码中硬编码任何语言的文本
|
||
|
||
### 4.6.2 国际化实现方式
|
||
|
||
#### 步骤 1: 在翻译字典中添加键值
|
||
|
||
**在 `src/locales/types.ts` 中定义类型:**
|
||
```typescript
|
||
export interface TranslationDictionary {
|
||
// ... 现有键
|
||
myComponent: {
|
||
title: string;
|
||
description: string;
|
||
buttonText: string;
|
||
};
|
||
}
|
||
```
|
||
|
||
**在 `src/locales/zh-CN.ts` 中添加中文翻译:**
|
||
```typescript
|
||
export const zhCN: TranslationDictionary = {
|
||
// ... 现有内容
|
||
myComponent: {
|
||
title: '我的组件',
|
||
description: '这是组件描述',
|
||
buttonText: '点击按钮',
|
||
},
|
||
};
|
||
```
|
||
|
||
**在 `src/locales/en-US.ts` 中添加英文翻译:**
|
||
```typescript
|
||
export const enUS: TranslationDictionary = {
|
||
// ... 现有内容
|
||
myComponent: {
|
||
title: 'My Component',
|
||
description: 'This is component description',
|
||
buttonText: 'Click Button',
|
||
},
|
||
};
|
||
```
|
||
|
||
#### 步骤 2: 在组件中使用翻译函数
|
||
|
||
**导入翻译函数:**
|
||
```typescript
|
||
import { t, localeManager } from '../../services/locale';
|
||
```
|
||
|
||
**使用翻译函数:**
|
||
```typescript
|
||
// 在组件中使用
|
||
const title = t('myComponent.title'); // 获取翻译文本
|
||
|
||
// 在 DOM 中使用
|
||
const titleEl = document.createElement('div');
|
||
titleEl.textContent = t('myComponent.title');
|
||
|
||
// 在 HTML 字符串中使用
|
||
const html = `<div>${t('myComponent.description')}</div>`;
|
||
```
|
||
|
||
#### 步骤 3: 监听语言变更
|
||
|
||
**在组件中订阅语言变更:**
|
||
```typescript
|
||
export class MyComponent implements IBimComponent {
|
||
private unsubscribeLocale: (() => void) | null = null;
|
||
|
||
public init() {
|
||
// 初始化时订阅语言变更
|
||
this.unsubscribeLocale = localeManager.subscribe(() => {
|
||
this.setLocales(); // 更新所有文本
|
||
});
|
||
|
||
// 初始设置
|
||
this.setLocales();
|
||
}
|
||
|
||
public setLocales(): void {
|
||
// 更新所有用户可见的文本
|
||
const titleEl = this.element.querySelector('.title');
|
||
if (titleEl) {
|
||
titleEl.textContent = t('myComponent.title');
|
||
}
|
||
}
|
||
|
||
public destroy() {
|
||
// 清理订阅
|
||
if (this.unsubscribeLocale) {
|
||
this.unsubscribeLocale();
|
||
this.unsubscribeLocale = null;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.6.3 国际化注意事项
|
||
|
||
#### ✅ 必须做的
|
||
|
||
1. **所有用户可见文本使用 `t(key)`**
|
||
```typescript
|
||
// ✅ 正确
|
||
button.textContent = t('toolbar.home');
|
||
|
||
// ❌ 错误
|
||
button.textContent = '首页';
|
||
```
|
||
|
||
2. **翻译键使用有意义的路径**
|
||
```typescript
|
||
// ✅ 正确:按功能模块组织
|
||
t('toolbar.home')
|
||
t('dialog.title')
|
||
t('button.save')
|
||
|
||
// ❌ 错误:键名不清晰
|
||
t('text1')
|
||
t('label')
|
||
```
|
||
|
||
3. **在所有语言文件中添加翻译**
|
||
- 添加新键时,必须同时更新 `zh-CN.ts` 和 `en-US.ts`
|
||
- 确保所有语言文件的结构一致
|
||
|
||
4. **实现 `setLocales()` 方法**
|
||
- 所有组件必须实现 `setLocales()` 方法
|
||
- 在方法中更新所有用户可见的文本
|
||
|
||
5. **订阅语言变更**
|
||
- 组件初始化时订阅 `localeManager.subscribe()`
|
||
- 组件销毁时取消订阅
|
||
|
||
#### ❌ 禁止做的
|
||
|
||
1. **禁止硬编码文本**
|
||
```typescript
|
||
// ❌ 错误:硬编码中文
|
||
const title = '首页';
|
||
|
||
// ❌ 错误:硬编码英文
|
||
const title = 'Home';
|
||
|
||
// ✅ 正确:使用翻译函数
|
||
const title = t('toolbar.home');
|
||
```
|
||
|
||
2. **禁止在翻译键中使用变量**
|
||
```typescript
|
||
// ❌ 错误:动态拼接键名
|
||
t(`toolbar.${buttonId}`);
|
||
|
||
// ✅ 正确:使用完整的键名
|
||
t('toolbar.home');
|
||
```
|
||
|
||
3. **禁止在翻译文本中拼接变量**
|
||
```typescript
|
||
// ❌ 错误:在翻译文本中拼接
|
||
const text = t('dialog.message') + userName;
|
||
|
||
// ✅ 正确:使用占位符(需要在翻译字典中支持)
|
||
// 注意:当前实现不支持占位符,需要扩展 LocaleManager
|
||
```
|
||
|
||
4. **禁止忽略语言变更**
|
||
- 组件必须响应语言切换
|
||
- 不能只在初始化时设置文本
|
||
|
||
### 4.6.4 国际化最佳实践
|
||
|
||
#### 翻译键的组织结构
|
||
|
||
```typescript
|
||
// 按功能模块组织
|
||
TranslationDictionary {
|
||
toolbar: { // 工具栏相关
|
||
home: string;
|
||
info: string;
|
||
},
|
||
dialog: { // 弹窗相关
|
||
title: string;
|
||
content: string;
|
||
},
|
||
button: { // 按钮相关
|
||
save: string;
|
||
cancel: string;
|
||
},
|
||
message: { // 消息相关
|
||
success: string;
|
||
error: string;
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 组件中的国际化实现示例
|
||
|
||
```typescript
|
||
import { t, localeManager } from '../../services/locale';
|
||
import { IBimComponent } from '../../types/component';
|
||
|
||
export class MyDialog implements IBimComponent {
|
||
private element: HTMLElement;
|
||
private unsubscribeLocale: (() => void) | null = null;
|
||
|
||
constructor(container: HTMLElement) {
|
||
this.element = this.createDOM();
|
||
container.appendChild(this.element);
|
||
}
|
||
|
||
public init() {
|
||
// 订阅语言变更
|
||
this.unsubscribeLocale = localeManager.subscribe(() => {
|
||
this.setLocales();
|
||
});
|
||
|
||
// 初始设置
|
||
this.setLocales();
|
||
}
|
||
|
||
public setLocales(): void {
|
||
// 更新标题
|
||
const titleEl = this.element.querySelector('.dialog-title');
|
||
if (titleEl) {
|
||
titleEl.textContent = t('dialog.myDialog.title');
|
||
}
|
||
|
||
// 更新内容
|
||
const contentEl = this.element.querySelector('.dialog-content');
|
||
if (contentEl) {
|
||
contentEl.textContent = t('dialog.myDialog.content');
|
||
}
|
||
|
||
// 更新按钮
|
||
const buttonEl = this.element.querySelector('.dialog-button');
|
||
if (buttonEl) {
|
||
buttonEl.textContent = t('button.confirm');
|
||
}
|
||
}
|
||
|
||
public destroy() {
|
||
if (this.unsubscribeLocale) {
|
||
this.unsubscribeLocale();
|
||
this.unsubscribeLocale = null;
|
||
}
|
||
this.element.remove();
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 添加新语言支持
|
||
|
||
1. 在 `src/locales/types.ts` 中扩展 `LocaleType`:
|
||
```typescript
|
||
export type LocaleType = 'zh-CN' | 'en-US' | 'ja-JP'; // 添加日语
|
||
```
|
||
|
||
2. 创建新的翻译文件 `src/locales/ja-JP.ts`:
|
||
```typescript
|
||
import { TranslationDictionary } from './types';
|
||
|
||
export const jaJP: TranslationDictionary = {
|
||
// 添加所有翻译
|
||
};
|
||
```
|
||
|
||
3. 在 `src/services/locale.ts` 中注册新语言:
|
||
```typescript
|
||
import { jaJP } from '../locales/ja-JP';
|
||
|
||
private messages: Record<LocaleType, TranslationDictionary> = {
|
||
'zh-CN': zhCN,
|
||
'en-US': enUS,
|
||
'ja-JP': jaJP, // 添加新语言
|
||
};
|
||
```
|
||
|
||
### 4.6.5 国际化检查清单
|
||
|
||
在开发新功能时,确保:
|
||
|
||
- [ ] 所有用户可见的文本都使用 `t(key)` 函数
|
||
- [ ] 在 `types.ts` 中定义了新的翻译键类型
|
||
- [ ] 在 `zh-CN.ts` 中添加了中文翻译
|
||
- [ ] 在 `en-US.ts` 中添加了英文翻译
|
||
- [ ] 组件实现了 `setLocales()` 方法
|
||
- [ ] 组件订阅了语言变更事件
|
||
- [ ] 组件销毁时取消了语言订阅
|
||
- [ ] 没有硬编码任何语言的文本
|
||
- [ ] 翻译键名清晰、有意义
|
||
|
||
---
|
||
|
||
## 5. AI 工作规则
|
||
|
||
### 5.1 AI 编码规范
|
||
|
||
#### 语言要求(强制)
|
||
- **所有输出必须使用中文**,包括:
|
||
- 代码注释 (**强制:所有代码注释必须使用中文,解释清晰详细**)
|
||
- 文档说明
|
||
- 与用户交流
|
||
- 错误信息
|
||
- 日志输出
|
||
- **思考过程也必须使用中文**:
|
||
- 分析问题时用中文思考
|
||
- 解释代码逻辑时用中文
|
||
- 讨论设计方案时用中文
|
||
- **代码中的字符串**:根据业务需求,但注释和文档必须中文
|
||
|
||
#### 代码可读性
|
||
- **优先保证代码可读性**,有时可以不使用高级函数,使用低级函数
|
||
- **必须添加详细的中文注释**,解释代码逻辑和设计意图
|
||
- 函数、类、接口必须有 JSDoc 注释(使用中文)
|
||
- 复杂逻辑必须添加行内注释说明
|
||
|
||
#### 代码风格
|
||
- 使用 TypeScript 严格模式
|
||
- 遵循项目现有的命名规范(见 2.3 节)
|
||
- 保持代码格式一致(使用项目配置的格式化工具)
|
||
- 保持缩进和空行的一致性
|
||
|
||
#### 类型安全
|
||
- 充分利用 TypeScript 类型系统
|
||
- 避免使用 `any`,必要时使用 `unknown`
|
||
- 为所有公共 API 提供类型定义
|
||
- 使用类型推断,但复杂类型必须显式声明
|
||
|
||
#### 组件使用规范
|
||
- **严禁直接使用组件类**,必须通过 Manager 使用(见 4.0 节)
|
||
- 新增组件时,必须创建对应的 Manager
|
||
- Manager 必须继承 `BimComponent` 基类
|
||
- 组件必须实现 `IBimComponent` 接口
|
||
- **组件必须支持国际化**(见 4.6 节)
|
||
|
||
#### 注释规范
|
||
```typescript
|
||
/**
|
||
* 函数功能描述(中文)
|
||
* @param param1 参数说明(中文)
|
||
* @param param2 参数说明(中文)
|
||
* @returns 返回值说明(中文)
|
||
*/
|
||
function example(param1: string, param2: number): boolean {
|
||
// 行内注释说明关键逻辑(中文)
|
||
return true;
|
||
}
|
||
```
|
||
|
||
#### 错误处理规范
|
||
- 所有异步操作必须有错误处理
|
||
- 使用 `try-catch` 捕获可能的异常
|
||
- 错误信息必须使用中文
|
||
- 提供有意义的错误信息,帮助调试
|
||
|
||
#### 性能考虑
|
||
- 使用 `requestAnimationFrame` 优化动画性能
|
||
- 避免频繁的 DOM 操作,使用批量更新
|
||
- 合理使用事件委托,减少事件监听器数量
|
||
- 及时清理不需要的监听器和定时器
|
||
|
||
### 5.2 问答方式和开发流程规范
|
||
|
||
#### 用户询问"如何实现"时的处理流程
|
||
|
||
**当用户询问如何实现某个功能时,必须遵循以下流程:**
|
||
|
||
1. **分析需求**:用中文理解用户需求,明确要实现的功能
|
||
2. **制定详细开发计划**:必须包含以下内容:
|
||
- **需要修改的文件列表**:
|
||
- 列出每个需要修改的文件路径
|
||
- 说明每个文件的修改内容(添加什么、修改什么)
|
||
- **需要新增的文件列表**:
|
||
- 列出每个需要新增的文件路径
|
||
- 说明每个文件的作用和内容概要
|
||
- **需要删除的文件列表**:
|
||
- 列出每个需要删除的文件路径
|
||
- 说明删除的原因
|
||
- **注意**:删除的文件必须移动到回收文件夹,不能直接删除
|
||
- **每个文件的作用说明**:
|
||
- 详细说明每个文件在整体功能中的作用
|
||
- 说明文件之间的依赖关系
|
||
- **对整体结构的影响**:
|
||
- 说明对现有架构的影响
|
||
- 说明对现有功能的影响
|
||
- 说明是否需要更新文档
|
||
- 说明可能的风险点
|
||
3. **展示开发计划**:以清晰的格式展示给用户
|
||
4. **等待用户确认**:**在用户明确同意之前,绝对不能修改任何代码**
|
||
5. **用户同意后执行**:只有在用户明确表示同意后,才能开始修改代码
|
||
|
||
**示例格式**:
|
||
|
||
```
|
||
## 开发计划
|
||
|
||
### 需要修改的文件
|
||
1. `src/managers/dialog-manager.ts`
|
||
- 修改:添加新的 `showCustomDialog()` 方法
|
||
- 作用:提供自定义弹窗的快捷方法
|
||
|
||
2. `src/types/events.ts`
|
||
- 修改:在 `EngineEvents` 接口中添加 `'ui:custom-dialog'` 事件类型
|
||
- 作用:定义新的事件类型,支持事件总线通信
|
||
|
||
### 需要新增的文件
|
||
1. `src/components/dialog/customDialog/index.ts`
|
||
- 作用:实现自定义弹窗组件
|
||
- 内容:包含 CustomDialog 类,实现 IBimComponent 接口
|
||
|
||
2. `src/components/dialog/customDialog/index.css`
|
||
- 作用:自定义弹窗的样式文件
|
||
|
||
### 需要删除的文件
|
||
1. `src/components/dialog/oldDialog.ts`
|
||
- 原因:已被新组件替代
|
||
- **处理方式**:移动到 `.recycle/YYYY-MM-DD/` 文件夹(使用当前日期)
|
||
|
||
### 对整体结构的影响
|
||
- **架构影响**:新增一个 Dialog 子类型,不影响现有架构
|
||
- **功能影响**:不影响现有弹窗功能,只是新增功能
|
||
- **文档更新**:需要更新 AI_COLLABORATION.md 中的组件清单
|
||
- **风险点**:无重大风险,向后兼容
|
||
|
||
请确认是否按照此计划进行开发?
|
||
```
|
||
|
||
#### 用户直接要求修改时的处理
|
||
|
||
**当用户直接要求修改代码时(如"帮我修改XXX"、"实现XXX功能"),可以:**
|
||
- 直接执行代码修改
|
||
- 但仍需遵循其他规范(国际化、组件使用规范等)
|
||
- 删除文件时仍需移动到回收文件夹
|
||
|
||
#### 文件删除规范(强制)
|
||
|
||
**严禁直接删除文件,必须遵循以下流程:**
|
||
|
||
1. **创建回收文件夹**(如果不存在):
|
||
- 在项目根目录创建 `.recycle/` 文件夹
|
||
- 此文件夹用于存放被删除的文件
|
||
|
||
2. **按时间组织文件夹**:
|
||
- 在 `.recycle/` 下按日期创建子文件夹,格式:`YYYY-MM-DD`
|
||
- 例如:`2024-01-15`、`2024-12-25`
|
||
- 同一天删除的文件存放在同一个日期文件夹中
|
||
|
||
3. **移动文件而非删除**:
|
||
```bash
|
||
# 错误方式 ❌
|
||
rm src/old-file.ts
|
||
|
||
# 正确方式 ✅
|
||
# 获取当前日期(格式:YYYY-MM-DD)
|
||
DATE=$(date +%Y-%m-%d)
|
||
mkdir -p .recycle/$DATE
|
||
mv src/old-file.ts .recycle/$DATE/src/old-file.ts
|
||
```
|
||
|
||
4. **保持目录结构**:
|
||
- 在日期文件夹中保持原文件的目录结构
|
||
- 例如:`src/components/old.ts` → `.recycle/2024-01-15/src/components/old.ts`
|
||
|
||
5. **添加删除说明**(可选):
|
||
- 在对应日期文件夹中创建 `README.md` 记录删除原因
|
||
- 格式:
|
||
```
|
||
## 2024-01-15 删除的文件
|
||
|
||
- `src/components/old.ts`: 被新组件替代
|
||
- `src/managers/old-manager.ts`: 功能重构,使用新 Manager
|
||
```
|
||
|
||
6. **恢复文件**:
|
||
- 如果发现误删,可以从对应日期文件夹中恢复
|
||
- 恢复后从 `.recycle/` 中移除
|
||
|
||
**回收文件夹结构示例**:
|
||
```
|
||
.recycle/
|
||
├── 2024-01-15/
|
||
│ ├── README.md
|
||
│ └── src/
|
||
│ ├── components/
|
||
│ │ └── old-component.ts
|
||
│ └── managers/
|
||
│ └── old-manager.ts
|
||
├── 2024-02-20/
|
||
│ ├── README.md
|
||
│ └── src/
|
||
│ └── types/
|
||
│ └── old-types.ts
|
||
└── 2024-12-25/
|
||
├── README.md
|
||
└── demo/
|
||
└── old-demo.html
|
||
```
|
||
|
||
**注意事项**:
|
||
- 日期格式必须使用 `YYYY-MM-DD`(如 `2024-01-15`)
|
||
- 如果同一天删除多个文件,都存放在同一个日期文件夹中
|
||
- 日期文件夹按时间倒序排列,最新的在最前面
|
||
|
||
### 5.3 文档更新规则
|
||
|
||
#### 必须更新的情况
|
||
- **新增文件**: 在 "文件结构说明" 部分添加文件描述
|
||
- **删除文件**: 从文档中移除对应条目(但文件移动到 `.recycle/` 文件夹)
|
||
- **修改文件功能**: 更新对应文件的描述
|
||
- **新增组件**:
|
||
- 在 "组件和事件清单" 部分添加
|
||
- **必须创建对应的组件详细文档**(在 `docs/components/` 目录下)
|
||
- **修改组件**:
|
||
- 更新 "组件和事件清单" 部分
|
||
- **必须同步更新对应的组件详细文档**(`docs/components/` 目录下的对应文档)
|
||
- **新增事件**: 在 "事件总线定义" 部分添加
|
||
- **修改架构**: 更新 "架构设计思想" 部分
|
||
- **修改构建流程**: 更新 "构建和运行" 部分
|
||
|
||
#### 更新方式
|
||
1. 修改代码后,立即更新本文档
|
||
2. 确保文档与代码保持一致
|
||
3. 如果发现文档过时,优先更新文档
|
||
|
||
### 5.4 思考和工作流程规范
|
||
|
||
#### 思考过程要求
|
||
- **所有思考过程必须使用中文**
|
||
- 分析问题时,用中文描述问题、分析思路、得出结论
|
||
- 解释代码时,用中文说明逻辑、设计意图、实现方式
|
||
- 讨论方案时,用中文描述优缺点、选择理由
|
||
|
||
#### 工作流程
|
||
1. **理解需求**:用中文理解用户需求,明确任务目标
|
||
2. **分析问题**:用中文分析问题,梳理相关代码和架构
|
||
3. **设计方案**:用中文设计解决方案,考虑边界情况
|
||
4. **实现代码**:编写代码,添加中文注释
|
||
5. **测试验证**:用中文描述测试结果和发现的问题
|
||
6. **更新文档**:用中文更新相关文档
|
||
|
||
#### 代码审查要点
|
||
- **检查开发流程规范**:
|
||
- 如果是询问"如何实现",是否先提供了详细的开发计划
|
||
- 是否在用户同意后才修改代码
|
||
- 删除的文件是否移动到 `.recycle/` 文件夹而非直接删除
|
||
- 检查是否遵循组件使用规范(通过 Manager)
|
||
- **检查是否支持国际化**:
|
||
- 所有用户可见文本是否使用 `t(key)` 函数
|
||
- 是否在所有语言文件中添加了翻译
|
||
- 组件是否实现了 `setLocales()` 方法
|
||
- 组件是否订阅了语言变更事件
|
||
- 检查注释是否完整且为中文
|
||
- 检查错误处理是否完善
|
||
- 检查资源是否正确释放
|
||
- 检查类型定义是否完整
|
||
|
||
### 5.5 其他注意事项
|
||
|
||
#### 组件开发
|
||
- 所有 UI 组件必须实现 `IBimComponent` 接口
|
||
- 所有 Manager 必须继承 `BimComponent` 基类
|
||
- **组件必须通过 Manager 使用,不允许直接使用组件类**
|
||
- **组件必须支持国际化**(见 4.6 节):
|
||
- 所有用户可见文本使用 `t(key)` 函数
|
||
- 实现 `setLocales()` 方法
|
||
- 订阅语言变更事件
|
||
- 严禁硬编码任何语言的文本
|
||
- 组件销毁时必须清理所有资源(事件监听、定时器等)
|
||
- 新增组件时,必须同时创建对应的 Manager
|
||
|
||
#### 主题和国际化
|
||
- 组件必须支持主题切换(通过 `setTheme()` 方法)
|
||
- **组件必须支持国际化**(通过 `setLocales()` 方法)
|
||
- **所有用户可见的文本必须使用 `t(key)` 函数进行翻译**
|
||
- **严禁硬编码中文或英文文本**
|
||
- 新增文本时,必须在所有语言文件中添加对应的翻译键
|
||
- **详细实现方式请参考 4.6 节《国际化实现指南》**
|
||
|
||
#### 事件总线使用规范
|
||
- **根据场景选择通信方式**:
|
||
- **简单场景**:使用直接调用方法(如 `engine.dialog.create()`)
|
||
- **复杂场景**:使用事件总线(需要多个监听者、跨多层传递、解耦需求)
|
||
- **事件命名遵循规范**(`ui:`、`engine:`、`sys:` 前缀)
|
||
- **事件监听必须清理**:组件销毁时取消所有事件订阅
|
||
- **类型安全**:使用 `EngineEvents` 接口确保事件类型正确
|
||
|
||
#### 性能优化
|
||
- 使用 `requestAnimationFrame` 优化动画性能
|
||
- 避免频繁的 DOM 操作,使用批量更新
|
||
- 合理使用事件委托,减少事件监听器数量
|
||
|
||
#### 错误处理
|
||
- 所有异步操作必须有错误处理
|
||
- 使用 `try-catch` 捕获可能的异常
|
||
- 提供有意义的错误信息
|
||
|
||
#### 测试
|
||
- 确保代码修改后不影响现有功能
|
||
- 在 demo 中测试新功能
|
||
- 检查控制台是否有错误或警告
|
||
|
||
### 5.6 常见任务指南
|
||
|
||
#### 添加新组件
|
||
1. 在 `src/components/` 创建组件目录
|
||
2. 实现 `IBimComponent` 接口
|
||
3. 创建对应的类型定义文件
|
||
4. 创建对应的样式文件
|
||
5. **必须创建对应的 Manager**(在 `src/managers/` 目录)
|
||
6. **实现国际化支持**:
|
||
- 在 `src/locales/types.ts` 中添加翻译键类型
|
||
- 在 `src/locales/zh-CN.ts` 和 `en-US.ts` 中添加翻译
|
||
- 在组件中实现 `setLocales()` 方法
|
||
- 订阅语言变更事件
|
||
7. 在 `BimEngine` 中初始化 Manager 并暴露
|
||
8. 在 `src/index.ts` 导出(如需要,但不推荐直接导出组件)
|
||
9. **创建组件详细文档**:
|
||
- 在 `docs/components/` 目录下创建对应的组件文档(如 `dialog.md`)
|
||
- 文档必须包含以下 12 个部分(参考现有组件文档):
|
||
1. 组件概述
|
||
2. 组件类 API 文档
|
||
3. 分化组件说明
|
||
4. Manager API 文档
|
||
5. UI 详细描述
|
||
6. 逻辑流程详细描述
|
||
7. 国际化支持
|
||
8. 主题支持
|
||
9. 使用示例
|
||
10. 实现细节(供 AI 重现)
|
||
11. 类型定义
|
||
12. 文件清单
|
||
- **文档必须非常详细**,详细到其他 AI 可以直接根据文档重现组件
|
||
10. 更新本文档
|
||
|
||
**重要**:
|
||
- 组件必须通过 Manager 使用,不要直接导出组件类供外部使用
|
||
- 组件必须支持国际化,所有用户可见文本使用 `t(key)` 函数
|
||
- **组件有更改时,必须同步更新对应的组件详细文档**(`docs/components/` 目录下的对应文档)
|
||
|
||
#### 添加新 Manager
|
||
1. 在 `src/managers/` 创建 Manager 文件
|
||
2. 继承 `BimComponent` 基类
|
||
3. 在 `BimEngine` 中初始化
|
||
4. 在 `BimEngine` 中暴露公共属性
|
||
5. 更新本文档
|
||
|
||
#### 添加新事件
|
||
1. **判断是否需要事件总线**:
|
||
- 如果只需要简单的一对一调用 → 使用直接方法调用
|
||
- 如果需要多个监听者或跨多层传递 → 使用事件总线
|
||
2. 如果使用事件总线,在 `src/types/events.ts` 的 `EngineEvents` 接口中添加事件类型
|
||
3. 在相关组件中发送/监听事件
|
||
4. 确保组件销毁时取消事件订阅
|
||
5. 更新本文档
|
||
|
||
#### 修改主题配置
|
||
1. 在 `src/themes/presets.ts` 修改预设主题
|
||
2. 或在 `src/themes/types.ts` 扩展 `ThemeConfig` 接口
|
||
3. 确保所有组件正确应用新主题属性
|
||
4. 更新本文档(如主题结构有变化)
|
||
|
||
#### 添加新的翻译文本
|
||
1. 在 `src/locales/types.ts` 的 `TranslationDictionary` 接口中添加新的键
|
||
2. 在 `src/locales/zh-CN.ts` 中添加中文翻译
|
||
3. 在 `src/locales/en-US.ts` 中添加英文翻译
|
||
4. 在相关组件中使用 `t(key)` 函数获取翻译
|
||
5. 确保组件实现了 `setLocales()` 方法并订阅语言变更
|
||
6. 更新本文档(如添加新语言支持)
|
||
|
||
---
|
||
|
||
## 📝 文档维护记录
|
||
|
||
| 日期 | 修改内容 | 修改人 |
|
||
|------|---------|--------|
|
||
| 2024-XX-XX | 初始创建 | AI Assistant |
|
||
|
||
---
|
||
|
||
**重要提醒**: 本文档是 AI 协作的重要参考,请保持文档与代码同步更新!
|
||
|