266 lines
8.7 KiB
TypeScript
266 lines
8.7 KiB
TypeScript
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,
|
|
},
|
|
);
|