feat: 完成 4 个TabBar 页面初版样式修改

This commit is contained in:
R524809
2026-04-02 17:05:55 +08:00
parent b18dbcb0d1
commit 206c44cf6d
61 changed files with 4670 additions and 996 deletions
-161
View File
@@ -1,161 +0,0 @@
import type {
WorksheetDefinition,
WorksheetType,
} from '../../core/models/worksheet';
import {
getWorksheetPath,
getWorksheetsByAge,
getWorksheetsByCategory,
} from '../../core/data/worksheets';
type AgeFilterKey = 'all' | '3-4' | '4-5' | '5-6' | '6-7' | '7-8';
type DiffFilterKey = 'all' | 'beginner' | 'basic' | 'intermediate';
const AGE_BAND: Record<Exclude<AgeFilterKey, 'all'>, [number, number]> = {
'3-4': [3, 4],
'4-5': [4, 5],
'5-6': [5, 6],
'6-7': [6, 7],
'7-8': [7, 8],
};
const DIFF_LABEL: Record<string, string> = {
beginner: '入门',
basic: '基础',
intermediate: '进阶',
advanced: '进阶+',
};
type DisplayItem = WorksheetType & {
ageRangeLabel: string;
difficultyLabel: string;
};
function filterByAgeBand(
list: WorksheetType[],
band: AgeFilterKey,
): WorksheetType[] {
if (band === 'all') return list;
const [lo, hi] = AGE_BAND[band];
const map = new Map<string, WorksheetType>();
for (let age = lo; age <= hi; age += 1) {
getWorksheetsByAge(list, age).forEach((w) => map.set(w.id, w));
}
return Array.from(map.values());
}
function filterByDifficulty(
list: WorksheetType[],
diff: DiffFilterKey,
): WorksheetType[] {
if (diff === 'all') return list;
return list.filter((w) => w.difficulty === diff);
}
function toDisplayList(list: WorksheetType[]): DisplayItem[] {
return list.map((w) => ({
...w,
ageRangeLabel:
w.ageRange && w.ageRange.length === 2
? `${w.ageRange[0]}-${w.ageRange[1]}`
: '',
difficultyLabel: w.difficulty ? DIFF_LABEL[w.difficulty] || '' : '',
}));
}
Page({
data: {
title: '分类',
sourceItems: [] as WorksheetDefinition[],
items: [] as DisplayItem[],
ageFilters: [
{ key: 'all', label: '全部' },
{ key: '3-4', label: '3-4岁' },
{ key: '4-5', label: '4-5岁' },
{ key: '5-6', label: '5-6岁' },
{ key: '6-7', label: '6-7岁' },
{ key: '7-8', label: '7-8岁' },
],
diffFilters: [
{ key: 'all', label: '全部' },
{ key: 'beginner', label: '⭐ 入门' },
{ key: 'basic', label: '⭐⭐ 基础' },
{ key: 'intermediate', label: '⭐⭐⭐ 进阶' },
],
activeAge: 'all' as AgeFilterKey,
activeDiff: 'all' as DiffFilterKey,
},
onLoad(options: {
category?: string;
minAge?: string;
maxAge?: string;
title?: string;
}) {
const category = options.category || 'all';
let base = getWorksheetsByCategory(category);
const minAge = options.minAge != null ? Number(options.minAge) : NaN;
const maxAge = options.maxAge != null ? Number(options.maxAge) : NaN;
if (!Number.isNaN(minAge) && !Number.isNaN(maxAge)) {
const map = new Map<string, WorksheetDefinition>();
const lo = Math.min(minAge, maxAge);
const hi = Math.max(minAge, maxAge);
for (let age = lo; age <= hi; age += 1) {
getWorksheetsByAge(base, age).forEach((w) => map.set(w.id, w));
}
base = Array.from(map.values());
}
const title = options.title
? decodeURIComponent(options.title)
: '分类';
this.setData({
title,
sourceItems: base,
});
wx.setNavigationBarTitle({ title });
this.applyFilters();
},
applyFilters() {
const { sourceItems, activeAge, activeDiff } = this.data;
let next = filterByAgeBand(sourceItems, activeAge);
next = filterByDifficulty(next, activeDiff);
this.setData({ items: toDisplayList(next) });
},
onAgeFilter(e: WechatMiniprogram.TouchEvent) {
const key = e.currentTarget.dataset.key as AgeFilterKey;
if (!key) return;
this.setData({ activeAge: key }, () => this.applyFilters());
},
onDiffFilter(e: WechatMiniprogram.TouchEvent) {
const key = e.currentTarget.dataset.key as DiffFilterKey;
if (!key) return;
this.setData({ activeDiff: key }, () => this.applyFilters());
},
buildWorksheetUrl(w: WorksheetType): string {
let url = getWorksheetPath(w);
if (!url) return '';
if (w.mode) {
url += url.includes('?') ? `&mode=${w.mode}` : `?mode=${w.mode}`;
}
return url;
},
onCardTap(e: WechatMiniprogram.TouchEvent) {
const id = e.currentTarget.dataset.id as string;
const w = this.data.items.find((item) => item.id === id);
if (!w) return;
const url = this.buildWorksheetUrl(w);
if (!url) {
wx.showToast({ title: '暂无法打开', icon: 'none' });
return;
}
wx.navigateTo({ url });
},
});