speaking.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import { defineStore } from 'pinia'
  2. import type {
  3. TopicDiscussionConfig,
  4. PracticeMode,
  5. ScoreMode,
  6. EvalDimensions,
  7. PreviewDialogueState,
  8. } from '@/types/englishSpeaking'
  9. const DEFAULT_CONFIG: TopicDiscussionConfig = {
  10. topic: 'How I get to school',
  11. grade: 'grade5-1',
  12. selectedRole: 'tom',
  13. learningGoals: {
  14. vocabulary: ['on foot', 'by bus', 'by bike', 'by car', 'by underground', 'bus stop', 'near', 'far from'],
  15. sentences: [
  16. 'How do you come to school?',
  17. 'I come to school by bus.',
  18. 'I come to school on foot.',
  19. 'Do you live near school?',
  20. 'I live far from school.',
  21. 'How long does it take?',
  22. ],
  23. },
  24. practice: {
  25. mode: 'time',
  26. rounds: 20,
  27. duration: 5,
  28. showEnglish: true,
  29. taskHint: true,
  30. stutterHint: true,
  31. },
  32. evaluation: {
  33. showReport: true,
  34. dimensions: {
  35. accuracy: true,
  36. fluency: true,
  37. completeness: true,
  38. rhythm: true,
  39. },
  40. scoreMode: 'letter',
  41. },
  42. }
  43. export const useSpeakingStore = defineStore('speaking', {
  44. state: () => ({
  45. config: { ...DEFAULT_CONFIG } as TopicDiscussionConfig,
  46. // 话题讨论预览当前阶段(由 TopicDiscussionPreview 同步)
  47. previewState: 'ready' as PreviewDialogueState,
  48. // 请求重置预览的递增信号(由 CanvasTool 触发 → TopicDiscussionPreview 监听)
  49. resetSignal: 0,
  50. // 请求打开配置面板的递增信号(由画布点击 77 型 frame 触发 → CollapsibleToolbar + SpeakingPanel 监听)
  51. openConfigSignal: 0,
  52. }),
  53. actions: {
  54. // 重置为默认配置
  55. resetConfig() {
  56. this.config = JSON.parse(JSON.stringify(DEFAULT_CONFIG))
  57. },
  58. setPreviewState(state: PreviewDialogueState) {
  59. this.previewState = state
  60. },
  61. requestResetPreview() {
  62. this.resetSignal += 1
  63. },
  64. openConfigPanel() {
  65. this.openConfigSignal += 1
  66. },
  67. // 用推荐卡片数据预填充
  68. prefillFromTask(topic: string, vocabulary: string[], sentences: string[]) {
  69. this.resetConfig()
  70. this.config.topic = topic
  71. this.config.learningGoals.vocabulary = [...vocabulary]
  72. this.config.learningGoals.sentences = [...sentences]
  73. },
  74. // 话题
  75. updateTopic(topic: string) {
  76. this.config.topic = topic
  77. },
  78. // 年级
  79. updateGrade(grade: string) {
  80. this.config.grade = grade
  81. },
  82. // 学习目标 - 词汇
  83. addVocabulary(word: string) {
  84. this.config.learningGoals.vocabulary.push(word)
  85. },
  86. removeVocabulary(index: number) {
  87. this.config.learningGoals.vocabulary.splice(index, 1)
  88. },
  89. // 学习目标 - 句型
  90. addSentence(sentence: string) {
  91. this.config.learningGoals.sentences.push(sentence)
  92. },
  93. removeSentence(index: number) {
  94. this.config.learningGoals.sentences.splice(index, 1)
  95. },
  96. updateSentence(index: number, sentence: string) {
  97. this.config.learningGoals.sentences[index] = sentence
  98. },
  99. // 练习设置
  100. updatePracticeMode(mode: PracticeMode) {
  101. this.config.practice.mode = mode
  102. },
  103. updateRounds(rounds: number) {
  104. this.config.practice.rounds = rounds
  105. },
  106. updateDuration(duration: number) {
  107. this.config.practice.duration = duration
  108. },
  109. togglePracticeSetting(key: 'showEnglish' | 'taskHint' | 'stutterHint') {
  110. this.config.practice[key] = !this.config.practice[key]
  111. },
  112. // 评估设置
  113. toggleShowReport() {
  114. this.config.evaluation.showReport = !this.config.evaluation.showReport
  115. },
  116. toggleEvalDimension(dimension: keyof EvalDimensions) {
  117. this.config.evaluation.dimensions[dimension] = !this.config.evaluation.dimensions[dimension]
  118. },
  119. updateScoreMode(scoreMode: ScoreMode) {
  120. this.config.evaluation.scoreMode = scoreMode
  121. },
  122. },
  123. })