aiPptSemanticDesign.mjs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { modelDesignFixture } from './aiPptModelDesign.mjs'
  2. // 复现测试环境暴露的内容组织问题,图片仅为本地渲染测试资源。
  3. export function semanticDesignFixture(imageUrl) {
  4. const outline = modelDesignFixture(imageUrl)
  5. const set = (i, title, headline, points, composition, mode = 'text_only', presentation = 'plain') => {
  6. const page = outline.pages[i]
  7. Object.assign(page, { title, subtitle: '', bullets: points, studentContent: { headline, points }, classroomAction: {}, interaction: null,
  8. image: mode === 'generated_image' ? { url: imageUrl, width: 960, height: 720 } : undefined, requiredVisual: false, resourceBindings: [],
  9. visualPlan: { composition, visualMode: mode, textPresentation: presentation, visualShare: .55, imageNecessity: mode === 'generated_image' ? 'supporting' : 'none', imagePurpose: mode === 'generated_image' ? 'scene' : 'none' } })
  10. return page
  11. }
  12. set(0, '凤鸣山谷的故事', '听听山谷里的声音', [], 'full_scene')
  13. set(3, '风与虎(对比听)', '听听风和虎', ['风的声音:有时强,有时弱', '老虎的声音:又长又沉'], 'comparison', 'generated_image', 'cards')
  14. const structured = set(4, '比较两种声音', '哪种声音更长?', ['说说你的发现'], 'comparison')
  15. structured.studentContent.comparisonGroups = [{ label: '风', points: ['声音有时强,有时弱'] }, { label: '老虎', points: ['声音又长又沉'] }]
  16. structured.classroomAction.studentTask = '用手势表现声音'
  17. set(5, '模仿小演员', '学学它们的声音', ['学小鸟叫', '学蜜蜂嗡嗡', '学风吹树叶', '学老虎吼叫'], 'steps', 'native_diagram', 'steps')
  18. set(6, '动物节奏队', '给动物配节奏', ['老虎:X - | X -', '蜜蜂:XX XX | XX XX'], 'concept_grid', 'native_diagram', 'grid')
  19. const steps = set(7, '合作小乐队', '和伙伴一起试试', [], 'steps', 'native_diagram', 'steps')
  20. steps.studentContent.steps = ['两人轮流拍一拍', '一起完成节奏']
  21. steps.classroomAction.studentTask = '听到提示后一起开始'
  22. steps.bullets = ['旧正文不应再次混入步骤']
  23. return outline
  24. }
  25. // 测试环境退化用例:大图下四条正文、仅 steps 有内容的排练页。
  26. export function densityRegressionFixture(imageUrl) {
  27. const outline = semanticDesignFixture(imageUrl)
  28. outline.textbookName = '人教版(2024版)一年级上册(新)'
  29. Object.assign(outline.pages[4], {
  30. title: '学一学:模仿动物叫', type: 'performance_activity', bullets: [],
  31. studentContent: { headline: '一起学动物叫', points: ['蛐蛐:细细的,yi-yi-yi', '蝈蝈:咯-咯-咯', '蜜蜂:嗡嗡嗡', '老虎:嗷~'] },
  32. classroomAction: { studentTask: '一起学动物叫' },
  33. image: { url: imageUrl, width: 1584, height: 560 }, resourceBindings: [],
  34. visualPlan: { composition: 'image_top', visualMode: 'generated_image', textPresentation: 'cards', visualShare: .65 }
  35. })
  36. Object.assign(outline.pages[8], {
  37. title: '分组排练:山谷音乐会', type: 'performance_activity', bullets: [], image: undefined, resourceBindings: [], requiredVisual: false,
  38. studentContent: { headline: '排练开始', points: [], steps: ['分好角色', '轮流练习', '一起合奏'] },
  39. classroomAction: { studentTask: '听老师指令,和组员一起练习' },
  40. visualPlan: { composition: 'steps', visualMode: 'native_diagram', textPresentation: 'steps', imagePurpose: 'none' }
  41. })
  42. return outline
  43. }
  44. // 最新线上主图过小:三条短提示被纵排,挤压横向场景图。
  45. export function heroImageRegressionFixture(imageUrl) {
  46. const outline = semanticDesignFixture(imageUrl)
  47. outline.textbookName = '人教版(2024版)一年级上册(新)'
  48. const scenes = [
  49. [0, 'cover', '凤鸣山谷的故事', '观看图片,记住角色名字。', ['凤凰小九', '伶伦', '麒麟麒麒']],
  50. [1, 'scene_intro', '走进凤鸣山谷', '仔细观察画面,说出看到的事物和想到的声音。', ['你看到了什么?', '听到了什么?', '谁住在山谷里?']],
  51. [11, 'summary', '回忆山谷之旅', '回忆并分享自己的收获。', ['今天我们学会了什么?', '声音有强、弱、长、短、高、低', '音乐是沟通的语言']]
  52. ]
  53. for (const [index, type, title, headline, points] of scenes) Object.assign(outline.pages[index], {
  54. type, title, bullets: points, subtitle: '', studentContent: { headline, points }, classroomAction: {}, interaction: null,
  55. image: { url: imageUrl, width: 1584, height: 560 }, resourceBindings: [], requiredVisual: true,
  56. visualPlan: { composition: index === 0 ? 'full_scene' : 'image_top', visualMode: 'generated_image', textPresentation: 'plain',
  57. visualShare: .55, imageNecessity: 'essential', imagePurpose: 'scene' }
  58. })
  59. return outline
  60. }