aiCoursewareTemplates.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. import type { AiCoursewareOutline } from "@/api/aiCourseware"
  2. export type AiCoursewareTemplateId =
  3. | "fairytale-forest"
  4. | "warm-handdrawn"
  5. | "music-doodle"
  6. | "ink-wash"
  7. | "stage-documentary"
  8. | "modern-geometry"
  9. export type AiCoursewareTemplatePageRole =
  10. | "cover"
  11. | "intro"
  12. | "goal"
  13. | "story"
  14. | "listen"
  15. | "knowledge"
  16. | "interaction"
  17. | "performance"
  18. | "practice"
  19. | "activity"
  20. | "summary"
  21. | "content"
  22. export interface AiCoursewareThemePalette {
  23. primary: string
  24. secondary: string
  25. accent: string
  26. warm: string
  27. background: string
  28. surface: string
  29. soft: string
  30. text: string
  31. muted: string
  32. dark: string
  33. }
  34. export interface AiCoursewareTemplate {
  35. id: AiCoursewareTemplateId
  36. name: string
  37. sourceName: string
  38. scene: string
  39. description: string
  40. templateFile: string
  41. templateSlides: number
  42. baseStyle: "cartoon" | "clean"
  43. layoutFamily: "story" | "education" | "academic" | "culture" | "technology" | "activity"
  44. typography: string
  45. backgroundStyle: string
  46. illustrationStyle: string
  47. pageLayouts: Partial<Record<AiCoursewareTemplatePageRole, string>>
  48. visualPrompt: string
  49. palettes: [AiCoursewareThemePalette, AiCoursewareThemePalette, AiCoursewareThemePalette]
  50. }
  51. const playfulPalettes: AiCoursewareTemplate["palettes"] = [
  52. palette("#E64A78", "#168F86", "#F28C28", "#FFD66B", "#FFF9F5", "#EAF7F4", "#263238", "#6B7C8F", "#283B4A"),
  53. palette("#3478C8", "#32A07C", "#F08A3C", "#F7D66D", "#F7FBF8", "#E6F5EE", "#24333B", "#69808A", "#24495C"),
  54. palette("#7A5AC8", "#20A39E", "#EE6C78", "#FFD166", "#FBF8FF", "#F0EAFB", "#312D3D", "#756E84", "#3C3154")
  55. ]
  56. const freshPalettes: AiCoursewareTemplate["palettes"] = [
  57. palette("#2878C8", "#23967F", "#F19A3E", "#F6D365", "#F5FAFC", "#E5F4F1", "#20313A", "#6B7E88", "#244B5A"),
  58. palette("#347D73", "#4B8BBE", "#E07A5F", "#F2CC8F", "#F7FBFA", "#E4F1EE", "#21343A", "#687C82", "#284C52"),
  59. palette("#526FA8", "#5C9EAD", "#E98B73", "#F3C677", "#F7F9FC", "#E8EEF7", "#243040", "#6E7887", "#2C405F")
  60. ]
  61. const stagePalettes: AiCoursewareTemplate["palettes"] = [
  62. palette("#26344E", "#697C9B", "#C88B3D", "#E6C26D", "#F7F8FA", "#E9EDF3", "#172231", "#697586", "#1C2940"),
  63. palette("#4A3553", "#7E8EA8", "#C4725A", "#E2B567", "#FAF8FA", "#F0EBF1", "#2B2630", "#776F7A", "#392B40"),
  64. palette("#344B5C", "#4C7D7D", "#B96B49", "#DAB66F", "#F7FAFA", "#E7F0EF", "#1F3034", "#63777A", "#263F49")
  65. ]
  66. const orientalPalettes: AiCoursewareTemplate["palettes"] = [
  67. palette("#9D2B22", "#36594B", "#C58A35", "#D9B66F", "#F7F1E7", "#EFE5D4", "#332A24", "#746A5F", "#4A2722"),
  68. palette("#7D3530", "#446052", "#B07942", "#D6BC7C", "#F5F0E8", "#E9E1D4", "#302C28", "#706A62", "#3E302B"),
  69. palette("#6E3F63", "#496554", "#B4864C", "#DCC68C", "#F8F3EA", "#EEE5D8", "#342D33", "#766D74", "#45333F")
  70. ]
  71. const geometryPalettes: AiCoursewareTemplate["palettes"] = [
  72. palette("#287B72", "#4FAD93", "#E07A35", "#E9C66D", "#F8FBFA", "#E7F3EF", "#20342F", "#6B817A", "#1E5A52"),
  73. palette("#236D98", "#58A6A6", "#E08D50", "#EBCB7A", "#F7FAFC", "#E6F1F4", "#1D3038", "#678089", "#1E5967"),
  74. palette("#4B6E9B", "#76A48C", "#C87863", "#DCC280", "#FAFBF9", "#EDF2EA", "#273038", "#737E83", "#415B79")
  75. ]
  76. const doodlePalettes: AiCoursewareTemplate["palettes"] = [
  77. palette("#F05A47", "#13A89E", "#6C63D9", "#F6C945", "#FFF8F2", "#FDEBDD", "#2D2B36", "#756F7C", "#3A3550"),
  78. palette("#EC4899", "#0EA5A4", "#F97316", "#FACC15", "#FFF7FB", "#FCE7F3", "#302937", "#7A6D7D", "#46354D"),
  79. palette("#7C5CE7", "#18A999", "#F06449", "#FFD166", "#FAF8FF", "#ECE8FB", "#302D3C", "#746E82", "#403755")
  80. ]
  81. export const AI_COURSEWARE_TEMPLATES: AiCoursewareTemplate[] = [
  82. {
  83. id: "fairytale-forest",
  84. name: "童话森林",
  85. sourceName: "参考《动画音乐会》的童话场景语言",
  86. scene: "低年级歌曲与律动",
  87. description: "绘本场景、故事导入和童趣互动",
  88. templateFile: "/ai-courseware-templates/fairytale-forest.pptx",
  89. templateSlides: 4,
  90. baseStyle: "cartoon",
  91. layoutFamily: "story",
  92. typography: "圆润醒目的低龄课堂字体层级,标题短而大,正文不低于30px",
  93. backgroundStyle: "绘本式连续场景背景,保留大面积干净文字区",
  94. illustrationStyle: "统一儿童绘本插画,角色造型、服装和标志色跨页一致",
  95. pageLayouts: {
  96. cover: "cover_scene",
  97. intro: "story_stage",
  98. story: "story_stage",
  99. listen: "full_image_question",
  100. goal: "observe_question",
  101. interaction: "action_demo",
  102. activity: "action_demo",
  103. performance: "performance_stage",
  104. practice: "practice_check",
  105. summary: "visual_summary"
  106. },
  107. visualPrompt: "童话森林音乐课堂风格,画面亲切活泼,使用统一绘本场景、自然边框和明确文字区,避免商务卡片堆叠。",
  108. palettes: playfulPalettes
  109. },
  110. {
  111. id: "warm-handdrawn",
  112. name: "温暖手绘",
  113. sourceName: "参考《音乐小屋》的温暖手绘语言",
  114. scene: "小学音乐活动",
  115. description: "轻柔插画、情境聆听和课堂练习",
  116. templateFile: "/ai-courseware-templates/warm-handdrawn.pptx",
  117. templateSlides: 4,
  118. baseStyle: "clean",
  119. layoutFamily: "education",
  120. typography: "清晰现代的教学字体层级,标题明确,正文适合远距离投屏",
  121. backgroundStyle: "浅色教育场景与克制几何底纹",
  122. illustrationStyle: "简洁教育插画或真实课堂素材,主体明确",
  123. pageLayouts: {
  124. cover: "cover_scene",
  125. intro: "split_image",
  126. story: "split_image",
  127. listen: "listen_wave",
  128. goal: "goal_cards",
  129. knowledge: "knowledge_cards",
  130. interaction: "observe_question",
  131. activity: "activity_steps",
  132. practice: "practice_check",
  133. summary: "summary_checklist"
  134. },
  135. visualPrompt: "温暖手绘音乐课件风格,留白充足、结构清楚、色彩柔和,使用统一儿童手绘元素,兼顾教师讲解和学生远距离阅读。",
  136. palettes: freshPalettes
  137. },
  138. {
  139. id: "stage-documentary",
  140. name: "舞台纪实",
  141. sourceName: "参考《鼓乐》的写实音乐现场氛围",
  142. scene: "世界音乐与演出欣赏",
  143. description: "大图舞台、演出现场和音乐文化体验",
  144. templateFile: "/ai-courseware-templates/stage-documentary.pptx",
  145. templateSlides: 4,
  146. baseStyle: "clean",
  147. layoutFamily: "academic",
  148. typography: "具有演出节目单感的标题、正文和注释三级层级",
  149. backgroundStyle: "深浅对比的舞台画面与克制文字承载区",
  150. illustrationStyle: "写实演出、乐器和地域音乐素材优先",
  151. pageLayouts: {
  152. cover: "cover_scene",
  153. intro: "full_image_question",
  154. story: "split_image",
  155. listen: "compare_listen",
  156. goal: "goal_cards",
  157. knowledge: "knowledge_cards",
  158. interaction: "listen_compare_visual",
  159. practice: "practice_check",
  160. summary: "summary_checklist"
  161. },
  162. visualPrompt: "舞台纪实音乐课堂风格,以高质量演出或音乐文化大图建立氛围,文字置于清晰承载区,标题有节目单感,减少无关装饰。",
  163. palettes: stagePalettes
  164. },
  165. {
  166. id: "ink-wash",
  167. name: "水墨国风",
  168. sourceName: "参考《姑苏行》《十面埋伏》的东方意境",
  169. scene: "传统文化主题",
  170. description: "民歌、戏曲、民族音乐和传统节日",
  171. templateFile: "/ai-courseware-templates/ink-wash.pptx",
  172. templateSlides: 4,
  173. baseStyle: "clean",
  174. layoutFamily: "culture",
  175. typography: "现代中文标题与舒展正文层级",
  176. backgroundStyle: "米白纸感与克制东方纹样",
  177. illustrationStyle: "统一现代东方插画,避免素材拼贴",
  178. pageLayouts: {
  179. cover: "cover_scene",
  180. intro: "story_stage",
  181. story: "story_stage",
  182. listen: "full_image_question",
  183. goal: "observe_question",
  184. knowledge: "knowledge_cards",
  185. interaction: "action_demo",
  186. practice: "practice_check",
  187. summary: "visual_summary"
  188. },
  189. visualPrompt: "水墨国风音乐课堂风格,使用米白、黛色和朱砂色,借景留白、装饰克制,突出传统器乐意境与课堂可读性。",
  190. palettes: orientalPalettes
  191. },
  192. {
  193. id: "modern-geometry",
  194. name: "现代几何",
  195. sourceName: "参考《探索旋律结构的规律》的现代几何版式",
  196. scene: "项目学习与乐理分析",
  197. description: "结构讲解、旋律分析和知识项目展示",
  198. templateFile: "/ai-courseware-templates/modern-geometry.pptx",
  199. templateSlides: 4,
  200. baseStyle: "clean",
  201. layoutFamily: "technology",
  202. typography: "高对比现代标题与简洁正文层级",
  203. backgroundStyle: "浅色几何分区、轻量网格和清晰信息层级",
  204. illustrationStyle: "统一等距几何和音乐结构图形,避免无关赛博装饰",
  205. pageLayouts: {
  206. cover: "cover_scene",
  207. intro: "full_image_question",
  208. story: "full_image_question",
  209. listen: "sound_timeline",
  210. goal: "observe_question",
  211. knowledge: "knowledge_cards",
  212. interaction: "listen_compare_visual",
  213. practice: "practice_check",
  214. summary: "visual_summary"
  215. },
  216. visualPrompt: "现代几何音乐课堂风格,使用浅色几何分区、等距图形和绿色蓝色点缀,突出旋律结构、项目步骤和知识关系。",
  217. palettes: geometryPalettes
  218. },
  219. {
  220. id: "music-doodle",
  221. name: "音符涂鸦",
  222. sourceName: "参考《溜冰圆舞曲》的音符涂鸦语言",
  223. scene: "乐理、节奏与欣赏",
  224. description: "音符插画、节奏任务和轻松知识讲解",
  225. templateFile: "/ai-courseware-templates/music-doodle.pptx",
  226. templateSlides: 4,
  227. baseStyle: "cartoon",
  228. layoutFamily: "activity",
  229. typography: "大字号动作指令与清晰编号层级",
  230. backgroundStyle: "明快舞台或课堂活动场景",
  231. illustrationStyle: "统一动作示范插画,人物姿态清楚",
  232. pageLayouts: {
  233. cover: "cover_scene",
  234. intro: "full_image_question",
  235. story: "story_stage",
  236. listen: "listen_compare_visual",
  237. goal: "action_demo",
  238. interaction: "action_demo",
  239. activity: "group_mission",
  240. performance: "performance_stage",
  241. practice: "practice_check",
  242. summary: "visual_summary"
  243. },
  244. visualPrompt: "音符涂鸦音乐课堂风格,使用深蓝手绘音符、轻量星点和清晰任务编号,轻松但不幼稚,避免信息拥挤。",
  245. palettes: doodlePalettes
  246. }
  247. ]
  248. export function getAiCoursewareTemplate(id?: string) {
  249. return AI_COURSEWARE_TEMPLATES.find(template => template.id === id) || AI_COURSEWARE_TEMPLATES[1]
  250. }
  251. export function getAiCoursewarePalette(id: string | undefined, variant = 0) {
  252. const template = getAiCoursewareTemplate(id)
  253. return template.palettes[Math.abs(variant) % template.palettes.length]
  254. }
  255. export function recommendAiCoursewareTemplate(outline: AiCoursewareOutline): { id: AiCoursewareTemplateId; reason: string } {
  256. const text = [
  257. outline.title,
  258. outline.gradeName,
  259. outline.unitName,
  260. outline.chapterName,
  261. outline.courseType,
  262. ...(outline.pages || []).flatMap(page => [page.title, page.teachingStage, page.teachingPurpose])
  263. ]
  264. .filter(Boolean)
  265. .join(" ")
  266. if (/民歌|民族|戏曲|京剧|昆曲|古琴|国乐|传统|节日|非遗|中国风|民乐|古筝|二胡|琵琶/.test(text)) {
  267. return { id: "ink-wash", reason: "课程包含传统文化、民乐或民族音乐内容" }
  268. }
  269. if (/旋律结构|曲式|乐理|和声|分析|项目|探究|规律|结构/.test(text)) {
  270. return { id: "modern-geometry", reason: "课程以结构分析、项目探究或乐理讲解为主" }
  271. }
  272. if (/分组|小组|节奏游戏|律动|表演|展示|闯关|任务|活动|节拍|节奏/.test(text)) {
  273. return { id: "music-doodle", reason: "课程以节奏任务、互动练习或学生参与为主" }
  274. }
  275. if (/世界音乐|打击乐|鼓乐|管弦乐|交响乐|音乐会|舞台|演出|爵士|摇滚|非洲|拉丁/.test(text)) {
  276. return { id: "stage-documentary", reason: "课程适合以音乐现场或文化影像建立氛围" }
  277. }
  278. if (/[初高]中|七年级|八年级|九年级/.test(text)) {
  279. return { id: "stage-documentary", reason: "课程面向中学阶段,适合更成熟的演出与音乐文化视觉" }
  280. }
  281. if (/一年级|二年级|低年级|故事|童话|动物|情境|儿歌/.test(text)) {
  282. return { id: "fairytale-forest", reason: "课程面向低龄学生或采用故事化导入" }
  283. }
  284. return { id: "warm-handdrawn", reason: "适合常规小学音乐课的聆听、演唱与练习结构" }
  285. }
  286. function palette(
  287. primary: string,
  288. secondary: string,
  289. accent: string,
  290. warm: string,
  291. background: string,
  292. soft: string,
  293. text: string,
  294. muted: string,
  295. dark: string,
  296. surface = "#FFFFFF"
  297. ): AiCoursewareThemePalette {
  298. return { primary, secondary, accent, warm, background, surface, soft, text, muted, dark }
  299. }