247 lines
6.3 KiB
Markdown
247 lines
6.3 KiB
Markdown
# useCleaner 重构说明
|
||
|
||
本文档记录 `src/renderer/src/hooks/useCleaner.ts` 的第一阶段重构工作。目标不是一次性把整个 Cleaner 页面完全组件化,而是优先拆出共享类型、纯函数和 IPC 编排逻辑,让 `useCleaner` 从“大而全逻辑容器”逐步收敛为“组合层”。
|
||
|
||
## 1. 重构背景
|
||
|
||
重构前,`useCleaner.ts` 同时负责:
|
||
|
||
- 页面初始化
|
||
- 权限判断
|
||
- sessionStorage 持久化
|
||
- 校验请求
|
||
- 结果筛选
|
||
- 勾选状态处理
|
||
- 删除计划构建
|
||
- 保存物料变更
|
||
- Cleaner 执行编排
|
||
- 导出编排
|
||
- 弹窗确认
|
||
- 报告状态维护
|
||
|
||
这导致它虽然名义上是一个 hook,但实际上已经接近一个“前端页面服务总线”。
|
||
|
||
## 2. 重构目标
|
||
|
||
本次重构目标是:
|
||
|
||
- 提取共享类型,消除重复定义
|
||
- 提取纯函数,隔离无副作用逻辑
|
||
- 提取 IPC / 异步编排,隔离对 `window.electron` 的直接调用
|
||
- 保持 `useCleaner()` 返回值和 `CleanerPage.tsx` 使用方式不变
|
||
|
||
## 3. 重构后结构
|
||
|
||
```mermaid
|
||
graph TD
|
||
Page[CleanerPage.tsx]
|
||
Hook[useCleaner.ts]
|
||
|
||
subgraph CleanerHookModules[Cleaner Hook Modules]
|
||
Types[hooks/cleaner/types.ts]
|
||
Helpers[hooks/cleaner/helpers.ts]
|
||
Api[hooks/cleaner/api.ts]
|
||
end
|
||
|
||
subgraph ExternalDeps[External Dependencies]
|
||
Electron[window.electron]
|
||
Store[useAppStore / Toast]
|
||
Dialog[ConfirmDialog]
|
||
end
|
||
|
||
Page --> Hook
|
||
Hook --> Types
|
||
Hook --> Helpers
|
||
Hook --> Api
|
||
Hook --> Store
|
||
Hook --> Dialog
|
||
Api --> Electron
|
||
```
|
||
|
||
## 4. 本次拆分内容
|
||
|
||
### 4.1 共享类型
|
||
|
||
新增:
|
||
|
||
- `src/renderer/src/hooks/cleaner/types.ts`
|
||
|
||
统一收敛了以下类型:
|
||
|
||
- `ValidationRequest`
|
||
- `ValidationResult`
|
||
- `ValidationStats`
|
||
- `ValidationResponsePayload`
|
||
- `CleanerProgress`
|
||
- `CleanerReportData`
|
||
- `CleanerInitializationResult`
|
||
- `CleanerConfigResult`
|
||
|
||
这一步解决了原来多个文件重复定义同类类型的问题,比如:
|
||
|
||
- `useCleaner.ts`
|
||
- `useValidation.ts`
|
||
- `ExecutionReportDialog.tsx`
|
||
|
||
### 4.2 纯函数与数据构造
|
||
|
||
新增:
|
||
|
||
- `src/renderer/src/hooks/cleaner/helpers.ts`
|
||
|
||
提取出的纯函数包括:
|
||
|
||
- `getStoredBoolean()`
|
||
- `getStoredValidationMode()`
|
||
- `filterValidationResults()`
|
||
- `buildDeletionPlan()`
|
||
- `buildExportItems()`
|
||
|
||
这些逻辑之前都散落在 `useCleaner.ts` 的 `useMemo` 或事件处理函数里,现在可以单独测试。
|
||
|
||
### 4.3 IPC 与异步编排
|
||
|
||
新增:
|
||
|
||
- `src/renderer/src/hooks/cleaner/api.ts`
|
||
|
||
提取出的异步编排包括:
|
||
|
||
- `initializeCleanerPage()`
|
||
- `loadCleanerConfig()`
|
||
- `runValidationRequest()`
|
||
- `saveDeletionPlan()`
|
||
- `reloadManagers()`
|
||
- `runCleanerExecution()`
|
||
- `exportCleanerResults()`
|
||
|
||
这样做之后,`useCleaner.ts` 不再需要在每个 handler 里直接拼接 `window.electron.xxx` 调用细节。
|
||
|
||
## 5. useCleaner 的角色变化
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph Before[重构前]
|
||
A[useCleaner.ts]
|
||
A --> A1[本地状态]
|
||
A --> A2[筛选逻辑]
|
||
A --> A3[删除计划构建]
|
||
A --> A4[执行清理请求]
|
||
A --> A5[导出请求]
|
||
A --> A6[初始化请求]
|
||
A --> A7[共享类型定义]
|
||
end
|
||
|
||
subgraph After[重构后]
|
||
B[useCleaner.ts]
|
||
B --> B1[组合状态]
|
||
B --> B2[调用 helpers]
|
||
B --> B3[调用 api]
|
||
|
||
C[helpers.ts]
|
||
D[api.ts]
|
||
E[types.ts]
|
||
|
||
B --> C
|
||
B --> D
|
||
B --> E
|
||
end
|
||
```
|
||
|
||
重构后,`useCleaner.ts` 更接近“组合层”:
|
||
|
||
- 管理 React state
|
||
- 串联用户交互流程
|
||
- 调用 helpers 和 api
|
||
- 将最终能力暴露给页面
|
||
|
||
## 6. 受影响的文件
|
||
|
||
### 6.1 主体修改
|
||
|
||
- `src/renderer/src/hooks/useCleaner.ts`
|
||
- `src/renderer/src/hooks/useValidation.ts`
|
||
- `src/renderer/src/components/ExecutionReportDialog.tsx`
|
||
|
||
### 6.2 新增模块
|
||
|
||
- `src/renderer/src/hooks/cleaner/types.ts`
|
||
- `src/renderer/src/hooks/cleaner/helpers.ts`
|
||
- `src/renderer/src/hooks/cleaner/api.ts`
|
||
|
||
### 6.3 新增测试
|
||
|
||
- `tests/unit/cleaner-helpers.test.ts`
|
||
|
||
## 7. 具体收益
|
||
|
||
### 7.1 类型一致性提升
|
||
|
||
之前 `ValidationResult`、`CleanerProgress` 在多个文件重复定义,修改字段时容易遗漏。
|
||
现在统一从 `hooks/cleaner/types.ts` 引用,降低了类型漂移风险。
|
||
|
||
### 7.2 可测试性提升
|
||
|
||
原先删除计划构建、筛选和导出映射逻辑只能通过 hook 间接覆盖。
|
||
现在这些逻辑已经被抽成纯函数,可以直接做单测。
|
||
|
||
### 7.3 Hook 复杂度下降
|
||
|
||
虽然 `useCleaner.ts` 还没有变成一个很小的文件,但其中的“细节密度”已经明显下降:
|
||
|
||
- 数据变换逻辑外提
|
||
- API 编排逻辑外提
|
||
- 重复类型移除
|
||
|
||
### 7.4 为下一步组件拆分做准备
|
||
|
||
后续如果要拆 `CleanerPage.tsx`:
|
||
|
||
- 左侧筛选区
|
||
- 表格工具栏
|
||
- 底部执行区
|
||
|
||
这些组件就可以直接消费已经整理好的 hook 能力,而不是继续把逻辑往页面里塞。
|
||
|
||
## 8. 验证方式
|
||
|
||
本次重构后执行了以下验证:
|
||
|
||
- `npm run typecheck:node`
|
||
- `tests/unit/cleaner-helpers.test.ts`
|
||
- `tests/unit/cleaner.test.ts`
|
||
|
||
## 9. 新增测试覆盖点
|
||
|
||
`tests/unit/cleaner-helpers.test.ts` 覆盖了:
|
||
|
||
- 非管理员筛选逻辑
|
||
- 删除计划构建逻辑
|
||
- 导出数据构建逻辑
|
||
|
||
## 10. 仍然保留在 useCleaner 中的内容
|
||
|
||
为了控制改动风险,这次没有继续下沉以下能力:
|
||
|
||
- `ConfirmDialog` 的 Promise 封装
|
||
- 编辑状态 `editingCell / editValue`
|
||
- `isRunning / isExecuting / isReportDialogOpen` 等 UI 状态
|
||
- 页面层直接依赖的完整返回对象
|
||
|
||
这些能力仍然保留在 `useCleaner.ts`,因为它们和当前页面交互绑定较深。
|
||
|
||
## 11. 下一步建议
|
||
|
||
基于目前的结构,建议下一阶段继续做:
|
||
|
||
1. 拆 `CleanerPage.tsx` 为“左侧筛选区”和“右侧结果与执行区”两个子组件。
|
||
2. 将 `showConfirmDialog()` 封装为独立 hook,例如 `useConfirmDialogController()`。
|
||
3. 将 inline edit 相关逻辑提取到更专门的 manager-assignment controller。
|
||
4. 视情况把 Cleaner 相关状态进一步收敛到专门 store 或 domain hook 中。
|
||
|
||
## 12. 总结
|
||
|
||
这次 `useCleaner` 重构的核心价值,不是“让文件立刻变得很小”,而是先把最容易复用、最适合测试、最不应继续堆在 hook 里的部分拆出来。
|
||
|
||
它为接下来的页面组件拆分提供了一个更稳的基础,也让 Cleaner 模块开始从“页面驱动逻辑”向“模块化前端能力”转变。
|