feat: worksheet发布功能开发
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import LetterTracingDraw from './draw/letterTracingDraw';
|
||||
import { createPage, type CanvasDataState } from '../../base/pageMixin';
|
||||
import { defaultShareConfig } from '../../config/config';
|
||||
import { getWorksheetById } from '../../core/data/worksheets';
|
||||
import {
|
||||
generateLetterTracing,
|
||||
mergeLetterTracingConfig,
|
||||
@@ -9,6 +8,12 @@ import {
|
||||
type LetterTracingGeneratorConfig,
|
||||
type LetterTracingMode,
|
||||
} from './generators/letter-tracing-generator';
|
||||
import {
|
||||
getModeInfo,
|
||||
getPublishMetaByMode,
|
||||
isValidMode,
|
||||
LETTER_TRACING_MODE_OPTIONS,
|
||||
} from './letterTracing.config';
|
||||
import { LETTERS_UPPER, LETTERS_PAIRS } from '../shared/data/alphabet';
|
||||
import {
|
||||
DEFAULT_LETTER_PROFILE,
|
||||
@@ -16,75 +21,24 @@ import {
|
||||
type FontProfile,
|
||||
} from '../shared/data/fontProfiles';
|
||||
import { loadLetterFont } from '../shared/draw/drawTools';
|
||||
|
||||
/** 练习模式定义(顺序与产品文档一致),同时用于模式选择器和页面元信息 */
|
||||
const MODES = [
|
||||
{
|
||||
id: 'letter-tracing-single',
|
||||
icon: 'start-a',
|
||||
label: '默认字帖',
|
||||
desc: '配图、例句与描红',
|
||||
},
|
||||
{
|
||||
id: 'letter-tracing-upper-lower',
|
||||
icon: 'draw-o',
|
||||
// label: '字母总览',
|
||||
label: '基础描红',
|
||||
desc: 'Uppercase / Lowercase 总览',
|
||||
},
|
||||
{
|
||||
id: 'letter-tracing-case-pairing',
|
||||
icon: 'font-size',
|
||||
label: '大小写对照',
|
||||
desc: '半组字母左大写右小写',
|
||||
},
|
||||
{
|
||||
id: 'letter-tracing-two-column',
|
||||
icon: 'two-columns',
|
||||
label: '两列描红',
|
||||
desc: '左 A–M、右 N–Z 配对描红',
|
||||
},
|
||||
{
|
||||
id: 'letter-tracing-half',
|
||||
icon: 'square-half',
|
||||
label: '13字母半表',
|
||||
desc: '每行一个字母,13 字母半表',
|
||||
},
|
||||
{
|
||||
id: 'letter-tracing-three',
|
||||
icon: 'ABC-list',
|
||||
label: '三字母精练',
|
||||
desc: '每页聚焦 3 个字母深度书写',
|
||||
},
|
||||
{
|
||||
id: 'letter-tracing-daily-checkin',
|
||||
icon: 'draw-o',
|
||||
label: '每日打卡',
|
||||
desc: '四宫格每日字母打卡练习',
|
||||
},
|
||||
] as const;
|
||||
|
||||
const MODE_MAP = Object.fromEntries(MODES.map((m) => [m.id, m])) as Record<
|
||||
string,
|
||||
(typeof MODES)[number]
|
||||
>;
|
||||
import type { DebugPublishMeta } from '../../utils/debugPublish';
|
||||
|
||||
/** 三字母精练分组:26 字母每 3 个一组 */
|
||||
const TRIPLE_GROUPS: { label: string; letters: string[] }[] = [];
|
||||
const TRIPLE_GROUPS: { title: string; letters: string[] }[] = [];
|
||||
for (let i = 0; i < LETTERS_UPPER.length; i += 3) {
|
||||
const group = LETTERS_UPPER.slice(i, i + 3);
|
||||
const label =
|
||||
const title =
|
||||
group.length > 1 ? `${group[0]}–${group[group.length - 1]}` : group[0];
|
||||
TRIPLE_GROUPS.push({ label, letters: [...group] });
|
||||
TRIPLE_GROUPS.push({ title, letters: [...group] });
|
||||
}
|
||||
|
||||
/** 每日打卡分组:4 个字母一组 */
|
||||
const DAILY_GROUPS: { label: string; letters: string[] }[] = [];
|
||||
const DAILY_GROUPS: { title: string; letters: string[] }[] = [];
|
||||
for (let i = 0; i < LETTERS_UPPER.length; i += 4) {
|
||||
const group = LETTERS_UPPER.slice(i, i + 4);
|
||||
const label =
|
||||
const title =
|
||||
group.length > 1 ? `${group[0]}–${group[group.length - 1]}` : group[0];
|
||||
DAILY_GROUPS.push({ label, letters: [...group] });
|
||||
DAILY_GROUPS.push({ title, letters: [...group] });
|
||||
}
|
||||
|
||||
function getDailyGroupIndex(letters?: string[]): number {
|
||||
@@ -93,11 +47,7 @@ function getDailyGroupIndex(letters?: string[]): number {
|
||||
return idx >= 0 ? idx : 0;
|
||||
}
|
||||
|
||||
/** 根据 worksheetId 查找页面元信息 */
|
||||
function pageInfoLookup(id: string) {
|
||||
const m = MODE_MAP[id];
|
||||
return m ? { title: m.label, desc: m.desc } : undefined;
|
||||
}
|
||||
const pageInfoLookup = getModeInfo;
|
||||
|
||||
type PageData = CanvasDataState & {
|
||||
worksheetId: string;
|
||||
@@ -110,13 +60,17 @@ type PageData = CanvasDataState & {
|
||||
showNextLetter: boolean;
|
||||
showTripleGroupPicker: boolean;
|
||||
showDailyGroupPicker: boolean;
|
||||
tripleGroups: { label: string; letters: string[] }[];
|
||||
tripleGroups: { title: string; letters: string[] }[];
|
||||
selectedTripleGroupIdx: number;
|
||||
dailyGroups: { label: string; letters: string[] }[];
|
||||
dailyGroups: { title: string; letters: string[] }[];
|
||||
selectedDailyGroupIdx: number;
|
||||
letterGrid: string[];
|
||||
modeOptions: ReadonlyArray<{ id: string; label: string; desc: string }>;
|
||||
modeOptions: typeof LETTER_TRACING_MODE_OPTIONS;
|
||||
isPreviewFavorite: boolean;
|
||||
isDevEnv: boolean;
|
||||
debugPublishVisible: boolean;
|
||||
debugPublishLoading: boolean;
|
||||
debugPublishMeta: DebugPublishMeta | null;
|
||||
};
|
||||
|
||||
createPage(
|
||||
@@ -148,8 +102,12 @@ createPage(
|
||||
dailyGroups: DAILY_GROUPS,
|
||||
selectedDailyGroupIdx: 0,
|
||||
letterGrid: LETTERS_PAIRS,
|
||||
modeOptions: [...MODES],
|
||||
modeOptions: LETTER_TRACING_MODE_OPTIONS,
|
||||
isPreviewFavorite: false,
|
||||
isDevEnv: false,
|
||||
debugPublishVisible: false,
|
||||
debugPublishLoading: false,
|
||||
debugPublishMeta: null,
|
||||
} as unknown as PageData,
|
||||
|
||||
/** 页面加载:从路由参数获取 worksheetId、letter、case、font 并应用,同时预加载字体 */
|
||||
@@ -164,9 +122,10 @@ createPage(
|
||||
}
|
||||
loadLetterFont(this.fontProfile).catch(() => {});
|
||||
const worksheetId =
|
||||
options.id && MODE_MAP[options.id]
|
||||
options.id && isValidMode(options.id)
|
||||
? options.id
|
||||
: 'letter-tracing-single';
|
||||
this.syncDebugPublishEnv();
|
||||
this.applyWorksheet(worksheetId);
|
||||
|
||||
const updates: Partial<PageData> = {};
|
||||
@@ -216,11 +175,11 @@ createPage(
|
||||
});
|
||||
},
|
||||
|
||||
/** 构建运行时生成器配置:合并 worksheet 预设 + 当前页面状态 */
|
||||
/** 构建运行时生成器配置:合并页面模式预设 + 当前页面状态 */
|
||||
buildRuntimeConfig(): LetterTracingGeneratorConfig {
|
||||
const def = getWorksheetById(this.data.worksheetId);
|
||||
const base = (def?.generatorConfig ??
|
||||
{}) as Partial<LetterTracingGeneratorConfig>;
|
||||
const base: Partial<LetterTracingGeneratorConfig> = {
|
||||
mode: this.data.traceMode,
|
||||
};
|
||||
const letterCase =
|
||||
this.data.traceMode === 'letter-tracing-single'
|
||||
? (base.letterCase ?? 'upper')
|
||||
@@ -321,6 +280,14 @@ createPage(
|
||||
});
|
||||
},
|
||||
|
||||
getPublishMeta(): DebugPublishMeta {
|
||||
const meta = getPublishMetaByMode(this.data.worksheetId);
|
||||
if (!meta) {
|
||||
throw new Error('当前题型配置不存在');
|
||||
}
|
||||
return meta;
|
||||
},
|
||||
|
||||
/** 用户在三字母分组选择器中选择了一组 */
|
||||
onSelectTripleGroup(e: WechatMiniprogram.TouchEvent) {
|
||||
const idx = Number(e.currentTarget.dataset.idx);
|
||||
@@ -338,9 +305,9 @@ createPage(
|
||||
},
|
||||
|
||||
/**
|
||||
* 应用指定的 worksheet 配置到页面状态
|
||||
* 根据 worksheet 的 generatorConfig 决定 UI 控件的显隐(字母选择器、大小写切换等)
|
||||
* @param worksheetId - 要应用的 worksheet ID
|
||||
* 应用指定的页面模式配置到页面状态
|
||||
* 根据当前模式的运行时默认参数决定 UI 控件的显隐(字母选择器、大小写切换等)
|
||||
* @param worksheetId - 要应用的模式 ID
|
||||
* @param options.preserveLetter - 是否保留当前选中的字母(模式切换时使用)
|
||||
* @param options.redraw - 是否立即重绘 Canvas
|
||||
*/
|
||||
@@ -351,11 +318,12 @@ createPage(
|
||||
redraw?: boolean;
|
||||
},
|
||||
) {
|
||||
const def = getWorksheetById(worksheetId);
|
||||
console.log('def', def);
|
||||
const base = (def?.generatorConfig ??
|
||||
{}) as Partial<LetterTracingGeneratorConfig>;
|
||||
const merged = mergeLetterTracingConfig(base, {});
|
||||
if (!isValidMode(worksheetId)) return;
|
||||
|
||||
const merged = mergeLetterTracingConfig(
|
||||
{ mode: worksheetId as LetterTracingMode },
|
||||
{},
|
||||
);
|
||||
|
||||
const traceMode = merged.mode;
|
||||
const showLetterPicker = traceMode === 'letter-tracing-single';
|
||||
@@ -397,10 +365,7 @@ createPage(
|
||||
selectedDailyGroupIdx,
|
||||
},
|
||||
() => {
|
||||
this.initPageInfo(
|
||||
worksheetId,
|
||||
MODE_MAP[worksheetId]?.label ?? '字母描红',
|
||||
);
|
||||
this.initPageInfo(worksheetId, '字母描红');
|
||||
|
||||
if (this.drawService) {
|
||||
this.drawService.options.title = this.data.pageTitle;
|
||||
|
||||
Reference in New Issue
Block a user