Files
NextEdu/src/modules/lesson-preparation/constants.ts
SpecialX 97e59b95a1 refactor(lesson-preparation): V2 审计深度修复 — Server Actions i18n + 错误码模式 + 类型断言清零 + a11y 深度修复 + Tracker 埋点接入
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 文档
2026-06-22 18:45:35 +08:00

118 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;