V2-1: 12 个 Server Action 通过 getTranslations 翻译错误消息;Service/DataAccess 层抛出错误码异常(PublishServiceError/LessonPlanDataError),Actions 层通过 PUBLISH_ERROR_KEY_MAP 翻译为 i18n 消息 V2-2: SYSTEM_TEMPLATES name/title 改为 i18n 键,createLessonPlan 接受 translateTitle 函数在服务端翻译后存储到 DB V2-3: 8 处 as unknown as 断言替换为显式类型映射函数(mapRowToLessonPlan/mapRowToListItem/mapRowToTemplate/mapRowToVersion)+ 类型守卫(isLessonPlanStatus/isTemplateType/isTemplateScope) V2-4: MiniMap nodeColor 复用 lib/node-summary.ts 的 getNodeColor V2-5: a11y 深度修复 — lesson-plan-filters/exercise-block/inline-question-editor 的 select 添加 label htmlFor 关联;exercise-block 题目列表改为 ul/li;node-editor 画布添加 role=application + 键盘导航配置 V2-6: Tracker 埋点接入 — 新增 useLessonPlanTrackerSafe hook,在 create/save/publish/revert/duplicate/archive 6 处调用 tracker.track 同步更新架构图 004 和 005 文档
118 lines
4.0 KiB
TypeScript
118 lines
4.0 KiB
TypeScript
import type { BlockType, TemplateBlockSkeleton, TemplateScope } from "./types";
|
||
|
||
// block 类型 → i18n 键(实际文本由 useTranslations("lessonPreparation").blockType.${type} 翻译)
|
||
// 保留此映射用于:1) 新节点默认标题的 i18n 键查找 2) 类型守卫
|
||
export const BLOCK_TYPE_KEYS: Record<BlockType, string> = {
|
||
objective: "objective",
|
||
key_point: "key_point",
|
||
import: "import",
|
||
new_teaching: "new_teaching",
|
||
consolidation: "consolidation",
|
||
summary: "summary",
|
||
homework: "homework",
|
||
blackboard: "blackboard",
|
||
text_study: "text_study",
|
||
exercise: "exercise",
|
||
rich_text: "rich_text",
|
||
reflection: "reflection",
|
||
};
|
||
|
||
// 向后兼容:保留 BLOCK_TYPE_LABELS 名称但值为 i18n 键(实际翻译由组件层完成)
|
||
// @deprecated 使用 BLOCK_TYPE_KEYS 或 useTranslations("lessonPreparation").blockType.${type} 替代
|
||
export const BLOCK_TYPE_LABELS: Record<BlockType, string> = BLOCK_TYPE_KEYS;
|
||
|
||
// 富文本类 block(共享同一编辑组件)
|
||
export const RICH_TEXT_BLOCK_TYPES: BlockType[] = [
|
||
"objective",
|
||
"key_point",
|
||
"import",
|
||
"new_teaching",
|
||
"consolidation",
|
||
"summary",
|
||
"homework",
|
||
"blackboard",
|
||
"rich_text",
|
||
"reflection",
|
||
];
|
||
|
||
// 系统预设模板骨架(seed 用)
|
||
// V2-2 修复:title/hint 存储 i18n 键,由 createLessonPlan 调用 getTranslations 翻译
|
||
// 键格式:`template.blocks.${templateId}.${blockIndex}.title` 或 `blockType.${type}`(默认)
|
||
export interface SystemTemplateDef {
|
||
id: string; // 固定 ID,便于幂等
|
||
name: string; // i18n 键:template.names.${id}
|
||
scope: TemplateScope;
|
||
blocks: TemplateBlockSkeleton[];
|
||
}
|
||
|
||
export const SYSTEM_TEMPLATES: SystemTemplateDef[] = [
|
||
{
|
||
id: "tpl_regular",
|
||
name: "tpl_regular", // i18n 键
|
||
scope: "regular",
|
||
blocks: [
|
||
{ type: "objective", title: "blockType.objective" },
|
||
{ type: "key_point", title: "blockType.key_point" },
|
||
{ type: "import", title: "blockType.import" },
|
||
{ type: "new_teaching", title: "blockType.new_teaching" },
|
||
{ type: "consolidation", title: "blockType.consolidation" },
|
||
{ type: "summary", title: "blockType.summary" },
|
||
{ type: "homework", title: "blockType.homework" },
|
||
{ type: "blackboard", title: "blockType.blackboard" },
|
||
],
|
||
},
|
||
{
|
||
id: "tpl_review",
|
||
name: "tpl_review",
|
||
scope: "review",
|
||
blocks: [
|
||
{ type: "objective", title: "blockType.objective" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_review.1" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_review.2" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_review.3" },
|
||
{ type: "exercise", title: "blockType.exercise" },
|
||
{ type: "summary", title: "blockType.summary" },
|
||
],
|
||
},
|
||
{
|
||
id: "tpl_experiment",
|
||
name: "tpl_experiment",
|
||
scope: "experiment",
|
||
blocks: [
|
||
{ type: "objective", title: "blockType.objective" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_experiment.1" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_experiment.2" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_experiment.3" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_experiment.4" },
|
||
{ type: "summary", title: "blockType.summary" },
|
||
],
|
||
},
|
||
{
|
||
id: "tpl_inquiry",
|
||
name: "tpl_inquiry",
|
||
scope: "inquiry",
|
||
blocks: [
|
||
{ type: "rich_text", title: "template.blocks.tpl_inquiry.0" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_inquiry.1" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_inquiry.2" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_inquiry.3" },
|
||
{ type: "rich_text", title: "template.blocks.tpl_inquiry.4" },
|
||
],
|
||
},
|
||
{
|
||
id: "tpl_blank",
|
||
name: "tpl_blank",
|
||
scope: "blank",
|
||
blocks: [],
|
||
},
|
||
];
|
||
|
||
export const LESSON_PLAN_STATUS_KEYS: Record<string, string> = {
|
||
draft: "draft",
|
||
published: "published",
|
||
archived: "archived",
|
||
};
|
||
|
||
// @deprecated 使用 useTranslations("lessonPreparation").status.${key} 替代
|
||
export const LESSON_PLAN_STATUS_LABELS: Record<string, string> = LESSON_PLAN_STATUS_KEYS;
|