feat: 新增幼儿测字表
This commit is contained in:
@@ -0,0 +1,265 @@
|
||||
import WordTestDrawService from './draw/wordTestDrawService';
|
||||
import {
|
||||
buildWordTestCategories,
|
||||
buildWordTestGroups,
|
||||
DEFAULT_WORD_TEST_CATEGORY_ID,
|
||||
findWordTestCategory,
|
||||
type WordTestCategory,
|
||||
type WordTestGroup,
|
||||
} from './data/wordTestCategories';
|
||||
import {
|
||||
getModeInfo,
|
||||
getPublishMetaByMode,
|
||||
isValidMode,
|
||||
WORD_TEST_WORKSHEET_ID,
|
||||
} from './wordTestSheet.config';
|
||||
import { createPage, type CanvasDataState } from '../../base/pageMixin';
|
||||
import { defaultShareConfig } from '../../config/config';
|
||||
import type { DebugPublishMeta } from '../../utils/debugPublish';
|
||||
import {
|
||||
addFavorite,
|
||||
removeFavorite,
|
||||
batchCheckFavorited,
|
||||
} from '../../utils/favorites';
|
||||
|
||||
const pageInfoLookup = getModeInfo;
|
||||
|
||||
function buildSelectedMap(id: string | null): Record<string, boolean> {
|
||||
if (!id) return {};
|
||||
return { [id]: true };
|
||||
}
|
||||
|
||||
type PageData = CanvasDataState & {
|
||||
worksheetId: string;
|
||||
categoryList: WordTestCategory[];
|
||||
groupList: WordTestGroup[];
|
||||
selectedCategoryId: string;
|
||||
selectedGroupIndex: number;
|
||||
selectedCategoryMap: Record<string, boolean>;
|
||||
selectedGroupMap: Record<string, boolean>;
|
||||
isPreviewFavorite: boolean;
|
||||
isDevEnv: boolean;
|
||||
debugPublishVisible: boolean;
|
||||
debugPublishLoading: boolean;
|
||||
debugPublishMeta: DebugPublishMeta | null;
|
||||
};
|
||||
|
||||
createPage(
|
||||
{
|
||||
canvas: null as Canvas | null,
|
||||
ctx: null as RenderingContext | null,
|
||||
boxHeight: 0,
|
||||
boxWidth: 0,
|
||||
drawService: null as WordTestDrawService | null,
|
||||
_favoritedMap: {} as Record<string, boolean>,
|
||||
|
||||
data: {
|
||||
pageTitle: '测字表',
|
||||
functionId: WORD_TEST_WORKSHEET_ID,
|
||||
hasContent: false,
|
||||
showShareDialog: false,
|
||||
worksheetId: WORD_TEST_WORKSHEET_ID,
|
||||
categoryList: [] as WordTestCategory[],
|
||||
groupList: [] as WordTestGroup[],
|
||||
selectedCategoryId: DEFAULT_WORD_TEST_CATEGORY_ID,
|
||||
selectedGroupIndex: 1,
|
||||
selectedCategoryMap: buildSelectedMap(
|
||||
DEFAULT_WORD_TEST_CATEGORY_ID,
|
||||
),
|
||||
selectedGroupMap: buildSelectedMap('1'),
|
||||
isPreviewFavorite: false,
|
||||
isDevEnv: false,
|
||||
debugPublishVisible: false,
|
||||
debugPublishLoading: false,
|
||||
debugPublishMeta: null,
|
||||
} as unknown as PageData,
|
||||
|
||||
onLoad(options: { id?: string }) {
|
||||
this.syncDebugPublishEnv();
|
||||
|
||||
const worksheetId =
|
||||
options.id && isValidMode(options.id)
|
||||
? options.id
|
||||
: WORD_TEST_WORKSHEET_ID;
|
||||
|
||||
const categoryList = buildWordTestCategories();
|
||||
const defaultCategory =
|
||||
findWordTestCategory(
|
||||
categoryList,
|
||||
DEFAULT_WORD_TEST_CATEGORY_ID,
|
||||
) || categoryList[0];
|
||||
const selectedCategoryId = defaultCategory?.id || '';
|
||||
const groupList = buildWordTestGroups(defaultCategory?.words || []);
|
||||
|
||||
this.setData({
|
||||
worksheetId,
|
||||
functionId: worksheetId,
|
||||
categoryList,
|
||||
groupList,
|
||||
selectedCategoryId,
|
||||
selectedGroupIndex: 1,
|
||||
selectedCategoryMap: buildSelectedMap(selectedCategoryId),
|
||||
selectedGroupMap: buildSelectedMap('1'),
|
||||
});
|
||||
|
||||
this.initPageInfo(worksheetId, '测字表');
|
||||
this.loadFavoritedMap();
|
||||
},
|
||||
|
||||
onCanvasReady(e: WechatMiniprogram.CustomEvent) {
|
||||
const category = this.getSelectedCategory();
|
||||
this.initCanvasFromComponent(e.detail, {
|
||||
createDrawService: (
|
||||
canvas: Canvas,
|
||||
ctx: RenderingContext,
|
||||
opts?: Record<string, unknown>,
|
||||
) => new WordTestDrawService(canvas, ctx, opts),
|
||||
drawServiceOptions: {
|
||||
title: this.getSheetTitle(category),
|
||||
},
|
||||
onCanvasReady: () => {
|
||||
this.drawCanvas();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
getSelectedCategory(): WordTestCategory | undefined {
|
||||
return findWordTestCategory(
|
||||
this.data.categoryList,
|
||||
this.data.selectedCategoryId,
|
||||
);
|
||||
},
|
||||
|
||||
getSelectedGroup(): WordTestGroup | undefined {
|
||||
return (this.data.groupList as WordTestGroup[]).find(
|
||||
(group: WordTestGroup) =>
|
||||
group.index === this.data.selectedGroupIndex,
|
||||
);
|
||||
},
|
||||
|
||||
getSheetTitle(category?: WordTestCategory): string {
|
||||
if (!category) return '测字表';
|
||||
return `${category.name}(测字表)`;
|
||||
},
|
||||
|
||||
async drawCanvas() {
|
||||
if (!this.drawService) return;
|
||||
|
||||
const group = this.getSelectedGroup();
|
||||
if (!group || group.words.length === 0) {
|
||||
this.setData({ hasContent: false });
|
||||
return;
|
||||
}
|
||||
|
||||
const category = this.getSelectedCategory();
|
||||
const title = this.getSheetTitle(category);
|
||||
|
||||
try {
|
||||
(this.drawService as WordTestDrawService).options.title = title;
|
||||
await (this.drawService as WordTestDrawService).draw({
|
||||
words: group.words,
|
||||
pageNumber: group.index,
|
||||
});
|
||||
this.setData({ hasContent: true });
|
||||
} catch (e) {
|
||||
console.error('wordTestSheet draw failed', e);
|
||||
this.setData({ hasContent: false });
|
||||
}
|
||||
},
|
||||
|
||||
onSelectCategory(e: WechatMiniprogram.TouchEvent) {
|
||||
const id = e.currentTarget.dataset.id as string;
|
||||
if (!id || id === this.data.selectedCategoryId) return;
|
||||
|
||||
const category = findWordTestCategory(this.data.categoryList, id);
|
||||
if (!category) return;
|
||||
|
||||
const groupList = buildWordTestGroups(category.words);
|
||||
|
||||
this.setData(
|
||||
{
|
||||
selectedCategoryId: id,
|
||||
selectedCategoryMap: buildSelectedMap(id),
|
||||
groupList,
|
||||
selectedGroupIndex: 1,
|
||||
selectedGroupMap: buildSelectedMap('1'),
|
||||
},
|
||||
() => this.drawCanvas(),
|
||||
);
|
||||
},
|
||||
|
||||
onSelectGroup(e: WechatMiniprogram.TouchEvent) {
|
||||
const index = Number(e.currentTarget.dataset.index);
|
||||
if (!index || index === this.data.selectedGroupIndex) return;
|
||||
|
||||
this.setData(
|
||||
{
|
||||
selectedGroupIndex: index,
|
||||
selectedGroupMap: buildSelectedMap(String(index)),
|
||||
},
|
||||
() => this.drawCanvas(),
|
||||
);
|
||||
},
|
||||
|
||||
onPreviewRefresh() {
|
||||
const groupList = this.data.groupList as WordTestGroup[];
|
||||
if (!groupList.length) {
|
||||
this.drawCanvas();
|
||||
return;
|
||||
}
|
||||
|
||||
const currentIdx = groupList.findIndex(
|
||||
(group) => group.index === this.data.selectedGroupIndex,
|
||||
);
|
||||
const nextIdx =
|
||||
currentIdx < 0 ? 0 : (currentIdx + 1) % groupList.length;
|
||||
const nextGroup = groupList[nextIdx];
|
||||
|
||||
this.setData(
|
||||
{
|
||||
selectedGroupIndex: nextGroup.index,
|
||||
selectedGroupMap: buildSelectedMap(String(nextGroup.index)),
|
||||
},
|
||||
() => this.drawCanvas(),
|
||||
);
|
||||
},
|
||||
|
||||
async onPreviewFavorite() {
|
||||
const next = !this.data.isPreviewFavorite;
|
||||
this.setData({ isPreviewFavorite: next });
|
||||
const id = this.data.worksheetId;
|
||||
if (id) {
|
||||
this._favoritedMap[id] = next;
|
||||
if (next) {
|
||||
addFavorite(id);
|
||||
} else {
|
||||
removeFavorite(id);
|
||||
}
|
||||
}
|
||||
wx.showToast({
|
||||
title: next ? '收藏成功' : '已取消收藏',
|
||||
icon: 'none',
|
||||
});
|
||||
},
|
||||
|
||||
async loadFavoritedMap() {
|
||||
const ids = [WORD_TEST_WORKSHEET_ID];
|
||||
this._favoritedMap = await batchCheckFavorited(ids);
|
||||
if (this._favoritedMap[this.data.worksheetId]) {
|
||||
this.setData({ isPreviewFavorite: true });
|
||||
}
|
||||
},
|
||||
|
||||
getPublishMeta(): DebugPublishMeta {
|
||||
const meta = getPublishMetaByMode(this.data.worksheetId);
|
||||
if (!meta) {
|
||||
throw new Error('当前题型配置不存在');
|
||||
}
|
||||
return meta;
|
||||
},
|
||||
},
|
||||
{
|
||||
shareConfig: defaultShareConfig,
|
||||
pageInfoLookup,
|
||||
},
|
||||
);
|
||||
Reference in New Issue
Block a user