| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- <template>
- <div v-if="words.length" class="word-pronunciation-display">
- <span
- v-for="(w, i) in words"
- :key="i"
- class="wpd-word"
- :class="`wpd-${classFor(w)}`"
- :title="`${w.word} · ${w.errorType} · ${Math.round(w.accuracyScore)}`"
- >{{ w.word }}</span>
- </div>
- </template>
- <script lang="ts" setup>
- import type { WordAnalysisItem } from '@/types/englishSpeaking'
- interface Props {
- words: WordAnalysisItem[]
- }
- defineProps<Props>()
- // 判定规则:
- // - Omission → missed(灰)
- // - Mispronunciation / Insertion → wrong(红)
- // - error_type=None 时按 accuracy_score 分层:
- // < 60 → wrong(红)
- // 60-79 → warning(橙)
- // ≥ 80 → correct(绿)
- function classFor(w: WordAnalysisItem): 'correct' | 'warning' | 'wrong' | 'missed' | 'ignored' {
- if (w.errorType === 'Omission') return 'missed'
- if (w.errorType === 'Mispronunciation' || w.errorType === 'Insertion') return 'wrong'
- if (w.errorType !== 'None') return 'ignored'
- const acc = w.accuracyScore
- if (acc < 60) return 'wrong'
- if (acc < 80) return 'warning'
- return 'correct'
- }
- </script>
- <style lang="scss" scoped>
- .word-pronunciation-display {
- font-size: 12px;
- color: #1f2937;
- line-height: 2;
- word-wrap: break-word;
- }
- .wpd-word {
- display: inline-block;
- margin-right: 8px;
- border-bottom: 2px solid transparent;
- padding-bottom: 1px;
- }
- .wpd-correct { border-bottom-color: #16a34a; }
- .wpd-warning { border-bottom-color: #f59e0b; }
- .wpd-wrong { border-bottom-color: #ef4444; }
- .wpd-missed { border-bottom-color: #9ca3af; }
- .wpd-ignored { border-bottom-color: transparent; }
- </style>
|