From e193369478b53a2632957d0a8744cf9a19fde139 Mon Sep 17 00:00:00 2001 From: R524809 Date: Mon, 8 Dec 2025 13:43:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:2.4.5=20=E4=BF=AE=E6=94=B9=E9=A6=96?= =?UTF-8?q?=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- miniprogram/app.json | 14 ++-- miniprogram/constants/mathFunctions.ts | 16 ++-- .../numberDecompose/numberDecompose.ts | 83 +++++++++++++++---- .../service/numberDecomposeContentDraw.ts | 33 +++++--- miniprogram/pages/index/index.ts | 4 +- miniprogram/pages/mathIndex/mathIndex.less | 2 +- miniprogram/pages/mathIndex/mathIndex.wxml | 8 +- 7 files changed, 110 insertions(+), 50 deletions(-) diff --git a/miniprogram/app.json b/miniprogram/app.json index 81efe87..6b7a871 100644 --- a/miniprogram/app.json +++ b/miniprogram/app.json @@ -1,8 +1,8 @@ { "pages": [ + "pages/mathIndex/mathIndex", "pages/index/index", "pages/shape/index", - "pages/mathIndex/mathIndex", "pages/copyBook/copyBook", "pages/debug/debug" ], @@ -56,18 +56,18 @@ "selectedColor": "#F5BC00", "backgroundColor": "#fff", "list": [ - { - "pagePath": "pages/index/index", - "iconPath": "assets/tabBar/icon-word.png", - "selectedIconPath": "assets/tabBar/icon-word-active.png", - "text": "识字" - }, { "pagePath": "pages/mathIndex/mathIndex", "iconPath": "assets/tabBar/icon-math.png", "selectedIconPath": "assets/tabBar/icon-math-active.png", "text": "数学" }, + { + "pagePath": "pages/index/index", + "iconPath": "assets/tabBar/icon-word.png", + "selectedIconPath": "assets/tabBar/icon-word-active.png", + "text": "识字" + }, { "pagePath": "pages/shape/index", "iconPath": "assets/tabBar/icon-shape.png", diff --git a/miniprogram/constants/mathFunctions.ts b/miniprogram/constants/mathFunctions.ts index 14ecb9b..d060dcc 100644 --- a/miniprogram/constants/mathFunctions.ts +++ b/miniprogram/constants/mathFunctions.ts @@ -30,13 +30,6 @@ export const MATH_FUNCTION_TYPES: MathFunctionType[] = [ icon: '🎨', }, // 第二阶段:数数与计数 - { - id: 'counting-select', - page: 'countingSelect', - title: '数一数,选一选', - desc: '数出物品数量,圈出正确答案', - icon: '✓', - }, { id: 'counting-matching', page: 'countMatch', @@ -44,6 +37,13 @@ export const MATH_FUNCTION_TYPES: MathFunctionType[] = [ desc: '通过连线配对数字和对应的数量图形', icon: '🔗', }, + { + id: 'counting-select', + page: 'countingSelect', + title: '数一数,选一选', + desc: '数出物品数量,圈出正确答案', + icon: '✓', + }, { id: 'counting-fill', page: 'countingSelect', @@ -70,7 +70,7 @@ export const MATH_FUNCTION_TYPES: MathFunctionType[] = [ id: 'number-decompose', page: 'numberDecompose', title: '10以内数的分与合', - desc: '学习数的分解与组合', + desc: '把数字分一分,合一合', icon: '🔢', }, // 第四阶段:简单运算(从易到难) diff --git a/miniprogram/mathPages/numberDecompose/numberDecompose.ts b/miniprogram/mathPages/numberDecompose/numberDecompose.ts index 2e0775d..57c2811 100644 --- a/miniprogram/mathPages/numberDecompose/numberDecompose.ts +++ b/miniprogram/mathPages/numberDecompose/numberDecompose.ts @@ -106,22 +106,31 @@ Page({ }, /** - * 生成分解数据 + * 生成分解数据(确保不重复) */ generateDecomposeData() { const mode = this.data.currentType; const problems: Array<{ - whole: number; + whole: number | null; part1: number | null; part2: number | null; imageIndex?: number; imageType?: 'fruits' | 'twelve-animals'; }> = []; + // 用于去重的 Set,存储题目唯一标识 + // 格式:对于分解模式 "whole:part1:part2:showPart1",对于组合模式 "part1:part2" + const usedKeys = new Set(); + if (mode === 'with-image') { - // 有图片模式:6个题目,一行两列,总共三行 - const problemCount = 6; - for (let i = 0; i < problemCount; i++) { + // 有图片模式:9个题目,一行三列,总共三行 + const problemCount = 9; + let attempts = 0; + const maxAttempts = problemCount * 50; // 最大尝试次数 + + while (problems.length < problemCount && attempts < maxAttempts) { + attempts++; + // 生成总数(2-10) const whole = Math.floor(Math.random() * 9) + 2; // 随机选择一个部分(1 到 whole-1) @@ -130,11 +139,18 @@ Page({ // 随机决定显示 part1 还是 part2(另一个为 null) const showPart1 = Math.random() < 0.5; - const problem = { - whole, - part1: showPart1 ? part1 : null, - part2: showPart1 ? null : part2, - }; + + // 生成唯一标识(统一格式:part1 <= part2) + const minPart = Math.min(part1, part2); + const maxPart = Math.max(part1, part2); + const key = `${whole}:${minPart}:${maxPart}:${showPart1}`; + + // 检查是否已存在 + if (usedKeys.has(key)) { + continue; + } + + usedKeys.add(key); // 随机选择图片类型和索引 const imageType: 'fruits' | 'twelve-animals' = @@ -144,15 +160,22 @@ Page({ Math.floor(Math.random() * maxImageIndex) + 1; problems.push({ - ...problem, + whole, + part1: showPart1 ? part1 : null, + part2: showPart1 ? null : part2, imageIndex, imageType, }); } } else if (mode === 'decompose') { - // 分模式:12个题目,一行3个,总共4行 + // 分模式:15个题目,一行3个,总共5行 const problemCount = 15; - for (let i = 0; i < problemCount; i++) { + let attempts = 0; + const maxAttempts = problemCount * 50; // 最大尝试次数 + + while (problems.length < problemCount && attempts < maxAttempts) { + attempts++; + // 生成总数(2-10) const whole = Math.floor(Math.random() * 9) + 2; // 随机选择一个部分(1 到 whole-1) @@ -161,6 +184,19 @@ Page({ // 随机决定显示 part1 还是 part2(另一个为 null) const showPart1 = Math.random() < 0.5; + + // 生成唯一标识(统一格式:part1 <= part2) + const minPart = Math.min(part1, part2); + const maxPart = Math.max(part1, part2); + const key = `${whole}:${minPart}:${maxPart}:${showPart1}`; + + // 检查是否已存在 + if (usedKeys.has(key)) { + continue; + } + + usedKeys.add(key); + problems.push({ whole, part1: showPart1 ? part1 : null, @@ -168,15 +204,32 @@ Page({ }); } } else if (mode === 'compose') { - // 组合模式:12个题目,一行3个,总共4行 + // 组合模式:15个题目,一行3个,总共5行 const problemCount = 15; - for (let i = 0; i < problemCount; i++) { + let attempts = 0; + const maxAttempts = problemCount * 50; // 最大尝试次数 + + while (problems.length < problemCount && attempts < maxAttempts) { + attempts++; + // 生成总数(2-10) const whole = Math.floor(Math.random() * 9) + 2; // 随机选择一个部分(1 到 whole-1) const part1 = Math.floor(Math.random() * (whole - 1)) + 1; const part2 = whole - part1; + // 生成唯一标识(统一格式:part1 <= part2) + const minPart = Math.min(part1, part2); + const maxPart = Math.max(part1, part2); + const key = `${minPart}:${maxPart}`; + + // 检查是否已存在 + if (usedKeys.has(key)) { + continue; + } + + usedKeys.add(key); + // 组合模式:两个部分都显示,根节点为 null problems.push({ whole: null, // 根节点需要填写 diff --git a/miniprogram/mathPages/service/numberDecomposeContentDraw.ts b/miniprogram/mathPages/service/numberDecomposeContentDraw.ts index e55f4a3..8e407dd 100644 --- a/miniprogram/mathPages/service/numberDecomposeContentDraw.ts +++ b/miniprogram/mathPages/service/numberDecomposeContentDraw.ts @@ -85,7 +85,7 @@ export async function drawNumberDecomposeContent({ } /** - * 有图片模式:一行两列,总共三行(6个题目) + * 有图片模式:一行三列,总共三行(9个题目) */ async function drawWithImageMode( canvas: WechatMiniprogram.Canvas, @@ -103,21 +103,21 @@ async function drawWithImageMode( const leftMargin = 30; const rightMargin = 30; const topMargin = 20; - const boxSpacing = 40; - const rowSpacing = 40; + const boxSpacing = 20; + const rowSpacing = 32; // 计算每个框的尺寸 const availableWidth = canvasWidth - leftMargin - rightMargin; - const boxWidth = (availableWidth - boxSpacing) / 2; // 2列,1个间距 - const imageAreaHeight = 116; // 图片区域高度 + const boxWidth = (availableWidth - boxSpacing * 2) / 3; // 3列,2个间距 + const imageAreaHeight = 120; // 图片区域高度 const treeAreaHeight = 80; // 二叉树区域高度 let currentY = startY + topMargin; - // 绘制2列3行 + // 绘制3列3行 for (let row = 0; row < 3; row++) { - for (let col = 0; col < 2; col++) { - const problemIndex = row * 2 + col; + for (let col = 0; col < 3; col++) { + const problemIndex = row * 3 + col; if (problemIndex >= problems.length) { continue; } @@ -437,9 +437,10 @@ async function drawImagesInBox( const config = imageConfig[imageType] || imageConfig['twelve-animals']; - const padding = 8; - const availableWidth = boxWidth - padding * 2; - const availableHeight = boxHeight - padding * 2; + const horizontalPadding = 5; + const verticalPadding = 10; + const availableWidth = boxWidth - horizontalPadding * 2; + const availableHeight = boxHeight - verticalPadding * 2; // 根据数量确定每行的图片数和图片大小 let imagesPerRow: number; @@ -479,11 +480,17 @@ async function drawImagesInBox( const col = i % imagesPerRow; const imageX = - boxX + padding + imageSpacing + col * (imageSize + imageSpacing); + boxX + + horizontalPadding + + imageSpacing + + col * (imageSize + imageSpacing); const imageY = boxY + - padding + + verticalPadding + + // 这两段代码是用于计算每一张图片在Y轴方向上的实际位置(imageY 变量) + // 第一行:如果有多于一行,行间用 rowSpacing,否则单行时图片整体垂直居中排列。 (rows > 1 ? rowSpacing : (availableHeight - imageSize) / 2) + + // 第二行:加上具体第 row 行的纵向偏移(每张图片的高度加上行间距,再乘以行号)。 row * (imageSize + (rows > 1 ? rowSpacing : 0)); if (boxImage) { diff --git a/miniprogram/pages/index/index.ts b/miniprogram/pages/index/index.ts index 6ceecae..1ec36aa 100644 --- a/miniprogram/pages/index/index.ts +++ b/miniprogram/pages/index/index.ts @@ -23,7 +23,7 @@ Page({ currentColor: '', showIntroductionPopup: false, showSelectWordPopup: false, // 选择文字弹窗 - selectedTemplate: 'find', // 选中的模板类型 + selectedTemplate: 'grid', // 选中的模板类型 grid 或 find 模式 env: 'release', isPCDevtool: false, showShareDialog: false, // 显示分享引导弹窗 @@ -53,7 +53,7 @@ Page({ { color: '#8A2BE2', word: '您' }, ], selectedWords: ['涂', '鸦', '丫', '欢', '迎', '您'], - showIntroductionPopup: true, + // showIntroductionPopup: true, env: getApp().globalData.env || 'release', }, () => { diff --git a/miniprogram/pages/mathIndex/mathIndex.less b/miniprogram/pages/mathIndex/mathIndex.less index 1f774cc..b175ed8 100644 --- a/miniprogram/pages/mathIndex/mathIndex.less +++ b/miniprogram/pages/mathIndex/mathIndex.less @@ -16,7 +16,7 @@ page { .math-page-header { margin-bottom: 40rpx; text-align: center; - padding-top: 20rpx; + padding-top: 28rpx; } .math-page-title { diff --git a/miniprogram/pages/mathIndex/mathIndex.wxml b/miniprogram/pages/mathIndex/mathIndex.wxml index be7428e..cae7d8a 100644 --- a/miniprogram/pages/mathIndex/mathIndex.wxml +++ b/miniprogram/pages/mathIndex/mathIndex.wxml @@ -1,10 +1,10 @@ - 数学学习涂鸦卡 - 选择功能,生成可打印的数学学习涂鸦卡 + 数感启蒙 + + 选择功能,生成可打印的数感启蒙涂鸦卡 +