import CalculationPracticeDraw from '../shared/service/calculationPracticeDraw'; import { createMathPage, CanvasDataState, } from '../shared/common/mathPageMixin'; type OperationType = 'addition' | 'subtraction' | 'mixed'; createMathPage({ canvas: null as Canvas | null, ctx: null as RenderingContext | null, boxHeight: 0, boxWidth: 0, drawService: null as CalculationPracticeDraw | null, calculationPracticeData: null as { problems: Array<{ left: number; operator: '+' | '-'; right: number; result: number; }>; } | null, data: { pageTitle: '计算练习题', functionId: '', hasContent: false, showShareDialog: false, operationType: 'addition' as OperationType, // 运算类型:加法、减法、混合 currentMode: 'within-10', // 默认10以内 currentModeName: '10以内', typeActions: [ { name: '10以内', value: 'within-10' }, { name: '20以内', value: 'within-20' }, { name: '50以内', value: 'within-50' }, { name: '100以内', value: 'within-100' }, ], } as CanvasDataState & { operationType: OperationType; currentMode: string; currentModeName: string; typeActions: Array<{ name: string; value: string }>; }, onLoad(options: { id?: string; type?: string }) { const functionId = options.id || 'practice-addition'; // 根据 functionId 确定运算类型 let operationType: OperationType = 'addition'; if (functionId === 'practice-subtraction') { operationType = 'subtraction'; } else if (functionId === 'practice-mixed') { operationType = 'mixed'; } else if (options.type) { operationType = options.type as OperationType; } let pageTitle = '计算练习题'; if (operationType === 'addition') { pageTitle = '加法运算'; } else if (operationType === 'subtraction') { pageTitle = '减法运算'; } else if (operationType === 'mixed') { pageTitle = '混合运算'; } this.setData({ operationType, pageTitle, }); this.initPageInfo(functionId, pageTitle); }, onReady() { this.initCanvas({ createDrawService: ( canvas: Canvas, ctx: RenderingContext, options?: Record, ) => { return new CalculationPracticeDraw(canvas, ctx, options); }, drawServiceOptions: {}, onCanvasReady: () => { // 初始随机生成 this.onRandom(); }, }); }, /** * 绘制Canvas内容 */ async drawCanvas() { if (!this.ctx || !this.drawService || !this.calculationPracticeData) { return; } try { await this.drawService.draw(this.calculationPracticeData); this.setData({ hasContent: true }); } catch (error) { console.error('绘制失败:', error); this.setData({ hasContent: false }); } }, /** * 随机生成 */ onRandom() { // 根据当前模式确定最大值 let maxValue = 10; if (this.data.currentMode === 'within-20') { maxValue = 20; } else if (this.data.currentMode === 'within-50') { maxValue = 50; } else if (this.data.currentMode === 'within-100') { maxValue = 100; } const problems: Array<{ left: number; operator: '+' | '-'; right: number; result: number; }> = []; const usedProblems = new Set(); let attempts = 0; const maxAttempts = 2000; const targetCount = 11 * 3; // 12行3列 = 36道题 while (problems.length < targetCount && attempts < maxAttempts) { attempts++; let left: number; let right: number; let operator: '+' | '-'; let result: number; // 根据运算类型生成题目 if (this.data.operationType === 'addition') { // 加法:left + right <= maxValue left = Math.floor(Math.random() * (maxValue - 1)) + 1; // 1 到 maxValue-1 const maxRight = maxValue - left; right = Math.floor(Math.random() * maxRight) + 1; // 1 到 maxRight operator = '+'; result = left + right; } else if (this.data.operationType === 'subtraction') { // 减法:left - right >= 0, left <= maxValue left = Math.floor(Math.random() * maxValue) + 1; // 1 到 maxValue right = Math.floor(Math.random() * left) + 1; // 1 到 left operator = '-'; result = left - right; } else { // 混合运算:随机选择加法或减法 const isAddition = Math.random() < 0.5; if (isAddition) { left = Math.floor(Math.random() * (maxValue - 1)) + 1; const maxRight = maxValue - left; right = Math.floor(Math.random() * maxRight) + 1; operator = '+'; result = left + right; } else { left = Math.floor(Math.random() * maxValue) + 1; right = Math.floor(Math.random() * left) + 1; operator = '-'; result = left - right; } } // 使用 "left,operator,right" 作为唯一标识,避免重复 const problemKey = `${left},${operator},${right}`; if (usedProblems.has(problemKey)) { continue; } usedProblems.add(problemKey); problems.push({ left, operator, right, result, }); } if (problems.length < targetCount) { console.warn( `只生成了 ${problems.length} 道题目,可能符合条件的题目组合不足`, ); } this.calculationPracticeData = { problems }; this.drawCanvas(); }, /** 选择类型 */ onSelectType(event: any) { const { name, value } = event.detail; this.setData({ currentMode: value, currentModeName: name, }); // 重新生成数据 this.onRandom(); }, });