Files
doodle-mini/miniprogram/service/REFACTOR_SUMMARY.md
T
2025-12-11 13:02:44 +08:00

6.3 KiB
Raw Blame History

绘制服务重构总结

重构目标

基于 baseDraw.tsbaseHeaderDraw.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)

提供以下公共功能:

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() 方法,通常包含以下步骤:

    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    # ❌ 已删除

使用示例

创建新的绘制服务

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 命名,接收参数包括 canvasctx、数据、canvasWidthstartY
  2. 坐标管理:使用 this.currentY 管理垂直坐标,ContentDraw 函数需要更新该值
  3. Header 类型:通过 this.headerType 判断使用完整 Header 还是迷你 Header
  4. 逻辑像素:所有尺寸都已除以 3,使用逻辑像素

后续优化建议

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