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 { if (!id) return {}; return { [id]: true }; } type PageData = CanvasDataState & { worksheetId: string; categoryList: WordTestCategory[]; groupList: WordTestGroup[]; selectedCategoryId: string; selectedGroupIndex: number; selectedCategoryMap: Record; selectedGroupMap: Record; 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, 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, ) => 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, }, );