# TemplatePanel Composables

## 概述

这个目录包含了 TemplatePanel 的所有业务逻辑，采用 Vue 3 Composition API 的最佳实践，将视图层和逻辑层分离。

## 架构设计

```
TemplatePanel (视图层)
    ↓ 使用
Composables (逻辑层)
    ↓ 调用
API & Store (数据层)
```

## Composables 列表

### 1. useTemplate.ts
**职责**: 模板的 CRUD 操作和状态管理

**核心功能**:
- 加载模板列表
- 创建新模板
- 预览模板
- 应用模板
- 删除模板

**使用示例**:
```typescript
import { useTemplate } from './composables'

const { 
  templates, 
  isLoading,
  loadTemplates, 
  createTemplate,
  previewTemplate 
} = useTemplate()

// 加载模板
await loadTemplates()

// 创建模板
showCreateDialog.value = true
createForm.value.name = 'My Template'
await createTemplate()

// 预览模板
await previewTemplate('My Template')
```

**导出内容**:
| 名称 | 类型 | 说明 |
|------|------|------|
| `templates` | `Ref` | 模板列表 |
| `isLoading` | `Ref<boolean>` | 加载状态 |
| `selectedTemplate` | `Ref<string \| null>` | 当前选中的模板 |
| `loadTemplates()` | `Function` | 加载模板列表 |
| `createTemplate()` | `Function` | 创建新模板 |
| `previewTemplate(name)` | `Function` | 预览模板 |
| `confirmApply()` | `Function` | 确认应用模板 |
| `deleteTemplate(name)` | `Function` | 删除模板 |

---

### 2. useDirectory.ts
**职责**: 目录浏览、路径导航和文件扫描

**核心功能**:
- 浏览文件系统
- 导航到父目录
- 设置图片/JSON目录
- 扫描文件对

**使用示例**:
```typescript
import { useDirectory } from './composables'

const { 
  currentPath,
  pathInput,
  browsePath,
  setAsImageDir,
  scanFiles 
} = useDirectory()

// 浏览目录
pathInput.value = '/Users/data'
await browsePath(pathInput.value)

// 设置目录
setAsImageDir()
setAsJsonDir()

// 扫描文件
const result = await scanFiles()
```

**导出内容**:
| 名称 | 类型 | 说明 |
|------|------|------|
| `currentPath` | `ComputedRef<string>` | 当前路径 |
| `isBrowsing` | `Ref<boolean>` | 浏览中状态 |
| `pathInput` | `Ref<string>` | 路径输入框值 |
| `browsePath(path)` | `Function` | 浏览指定路径 |
| `goToParent()` | `Function` | 返回上级目录 |
| `setAsImageDir()` | `Function` | 设为图片目录 |
| `setAsJsonDir()` | `Function` | 设为JSON目录 |
| `scanFiles()` | `Function` | 扫描文件对 |

---

### 3. useDataSource.ts
**职责**: 预定义数据源的加载和选择

**核心功能**:
- 加载数据源配置
- 选择数据源
- 自动导航到数据源目录

**使用示例**:
```typescript
import { useDataSource } from './composables'

const { 
  dataSources,
  activeDataSourceName,
  loadDataSources,
  selectDataSource 
} = useDataSource()

// 加载数据源
await loadDataSources()

// 选择数据源
await selectDataSource('流水分析数据源')
```

**导出内容**:
| 名称 | 类型 | 说明 |
|------|------|------|
| `dataSources` | `ComputedRef` | 数据源列表 |
| `hasDataSources` | `ComputedRef<boolean>` | 是否有数据源 |
| `activeDataSource` | `ComputedRef` | 当前激活的数据源 |
| `loadDataSources()` | `Function` | 加载数据源列表 |
| `selectDataSource(name)` | `Function` | 选择数据源 |

---

### 4. useBatchProcess.ts
**职责**: 批量处理的配置、执行和进度跟踪

**核心功能**:
- 配置批量处理选项
- 执行批量处理
- 跟踪处理进度
- 展示处理结果

**使用示例**:
```typescript
import { useBatchProcess } from './composables'

const { 
  batchConfig,
  batchProgress,
  batchProgressPercentage,
  canStartBatch,
  startBatchProcess 
} = useBatchProcess()

// 配置选项
batchConfig.value.parallel = true
batchConfig.value.adjustRows = true

// 开始处理
if (canStartBatch.value) {
  await startBatchProcess()
}

// 监控进度
console.log(`进度: ${batchProgressPercentage.value}%`)
```

**导出内容**:
| 名称 | 类型 | 说明 |
|------|------|------|
| `batchConfig` | `Ref<BatchConfig>` | 批量配置 |
| `batchProgress` | `Ref<BatchProgress>` | 处理进度 |
| `batchResults` | `Ref<BatchResult[]>` | 处理结果 |
| `canStartBatch` | `ComputedRef<boolean>` | 是否可以开始 |
| `batchProgressPercentage` | `ComputedRef<number>` | 进度百分比 |
| `startBatchProcess()` | `Function` | 开始批量处理 |
| `resetBatchState()` | `Function` | 重置状态 |

---

### 5. useFileList.ts
**职责**: 文件对的导航和加载

**核心功能**:
- 文件列表导航
- 跳转到指定文件
- 更新标注状态
- 统计信息

**使用示例**:
```typescript
import { useFileList } from './composables'

const { 
  filePairs,
  currentFilePair,
  currentPairIndex,
  nextPair,
  prevPair,
  getFileStats 
} = useFileList()

// 导航
nextPair()
prevPair()

// 跳转
goToFirstUnlabeled()

// 统计
const stats = getFileStats()
console.log(`完成度: ${stats.percentage}%`)
```

**导出内容**:
| 名称 | 类型 | 说明 |
|------|------|------|
| `filePairs` | `ComputedRef` | 文件对列表 |
| `currentFilePair` | `ComputedRef` | 当前文件对 |
| `currentPairIndex` | `ComputedRef<number>` | 当前索引 |
| `labeledCount` | `ComputedRef<number>` | 已标注数量 |
| `unlabeledCount` | `ComputedRef<number>` | 未标注数量 |
| `nextPair()` | `Function` | 下一个文件 |
| `prevPair()` | `Function` | 上一个文件 |
| `goToPair(index)` | `Function` | 跳转到指定文件 |
| `getFileStats()` | `Function` | 获取统计信息 |

---

## 在 TemplatePanel 中使用

### 完整示例

```vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { 
  useTemplate, 
  useDirectory, 
  useDataSource,
  useBatchProcess,
  useFileList 
} from './template-panel/composables'

// 使用所有 composables
const { 
  templates, 
  loadTemplates, 
  previewTemplate 
} = useTemplate()

const { 
  browsePath, 
  scanFiles 
} = useDirectory()

const { 
  loadDataSources, 
  selectDataSource 
} = useDataSource()

const { 
  startBatchProcess,
  batchProgressPercentage 
} = useBatchProcess()

const { 
  nextPair,
  getCurrentFileParams 
} = useFileList()

// 初始化
onMounted(async () => {
  await loadTemplates()
  await loadDataSources()
  await browsePath('~')
})

// 事件处理
async function handlePreview(name: string) {
  await previewTemplate(name)
}

async function handleScan() {
  await scanFiles()
}

async function handleBatch() {
  await startBatchProcess()
}
</script>
```

## 优势

### ✅ 代码组织
- **关注点分离**: 视图和逻辑完全分离
- **单一职责**: 每个 composable 只负责一个功能域
- **易于维护**: 小文件，清晰的职责边界

### ✅ 可测试性
```typescript
// 单元测试示例
import { useTemplate } from './useTemplate'

describe('useTemplate', () => {
  it('should load templates', async () => {
    const { loadTemplates, templates } = useTemplate()
    await loadTemplates()
    expect(templates.value.length).toBeGreaterThan(0)
  })
})
```

### ✅ 可复用性
```typescript
// 可以在其他组件中复用
import { useDirectory } from '@/components/panels/template-panel/composables'

export default {
  setup() {
    const { browsePath } = useDirectory()
    // 复用目录浏览逻辑
  }
}
```

### ✅ 类型安全
- 完整的 TypeScript 支持
- 自动类型推导
- IDE 智能提示

## 迁移指南

### 从原 TemplatePanel.vue 迁移

**步骤1**: 导入 composables
```typescript
import { useTemplate, useDirectory } from './composables'
```

**步骤2**: 替换原有的 ref/computed/function
```typescript
// 原来
const isLoading = ref(false)
async function loadTemplates() { ... }

// 现在
const { isLoading, loadTemplates } = useTemplate()
```

**步骤3**: 删除原有的业务逻辑
```vue
<script setup lang="ts">
// 删除所有业务逻辑代码
// 只保留 composables 调用和事件处理
</script>
```

**步骤4**: 测试验证
- 确保所有功能正常
- 检查类型提示
- 验证性能

## 最佳实践

### 1. 按需导入
```typescript
// ✅ 好 - 按需导入
import { useTemplate } from './composables'

// ❌ 不好 - 导入全部
import * as composables from './composables'
```

### 2. 解构使用
```typescript
// ✅ 好 - 清晰的依赖
const { loadTemplates, templates } = useTemplate()

// ❌ 不好 - 不透明的依赖
const template = useTemplate()
```

### 3. 命名规范
```typescript
// ✅ 好 - 语义化命名
const { isLoading: isLoadingTemplates } = useTemplate()

// ❌ 不好 - 命名冲突
const { isLoading } = useTemplate()
const { isLoading } = useDirectory() // 冲突！
```

### 4. 错误处理
```typescript
// ✅ 好 - 统一错误处理
const { loadTemplates } = useTemplate()
try {
  await loadTemplates()
} catch (error) {
  // composable 内部已处理，这里可选
}
```

## 性能考虑

- **响应式优化**: 使用 `computed` 而非 `watch`
- **避免过度计算**: 复杂计算使用 `computed` 缓存
- **按需加载**: 只在需要时调用 API
- **批量更新**: 使用 `nextTick` 或批量操作

## 后续计划

### Phase 2: 拆分子组件
- [ ] TemplateList.vue
- [ ] BatchProcessor.vue
- [ ] FileList.vue
- [ ] DirectoryBrowser.vue

### Phase 3: 完全模块化
- [ ] 独立的子组件树
- [ ] 组件间通信优化
- [ ] 性能优化

## 贡献指南

添加新 composable 时：
1. 创建新文件 `useXxx.ts`
2. 遵循现有命名规范
3. 添加完整的 JSDoc 注释
4. 导出到 `index.ts`
5. 更新此 README

---

**最后更新**: 2025-12-08
**维护者**: GitHub Copilot
**版本**: 1.0.0
