import React, { useEffect, useRef, useState } from 'react'
import { EXAMPLE_RATE, playSeq, setAudioRate, stopAudio } from '../audio'
+import { posToZh } from '../pos'
/**
* 循环播放(听学模式):整组无限循环,适合躺着只听。
*
* 默认序列模板(缺例句/搭配的词自动跳过对应段):
- * 1 单词 ×2 → 2 逐字母 → 3 中文含义+词性 → 4 例句 → 5 例句中文 → 6 搭配 → 7 搭配中文
+ * 1 单词 → 2 逐字母拼写 → 3 单词 → 4 逐字母拼写 → 5 中文含义+词性 → 6 例句 → 7 例句中文 → 8 搭配 → 9 搭配中文
+ * 拼写顺序遵循「一遍读音一遍拼写,一遍读音一遍拼写」。
*
* 播放统一走 audio.js 的单例播放器,避免切词/重复点击造成叠音。
*/
const BASE_LABEL = {
word: '单词',
- word2: '单词(第二遍)',
letters: '逐字母拼写',
zh: '中文含义',
example: '例句(慢速)',
if (!w) return []
const q = [
{ key: 'word', text: w.word, lang: 'en' },
- { key: 'word2', text: w.word, lang: 'en' },
{ key: 'letters', text: w.word.split('').join('-'), lang: 'en' },
- { key: 'zh', text: `${w.meaning || ''} ${w.pos || ''}`.trim(), lang: 'zh' },
+ { key: 'word', text: w.word, lang: 'en' },
+ { key: 'letters', text: w.word.split('').join('-'), lang: 'en' },
+ { key: 'zh', text: `${w.meaning || ''} ${posToZh(w.pos) || ''}`.trim(), lang: 'zh' },
]
if (w.example) {
q.push({ key: 'example', text: w.example, lang: 'en', rate: baseRate * EXAMPLE_RATE })
--- /dev/null
+// 词性缩写 → 中文朗读文本,供 TTS 使用。
+// 例:n. → 名词;n./v. → 名词/动词
+const POS_MAP = {
+ n: '名词',
+ v: '动词',
+ adj: '形容词',
+ adv: '副词',
+ prep: '介词',
+ conj: '连词',
+ pron: '代词',
+ num: '数词',
+ int: '感叹词',
+ art: '冠词',
+ aux: '助动词',
+ det: '限定词',
+ abbr: '缩写',
+ pl: '复数',
+ sb: '某人',
+ sth: '某物',
+}
+
+export function posToZh(pos) {
+ if (!pos) return ''
+ return String(pos)
+ .split('/')
+ .map((t) => {
+ const key = t.trim().replace(/\.$/, '').toLowerCase()
+ return POS_MAP[key] || t.trim()
+ })
+ .join('/')
+}