# 绘制服务重构总结

## 重构目标

基于 `baseDraw.ts` 和 `baseHeaderDraw.ts` 统一所有绘制服务的公共部分，提取并统一 Header 绘制功能。

## 完成的工作

### 1. ✅ 统一基础服务类

所有绘制服务现在都继承自 `BaseDrawService`（位于 `service/baseDraw.ts`）：

- ✅ `AdditionDraw` - 加减法计算
- ✅ `CompareDraw` - 数一数比大小
- ✅ `CountMatchDraw` - 数一数连一连
- ✅ `CountingSelectDraw` - 数一数选一选/填一填
- ✅ `MissingNumberDraw` - 填上缺少的数字
- ✅ `NumberColorDraw` - 按数字涂颜色
- ✅ `NumberDecomposeDraw` - 10以内数的分与合
- ✅ `NumberFindDraw` - 数字涂色（找数字、写数字）

### 2. ✅ 统一 Header 绘制

所有服务使用统一的 Header 绘制功能（位于 `service/baseHeaderDraw.ts`）：

- `drawBaseHeader()` - 完整 Header（包含 Logo、应用名称、标题、副标题）
- `drawBaseMiniHeader()` - 迷你 Header（简化版本）

### 3. ✅ 修复相关导入

- ✅ 修复 `base/pageMixin.ts` 中的导入路径
    - 从 `../mathPages/service/baseMathDraw` 改为 `../service/baseDraw`

### 4. ✅ 清理旧文件

- ✅ 删除 `mathPages/shared/service/baseMathDraw.ts`（已被 `BaseDrawService` 替代）
- ✅ 删除 `mathPages/shared/service/mathHeaderDraw.ts`（已被 `baseHeaderDraw.ts` 替代）

## 架构设计

### 基础服务类 (`BaseDrawService`)

提供以下公共功能：

```typescript
class BaseDrawService {
    // Canvas 和上下文
    canvas: Canvas;
    ctx: RenderingContext;

    // 配置
    options: Record<string, any>;
    paperSize: PaperSize;
    headerType: PrintHeader;

    // 坐标管理
    currentX: number;
    currentY: number;
    canvasWidth: number;
    canvasHeight: number;

    // 公共方法
    setPrintConfig(); // 设置打印配置
    setPaper(); // 设置 Paper 尺寸
    clear(); // 清除画布
    drawHeader(); // 绘制完整 Header
    drawMiniHeader(); // 绘制迷你 Header
    drawDivider(); // 绘制分割线
}
```

### Header 绘制 (`baseHeaderDraw.ts`)

提供统一的 Header 绘制函数：

- `drawBaseHeader()` - 支持多种 Header 类型：

    - `wechat` - 微信小程序码（默认）
    - `LogoImage` - Logo 图片
    - `noLogoImage` - 无 Logo
    - `minimal` - 极简模式

- `drawBaseMiniHeader()` - 迷你版本，居中显示

### 具体服务类

每个具体服务类：

1. **继承 `BaseDrawService`**
2. **实现 `draw()` 方法**，通常包含以下步骤：

    ```typescript
    async draw(data: any) {
        // 1. 设置配置
        this.setPrintConfig();

        // 2. 清除并设置 Paper
        this.clear();
        this.setPaper();

        // 3. 绘制 Header
        if (this.headerType !== 'minimal') {
            await this.drawHeader();
        } else {
            this.drawMiniHeader();
        }

        // 4. 绘制分割线
        this.drawDivider();

        // 5. 绘制内容（调用 ContentDraw 函数）
        await drawXXXContent({
            canvas: this.canvas,
            ctx: this.ctx,
            data: data,
            canvasWidth: this.canvasWidth,
            startY: this.currentY,
        });
    }
    ```

3. **使用 ContentDraw 函数**绘制具体内容（例如 `drawAdditionContent`）

## 文件结构

```
service/
├── baseDraw.ts              # 基础绘制服务类 ✅
├── baseHeaderDraw.ts        # Header 绘制函数 ✅
└── ...

mathPages/shared/service/
├── additionDraw.ts          # 加减法绘制服务 ✅
├── compareDraw.ts           # 比较绘制服务 ✅
├── countMatchDraw.ts        # 连线绘制服务 ✅
├── countingSelectDraw.ts    # 选择绘制服务 ✅
├── missingNumberDraw.ts     # 缺失数字绘制服务 ✅
├── numberColorDraw.ts       # 数字涂色绘制服务 ✅
├── numberDecomposeDraw.ts   # 分解绘制服务 ✅
├── numberFindDraw.ts        # 数字查找绘制服务 ✅
├── additionContentDraw.ts   # 加减法内容绘制
├── compareContentDraw.ts    # 比较内容绘制
├── ...                      # 其他 ContentDraw 函数
└── (已删除)
    ├── baseMathDraw.ts      # ❌ 已删除
    └── mathHeaderDraw.ts    # ❌ 已删除
```

## 使用示例

### 创建新的绘制服务

```typescript
import { BaseDrawService } from '../../../service/baseDraw';
import { drawMyContent } from './myContentDraw';

class MyDraw extends BaseDrawService {
    myData: any;

    constructor(
        canvas: Canvas,
        ctx: RenderingContext,
        options?: Record<string, any>,
    ) {
        super(canvas, ctx, options);
        this.myData = null;
    }

    async draw(myData: any) {
        if (!myData) return;

        this.setPrintConfig();
        this.myData = myData;
        this.clear();
        this.setPaper();

        // 绘制 Header
        if (this.headerType !== 'minimal') {
            await this.drawHeader();
        } else {
            this.drawMiniHeader();
        }

        // 绘制内容
        this.drawDivider();
        await drawMyContent({
            canvas: this.canvas,
            ctx: this.ctx,
            data: this.myData,
            canvasWidth: this.canvasWidth,
            startY: this.currentY,
        });
    }
}

export default MyDraw;
```

## 优势

1. ✅ **代码复用**：公共逻辑集中在基类中
2. ✅ **统一 Header**：所有服务使用相同的 Header 绘制逻辑
3. ✅ **易于维护**：修改 Header 只需修改一个地方
4. ✅ **类型安全**：TypeScript 类型支持完整
5. ✅ **扩展性好**：新增服务只需继承基类并实现 `draw()` 方法

## 注意事项

1. **ContentDraw 函数**：具体内容绘制函数通常以 `drawXXXContent` 命名，接收参数包括 `canvas`、`ctx`、数据、`canvasWidth`、`startY` 等
2. **坐标管理**：使用 `this.currentY` 管理垂直坐标，ContentDraw 函数需要更新该值
3. **Header 类型**：通过 `this.headerType` 判断使用完整 Header 还是迷你 Header
4. **逻辑像素**：所有尺寸都已除以 3，使用逻辑像素

## 后续优化建议

1. 考虑将 ContentDraw 函数也提取到 `service/` 目录下的统一位置
2. 可以考虑创建更多的基础绘制工具函数（如绘制表格、绘制网格等）
3. 可以考虑支持更多 Paper 尺寸（目前仅支持 A4）
