From a6e8f4df02076505b8d24bc9767296cf6b55e7f2 Mon Sep 17 00:00:00 2001 From: R524809 Date: Fri, 29 May 2026 10:21:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=8E=A7=E7=AC=94?= =?UTF-8?q?=E7=BB=83=E4=B9=A0=EF=BC=8C=E5=A2=9E=E5=8A=A0=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E5=85=AC=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- miniprogram/app.json | 3 +- .../penControlSheet/penControlSheet.config.ts | 31 +- .../wordColoring/wordColoring.config.ts | 60 +--- miniprogram/config/config.ts | 6 + miniprogram/config/worksheets/focus.ts | 124 ++++++++ miniprogram/config/worksheets/index.ts | 7 + .../config/worksheets/letterTracing.ts | 81 +++++ miniprogram/config/worksheets/math.ts | 264 +++++++++++++++++ miniprogram/config/worksheets/penControl.ts | 15 + miniprogram/config/worksheets/pinyin.ts | 59 ++++ miniprogram/config/worksheets/types.ts | 13 + miniprogram/config/worksheets/wordColoring.ts | 26 ++ .../letterTracing/letterTracing.config.ts | 95 +----- .../focusPages/focusDraw/focusDraw.config.ts | 136 +-------- .../mathPages/mathDraw/mathDraw.config.ts | 277 +----------------- miniprogram/pages/home/home.data.ts | 21 ++ miniprogram/pages/home/home.less | 86 ++++++ miniprogram/pages/home/home.ts | 8 + miniprogram/pages/home/home.wxml | 37 +++ miniprogram/pages/profile/profile.ts | 3 +- .../pinyinDictation/pinyinDictation.config.ts | 74 +---- miniprogram/supportPages/debug/debug.ts | 7 + .../unreleasedDebug/unreleasedDebug.config.ts | 16 + .../unreleasedDebug/unreleasedDebug.json | 6 + .../unreleasedDebug/unreleasedDebug.less | 136 +++++++++ .../unreleasedDebug/unreleasedDebug.ts | 33 +++ .../unreleasedDebug/unreleasedDebug.wxml | 41 +++ .../worksheetSync/worksheetSync.ts | 52 ++-- 28 files changed, 1045 insertions(+), 672 deletions(-) create mode 100644 miniprogram/config/worksheets/focus.ts create mode 100644 miniprogram/config/worksheets/index.ts create mode 100644 miniprogram/config/worksheets/letterTracing.ts create mode 100644 miniprogram/config/worksheets/math.ts create mode 100644 miniprogram/config/worksheets/penControl.ts create mode 100644 miniprogram/config/worksheets/pinyin.ts create mode 100644 miniprogram/config/worksheets/types.ts create mode 100644 miniprogram/config/worksheets/wordColoring.ts create mode 100644 miniprogram/supportPages/unreleasedDebug/unreleasedDebug.config.ts create mode 100644 miniprogram/supportPages/unreleasedDebug/unreleasedDebug.json create mode 100644 miniprogram/supportPages/unreleasedDebug/unreleasedDebug.less create mode 100644 miniprogram/supportPages/unreleasedDebug/unreleasedDebug.ts create mode 100644 miniprogram/supportPages/unreleasedDebug/unreleasedDebug.wxml diff --git a/miniprogram/app.json b/miniprogram/app.json index a4f16c1..a487690 100644 --- a/miniprogram/app.json +++ b/miniprogram/app.json @@ -19,7 +19,8 @@ "homeContentManage/homeContentManage", "mathIndex/mathIndex", "focusIndex/focusIndex", - "worksheetSync/worksheetSync" + "worksheetSync/worksheetSync", + "unreleasedDebug/unreleasedDebug" ], "independent": false }, diff --git a/miniprogram/chinesePages/penControlSheet/penControlSheet.config.ts b/miniprogram/chinesePages/penControlSheet/penControlSheet.config.ts index 9b87340..ee63eb7 100644 --- a/miniprogram/chinesePages/penControlSheet/penControlSheet.config.ts +++ b/miniprogram/chinesePages/penControlSheet/penControlSheet.config.ts @@ -1,34 +1,9 @@ import type { DebugPublishMeta } from '../../utils/debugPublish'; import { inferGradeFromAge } from '../../utils/debugPublish'; -import { PEN_CONTROL_MODE } from './generators/penControlGenerator'; +import { PEN_CONTROL_WORKSHEET_DEFINITIONS } from '../../config/worksheets/penControl'; -interface PenControlWorksheetDefinition { - id: typeof PEN_CONTROL_MODE; - icon: string; - title: string; - subtitle: string; - ageMin: number; - ageMax: number; - difficulty: 1 | 2 | 3 | 4; - tags: string[]; - sortOrder: number; -} - -export const PEN_CONTROL_WORKSHEET_DEFINITIONS = [ - { - id: PEN_CONTROL_MODE, - icon: 'edit', - title: '控笔组合练习', - subtitle: '3–6 种图形,每种占两行田字格', - ageMin: 3, - ageMax: 6, - difficulty: 1, - tags: ['控笔', '运笔', '田字格', '学前'], - sortOrder: 40, - }, -] as const satisfies ReadonlyArray; - -type PenControlWorksheetRow = (typeof PEN_CONTROL_WORKSHEET_DEFINITIONS)[number]; +type PenControlWorksheetRow = + (typeof PEN_CONTROL_WORKSHEET_DEFINITIONS)[number]; const WORKSHEET_BY_ID = Object.fromEntries( PEN_CONTROL_WORKSHEET_DEFINITIONS.map((m) => [m.id, m]), diff --git a/miniprogram/chinesePages/wordColoring/wordColoring.config.ts b/miniprogram/chinesePages/wordColoring/wordColoring.config.ts index 7f91438..598e7f2 100644 --- a/miniprogram/chinesePages/wordColoring/wordColoring.config.ts +++ b/miniprogram/chinesePages/wordColoring/wordColoring.config.ts @@ -1,78 +1,44 @@ import type { DebugPublishMeta } from '../../utils/debugPublish'; import { inferGradeFromAge } from '../../utils/debugPublish'; -import type { TemplateType } from '../shared/draw/drawServiceFactory'; +import type { TemplateType } from './draw/drawServiceFactory'; +import { WORD_COLORING_WORKSHEET_DEFINITIONS } from '../../config/worksheets/wordColoring'; -/** 本地 worksheet 元数据(与云库 `worksheets` 文档 `_id` 对齐) */ -interface WordColoringWorksheetDefinition { - id: string; - templateType: TemplateType; - icon: string; - title: string; - subtitle: string; - ageMin: number; - ageMax: number; - difficulty: 1 | 2 | 3 | 4; - tags: string[]; - sortOrder: number; -} - -export const WORD_COLORING_WORKSHEET_DEFINITIONS = [ - { - id: 'word-coloring-grid', - templateType: 'grid' as TemplateType, - icon: 'grid', - title: '网格涂色', - subtitle: '田字格涂色识字练习', - ageMin: 3, - ageMax: 6, - difficulty: 1, - tags: ['识字', '涂色', '田字格'], - sortOrder: 30, - }, - { - id: 'word-coloring-find', - templateType: 'find' as TemplateType, - icon: 'search', - title: '找字涂色', - subtitle: '在字海中找到目标字并涂色', - ageMin: 3, - ageMax: 6, - difficulty: 1, - tags: ['识字', '涂色', '找字'], - sortOrder: 31, - }, -] as const satisfies ReadonlyArray; +export { WORD_COLORING_WORKSHEET_DEFINITIONS }; type WordColoringWorksheetRow = (typeof WORD_COLORING_WORKSHEET_DEFINITIONS)[number]; -const WORD_COLORING_WORKSHEET_BY_ID = Object.fromEntries( +const WORKSHEET_BY_ID = Object.fromEntries( WORD_COLORING_WORKSHEET_DEFINITIONS.map((m) => [m.id, m]), ) as Record; /** 页面渲染用:模式选择器列表 */ export const WORD_COLORING_MODE_OPTIONS = WORD_COLORING_WORKSHEET_DEFINITIONS; +const WORD_COLORING_TEMPLATE_TYPES: Record = { + 'word-coloring-grid': 'grid', + 'word-coloring-find': 'find', +}; + /** 页面 pageInfoLookup 用 */ export function getModeInfo(id: string) { - const m = WORD_COLORING_WORKSHEET_BY_ID[id]; + const m = WORKSHEET_BY_ID[id]; return m ? { title: m.title, desc: m.subtitle } : undefined; } /** 判断 id 是否有效 */ export function isValidMode(id: string): boolean { - return id in WORD_COLORING_WORKSHEET_BY_ID; + return id in WORKSHEET_BY_ID; } /** 根据 id 获取 templateType */ export function getTemplateType(id: string): TemplateType { - const m = WORD_COLORING_WORKSHEET_BY_ID[id]; - return m?.templateType || 'grid'; + return WORD_COLORING_TEMPLATE_TYPES[id] || 'grid'; } /** 发布用:从当前 mode 生成 DebugPublishMeta */ export function getPublishMetaByMode(id: string): DebugPublishMeta | null { - const m = WORD_COLORING_WORKSHEET_BY_ID[id]; + const m = WORKSHEET_BY_ID[id]; if (!m) return null; return { id: m.id, diff --git a/miniprogram/config/config.ts b/miniprogram/config/config.ts index 1f03e9b..74b8633 100644 --- a/miniprogram/config/config.ts +++ b/miniprogram/config/config.ts @@ -6,6 +6,12 @@ // }, // }; +/** 当前应用版本号;profile 页和首页公告共用 */ +export const APP_VERSION = '3.0.1'; + +/** 当前版本的更新摘要,用于首页公告;改版本时一起改 */ +export const APP_VERSION_NOTE = '新增控笔练习'; + export const defaultPrintConfig: PrintConfig = { // header: 'LogoImage', header: 'wechat', diff --git a/miniprogram/config/worksheets/focus.ts b/miniprogram/config/worksheets/focus.ts new file mode 100644 index 0000000..abfabb3 --- /dev/null +++ b/miniprogram/config/worksheets/focus.ts @@ -0,0 +1,124 @@ +import type { WorksheetDefinition } from './types'; + +export const FOCUS_WORKSHEET_DEFINITIONS = [ + { + id: 'color-shape-match', + title: '根据颜色画图形', + subtitle: '根据颜色画出对应图形', + ageMin: 4, + ageMax: 6, + difficulty: 2, + tags: ['专注力', '颜色', '图形'], + sortOrder: 201, + }, + { + id: 'shape-symbol', + title: '图形符号配对', + subtitle: '根据图形画对应符号', + ageMin: 4, + ageMax: 6, + difficulty: 2, + tags: ['专注力', '图形', '符号'], + sortOrder: 202, + }, + { + id: 'position-coloring', + title: '方位涂涂乐', + subtitle: '观察位置,在方格中涂色', + ageMin: 4, + ageMax: 6, + difficulty: 2, + tags: ['专注力', '方位', '涂色'], + sortOrder: 203, + }, + { + id: 'color-pattern', + title: '颜色找规律', + subtitle: '观察颜色规律,涂色', + ageMin: 4, + ageMax: 6, + difficulty: 2, + tags: ['专注力', '颜色', '规律'], + sortOrder: 204, + }, + { + id: 'match-connect', + title: '连连看', + subtitle: '根据物品连一连', + ageMin: 3, + ageMax: 6, + difficulty: 1, + tags: ['专注力', '连线', '匹配'], + sortOrder: 205, + }, + { + id: 'line-recognition', + title: '线条识别', + subtitle: '认识不同线条,画对应线条', + ageMin: 3, + ageMax: 6, + difficulty: 1, + tags: ['专注力', '线条', '识别', '控笔'], + sortOrder: 206, + }, + { + id: 'grid-reasoning', + title: '方格推理', + subtitle: '推理出合并方格并连线', + ageMin: 5, + ageMax: 7, + difficulty: 3, + tags: ['专注力', '方格', '推理', '逻辑思维'], + sortOrder: 207, + }, + { + id: 'code-connect', + title: '译码连线', + subtitle: '按数字顺序连线', + ageMin: 5, + ageMax: 7, + difficulty: 3, + tags: ['专注力', '译码', '连线', '逻辑思维'], + sortOrder: 208, + }, + { + id: 'dot-connect', + title: '数字点连线', + subtitle: '按数字顺序连点成图', + ageMin: 4, + ageMax: 6, + difficulty: 1, + tags: ['专注力', '数字', '连线'], + sortOrder: 209, + }, + { + id: 'grid-drawing-3x3', + title: '格子仿画 3×3', + subtitle: '简单有趣,培养专注力', + ageMin: 3, + ageMax: 5, + difficulty: 1, + tags: ['专注力', '格子仿画', '观察'], + sortOrder: 210, + }, + { + id: 'grid-drawing-5x5', + title: '格子仿画 5×5', + subtitle: '创意挑战,提升观察力', + ageMin: 4, + ageMax: 6, + difficulty: 2, + tags: ['专注力', '格子仿画', '观察'], + sortOrder: 211, + }, + { + id: 'grid-drawing-7x7', + title: '格子仿画 7×7', + subtitle: '大师挑战,锻炼耐心', + ageMin: 6, + ageMax: 8, + difficulty: 3, + tags: ['专注力', '格子仿画', '耐心'], + sortOrder: 212, + }, +] as const satisfies ReadonlyArray; diff --git a/miniprogram/config/worksheets/index.ts b/miniprogram/config/worksheets/index.ts new file mode 100644 index 0000000..544b5d8 --- /dev/null +++ b/miniprogram/config/worksheets/index.ts @@ -0,0 +1,7 @@ +export type { WorksheetDefinition } from './types'; +export { MATH_WORKSHEET_DEFINITIONS } from './math'; +export { FOCUS_WORKSHEET_DEFINITIONS } from './focus'; +export { LETTER_TRACING_WORKSHEET_DEFINITIONS } from './letterTracing'; +export { PINYIN_DICTATION_WORKSHEET_DEFINITIONS } from './pinyin'; +export { PEN_CONTROL_WORKSHEET_DEFINITIONS } from './penControl'; +export { WORD_COLORING_WORKSHEET_DEFINITIONS } from './wordColoring'; diff --git a/miniprogram/config/worksheets/letterTracing.ts b/miniprogram/config/worksheets/letterTracing.ts new file mode 100644 index 0000000..1f4e073 --- /dev/null +++ b/miniprogram/config/worksheets/letterTracing.ts @@ -0,0 +1,81 @@ +import type { WorksheetDefinition } from './types'; + +export const LETTER_TRACING_WORKSHEET_DEFINITIONS = [ + { + id: 'letter-tracing-single', + icon: 'start-a', + title: '字母默认字帖', + subtitle: '配图、例句与描红', + ageMin: 4, + ageMax: 7, + difficulty: 1, + tags: ['字母', '描红', '看图描红'], + sortOrder: 42, + }, + { + id: 'letter-tracing-upper-lower', + icon: 'draw-o', + title: '字母基础描红', + subtitle: 'Uppercase / Lowercase 总览', + ageMin: 5, + ageMax: 7, + difficulty: 1, + tags: ['字母', '描红', '字母总览'], + sortOrder: 44, + }, + { + id: 'letter-tracing-case-pairing', + icon: 'font-size', + title: '大小写对照', + subtitle: '半组字母左大写右小写', + ageMin: 5, + ageMax: 7, + difficulty: 1, + tags: ['字母', '描红', '大小写练习'], + sortOrder: 45, + }, + { + id: 'letter-tracing-two-column', + icon: 'two-columns', + title: '两列描红', + subtitle: '左 A–M、右 N–Z 配对描红', + ageMin: 5, + ageMax: 7, + difficulty: 1, + tags: ['字母', '描红', '两列练习'], + sortOrder: 43, + }, + { + id: 'letter-tracing-half', + icon: 'square-half', + title: '13字母半表', + subtitle: '每行一个字母,13 字母半表', + ageMin: 5, + ageMax: 8, + difficulty: 2, + tags: ['字母', '描红', '半表练习'], + sortOrder: 47, + }, + { + id: 'letter-tracing-three', + icon: 'ABC-list', + title: '三字母精练', + subtitle: '每页聚焦 3 个字母深度书写', + ageMin: 5, + ageMax: 7, + difficulty: 2, + tags: ['字母', '描红', '三字母精练'], + sortOrder: 46, + }, + { + id: 'letter-tracing-daily-checkin', + icon: 'task-o', + title: '字母每日打卡', + subtitle: '四宫格每日字母打卡练习', + ageMin: 5, + ageMax: 7, + difficulty: 2, + tags: ['字母', '描红', '每日打卡'], + sortOrder: 48, + }, +] as const satisfies ReadonlyArray; diff --git a/miniprogram/config/worksheets/math.ts b/miniprogram/config/worksheets/math.ts new file mode 100644 index 0000000..cd58666 --- /dev/null +++ b/miniprogram/config/worksheets/math.ts @@ -0,0 +1,264 @@ +import type { WorksheetDefinition } from './types'; + +export const MATH_WORKSHEET_DEFINITIONS = [ + { + id: 'number-find', + title: '找数字,涂一涂', + subtitle: '找出目标数字并涂色', + ageMin: 3, + ageMax: 5, + difficulty: 1, + tags: ['数学', '数字认知', '涂色'], + sortOrder: 101, + }, + { + id: 'number-write', + title: '看数字,写一写', + subtitle: '按笔画顺序书写数字', + ageMin: 4, + ageMax: 6, + difficulty: 1, + tags: ['数学', '数字书写', '描红'], + sortOrder: 102, + }, + { + id: 'number-coloring', + title: '按数字,涂颜色', + subtitle: '按指定数字涂色', + ageMin: 3, + ageMax: 5, + difficulty: 1, + tags: ['数学', '数字认知', '涂色'], + sortOrder: 103, + }, + { + id: 'counting-matching', + title: '数一数,连一连', + subtitle: '连线配对数字和数量', + ageMin: 3, + ageMax: 5, + difficulty: 1, + tags: ['数学', '计数', '连线'], + sortOrder: 104, + }, + { + id: 'number-object-match', + title: '数物连线', + subtitle: '连线数量相同的物体和数字', + ageMin: 3, + ageMax: 5, + difficulty: 1, + tags: ['数学', '数物对应', '连线'], + sortOrder: 105, + }, + { + id: 'number-object-fill', + title: '数物填写', + subtitle: '数出数量,填写对应数字', + ageMin: 4, + ageMax: 6, + difficulty: 1, + tags: ['数学', '数物对应', '填写'], + sortOrder: 106, + }, + { + id: 'counting-select', + title: '数一数,选一选', + subtitle: '数出数量,圈出正确答案', + ageMin: 3, + ageMax: 5, + difficulty: 1, + tags: ['数学', '计数', '选择'], + sortOrder: 107, + }, + { + id: 'counting-fill', + title: '数一数,填一填', + subtitle: '数出物品数量,填写数字', + ageMin: 4, + ageMax: 6, + difficulty: 1, + tags: ['数学', '计数', '填写'], + sortOrder: 108, + }, + { + id: 'compare', + title: '数一数,比大小', + subtitle: '比较数量,填入 ><=', + ageMin: 4, + ageMax: 6, + difficulty: 2, + tags: ['数学', '比较', '数量'], + sortOrder: 109, + }, + { + id: 'number-sort', + title: '数字排序', + subtitle: '写出正确的数字顺序', + ageMin: 4, + ageMax: 6, + difficulty: 2, + tags: ['数学', '数字排序', '序列'], + sortOrder: 110, + }, + { + id: 'missing-number', + title: '填上缺少的数字', + subtitle: '找出并填写缺失数字', + ageMin: 4, + ageMax: 6, + difficulty: 2, + tags: ['数学', '数字序列', '填写'], + sortOrder: 111, + }, + { + id: 'number-decompose', + title: '10以内数的分与合', + subtitle: '把数字分一分,合一合', + ageMin: 5, + ageMax: 7, + difficulty: 1, + tags: ['数学', '分与合', '10以内'], + sortOrder: 112, + }, + { + id: 'number-decompose-20', + title: '20以内数的分与合', + subtitle: '把数字分一分,合一合', + ageMin: 5, + ageMax: 7, + difficulty: 2, + tags: ['数学', '分与合', '20以内'], + sortOrder: 113, + }, + { + id: 'one-digit-addition', + title: '一位数加法', + subtitle: '通过圆点学习一位数加法', + ageMin: 4, + ageMax: 6, + difficulty: 2, + tags: ['数学', '加法', '一位数'], + sortOrder: 114, + }, + { + id: 'addition-5', + title: '5以内加法', + subtitle: '图形化展示5以内加法', + ageMin: 4, + ageMax: 6, + difficulty: 1, + tags: ['数学', '加法', '5以内', '计算题'], + sortOrder: 115, + }, + { + id: 'addition-10', + title: '10以内加法', + subtitle: '图形化展示10以内加法', + ageMin: 4, + ageMax: 6, + difficulty: 2, + tags: ['数学', '加法', '10以内', '计算题'], + sortOrder: 116, + }, + { + id: 'subtraction-10', + title: '10以内减法', + subtitle: '图形化展示10以内减法', + ageMin: 5, + ageMax: 7, + difficulty: 2, + tags: ['数学', '减法', '10以内', '计算题'], + sortOrder: 117, + }, + { + id: 'addition-subtraction-10', + title: '10以内加减法', + subtitle: '加减法混合运算', + ageMin: 5, + ageMax: 7, + difficulty: 2, + tags: ['数学', '加减法', '10以内', '计算题'], + sortOrder: 118, + }, + { + id: 'make-ten', + title: '凑十法练习', + subtitle: '20以内进位加法', + ageMin: 5, + ageMax: 7, + difficulty: 3, + tags: ['数学', '凑十法', '进位加法', '计算题'], + sortOrder: 119, + }, + { + id: 'break-ten', + title: '破十法练习', + subtitle: '20以内退位减法', + ageMin: 5, + ageMax: 7, + difficulty: 3, + tags: ['数学', '破十法', '退位减法', '计算题'], + sortOrder: 120, + }, + { + id: 'flat-ten', + title: '平十法练习', + subtitle: '20以内退位减法', + ageMin: 5, + ageMax: 7, + difficulty: 3, + tags: ['数学', '平十法', '退位减法', '计算题'], + sortOrder: 121, + }, + { + id: 'borrow-ten', + title: '借十法练习', + subtitle: '20 以上退位减法', + ageMin: 6, + ageMax: 8, + difficulty: 4, + tags: ['数学', '借十法', '退位减法', '计算题'], + sortOrder: 122, + }, + { + id: 'practice-addition', + title: '加法运算', + subtitle: '10/20/50/100 以内加法', + ageMin: 6, + ageMax: 8, + difficulty: 3, + tags: ['数学', '口算', '加法', '计算题'], + sortOrder: 123, + }, + { + id: 'practice-subtraction', + title: '减法运算', + subtitle: '10/20/50/100以内减法', + ageMin: 6, + ageMax: 8, + difficulty: 3, + tags: ['数学', '口算', '减法', '计算题'], + sortOrder: 124, + }, + { + id: 'practice-mixed', + title: '混合运算', + subtitle: '10/20/50/100以内加减法混合', + ageMin: 6, + ageMax: 8, + difficulty: 3, + tags: ['数学', '口算', '加减法', '计算题'], + sortOrder: 125, + }, + { + id: 'multiplication-table', + title: '九九乘法表', + subtitle: '学习九九乘法口诀', + ageMin: 7, + ageMax: 8, + difficulty: 3, + tags: ['数学', '乘法', '九九乘法表'], + sortOrder: 126, + }, +] as const satisfies ReadonlyArray; diff --git a/miniprogram/config/worksheets/penControl.ts b/miniprogram/config/worksheets/penControl.ts new file mode 100644 index 0000000..2e188f8 --- /dev/null +++ b/miniprogram/config/worksheets/penControl.ts @@ -0,0 +1,15 @@ +import type { WorksheetDefinition } from './types'; + +export const PEN_CONTROL_WORKSHEET_DEFINITIONS = [ + { + id: 'pen-control-mix', + icon: 'edit', + title: '控笔练习', + subtitle: '多种控笔图形,运笔更轻松', + ageMin: 5, + ageMax: 7, + difficulty: 1, + tags: ['控笔', '运笔', '田字格', '学前'], + sortOrder: 40, + }, +] as const satisfies ReadonlyArray; diff --git a/miniprogram/config/worksheets/pinyin.ts b/miniprogram/config/worksheets/pinyin.ts new file mode 100644 index 0000000..8328a35 --- /dev/null +++ b/miniprogram/config/worksheets/pinyin.ts @@ -0,0 +1,59 @@ +import type { WorksheetDefinition } from './types'; + +export const PINYIN_DICTATION_WORKSHEET_DEFINITIONS = [ + { + id: 'pinyin-tracing', + icon: 'draw-o', + title: '拼音描红练习', + subtitle: '跟着描红学拼音字母', + ageMin: 5, + ageMax: 7, + difficulty: 1, + tags: ['拼音', '描红', '声母', '韵母'], + sortOrder: 50, + }, + { + id: 'pinyin-dictation', + icon: 'start-a', + title: '拼音默写练习', + subtitle: '空白格子默写拼音字母', + ageMin: 6, + ageMax: 8, + difficulty: 2, + tags: ['拼音', '默写', '声母', '韵母'], + sortOrder: 51, + }, + { + id: 'pinyin-tracing-v2', + icon: 'pen-draw', + title: '拼音描红 8 列', + subtitle: '跟写描红,声韵分块', + ageMin: 5, + ageMax: 7, + difficulty: 1, + tags: ['拼音', '描红', '声母', '韵母'], + sortOrder: 52, + }, + { + id: 'pinyin-dictation-v2', + icon: 'ABC-underline', + title: '拼音默写 8 列', + subtitle: '空白默写,声韵分块', + ageMin: 6, + ageMax: 8, + difficulty: 2, + tags: ['拼音', '默写', '声母', '韵母'], + sortOrder: 53, + }, + { + id: 'pinyin-daily', + icon: 'task-o', + title: '拼音每日打卡', + subtitle: '四宫格每日打卡练习', + ageMin: 5, + ageMax: 7, + difficulty: 2, + tags: ['拼音', '每日练习', '打卡'], + sortOrder: 54, + }, +] as const satisfies ReadonlyArray; diff --git a/miniprogram/config/worksheets/types.ts b/miniprogram/config/worksheets/types.ts new file mode 100644 index 0000000..7322c4b --- /dev/null +++ b/miniprogram/config/worksheets/types.ts @@ -0,0 +1,13 @@ +/** 本地 worksheet 元数据(与云库 `worksheets` 文档 `_id` 对齐) */ +export interface WorksheetDefinition { + id: string; + title: string; + subtitle: string; + ageMin: number; + ageMax: number; + difficulty: 1 | 2 | 3 | 4; + tags: string[]; + sortOrder: number; + /** 页面渲染时使用的图标,仅部分页面有 */ + icon?: string; +} diff --git a/miniprogram/config/worksheets/wordColoring.ts b/miniprogram/config/worksheets/wordColoring.ts new file mode 100644 index 0000000..2659f51 --- /dev/null +++ b/miniprogram/config/worksheets/wordColoring.ts @@ -0,0 +1,26 @@ +import type { WorksheetDefinition } from './types'; + +export const WORD_COLORING_WORKSHEET_DEFINITIONS = [ + { + id: 'word-coloring-grid', + icon: 'grid', + title: '网格涂色', + subtitle: '田字格涂色识字练习', + ageMin: 3, + ageMax: 6, + difficulty: 1, + tags: ['识字', '涂色', '田字格'], + sortOrder: 30, + }, + { + id: 'word-coloring-find', + icon: 'search', + title: '找字涂色', + subtitle: '在字海中找到目标字并涂色', + ageMin: 3, + ageMax: 6, + difficulty: 1, + tags: ['识字', '涂色', '找字'], + sortOrder: 31, + }, +] as const satisfies ReadonlyArray; diff --git a/miniprogram/englishPages/letterTracing/letterTracing.config.ts b/miniprogram/englishPages/letterTracing/letterTracing.config.ts index 3c0b022..4d7819b 100644 --- a/miniprogram/englishPages/letterTracing/letterTracing.config.ts +++ b/miniprogram/englishPages/letterTracing/letterTracing.config.ts @@ -1,99 +1,8 @@ -import type { LetterTracingMode } from './generators/letter-tracing-generator'; import type { DebugPublishMeta } from '../../utils/debugPublish'; import { inferGradeFromAge } from '../../utils/debugPublish'; +import { LETTER_TRACING_WORKSHEET_DEFINITIONS } from '../../config/worksheets/letterTracing'; -/** 本地 worksheet 元数据(与云库 `worksheets` 文档 `_id` 对齐) */ -interface LetterTracingWorksheetDefinition { - id: LetterTracingMode; - icon: string; - title: string; - subtitle: string; - ageMin: number; - ageMax: number; - difficulty: 1 | 2 | 3 | 4; - tags: string[]; - sortOrder: number; -} - -export const LETTER_TRACING_WORKSHEET_DEFINITIONS = [ - { - id: 'letter-tracing-single', - icon: 'start-a', - title: '字母默认字帖', - subtitle: '配图、例句与描红', - ageMin: 4, - ageMax: 7, - difficulty: 1, - tags: ['字母', '描红', '看图描红'], - sortOrder: 42, - }, - { - id: 'letter-tracing-upper-lower', - icon: 'draw-o', - title: '字母基础描红', - subtitle: 'Uppercase / Lowercase 总览', - ageMin: 5, - ageMax: 7, - difficulty: 1, - tags: ['字母', '描红', '字母总览'], - sortOrder: 44, - }, - { - id: 'letter-tracing-case-pairing', - icon: 'font-size', - title: '大小写对照', - subtitle: '半组字母左大写右小写', - ageMin: 5, - ageMax: 7, - difficulty: 1, - tags: ['字母', '描红', '大小写练习'], - sortOrder: 45, - }, - { - id: 'letter-tracing-two-column', - icon: 'two-columns', - title: '两列描红', - subtitle: '左 A–M、右 N–Z 配对描红', - ageMin: 5, - ageMax: 7, - difficulty: 1, - tags: ['字母', '描红', '两列练习'], - sortOrder: 43, - }, - { - id: 'letter-tracing-half', - icon: 'square-half', - title: '13字母半表', - subtitle: '每行一个字母,13 字母半表', - ageMin: 5, - ageMax: 8, - difficulty: 2, - tags: ['字母', '描红', '半表练习'], - sortOrder: 47, - }, - { - id: 'letter-tracing-three', - icon: 'ABC-list', - title: '三字母精练', - subtitle: '每页聚焦 3 个字母深度书写', - ageMin: 5, - ageMax: 7, - difficulty: 2, - tags: ['字母', '描红', '三字母精练'], - sortOrder: 46, - }, - { - id: 'letter-tracing-daily-checkin', - icon: 'task-o', - title: '字母每日打卡', - subtitle: '四宫格每日字母打卡练习', - ageMin: 5, - ageMax: 7, - difficulty: 2, - tags: ['字母', '描红', '每日打卡'], - sortOrder: 48, - }, -] as const satisfies ReadonlyArray; +export { LETTER_TRACING_WORKSHEET_DEFINITIONS }; type LetterTracingWorksheetRow = (typeof LETTER_TRACING_WORKSHEET_DEFINITIONS)[number]; diff --git a/miniprogram/focusPages/focusDraw/focusDraw.config.ts b/miniprogram/focusPages/focusDraw/focusDraw.config.ts index f1d6fcb..5646156 100644 --- a/miniprogram/focusPages/focusDraw/focusDraw.config.ts +++ b/miniprogram/focusPages/focusDraw/focusDraw.config.ts @@ -1,140 +1,8 @@ import type { DebugPublishMeta } from '../../utils/debugPublish'; import { inferGradeFromAge } from '../../utils/debugPublish'; +import { FOCUS_WORKSHEET_DEFINITIONS } from '../../config/worksheets/focus'; -/** 本地 worksheet 元数据(与云库 `worksheets` 文档 `_id` 对齐) */ -interface FocusWorksheetDefinition { - id: string; - title: string; - subtitle: string; - ageMin: number; - ageMax: number; - difficulty: 1 | 2 | 3 | 4; - tags: string[]; - sortOrder: number; -} - -export const FOCUS_WORKSHEET_DEFINITIONS = [ - { - id: 'color-shape-match', - title: '根据颜色画图形', - subtitle: '根据颜色画出对应图形', - ageMin: 4, - ageMax: 6, - difficulty: 2, - tags: ['专注力', '颜色', '图形'], - sortOrder: 201, - }, - { - id: 'shape-symbol', - title: '图形符号配对', - subtitle: '根据图形画对应符号', - ageMin: 4, - ageMax: 6, - difficulty: 2, - tags: ['专注力', '图形', '符号'], - sortOrder: 202, - }, - { - id: 'position-coloring', - title: '方位涂涂乐', - subtitle: '观察位置,在方格中涂色', - ageMin: 4, - ageMax: 6, - difficulty: 2, - tags: ['专注力', '方位', '涂色'], - sortOrder: 203, - }, - { - id: 'color-pattern', - title: '颜色找规律', - subtitle: '观察颜色规律,涂色', - ageMin: 4, - ageMax: 6, - difficulty: 2, - tags: ['专注力', '颜色', '规律'], - sortOrder: 204, - }, - { - id: 'match-connect', - title: '连连看', - subtitle: '根据物品连一连', - ageMin: 3, - ageMax: 6, - difficulty: 1, - tags: ['专注力', '连线', '匹配'], - sortOrder: 205, - }, - { - id: 'line-recognition', - title: '线条识别', - subtitle: '认识不同线条,画对应线条', - ageMin: 3, - ageMax: 6, - difficulty: 1, - tags: ['专注力', '线条', '识别', '控笔'], - sortOrder: 206, - }, - { - id: 'grid-reasoning', - title: '方格推理', - subtitle: '推理出合并方格并连线', - ageMin: 5, - ageMax: 7, - difficulty: 3, - tags: ['专注力', '方格', '推理', '逻辑思维'], - sortOrder: 207, - }, - { - id: 'code-connect', - title: '译码连线', - subtitle: '按数字顺序连线', - ageMin: 5, - ageMax: 7, - difficulty: 3, - tags: ['专注力', '译码', '连线', '逻辑思维'], - sortOrder: 208, - }, - { - id: 'dot-connect', - title: '数字点连线', - subtitle: '按数字顺序连点成图', - ageMin: 4, - ageMax: 6, - difficulty: 1, - tags: ['专注力', '数字', '连线'], - sortOrder: 209, - }, - { - id: 'grid-drawing-3x3', - title: '格子仿画 3×3', - subtitle: '简单有趣,培养专注力', - ageMin: 3, - ageMax: 5, - difficulty: 1, - tags: ['专注力', '格子仿画', '观察'], - sortOrder: 210, - }, - { - id: 'grid-drawing-5x5', - title: '格子仿画 5×5', - subtitle: '创意挑战,提升观察力', - ageMin: 4, - ageMax: 6, - difficulty: 2, - tags: ['专注力', '格子仿画', '观察'], - sortOrder: 211, - }, - { - id: 'grid-drawing-7x7', - title: '格子仿画 7×7', - subtitle: '大师挑战,锻炼耐心', - ageMin: 6, - ageMax: 8, - difficulty: 3, - tags: ['专注力', '格子仿画', '耐心'], - sortOrder: 212, - }, -] as const satisfies ReadonlyArray; +export { FOCUS_WORKSHEET_DEFINITIONS }; type FocusWorksheetDefinitionItem = (typeof FOCUS_WORKSHEET_DEFINITIONS)[number]; diff --git a/miniprogram/mathPages/mathDraw/mathDraw.config.ts b/miniprogram/mathPages/mathDraw/mathDraw.config.ts index fe9d525..aa1a873 100644 --- a/miniprogram/mathPages/mathDraw/mathDraw.config.ts +++ b/miniprogram/mathPages/mathDraw/mathDraw.config.ts @@ -1,281 +1,8 @@ import type { DebugPublishMeta } from '../../utils/debugPublish'; import { inferGradeFromAge } from '../../utils/debugPublish'; +import { MATH_WORKSHEET_DEFINITIONS } from '../../config/worksheets/math'; -/** 本地 worksheet 元数据(与云库 `worksheets` 文档 `_id` 对齐,用于发布与批量同步脚本) */ -interface MathWorksheetDefinition { - id: string; - title: string; - subtitle: string; - ageMin: number; - ageMax: number; - difficulty: 1 | 2 | 3 | 4; - tags: string[]; - sortOrder: number; -} - -export const MATH_WORKSHEET_DEFINITIONS = [ - { - id: 'number-find', - title: '找数字,涂一涂', - subtitle: '找出目标数字并涂色', - - ageMin: 3, - ageMax: 5, - difficulty: 1, - tags: ['数学', '数字认知', '涂色'], - sortOrder: 101, - }, - { - id: 'number-write', - title: '看数字,写一写', - subtitle: '按笔画顺序书写数字', - ageMin: 4, - ageMax: 6, - difficulty: 1, - tags: ['数学', '数字书写', '描红'], - sortOrder: 102, - }, - { - id: 'number-coloring', - title: '按数字,涂颜色', - subtitle: '按指定数字涂色', - ageMin: 3, - ageMax: 5, - difficulty: 1, - tags: ['数学', '数字认知', '涂色'], - sortOrder: 103, - }, - { - id: 'counting-matching', - title: '数一数,连一连', - subtitle: '连线配对数字和数量', - ageMin: 3, - ageMax: 5, - difficulty: 1, - tags: ['数学', '计数', '连线'], - sortOrder: 104, - }, - { - id: 'number-object-match', - title: '数物连线', - subtitle: '连线数量相同的物体和数字', - ageMin: 3, - ageMax: 5, - difficulty: 1, - tags: ['数学', '数物对应', '连线'], - sortOrder: 105, - }, - { - id: 'number-object-fill', - title: '数物填写', - subtitle: '数出数量,填写对应数字', - ageMin: 4, - ageMax: 6, - difficulty: 1, - tags: ['数学', '数物对应', '填写'], - sortOrder: 106, - }, - { - id: 'counting-select', - title: '数一数,选一选', - subtitle: '数出数量,圈出正确答案', - ageMin: 3, - ageMax: 5, - difficulty: 1, - tags: ['数学', '计数', '选择'], - sortOrder: 107, - }, - { - id: 'counting-fill', - title: '数一数,填一填', - subtitle: '数出物品数量,填写数字', - ageMin: 4, - ageMax: 6, - difficulty: 1, - tags: ['数学', '计数', '填写'], - sortOrder: 108, - }, - { - id: 'compare', - title: '数一数,比大小', - subtitle: '比较数量,填入 ><=', - ageMin: 4, - ageMax: 6, - difficulty: 2, - tags: ['数学', '比较', '数量'], - sortOrder: 109, - }, - { - id: 'number-sort', - title: '数字排序', - subtitle: '写出正确的数字顺序', - ageMin: 4, - ageMax: 6, - difficulty: 2, - tags: ['数学', '数字排序', '序列'], - sortOrder: 110, - }, - { - id: 'missing-number', - title: '填上缺少的数字', - subtitle: '找出并填写缺失数字', - ageMin: 4, - ageMax: 6, - difficulty: 2, - tags: ['数学', '数字序列', '填写'], - sortOrder: 111, - }, - { - id: 'number-decompose', - title: '10以内数的分与合', - subtitle: '把数字分一分,合一合', - ageMin: 5, - ageMax: 7, - difficulty: 1, - tags: ['数学', '分与合', '10以内'], - sortOrder: 112, - }, - { - id: 'number-decompose-20', - title: '20以内数的分与合', - subtitle: '把数字分一分,合一合', - ageMin: 5, - ageMax: 7, - difficulty: 2, - tags: ['数学', '分与合', '20以内'], - sortOrder: 113, - }, - { - id: 'one-digit-addition', - title: '一位数加法', - subtitle: '通过圆点学习一位数加法', - ageMin: 4, - ageMax: 6, - difficulty: 2, - tags: ['数学', '加法', '一位数'], - sortOrder: 114, - }, - { - id: 'addition-5', - title: '5以内加法', - subtitle: '图形化展示5以内加法', - ageMin: 4, - ageMax: 6, - difficulty: 1, - tags: ['数学', '加法', '5以内', '计算题'], - sortOrder: 115, - }, - { - id: 'addition-10', - title: '10以内加法', - subtitle: '图形化展示10以内加法', - ageMin: 4, - ageMax: 6, - difficulty: 2, - tags: ['数学', '加法', '10以内', '计算题'], - sortOrder: 116, - }, - { - id: 'subtraction-10', - title: '10以内减法', - subtitle: '图形化展示10以内减法', - ageMin: 5, - ageMax: 7, - difficulty: 2, - tags: ['数学', '减法', '10以内', '计算题'], - sortOrder: 117, - }, - { - id: 'addition-subtraction-10', - title: '10以内加减法', - subtitle: '加减法混合运算', - ageMin: 5, - ageMax: 7, - difficulty: 2, - tags: ['数学', '加减法', '10以内', '计算题'], - sortOrder: 118, - }, - { - id: 'make-ten', - title: '凑十法练习', - subtitle: '20以内进位加法', - ageMin: 5, - ageMax: 7, - difficulty: 3, - tags: ['数学', '凑十法', '进位加法', '计算题'], - sortOrder: 119, - }, - { - id: 'break-ten', - title: '破十法练习', - subtitle: '20以内退位减法', - ageMin: 5, - ageMax: 7, - difficulty: 3, - tags: ['数学', '破十法', '退位减法', '计算题'], - sortOrder: 120, - }, - { - id: 'flat-ten', - title: '平十法练习', - subtitle: '20以内退位减法', - ageMin: 5, - ageMax: 7, - difficulty: 3, - tags: ['数学', '平十法', '退位减法', '计算题'], - sortOrder: 121, - }, - { - id: 'borrow-ten', - title: '借十法练习', - subtitle: '20 以上退位减法', - ageMin: 6, - ageMax: 8, - difficulty: 4, - tags: ['数学', '借十法', '退位减法', '计算题'], - sortOrder: 122, - }, - { - id: 'practice-addition', - title: '加法运算', - subtitle: '10/20/50/100 以内加法', - ageMin: 6, - ageMax: 8, - difficulty: 3, - tags: ['数学', '口算', '加法', '计算题'], - sortOrder: 123, - }, - { - id: 'practice-subtraction', - title: '减法运算', - subtitle: '10/20/50/100以内减法', - ageMin: 6, - ageMax: 8, - difficulty: 3, - tags: ['数学', '口算', '减法', '计算题'], - sortOrder: 124, - }, - { - id: 'practice-mixed', - title: '混合运算', - subtitle: '10/20/50/100以内加减法混合', - ageMin: 6, - ageMax: 8, - difficulty: 3, - tags: ['数学', '口算', '加减法', '计算题'], - sortOrder: 125, - }, - { - id: 'multiplication-table', - title: '九九乘法表', - subtitle: '学习九九乘法口诀', - ageMin: 7, - ageMax: 8, - difficulty: 3, - tags: ['数学', '乘法', '九九乘法表'], - sortOrder: 126, - }, -] as const satisfies ReadonlyArray; +export { MATH_WORKSHEET_DEFINITIONS }; type MathWorksheetDefinitionItem = (typeof MATH_WORKSHEET_DEFINITIONS)[number]; diff --git a/miniprogram/pages/home/home.data.ts b/miniprogram/pages/home/home.data.ts index 883a52f..125ea34 100644 --- a/miniprogram/pages/home/home.data.ts +++ b/miniprogram/pages/home/home.data.ts @@ -1,6 +1,7 @@ import { CATEGORY_LIST_WITH_ALL } from '../../core/data/categories'; import { AGE_BANDS } from '../../core/data/difficulty'; import { CategoryId } from '../../core/models/category'; +import { APP_VERSION, APP_VERSION_NOTE } from '../../config/config'; export type HomeDisplayItem = { id: string; @@ -59,6 +60,26 @@ const HOME_AGE_BANDS: HomeDisplayDataset['ageBands'] = AGE_BANDS.map( }), ); +/** 首页跑马灯公告条(不随云端配置变化) */ +export type HomeNotice = { + id: string; + text: string; + /** 可选跳转路径,为空则点击不跳转 */ + path?: string; +}; + +export const HOME_NOTICES: HomeNotice[] = [ + { + id: 'welcome', + text: '欢迎来到 涂鸦丫,趣味练习纸任你选', + }, + { + id: `update-${APP_VERSION}`, + text: `${APP_VERSION} 上线:${APP_VERSION_NOTE}`, + path: '/chinesePages/penControlSheet/penControlSheet', + }, +]; + /** 首页固定:每日打卡练习(不随云端配置变化) */ export const HOME_DAILY_CHECKIN_ITEMS: HomeDisplayItem[] = [ { diff --git a/miniprogram/pages/home/home.less b/miniprogram/pages/home/home.less index 7c6ad66..dbac91f 100644 --- a/miniprogram/pages/home/home.less +++ b/miniprogram/pages/home/home.less @@ -48,6 +48,92 @@ margin-top: 48rpx; } +.home-notice-bar { + display: flex; + align-items: center; + margin: 24rpx @page-padding-x 0; + padding: 0 24rpx; + height: 64rpx; + border-radius: 999rpx; + background: fade(#ff8f1f, 10%); + overflow: hidden; + box-sizing: border-box; +} + +.home-notice-bar__label { + display: flex; + align-items: center; + flex-shrink: 0; + margin-right: 16rpx; + padding-right: 16rpx; + border-right: 2rpx solid fade(#b06b1a, 30%); + height: 36rpx; +} + +.home-notice-bar__icon { + font-size: 26rpx; + line-height: 1; +} + +.home-notice-bar__label-text { + margin-left: 8rpx; + font-size: 22rpx; + font-weight: 700; + color: #b06b1a; + line-height: 1; +} + +.home-notice-bar__viewport { + flex: 1; + min-width: 0; + overflow: hidden; + height: 100%; + display: flex; + align-items: center; +} + +.home-notice-bar__track { + display: inline-flex; + flex-wrap: nowrap; + white-space: nowrap; + animation: home-notice-scroll 12s linear infinite; + will-change: transform; +} + +.home-notice-bar__group { + display: inline-flex; + flex-shrink: 0; +} + +.home-notice-bar__item { + display: inline-flex; + align-items: center; + flex-shrink: 0; +} + +.home-notice-bar__text { + font-size: 24rpx; + color: #7a4c12; + line-height: 1; +} + +.home-notice-bar__sep { + margin: 0 24rpx; + font-size: 24rpx; + color: fade(#b06b1a, 50%); + line-height: 1; +} + +@keyframes home-notice-scroll { + 0% { + transform: translate3d(0, 0, 0); + } + + 100% { + transform: translate3d(-50%, 0, 0); + } +} + .home-hero-placeholder { margin: @section-gap @page-padding-x 0; height: 450rpx; diff --git a/miniprogram/pages/home/home.ts b/miniprogram/pages/home/home.ts index b81a09a..3d2e592 100644 --- a/miniprogram/pages/home/home.ts +++ b/miniprogram/pages/home/home.ts @@ -6,6 +6,7 @@ import { } from '../../utils/index'; import { HOME_DAILY_CHECKIN_ITEMS, + HOME_NOTICES, createEmptyHomeDataset, type HomeDisplayItem, type HomeDisplaySection, @@ -190,6 +191,7 @@ Page({ hotRecommends: SKELETON_HOT, dailyCheckinItems: HOME_DAILY_CHECKIN_ITEMS.map(toItemView), sections: [] as HomeDisplaySectionView[], + notices: HOME_NOTICES, loading: true, }, @@ -295,6 +297,12 @@ Page({ navigateByPath(path, title); }, + onTapNotice(e: WechatMiniprogram.TouchEvent) { + const path = e.currentTarget.dataset.path as string | undefined; + if (!path) return; + navigateByPath(path); + }, + onTapCard(e: WechatMiniprogram.CustomEvent) { const detail = (e.detail || {}) as { title?: string; path?: string }; const path = diff --git a/miniprogram/pages/home/home.wxml b/miniprogram/pages/home/home.wxml index 9aad542..5362f75 100644 --- a/miniprogram/pages/home/home.wxml +++ b/miniprogram/pages/home/home.wxml @@ -22,6 +22,43 @@ bind:change="onTabChange" /> + + + 📣 + 公告 + + + + + + {{item.text}} + · + + + + + + + { + wx.showToast({ title: '页面跳转失败', icon: 'none' }); + }, + }); + }, +}); diff --git a/miniprogram/supportPages/unreleasedDebug/unreleasedDebug.wxml b/miniprogram/supportPages/unreleasedDebug/unreleasedDebug.wxml new file mode 100644 index 0000000..5308a85 --- /dev/null +++ b/miniprogram/supportPages/unreleasedDebug/unreleasedDebug.wxml @@ -0,0 +1,41 @@ + + + 未上线页面 Debug + + 手动配置未发布页面的标题和路由,方便在手机上调试。 + + + + + 入口列表({{entries.length}}) + + + + + 🧪 + + + {{item.title}} + {{item.subtitle}} + + + + + + + + 暂无入口,请在 unreleasedDebug.config.ts 中配置。 + + + + + 当前不是开发环境,此页仅供调试使用。 + + diff --git a/miniprogram/supportPages/worksheetSync/worksheetSync.ts b/miniprogram/supportPages/worksheetSync/worksheetSync.ts index f3eb93b..cbba998 100644 --- a/miniprogram/supportPages/worksheetSync/worksheetSync.ts +++ b/miniprogram/supportPages/worksheetSync/worksheetSync.ts @@ -1,8 +1,13 @@ import { MOCK_SEED_COUNTS } from './mockLikes'; -import { MATH_WORKSHEET_DEFINITIONS } from '../../mathPages/mathDraw/mathDraw.config'; -import { FOCUS_WORKSHEET_DEFINITIONS } from '../../focusPages/focusDraw/focusDraw.config'; -import { LETTER_TRACING_WORKSHEET_DEFINITIONS } from '../../englishPages/letterTracing/letterTracing.config'; -import { PINYIN_DICTATION_MODE_OPTIONS } from '../../pinyinPages/pinyinDictation/pinyinDictation.config'; +import { + MATH_WORKSHEET_DEFINITIONS, + FOCUS_WORKSHEET_DEFINITIONS, + LETTER_TRACING_WORKSHEET_DEFINITIONS, + PINYIN_DICTATION_WORKSHEET_DEFINITIONS, + PEN_CONTROL_WORKSHEET_DEFINITIONS, + WORD_COLORING_WORKSHEET_DEFINITIONS, + type WorksheetDefinition, +} from '../../config/worksheets'; type CloudFunctionResult = { success?: boolean; @@ -25,13 +30,6 @@ async function callCloudFunction( return response.result || {}; } -type LocalDef = { - id: string; - ageMin: number; - ageMax: number; - tags: readonly string[]; -}; - function inferGradeFromAge(ageMin: number, ageMax: number): number { const centerAge = Math.round((ageMin + ageMax) / 2); const ageGradeMap: Record = { @@ -53,30 +51,38 @@ function inferGradeFromAge(ageMin: number, ageMax: number): number { type ConfigSource = { label: string; - data: readonly LocalDef[]; + data: ReadonlyArray; }; const CONFIG_SOURCES: ConfigSource[] = [ { label: 'math', - data: MATH_WORKSHEET_DEFINITIONS as unknown as LocalDef[], + data: MATH_WORKSHEET_DEFINITIONS, }, { label: 'focus', - data: FOCUS_WORKSHEET_DEFINITIONS as unknown as LocalDef[], + data: FOCUS_WORKSHEET_DEFINITIONS, }, { label: 'letterTracing', - data: LETTER_TRACING_WORKSHEET_DEFINITIONS as unknown as LocalDef[], + data: LETTER_TRACING_WORKSHEET_DEFINITIONS, }, { label: 'pinyin', - data: PINYIN_DICTATION_MODE_OPTIONS as unknown as LocalDef[], + data: PINYIN_DICTATION_WORKSHEET_DEFINITIONS, + }, + { + label: 'penControl', + data: PEN_CONTROL_WORKSHEET_DEFINITIONS, + }, + { + label: 'wordColoring', + data: WORD_COLORING_WORKSHEET_DEFINITIONS, }, ]; -function isLocalDef(value: unknown): value is LocalDef { - const row = value as Partial; +function isWorksheetDefinition(value: unknown): value is WorksheetDefinition { + const row = value as Partial; return ( !!row && typeof row.id === 'string' && @@ -86,22 +92,24 @@ function isLocalDef(value: unknown): value is LocalDef { ); } -async function loadConfigSource(source: ConfigSource): Promise { +async function loadConfigSource( + source: ConfigSource, +): Promise { const rows = source.data; - if (!Array.isArray(rows) || !rows.every(isLocalDef)) { + if (!Array.isArray(rows) || !rows.every(isWorksheetDefinition)) { throw new Error(`${source.label} 配置格式不正确`); } return [...rows]; } -async function collectAll(): Promise { +async function collectAll(): Promise { const groups = await Promise.all(CONFIG_SOURCES.map(loadConfigSource)); return groups.flat(); } -function assertUniqueIds(rows: LocalDef[]) { +function assertUniqueIds(rows: WorksheetDefinition[]) { const set = new Set(); for (const r of rows) { if (set.has(r.id)) {