# 事件系统设计

**设计日期**：2026-01-28  
**设计范围**：数据库客户端全局事件系统  
**状态**：设计阶段

---

## 一、设计概述

### 1.1 设计目标

- **简洁统一**：所有组件使用统一的事件命名和参数格式
- **易于扩展**：新增事件时，遵循统一规范，易于维护
- **类型安全**：使用 TypeScript 类型定义，确保类型安全
- **功能强大**：支持事件传递、事件拦截、事件日志等高级功能

### 1.2 设计原则

1. **命名规范**：事件名称使用 kebab-case，语义清晰
2. **参数统一**：事件参数使用对象格式，包含必要上下文信息
3. **类型定义**：所有事件都有明确的 TypeScript 类型定义
4. **文档完善**：每个事件都有清晰的文档说明

---

## 二、事件分类

### 2.1 连接相关事件

```typescript
// 连接选择
'connection-select': {
  connection: DbConnection
  database?: string  // 可选，选中的数据库
}

// 连接编辑
'connection-edit': {
  connectionId: number
}

// 连接删除
'connection-delete': {
  connectionId: number
}

// 连接刷新
'connection-refresh': {
  connectionId?: number  // 可选，不提供则刷新所有
}
```

### 2.2 表结构相关事件

```typescript
// 查看表结构
'table-structure': {
  connectionId: number
  database: string
  tableName: string  // 表名/集合名/Key名
  dbType: 'mysql' | 'mongo' | 'redis'
  nodeType: 'table' | 'collection' | 'key' | 'database' | 'connection'
}

// 表选择（生成SQL）
'table-select': {
  connectionId: number
  database: string
  tableName: string
  sql?: string  // 可选，预生成的SQL
}
```

### 2.3 SQL执行相关事件

```typescript
// SQL执行
'sql-execute': {
  sql: string
  connectionId: number
  database?: string
}

// SQL执行完成
'sql-execute-complete': {
  result: SqlResult
  error?: string
}
```

### 2.4 编辑器相关事件

```typescript
// SQL插入
'sql-insert': {
  sql: string
  tabKey?: string  // 可选，指定Tab
}

// Tab切换
'tab-switch': {
  tabKey: string
}

// Tab关闭
'tab-close': {
  tabKey: string
}
```

---

## 三、事件系统架构

### 3.1 事件总线设计

```typescript
// 事件总线接口
interface EventBus {
  // 注册事件监听器
  on<T = any>(event: string, handler: (data: T) => void): () => void
  
  // 注册一次性事件监听器
  once<T = any>(event: string, handler: (data: T) => void): void
  
  // 移除事件监听器
  off(event: string, handler?: Function): void
  
  // 触发事件
  emit<T = any>(event: string, data: T): void
  
  // 清除所有监听器
  clear(): void
}

// 全局事件总线实例
export const eventBus = createEventBus()
```

### 3.2 组件事件映射

```typescript
// ConnectionTree 组件事件
interface ConnectionTreeEvents {
  'connection-select': { connection: DbConnection; database?: string }
  'connection-edit': { connectionId: number }
  'connection-delete': { connectionId: number }
  'table-select': { connectionId: number; database: string; tableName: string }
  'table-structure': { 
    connectionId: number
    database: string
    tableName: string
    dbType: 'mysql' | 'mongo' | 'redis'
    nodeType: string
  }
  'new-connection': void
  'show-bookmarks': void
  'show-templates': void
}

// SqlEditor 组件事件
interface SqlEditorEvents {
  'execute': { sql: string }
  'execute-selected': { sql: string }
  'sql-insert': { sql: string; tabKey?: string }
  'tab-switch': { tabKey: string }
  'tab-close': { tabKey: string }
  'toggle-editor': void
}
```

---

## 四、事件命名规范

### 4.1 命名规则

- **格式**：`<组件>-<动作>` 或 `<功能>-<动作>`
- **示例**：
  - `connection-select`：连接选择
  - `table-structure`：表结构查看
  - `sql-execute`：SQL执行

### 4.2 动作词汇表

| 动作 | 说明 | 示例 |
|------|------|------|
| select | 选择 | `connection-select` |
| edit | 编辑 | `connection-edit` |
| delete | 删除 | `connection-delete` |
| create | 创建 | `tab-create` |
| close | 关闭 | `tab-close` |
| switch | 切换 | `tab-switch` |
| execute | 执行 | `sql-execute` |
| insert | 插入 | `sql-insert` |
| refresh | 刷新 | `connection-refresh` |

---

## 五、事件参数设计

### 5.1 参数原则

1. **对象格式**：所有事件参数使用对象，不使用多个参数
2. **必要信息**：包含事件处理所需的所有上下文信息
3. **可选字段**：使用可选字段（`?`）标记非必需信息
4. **类型明确**：所有字段都有明确的类型定义

### 5.2 参数示例

```typescript
// ✅ 好的设计：对象格式，类型明确
emit('table-structure', {
  connectionId: 1,
  database: 'test',
  tableName: 'users',
  dbType: 'mysql',
  nodeType: 'table'
})

// ❌ 不好的设计：多个参数，类型不明确
emit('table-structure', 1, 'test', 'users', 'mysql', 'table')
```

---

## 六、事件处理流程

### 6.1 事件触发流程

```
组件内触发事件
    ↓
emit('event-name', data)
    ↓
父组件监听事件
    ↓
调用处理函数
    ↓
更新状态/执行操作
```

### 6.2 事件拦截机制（可选）

```typescript
// 事件拦截器接口
interface EventInterceptor {
  beforeEmit?: (event: string, data: any) => boolean  // 返回false阻止事件
  afterEmit?: (event: string, data: any) => void      // 事件触发后执行
}

// 注册拦截器
eventBus.addInterceptor(interceptor)
```

---

## 七、实现细节

### 7.1 事件类型定义

```typescript
// 事件类型定义文件：types/events.ts
export interface ConnectionSelectEvent {
  connection: DbConnection
  database?: string
}

export interface TableStructureEvent {
  connectionId: number
  database: string
  tableName: string
  dbType: 'mysql' | 'mongo' | 'redis'
  nodeType: 'table' | 'collection' | 'key' | 'database' | 'connection'
}

// ... 其他事件类型
```

### 7.2 组件事件声明

```typescript
// ConnectionTree.vue
const emit = defineEmits<{
  'connection-select': [data: ConnectionSelectEvent]
  'table-structure': [data: TableStructureEvent]
  'table-select': [data: TableSelectEvent]
  // ... 其他事件
}>()
```

### 7.3 事件处理

```typescript
// index.vue
const handleTableStructure = (data: TableStructureEvent) => {
  // 加载表结构
  structureState.loadStructure(
    data.connectionId,
    data.database,
    data.tableName,
    data.dbType
  )
  // 切换到结构Tab
  resultTab.value = 'structure'
}
```

---

## 八、扩展性设计

### 8.1 事件日志（开发模式）

```typescript
// 开发模式下记录所有事件
if (import.meta.env.DEV) {
  eventBus.on('*', (event, data) => {
    console.log(`[Event] ${event}`, data)
  })
}
```

### 8.2 事件统计（可选）

```typescript
// 统计事件触发次数
const eventStats = new Map<string, number>()

eventBus.on('*', (event) => {
  eventStats.set(event, (eventStats.get(event) || 0) + 1)
})
```

---

## 九、实现优先级

### P0（必须实现）
1. ✅ 事件类型定义（TypeScript）
2. ✅ 连接相关事件
3. ✅ 表结构相关事件
4. ✅ SQL执行相关事件

### P1（重要功能）
1. 事件参数验证
2. 事件文档完善
3. 事件处理错误处理

### P2（优化功能）
1. 事件拦截机制
2. 事件日志（开发模式）
3. 事件统计

---

## 十、总结

事件系统设计遵循以下原则：

1. **简洁统一**：统一的事件命名和参数格式
2. **类型安全**：完整的 TypeScript 类型定义
3. **易于扩展**：清晰的事件分类和命名规范
4. **功能强大**：支持事件拦截、日志等高级功能

通过以上设计，可以实现一个简洁、强大、易扩展的事件系统。

