feat: 分类数据统一

This commit is contained in:
R524809
2026-04-23 10:54:22 +08:00
parent 2a1dbad164
commit b2ab123b4f
15 changed files with 757 additions and 221 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

+19 -44
View File
@@ -1,52 +1,27 @@
import type { CategoryType } from '../models/category';
export const CATEGORIES: CategoryType[] = [
{
id: 'math',
name: '数感启蒙',
icon: '📐',
color: '#e3f2fd',
gradient: ['#fff9c4', '#fff176'],
},
{
id: 'chinese',
name: '趣味识字',
icon: '✏️',
color: '#e8f5e9',
gradient: ['#c8e6c9', '#a5d6a7'],
},
{
id: 'english',
name: '英语启蒙',
icon: '🔤',
color: '#e0f7fa',
gradient: ['#b2ebf2', '#80deea'],
},
// {
// id: 'focus',
// name: '专注力',
// icon: '🧩',
// color: '#f3e5f5',
// gradient: ['#e1bee7', '#ce93d8'],
// },
{
id: 'puzzle',
name: '益智游戏',
icon: '🧩',
color: '#fff3e0',
gradient: ['#ffe0b2', '#ffcc80'],
},
{
id: 'craft',
name: '创意手工',
icon: '🌈',
color: '#fce4ec',
gradient: ['#f8bbd0', '#f48fb1'],
},
export const ALL_CATEGORY: CategoryType = {
id: 'all',
name: '全部',
icon: '📋',
};
export const CATEGORY_LIST: CategoryType[] = [
{ id: 'math', name: '数感启蒙', icon: '📐' },
{ id: 'puzzle', name: '益智游戏', icon: '🧩' },
{ id: 'pinyin', name: '汉语拼音', icon: '🔤' },
{ id: 'chinese', name: '趣味识字', icon: '✏️' },
{ id: 'english', name: '英语启蒙', icon: '🔤' },
{ id: 'craft', name: '创意手工', icon: '🌈' },
];
export const CATEGORY_LIST_WITH_ALL: CategoryType[] = [
ALL_CATEGORY,
...CATEGORY_LIST,
];
export function getCategoryById(id: string): CategoryType | undefined {
return CATEGORIES.find((c) => c.id === id);
return CATEGORY_LIST_WITH_ALL.find((c) => c.id === id);
}
export function getCategoryName(id: string): string {
+4 -6
View File
@@ -1,13 +1,11 @@
import type { WorksheetCategory } from './worksheet';
/** Tab / 首页用的分类展示模型 */
export interface CategoryType {
id: WorksheetCategory;
id: string;
name: string;
icon: string;
color: string;
/** 分类用于背景或装饰的渐变色,数组中为渐变起止的两个颜色值 */
gradient: [string, string];
img?: string;
color?: string;
sortOrder?: number;
}
/** 云集合 `categories` 文档(与小程序云开发方案 §3.4 对齐) */
@@ -14,7 +14,6 @@ import {
drawClosedFourLineGrid,
drawLetterInFourLineGrid,
loadLetterFont,
type LetterFontSizes,
} from '../../shared/draw/drawTools';
type DailyCheckinData = Extract<
@@ -34,7 +33,7 @@ const SECTION_PADDING_TOP = 12;
const SECTION_PADDING_BOTTOM = 10;
// 标题与上一元素的垂直间距(px)
const HEADER_TITLE_GAP = 24;
const HEADER_TITLE_GAP = 32;
// 标题与元信息(如日期、学号等)的间距(px)
const HEADER_META_GAP = 22;
// 正文内容距标题/元信息顶部的间距(px)
@@ -163,6 +162,7 @@ export default class DailyCheckinDraw extends BaseDrawService {
const cx = rect.x + rect.w / 2;
const titleY = rect.y + SECTION_PADDING_TOP + 12;
const metaY = titleY + HEADER_TITLE_GAP;
const metaUnderlineY = metaY + 5;
this.ctx.save();
this.ctx.fillStyle = '#322E25';
@@ -172,23 +172,21 @@ export default class DailyCheckinDraw extends BaseDrawService {
this.ctx.font = '20px serif';
this.ctx.fillText('每日打卡', cx, titleY);
this.ctx.font = '14px serif';
this.ctx.fillText('月', rect.x + rect.w * 0.34, metaY);
this.ctx.fillText('日', rect.x + rect.w * 0.48, metaY);
this.ctx.fillText('姓名:', rect.x + rect.w * 0.7, metaY);
this.ctx.font = '12px serif';
this.ctx.fillText('月', rect.x + 76, metaY);
this.ctx.fillText('日', rect.x + 122, metaY);
this.ctx.fillText('姓名:', rect.x + 176, metaY);
this.ctx.strokeStyle = '#8E897E';
this.ctx.lineWidth = 1;
this.ctx.setLineDash([]);
this.ctx.beginPath();
this.ctx.moveTo(rect.x + rect.w * 0.14, metaY + 4);
this.ctx.lineTo(rect.x + rect.w * 0.3, metaY + 4);
this.ctx.moveTo(rect.x + rect.w * 0.38, metaY + 4);
this.ctx.lineTo(rect.x + rect.w * 0.44, metaY + 4);
this.ctx.moveTo(rect.x + rect.w * 0.52, metaY + 4);
this.ctx.lineTo(rect.x + rect.w * 0.58, metaY + 4);
this.ctx.moveTo(rect.x + rect.w * 0.78, metaY + 4);
this.ctx.lineTo(rect.x + rect.w * 0.94, metaY + 4);
this.ctx.moveTo(rect.x + 40, metaUnderlineY);
this.ctx.lineTo(rect.x + 68, metaUnderlineY);
this.ctx.moveTo(rect.x + 85, metaUnderlineY);
this.ctx.lineTo(rect.x + 113, metaUnderlineY);
this.ctx.moveTo(rect.x + 195, metaUnderlineY);
this.ctx.lineTo(rect.x + 248, metaUnderlineY);
this.ctx.stroke();
this.ctx.restore();
@@ -237,13 +235,13 @@ export default class DailyCheckinDraw extends BaseDrawService {
(contentWidth - GRID_COL_GAP * (GRID_COLS - 1)) / GRID_COLS;
const cellH =
(contentHeight - GRID_ROW_GAP * (GRID_ROWS - 1)) / GRID_ROWS;
const pairGap = Math.min(16, cellW * 0.28);
const pairGap = 16;
const regularSizes = calcLetterFontSizes(
cellH * 0.86,
cellH * 0.98,
PRINT_CLEARLY_REGULAR,
);
const dashedSizes = calcLetterFontSizes(
cellH * 0.86,
cellH * 0.98,
PRINT_CLEARLY_DASHED,
);
@@ -10,29 +10,6 @@
bind:canvas-ready="onCanvasReady"
bind:favorite="onPreviewFavorite" />
<!-- 练习类型(2列卡片网格) -->
<view class="lt-section">
<text class="lt-section-title">练习类型</text>
<view class="lt-mode-grid">
<view
wx:for="{{modeOptions}}"
wx:key="id"
class="lt-mode-card {{worksheetId === item.id ? 'lt-mode-card--active' : ''}}"
data-id="{{item.id}}"
hover-class="lt-mode-card--pressed"
hover-start-time="0"
hover-stay-time="70"
bindtap="onSelectMode">
<toy-icon
name="{{item.icon}}"
size="42rpx"
color="{{worksheetId === item.id ? '#453900' : '#605b50'}}"
custom-class="lt-mode-card__icon" />
<text class="lt-mode-card__label">{{item.label}}</text>
</view>
</view>
</view>
<!-- 选择字母(默认字帖模式) -->
<view wx:if="{{showLetterPicker}}" class="lt-section">
<text class="lt-section-title">选择字母</text>
@@ -123,6 +100,30 @@
custom-class="lt-shuffle-btn__icon" />
<text class="lt-shuffle-btn__text">换一批</text>
</view>
<!-- 练习类型(2列卡片网格) -->
<view class="lt-section">
<text class="lt-section-title">练习类型</text>
<view class="lt-mode-grid">
<view
wx:for="{{modeOptions}}"
wx:key="id"
class="lt-mode-card {{worksheetId === item.id ? 'lt-mode-card--active' : ''}}"
data-id="{{item.id}}"
hover-class="lt-mode-card--pressed"
hover-start-time="0"
hover-stay-time="70"
bindtap="onSelectMode">
<toy-icon
name="{{item.icon}}"
size="42rpx"
color="{{worksheetId === item.id ? '#453900' : '#605b50'}}"
custom-class="lt-mode-card__icon" />
<text class="lt-mode-card__label">{{item.label}}</text>
</view>
</view>
</view>
<draw-ad type="mathDraw"></draw-ad>
</view>
</view>
+77 -87
View File
@@ -1,3 +1,5 @@
import { CATEGORY_LIST } from '../../core/data/categories';
export type CategoryItem = {
id: string;
title: string;
@@ -58,92 +60,80 @@ function item(input: ItemInput): CategoryItem {
return { ...input, likes, downloads, date: TODAY };
}
// prettier-ignore
export const CATEGORY_DATA: CategoryDataset = {
searchPlaceholder: '搜索练习纸...',
categories: [
{
id: 'math', name: '数感启蒙', icon: '📐',
items: [
item({ id: 'number-find', title: '找数字,涂一涂', subtitle: '在数字方阵中找出目标数字并涂色', icon: '🔍', img: '/assets/entrancePicture/math/number-find.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-find', available: true }),
item({ id: 'number-write', title: '看数字,写一写', subtitle: '按笔画顺序练习书写数字', icon: '✏️', img: '/assets/entrancePicture/math/number-write.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-write', available: true }),
item({ id: 'number-coloring', title: '按数字,涂颜色', subtitle: '按指定数字给对应圆圈涂色', icon: '🎨', img: '/assets/entrancePicture/math/number-coloring.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-coloring', available: true }),
item({ id: 'counting-matching', title: '数一数,连一连', subtitle: '连线配对数字和对应数量图形', icon: '🔗', img: '/assets/entrancePicture/math/count-match.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=counting-matching', available: true }),
item({ id: 'number-object-match', title: '数物连线', subtitle: '连线相同数量的物品和数字', icon: '🔗', img: '/assets/entrancePicture/math/number-object-match.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-object-match', available: true }),
item({ id: 'number-object-fill', title: '数物填写', subtitle: '数物品数量,填写对应数字', icon: '✏️', img: '/assets/entrancePicture/math/number-object-fill.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-object-fill', available: true }),
item({ id: 'counting-select', title: '数一数,选一选', subtitle: '数出物品数量,圈出正确答案', icon: '', img: '/assets/entrancePicture/math/counting-select.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=counting-select', available: true }),
item({ id: 'counting-fill', title: '数一数,填一填', subtitle: '数出物品数量,填写数字', icon: '✏️', img: '/assets/entrancePicture/math/counting-fill.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=counting-fill', available: true }),
item({ id: 'compare', title: '数一数,比大小', subtitle: '比较数量,填入 ><=', icon: '⚖️', img: '/assets/entrancePicture/math/compare.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=compare', available: true }),
item({ id: 'number-sort', title: '数字排序', subtitle: '写出正确的数字顺序', icon: '🔢', img: '/assets/entrancePicture/math/number-sort.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=number-sort', available: true }),
item({ id: 'missing-number', title: '填上缺少的数字', subtitle: '在数列中找出并填写缺失数字', icon: '', img: '/assets/entrancePicture/math/missing-number.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=missing-number', available: true }),
item({ id: 'number-decompose', title: '10以内数的分与合', subtitle: '把数字分一分,合一合', icon: '🔢', img: '/assets/entrancePicture/math/number-decompose.png', ageBand: age(4, 6), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-decompose', available: true }),
item({ id: 'number-decompose-20', title: '20以内数的分与合', subtitle: '把数字分一分,合一合', icon: '🔢', img: '/assets/entrancePicture/math/number-decompose-20.png', ageBand: age(5, 7), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=number-decompose-20', available: true }),
item({ id: 'one-digit-addition', title: '一位数加法', subtitle: '通过圆点学习一位数加法运算', icon: '', img: '/assets/entrancePicture/math/one-digit-addition.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=one-digit-addition', available: true }),
item({ id: 'addition-5', title: '5以内加法', subtitle: '图形化展示 5 以内加法', icon: '', img: '/assets/entrancePicture/math/addition-5.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=addition-5', available: true }),
item({ id: 'addition-10', title: '10以内加法', subtitle: '图形化展示 10 以内法', icon: '', img: '/assets/entrancePicture/math/addition-10.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=addition-10', available: true }),
item({ id: 'subtraction-10', title: '10以内减法', subtitle: '图形化展示 10 以内减法', icon: '', img: '/assets/entrancePicture/math/subtraction-10.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=subtraction-10', available: true }),
item({ id: 'addition-subtraction-10', title: '10以内加减法', subtitle: '加减法混合运算', icon: '±', img: '/assets/entrancePicture/math/addition-subtraction-10.png', ageBand: age(5, 7), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=addition-subtraction-10', available: true }),
item({ id: 'make-ten', title: '凑十法练习', subtitle: '20 以内进位加法', icon: '', img: '/assets/entrancePicture/math/make-ten.png', ageBand: age(5, 7), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=make-ten', available: true }),
item({ id: 'break-ten', title: '破十法练习', subtitle: '20 以内退位减法', icon: '', img: '/assets/entrancePicture/math/break-ten.png', ageBand: age(5, 7), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=break-ten', available: true }),
item({ id: 'flat-ten', title: '平十法练习', subtitle: '20 以内退位减法', icon: '', img: '/assets/entrancePicture/math/flat-ten.png', ageBand: age(5, 7), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=flat-ten', available: true }),
item({ id: 'borrow-ten', title: '借十法练习', subtitle: '20 以上退位减法', icon: '', img: '/assets/entrancePicture/math/borrow-ten.png', ageBand: age(6, 8), difficulty: d('advanced'), path: '/mathPages/mathDraw/mathDraw?id=borrow-ten', available: true }),
item({ id: 'practice-addition', title: '加法运算', subtitle: '10/20/50/100 以内加法', icon: '', img: '/assets/entrancePicture/math/practice-addition.png', ageBand: age(5, 8), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=practice-addition', available: true }),
item({ id: 'practice-subtraction', title: '减法运算', subtitle: '10/20/50/100 以内减法', icon: '', img: '/assets/entrancePicture/math/practice-subtraction.png', ageBand: age(5, 8), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=practice-subtraction', available: true }),
item({ id: 'practice-mixed', title: '混合运算', subtitle: '10/20/50/100 以内加减法混合', icon: '±', img: '/assets/entrancePicture/math/practice-mixed.png', ageBand: age(5, 8), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=practice-mixed', available: true }),
item({ id: 'multiplication-table', title: '九九乘法表', subtitle: '学习九九乘法口诀', icon: '✖️', img: '/assets/entrancePicture/math/multiplication-table.png', ageBand: age(6, 8), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=multiplication-table', available: true }),
],
},
{
id: 'pinyin', name: '汉语拼音', icon: '🔤',
items: [
item({ id: 'pinyin-initials', title: '声母描红', subtitle: '23个声母认读与书写练习', icon: '🔤', ageBand: age(5, 7), difficulty: d('basic'), path: '', available: false }),
item({ id: 'pinyin-finals', title: '韵母描红', subtitle: '24个韵母认读与书写练习', icon: '🔤', ageBand: age(5, 7), difficulty: d('basic'), path: '', available: false }),
item({ id: 'pinyin-overall', title: '整体认读音节', subtitle: '16个整体认读音节练习', icon: '🔤', ageBand: age(5, 7), difficulty: d('intermediate'), path: '', available: false }),
],
},
{
id: 'puzzle', name: '益智游戏', icon: '🧩',
items: [
item({ id: 'color-shape-match', title: '根据颜色画图形', subtitle: '根据颜色画出对应图形', icon: '🎯', img: '/assets/entrancePicture/focus/color-shape-match.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/focusPages/focusDraw/focusDraw?id=color-shape-match', available: true }),
item({ id: 'shape-symbol', title: '图形符号配对', subtitle: '根据图形画对应符号', icon: '🔗', img: '/assets/entrancePicture/focus/shape-symbol.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/focusPages/focusDraw/focusDraw?id=shape-symbol', available: true }),
item({ id: 'shape-recognition', title: '识别形状', subtitle: '识别形状,涂一涂', icon: '🔍', img: '/assets/entrancePicture/focus/shape-recognition.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/focusPages/focusDraw/focusDraw?id=shape-recognition', available: true }),
item({ id: 'position-coloring', title: '方位涂涂乐', subtitle: '观察位置,在方格中涂色', icon: '📍', img: '/assets/entrancePicture/focus/position-coloring.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/focusPages/focusDraw/focusDraw?id=position-coloring', available: true }),
item({ id: 'color-pattern', title: '颜色找规律', subtitle: '观察颜色规律,在空白图形中涂色', icon: '🎨', img: '/assets/entrancePicture/focus/color-pattern.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/focusPages/focusDraw/focusDraw?id=color-pattern', available: true }),
item({ id: 'match-connect', title: '连连看', subtitle: '根据物品连一连', icon: '🔗', img: '/assets/entrancePicture/focus/match-connect.png', ageBand: age(3, 6), difficulty: d('beginner'), path: '/focusPages/focusDraw/focusDraw?id=match-connect', available: true }),
item({ id: 'line-recognition', title: '线条识别', subtitle: '认识不同线条,画出颜色对应的线条', icon: '📏', img: '/assets/entrancePicture/focus/line-recognition.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/focusPages/focusDraw/focusDraw?id=line-recognition', available: true }),
item({ id: 'grid-reasoning', title: '方格推理', subtitle: '推理出合并方格并连线', icon: '🧩', img: '/assets/entrancePicture/focus/grid-reasoning.png', ageBand: age(5, 7), difficulty: d('intermediate'), path: '/focusPages/focusDraw/focusDraw?id=grid-reasoning', available: true }),
item({ id: 'code-connect', title: '译码连线', subtitle: '按数字顺序将数字对应颜色连线', icon: '🔢', img: '/assets/entrancePicture/focus/code-connect.png', ageBand: age(5, 7), difficulty: d('intermediate'), path: '/focusPages/focusDraw/focusDraw?id=code-connect', available: true }),
item({ id: 'dot-connect', title: '数字点连线', subtitle: '按数字顺序连点成图', icon: '🔗', img: '/assets/entrancePicture/focus/dot-connect.png', ageBand: age(3, 6), difficulty: d('beginner'), path: '/focusPages/focusDraw/focusDraw?id=dot-connect', available: true }),
item({ id: 'grid-drawing-3x3', title: '格子仿画 3×3', subtitle: '简单有趣,培养专注力', icon: '🎨', img: '/assets/entrancePicture/focus/grid-drawing-3x3.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/focusPages/focusDraw/focusDraw?id=grid-drawing-3x3', available: true }),
item({ id: 'grid-drawing-5x5', title: '格子仿画 5×5', subtitle: '创意挑战,提升观察力', icon: '🎨', img: '/assets/entrancePicture/focus/grid-drawing-5x5.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/focusPages/focusDraw/focusDraw?id=grid-drawing-5x5', available: true }),
item({ id: 'grid-drawing-7x7', title: '格子仿画 7×7', subtitle: '大师挑战,锻炼耐心', icon: '🎨', img: '/assets/entrancePicture/focus/grid-drawing-7x7.png', ageBand: age(5, 8), difficulty: d('intermediate'), path: '/focusPages/focusDraw/focusDraw?id=grid-drawing-7x7', available: true }),
],
},
{
id: 'chinese', name: '趣味识字', icon: '✏️',
items: [
item({ id: 'word-recognition', title: '识字卡', subtitle: '输入或选字生成涂色识字卡', icon: '📖', ageBand: age(3, 6), difficulty: d('beginner'), path: '/pages/index/index', available: true }),
item({ id: 'copybook', title: '练字帖', subtitle: '选字生成田字格笔顺练字帖', icon: '✏️', ageBand: age(4, 7), difficulty: d('basic'), path: '/pages/copyBook/copyBook', available: true }),
],
},
{
id: 'english', name: '英语启蒙', icon: '🔤',
items: [
item({ id: 'letter-tracing-single', title: '看图描红', subtitle: '单字母配图、例句与六行四线三格描红', icon: '🔠', img: '/assets/entrancePicture/english/letter-tracing-single.jpg', ageBand: age(4, 7), difficulty: d('beginner'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-single', available: true }),
item({ id: 'letter-tracing-upper-lower', title: '字母总览', subtitle: 'Uppercase / Lowercase 分区总览', icon: '🔡', img: '/assets/entrancePicture/english/letter-tracing-upper-lower.jpg', ageBand: age(4, 7), difficulty: d('beginner'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-upper-lower', available: true }),
item({ id: 'letter-tracing-case-pairing', title: '大小写练习', subtitle: '半组字母左大写右小写,逐行对照描红', icon: '✏️', img: '/assets/entrancePicture/english/letter-tracing-case-pairing.jpg', ageBand: age(4, 7), difficulty: d('beginner'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-case-pairing', available: true }),
item({ id: 'letter-tracing-two-column', title: '两列练习', subtitle: '左 A–M、右 NZ,大小写配对描红', icon: '🔤', img: '/assets/entrancePicture/english/letter-tracing-two-column.jpg', ageBand: age(4, 7), difficulty: d('beginner'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-two-column', available: true }),
item({ id: 'letter-tracing-half', title: '单字母逐行', subtitle: '13 字母半表逐字练习', icon: '📝', img: '/assets/entrancePicture/english/letter-tracing-half.jpg', ageBand: age(4, 7), difficulty: d('basic'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-half', available: true }),
item({ id: 'letter-tracing-three', title: '三字母精练', subtitle: '每页 3 个字母,大写 + 小写深度书写', icon: '🔤', img: '/assets/entrancePicture/english/letter-tracing-three.jpg', ageBand: age(4, 7), difficulty: d('basic'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-three', available: true }),
],
},
{
id: 'craft', name: '创意手工', icon: '🌈',
items: [
item({ id: 'craft-coloring', title: '涂色卡', subtitle: '动物、交通、节日主题涂色', icon: '🎨', ageBand: age(3, 6), difficulty: d('beginner'), path: '', available: false }),
item({ id: 'craft-origami', title: '折纸模板', subtitle: '打印后即可折叠的趣味模板', icon: '🪭', ageBand: age(4, 7), difficulty: d('basic'), path: '', available: false }),
item({ id: 'craft-stickers', title: '贴纸打印', subtitle: '奖励贴纸与装饰贴纸', icon: '⭐', ageBand: age(3, 8), difficulty: d('beginner'), path: '', available: false }),
],
},
const CATEGORY_ITEMS_BY_ID: Record<string, CategoryItem[]> = {
math: [
item({ id: 'number-find', title: '找数字,涂一涂', subtitle: '在数字方阵中找出目标数字并涂色', icon: '🔍', img: '/assets/entrancePicture/math/number-find.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-find', available: true }),
item({ id: 'number-write', title: '看数字,写一写', subtitle: '按笔画顺序练习书写数字', icon: '✏️', img: '/assets/entrancePicture/math/number-write.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-write', available: true }),
item({ id: 'number-coloring', title: '按数字,涂颜色', subtitle: '按指定数字给对应圆圈涂色', icon: '🎨', img: '/assets/entrancePicture/math/number-coloring.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-coloring', available: true }),
item({ id: 'counting-matching', title: '数一数,连一连', subtitle: '连线配对数字和对应数量图形', icon: '🔗', img: '/assets/entrancePicture/math/count-match.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=counting-matching', available: true }),
item({ id: 'number-object-match', title: '数物连线', subtitle: '连线相同数量的物品和数字', icon: '🔗', img: '/assets/entrancePicture/math/number-object-match.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-object-match', available: true }),
item({ id: 'number-object-fill', title: '数物填写', subtitle: '数物品数量,填写对应数字', icon: '✏️', img: '/assets/entrancePicture/math/number-object-fill.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-object-fill', available: true }),
item({ id: 'counting-select', title: '数一数,选一选', subtitle: '数出物品数量,圈出正确答案', icon: '', img: '/assets/entrancePicture/math/counting-select.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=counting-select', available: true }),
item({ id: 'counting-fill', title: '数一数,填一填', subtitle: '数出物品数量,填写数字', icon: '✏️', img: '/assets/entrancePicture/math/counting-fill.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=counting-fill', available: true }),
item({ id: 'compare', title: '数一数,比大小', subtitle: '比较数量,填入 ><=', icon: '⚖️', img: '/assets/entrancePicture/math/compare.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=compare', available: true }),
item({ id: 'number-sort', title: '数字排序', subtitle: '写出正确的数字顺序', icon: '🔢', img: '/assets/entrancePicture/math/number-sort.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=number-sort', available: true }),
item({ id: 'missing-number', title: '填上缺少的数字', subtitle: '在数列中找出并填写缺失数字', icon: '', img: '/assets/entrancePicture/math/missing-number.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=missing-number', available: true }),
item({ id: 'number-decompose', title: '10以内数的分与合', subtitle: '把数字分一分,合一合', icon: '🔢', img: '/assets/entrancePicture/math/number-decompose.png', ageBand: age(4, 6), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=number-decompose', available: true }),
item({ id: 'number-decompose-20', title: '20以内数的分与合', subtitle: '把数字分一分,合一合', icon: '🔢', img: '/assets/entrancePicture/math/number-decompose-20.png', ageBand: age(5, 7), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=number-decompose-20', available: true }),
item({ id: 'one-digit-addition', title: '一位数加法', subtitle: '通过圆点学习一位数加法运算', icon: '', img: '/assets/entrancePicture/math/one-digit-addition.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=one-digit-addition', available: true }),
item({ id: 'addition-5', title: '5以内加法', subtitle: '图形化展示 5 以内加法', icon: '', img: '/assets/entrancePicture/math/addition-5.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/mathPages/mathDraw/mathDraw?id=addition-5', available: true }),
item({ id: 'addition-10', title: '10以内加法', subtitle: '图形化展示 10 以内加法', icon: '', img: '/assets/entrancePicture/math/addition-10.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=addition-10', available: true }),
item({ id: 'subtraction-10', title: '10以内减法', subtitle: '图形化展示 10 以内减法', icon: '', img: '/assets/entrancePicture/math/subtraction-10.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=subtraction-10', available: true }),
item({ id: 'addition-subtraction-10', title: '10以内加减法', subtitle: '加减法混合运算', icon: '±', img: '/assets/entrancePicture/math/addition-subtraction-10.png', ageBand: age(5, 7), difficulty: d('basic'), path: '/mathPages/mathDraw/mathDraw?id=addition-subtraction-10', available: true }),
item({ id: 'make-ten', title: '凑十法练习', subtitle: '20 以内进位加法', icon: '', img: '/assets/entrancePicture/math/make-ten.png', ageBand: age(5, 7), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=make-ten', available: true }),
item({ id: 'break-ten', title: '破十法练习', subtitle: '20 以内退位减法', icon: '', img: '/assets/entrancePicture/math/break-ten.png', ageBand: age(5, 7), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=break-ten', available: true }),
item({ id: 'flat-ten', title: '平十法练习', subtitle: '20 以内退位减法', icon: '', img: '/assets/entrancePicture/math/flat-ten.png', ageBand: age(5, 7), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=flat-ten', available: true }),
item({ id: 'borrow-ten', title: '借十法练习', subtitle: '20 以上退位减法', icon: '', img: '/assets/entrancePicture/math/borrow-ten.png', ageBand: age(6, 8), difficulty: d('advanced'), path: '/mathPages/mathDraw/mathDraw?id=borrow-ten', available: true }),
item({ id: 'practice-addition', title: '加法运算', subtitle: '10/20/50/100 以内加法', icon: '', img: '/assets/entrancePicture/math/practice-addition.png', ageBand: age(5, 8), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=practice-addition', available: true }),
item({ id: 'practice-subtraction', title: '减法运算', subtitle: '10/20/50/100 以内减法', icon: '', img: '/assets/entrancePicture/math/practice-subtraction.png', ageBand: age(5, 8), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=practice-subtraction', available: true }),
item({ id: 'practice-mixed', title: '混合运算', subtitle: '10/20/50/100 以内加减法混合', icon: '±', img: '/assets/entrancePicture/math/practice-mixed.png', ageBand: age(5, 8), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=practice-mixed', available: true }),
item({ id: 'multiplication-table', title: '九九乘法表', subtitle: '学习九九乘法口诀', icon: '✖️', img: '/assets/entrancePicture/math/multiplication-table.png', ageBand: age(6, 8), difficulty: d('intermediate'), path: '/mathPages/mathDraw/mathDraw?id=multiplication-table', available: true }),
],
pinyin: [
item({ id: 'pinyin-initials', title: '声母描红', subtitle: '23个声母认读与书写练习', icon: '🔤', ageBand: age(5, 7), difficulty: d('basic'), path: '', available: false }),
item({ id: 'pinyin-finals', title: '韵母描红', subtitle: '24个韵母认读与书写练习', icon: '🔤', ageBand: age(5, 7), difficulty: d('basic'), path: '', available: false }),
item({ id: 'pinyin-overall', title: '整体认读音节', subtitle: '16个整体认读音节练习', icon: '🔤', ageBand: age(5, 7), difficulty: d('intermediate'), path: '', available: false }),
],
puzzle: [
item({ id: 'color-shape-match', title: '根据颜色画图形', subtitle: '根据颜色画出对应图形', icon: '🎯', img: '/assets/entrancePicture/focus/color-shape-match.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/focusPages/focusDraw/focusDraw?id=color-shape-match', available: true }),
item({ id: 'shape-symbol', title: '图形符号配对', subtitle: '根据图形画对应符号', icon: '🔗', img: '/assets/entrancePicture/focus/shape-symbol.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/focusPages/focusDraw/focusDraw?id=shape-symbol', available: true }),
item({ id: 'shape-recognition', title: '识别形状', subtitle: '识别形状,涂一涂', icon: '🔍', img: '/assets/entrancePicture/focus/shape-recognition.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/focusPages/focusDraw/focusDraw?id=shape-recognition', available: true }),
item({ id: 'position-coloring', title: '方位涂涂乐', subtitle: '观察位置,在方格中涂色', icon: '📍', img: '/assets/entrancePicture/focus/position-coloring.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/focusPages/focusDraw/focusDraw?id=position-coloring', available: true }),
item({ id: 'color-pattern', title: '颜色找规律', subtitle: '观察颜色规律,在空白图形中涂色', icon: '🎨', img: '/assets/entrancePicture/focus/color-pattern.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/focusPages/focusDraw/focusDraw?id=color-pattern', available: true }),
item({ id: 'match-connect', title: '连连看', subtitle: '根据物品连一连', icon: '🔗', img: '/assets/entrancePicture/focus/match-connect.png', ageBand: age(3, 6), difficulty: d('beginner'), path: '/focusPages/focusDraw/focusDraw?id=match-connect', available: true }),
item({ id: 'line-recognition', title: '线条识别', subtitle: '认识不同线条,画出颜色对应的线条', icon: '📏', img: '/assets/entrancePicture/focus/line-recognition.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/focusPages/focusDraw/focusDraw?id=line-recognition', available: true }),
item({ id: 'grid-reasoning', title: '方格推理', subtitle: '推理出合并方格并连线', icon: '🧩', img: '/assets/entrancePicture/focus/grid-reasoning.png', ageBand: age(5, 7), difficulty: d('intermediate'), path: '/focusPages/focusDraw/focusDraw?id=grid-reasoning', available: true }),
item({ id: 'code-connect', title: '译码连线', subtitle: '按数字顺序将数字对应颜色连线', icon: '🔢', img: '/assets/entrancePicture/focus/code-connect.png', ageBand: age(5, 7), difficulty: d('intermediate'), path: '/focusPages/focusDraw/focusDraw?id=code-connect', available: true }),
item({ id: 'dot-connect', title: '数字点连线', subtitle: '按数字顺序连点成图', icon: '🔗', img: '/assets/entrancePicture/focus/dot-connect.png', ageBand: age(3, 6), difficulty: d('beginner'), path: '/focusPages/focusDraw/focusDraw?id=dot-connect', available: true }),
item({ id: 'grid-drawing-3x3', title: '格子仿画 3×3', subtitle: '简单有趣,培养专注力', icon: '🎨', img: '/assets/entrancePicture/focus/grid-drawing-3x3.png', ageBand: age(3, 5), difficulty: d('beginner'), path: '/focusPages/focusDraw/focusDraw?id=grid-drawing-3x3', available: true }),
item({ id: 'grid-drawing-5x5', title: '格子仿画 5×5', subtitle: '创意挑战,提升观察力', icon: '🎨', img: '/assets/entrancePicture/focus/grid-drawing-5x5.png', ageBand: age(4, 6), difficulty: d('basic'), path: '/focusPages/focusDraw/focusDraw?id=grid-drawing-5x5', available: true }),
item({ id: 'grid-drawing-7x7', title: '格子仿画 7×7', subtitle: '大师挑战,锻炼耐心', icon: '🎨', img: '/assets/entrancePicture/focus/grid-drawing-7x7.png', ageBand: age(5, 8), difficulty: d('intermediate'), path: '/focusPages/focusDraw/focusDraw?id=grid-drawing-7x7', available: true }),
],
chinese: [
item({ id: 'word-recognition', title: '识字卡', subtitle: '输入或选字生成涂色识字卡', icon: '📖', ageBand: age(3, 6), difficulty: d('beginner'), path: '/pages/index/index', available: true }),
item({ id: 'copybook', title: '练字帖', subtitle: '选字生成田字格笔顺练字帖', icon: '✏️', ageBand: age(4, 7), difficulty: d('basic'), path: '/pages/copyBook/copyBook', available: true }),
],
english: [
item({ id: 'letter-tracing-single', title: '看图描红', subtitle: '单字母配图、例句与六行四线三格描红', icon: '🔠', img: '/assets/entrancePicture/english/letter-tracing-single.jpg', ageBand: age(4, 7), difficulty: d('beginner'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-single', available: true }),
item({ id: 'letter-tracing-single2', title: '看图描红', subtitle: '单字母配图、例句与六行四线三格描红', icon: '🔠', img: '/assets/entrancePicture/english/letter-tracing-single2.jpg', ageBand: age(4, 7), difficulty: d('beginner'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-single', available: true }),
item({ id: 'letter-tracing-upper-lower', title: '字母总览', subtitle: 'Uppercase / Lowercase 分区总览', icon: '🔡', img: '/assets/entrancePicture/english/letter-tracing-upper-lower.jpg', ageBand: age(4, 7), difficulty: d('beginner'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-upper-lower', available: true }),
item({ id: 'letter-tracing-case-pairing', title: '大小写练习', subtitle: '半组字母左大写右小写,逐行对照描红', icon: '✏️', img: '/assets/entrancePicture/english/letter-tracing-case-pairing.jpg', ageBand: age(4, 7), difficulty: d('beginner'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-case-pairing', available: true }),
item({ id: 'letter-tracing-two-column', title: '两列练习', subtitle: '左 A-M、右 N-Z,大小写配对描红', icon: '🔤', img: '/assets/entrancePicture/english/letter-tracing-two-column.jpg', ageBand: age(4, 7), difficulty: d('beginner'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-two-column', available: true }),
item({ id: 'letter-tracing-half', title: '单字母逐行', subtitle: '13 字母半表逐字练习', icon: '📝', img: '/assets/entrancePicture/english/letter-tracing-half.jpg', ageBand: age(4, 7), difficulty: d('basic'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-half', available: true }),
item({ id: 'letter-tracing-three', title: '三字母精练', subtitle: '每页 3 个字母,大写 + 小写深度书写', icon: '🔤', img: '/assets/entrancePicture/english/letter-tracing-three.jpg', ageBand: age(4, 7), difficulty: d('basic'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-three', available: true }),
item({ id: 'letter-tracing-daily-checkin', title: '每日打卡', subtitle: '四宫格每日字母打卡练习', icon: '🔤', img: '/assets/entrancePicture/english/letter-tracing-daily-checkin.jpg', ageBand: age(4, 7), difficulty: d('basic'), path: '/englishPages/letterTracing/letterTracing?id=letter-tracing-daily-checkin', available: true }),
],
craft: [
item({ id: 'craft-coloring', title: '涂色卡', subtitle: '动物、交通、节日主题涂色', icon: '🎨', ageBand: age(3, 6), difficulty: d('beginner'), path: '', available: false }),
item({ id: 'craft-origami', title: '折纸模板', subtitle: '打印后即可折叠的趣味模板', icon: '🪭', ageBand: age(4, 7), difficulty: d('basic'), path: '', available: false }),
item({ id: 'craft-stickers', title: '贴纸打印', subtitle: '奖励贴纸与装饰贴纸', icon: '⭐', ageBand: age(3, 8), difficulty: d('beginner'), path: '', available: false }),
],
};
export const CATEGORY_DATA: CategoryDataset = {
searchPlaceholder: '搜索练习纸...',
categories: CATEGORY_LIST.map((category) => ({
...category,
items: CATEGORY_ITEMS_BY_ID[category.id] ?? [],
})),
};
+3 -2
View File
@@ -134,8 +134,8 @@
}
.cat-card__thumb {
width: 160rpx;
height: 180rpx;
width: 168rpx;
height: 210rpx;
flex-shrink: 0;
border-radius: 10rpx;
display: flex;
@@ -143,6 +143,7 @@
justify-content: center;
overflow: hidden;
border: 1rpx solid #bbb;
background: #f0f0f0;
}
.cat-card__thumb-img {
+14 -30
View File
@@ -1,3 +1,4 @@
import { CATEGORY_LIST_WITH_ALL } from '../../core/data/categories';
import { CATEGORY_DATA, type CategoryItem } from './category.data';
type CategoryTab = {
@@ -6,54 +7,37 @@ type CategoryTab = {
icon: string;
};
type DisplayItem = CategoryItem & {
thumbBg: string;
};
const SIDEBAR_TABS: CategoryTab[] = CATEGORY_LIST_WITH_ALL.map(({ id, name, icon }) => ({
id,
name,
icon,
}));
const CATEGORY_BG: Record<string, string> = {
math: '#fff3c4',
pinyin: '#d8f0d0',
puzzle: '#f5e6dc',
chinese: '#d8f0d0',
english: '#e8f4ff',
craft: '#fce4ec',
};
const ALL_TAB: CategoryTab = { id: 'all', name: '全部', icon: '📋' };
const SIDEBAR_TABS: CategoryTab[] = [
ALL_TAB,
...CATEGORY_DATA.categories.map((c) => ({
id: c.id,
name: c.name,
icon: c.icon,
})),
];
function buildAllItems(): DisplayItem[] {
const items: DisplayItem[] = [];
function buildAllItems(): CategoryItem[] {
const items: CategoryItem[] = [];
for (const group of CATEGORY_DATA.categories) {
for (const item of group.items) {
items.push({
...item,
thumbBg: CATEGORY_BG[group.id] ?? '#f0e7d6',
});
}
}
return items;
}
function getItemsByCategory(categoryId: string): DisplayItem[] {
function getItemsByCategory(categoryId: string): CategoryItem[] {
if (categoryId === 'all') return buildAllItems();
const group = CATEGORY_DATA.categories.find((c) => c.id === categoryId);
if (!group) return [];
return group.items.map((item) => ({
...item,
thumbBg: CATEGORY_BG[group.id] ?? '#f0e7d6',
}));
}
function filterByKeyword(items: DisplayItem[], keyword: string): DisplayItem[] {
function filterByKeyword(
items: CategoryItem[],
keyword: string,
): CategoryItem[] {
if (!keyword) return items;
const kw = keyword.toLowerCase();
return items.filter(
@@ -77,7 +61,7 @@ Page({
searchKeyword: '',
sidebarTabs: SIDEBAR_TABS,
activeCategoryId: 'all',
displayItems: buildAllItems() as DisplayItem[],
displayItems: buildAllItems() as CategoryItem[],
scrollIntoViewId: '',
},
+1 -3
View File
@@ -57,9 +57,7 @@
data-title="{{item.title}}"
data-available="{{item.available}}"
bindtap="onTapItem">
<view
class="cat-card__thumb"
style="background-color: {{item.thumbBg}}">
<view class="cat-card__thumb">
<image
wx:if="{{item.img}}"
class="cat-card__thumb-img"
+4 -9
View File
@@ -1,3 +1,4 @@
import { CATEGORY_LIST_WITH_ALL } from '../../core/data/categories';
import { AGE_BANDS } from '../../core/data/difficulty';
export type HomeDisplayItem = {
@@ -43,15 +44,9 @@ export type HomeDisplayDataset = {
sections: HomeDisplaySection[];
};
const HOME_CATEGORY_TABS = [
{ id: 'all', name: '全部' },
{ id: 'math', name: '数感启蒙' },
{ id: 'pinyin', name: '汉语拼音' },
{ id: 'puzzle', name: '益智游戏' },
{ id: 'chinese', name: '趣味识字' },
{ id: 'english', name: '英语启蒙' },
{ id: 'craft', name: '创意手工' },
] as const;
const HOME_CATEGORY_TABS: HomeDisplayDataset['categoryTabs'] = CATEGORY_LIST_WITH_ALL.map(
({ id, name }) => ({ id, name }),
);
const HOME_AGE_BANDS = AGE_BANDS.map((item, index) => ({
key: item.key,