NormalModelChs.vue 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881
  1. <!-- -->
  2. <template>
  3. <div v-if="curQue" class="NNPE-ArticleView">
  4. <div
  5. v-if="
  6. ((curQue.mp3_list && curQue.mp3_list.length > 0 && curQue.mp3_list[0].url) ||
  7. config.isHasPY ||
  8. config.isHasEN) &&
  9. curQue.property.mp3_position === 'top'
  10. "
  11. class="aduioLine-box aduioLine-practice-npc"
  12. >
  13. <div class="aduioLine-content">
  14. <template v-if="curQue.mp3_list && curQue.mp3_list.length > 0 && curQue.mp3_list[0].url">
  15. <AudioLine
  16. ref="audioLine"
  17. audio-id="artNormalAudio"
  18. :mp3="curQue.mp3_list[0].url"
  19. :get-cur-time="getCurTime"
  20. :duration="curQue.mp3_list[0].media_duration"
  21. :mp3-source="curQue.mp3_list[0].source"
  22. :width="colLength == 2 ? 200 : 700"
  23. :ed="ed"
  24. type="audioLine"
  25. @emptyEd="emptyEd"
  26. :attrib="attrib"
  27. />
  28. </template>
  29. </div>
  30. <div class="aduioLine-right">
  31. <SvgIcon
  32. v-if="config.isHasPY"
  33. icon-class="pin-btn"
  34. size="16"
  35. :class="['pinyin-16', config.isShowPY ? '' : 'disabled']"
  36. :style="{ color: config.isShowPY ? (attrib ? attrib.topic_color : '') : '#DCDFE6' }"
  37. @click="changePinyin"
  38. />
  39. <SvgIcon
  40. v-if="config.isHasEN"
  41. icon-class="en-btn"
  42. size="16"
  43. :class="['EN-16', config.isShowEN ? '' : 'disabled']"
  44. :style="{ color: config.isShowEN ? (attrib ? attrib.topic_color : '') : '#DCDFE6' }"
  45. @click="changeEN"
  46. />
  47. </div>
  48. </div>
  49. <template v-if="!config.isHasEN || (config.isHasEN && !config.isShowEN)">
  50. <template v-if="resArr.length > 0">
  51. <div class="NPC-sentences-list">
  52. <div
  53. v-for="(item, index) in resArr"
  54. :key="'detail' + index"
  55. :class="['NNPE-detail', item.isTitle ? 'NNPE-detail-title' : '']"
  56. >
  57. <div
  58. class="wordsList-box"
  59. :class="[
  60. curQue.detail[index].paragraphAttr
  61. ? 'wordsList-box-' + curQue.detail[index].paragraphAttr.paragraphAlign
  62. : '',
  63. ]"
  64. >
  65. <img v-if="articleImg[0] && index == 0" :src="articleImg[index]" />
  66. <div :class="[item.isTitle ? 'NNPE-title' : '']">
  67. <div
  68. v-for="(pItem, pIndex) in item.wordsList"
  69. :key="'wordsList' + pIndex"
  70. class="NNPE-words"
  71. :class="[
  72. pItem.chs != '“' && pItem.wordIndex == 0 ? 'textLeft' : 'textCenter',
  73. pItem.chs == '“' ? 'textRight' : '',
  74. ]"
  75. @click="
  76. handleChangeTime(
  77. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  78. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  79. pItem.articleSentIndex,
  80. )
  81. "
  82. @mouseover="handleMouseover(pItem)"
  83. @mouseleave="handleMouseleave"
  84. >
  85. <template v-if="!pItem.width">
  86. <template v-if="pItem.isShow">
  87. <template
  88. v-if="
  89. item.wordsList[pIndex + 1] &&
  90. item.wordsList[pIndex + 1].chs &&
  91. (chsFhList.indexOf(item.wordsList[pIndex + 1].chs) > -1 ||
  92. NumberList.indexOf(item.wordsList[pIndex + 1].chs) > -1)
  93. "
  94. >
  95. <span v-if="pItem.leg > 0" class="NNPE-words-box">
  96. <span
  97. v-if="curQue.property.pinyin_position == 'top' && config.isShowPY && item.dhaspinyin"
  98. :class="[
  99. 'NNPE-pinyin',
  100. pItem.className ? pItem.className : '',
  101. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  102. ]"
  103. @click.stop="
  104. viewNotes(
  105. $event,
  106. pItem.pinyin,
  107. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  108. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  109. pItem.articleSentIndex,
  110. )
  111. "
  112. >{{ pItem.pinyin }}</span
  113. >
  114. <span
  115. class="NNPE-chs"
  116. :class="[
  117. item.timeList &&
  118. item.timeList[pItem.sentIndex] &&
  119. curTime >= item.timeList[pItem.sentIndex].bg &&
  120. curTime <= item.timeList[pItem.sentIndex].ed &&
  121. curTime
  122. ? 'active'
  123. : '',
  124. pItem.paraIndex == paraIndex && pItem.sentIndex == sentIndex ? 'overActive' : '',
  125. ]"
  126. :style="{
  127. fontFamily: pItem.config.fontFamily,
  128. height: '28px',
  129. display: 'inline-block',
  130. }"
  131. >
  132. <template>
  133. <span
  134. v-for="(wItem, wIndex) in pItem.leg"
  135. :key="'ci' + wIndex + pIndex + index"
  136. :class="[
  137. isPlaying &&
  138. pItem.chstimeList &&
  139. pItem.chstimeList[wIndex] &&
  140. curTime >= pItem.chstimeList[wIndex].wordBg &&
  141. curTime < item.timeList[pItem.sentIndex].ed
  142. ? 'wordActive'
  143. : '',
  144. ]"
  145. @click.stop="
  146. viewNotes(
  147. $event,
  148. pItem.chs[wIndex],
  149. item.timeList &&
  150. item.timeList[pItem.sentIndex] &&
  151. item.timeList[pItem.sentIndex].bg,
  152. item.timeList &&
  153. item.timeList[pItem.sentIndex] &&
  154. item.timeList[pItem.sentIndex].ed,
  155. pItem.articleSentIndex,
  156. )
  157. "
  158. >{{ NumberList.indexOf(pItem.pinyin) == -1 ? pItem.chs[wIndex] : '' }}</span
  159. >
  160. </template>
  161. </span>
  162. <span
  163. v-if="curQue.property.pinyin_position == 'bottom' && config.isShowPY && item.dhaspinyin"
  164. :class="[
  165. 'NNPE-pinyin',
  166. pItem.className ? pItem.className : '',
  167. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  168. ]"
  169. @click.stop="
  170. viewNotes(
  171. $event,
  172. pItem.pinyin,
  173. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  174. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  175. pItem.articleSentIndex,
  176. )
  177. "
  178. >{{ pItem.pinyin }}</span
  179. >
  180. </span>
  181. <span class="NNPE-words-box">
  182. <span
  183. v-if="curQue.property.pinyin_position == 'top' && config.isShowPY && item.dhaspinyin"
  184. :class="[
  185. 'NNPE-pinyin',
  186. noFont.indexOf(item.wordsList[pIndex + 1].pinyin) > -1 ? 'noFont' : '',
  187. ]"
  188. style="text-align: left"
  189. @click.stop="
  190. viewNotes(
  191. $event,
  192. item.wordsList[pIndex + 1].pinyin,
  193. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  194. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  195. pItem.articleSentIndex,
  196. )
  197. "
  198. >{{ item.wordsList[pIndex + 1].pinyin }}</span
  199. >
  200. <span
  201. class="NNPE-chs"
  202. style="text-align: left"
  203. :class="[
  204. isPlaying &&
  205. item.timeList &&
  206. item.timeList[pItem.sentIndex] &&
  207. curTime >= item.timeList[pItem.sentIndex].bg &&
  208. curTime <= item.timeList[pItem.sentIndex].ed &&
  209. curTime
  210. ? 'active'
  211. : '',
  212. pItem.paraIndex == paraIndex && pItem.sentIndex == sentIndex ? 'overActive' : '',
  213. pItem.chstimeList &&
  214. pItem.chstimeList[pItem.leg - 1] &&
  215. curTime >= pItem.chstimeList[pItem.leg - 1].wordBg &&
  216. curQue.wordTime &&
  217. curTime <= item.timeList[pItem.sentIndex].ed
  218. ? 'wordActive'
  219. : '',
  220. ]"
  221. :style="{
  222. fontFamily: item.wordsList[pIndex + 1].config.fontFamily,
  223. height: '28px',
  224. display: 'inline-block',
  225. width: item.wordsList[pIndex + 1].chs.trim() === '' ? '6px' : '',
  226. }"
  227. @click.stop="
  228. viewNotes(
  229. $event,
  230. item.wordsList[pIndex + 1].chs,
  231. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  232. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  233. pItem.articleSentIndex,
  234. )
  235. "
  236. >{{
  237. NumberList.indexOf(item.wordsList[pIndex + 1].pinyin) == -1
  238. ? item.wordsList[pIndex + 1].chs
  239. : ''
  240. }}</span
  241. >
  242. <span
  243. v-if="curQue.property.pinyin_position == 'bottom' && config.isShowPY && item.dhaspinyin"
  244. :class="[
  245. 'NNPE-pinyin',
  246. noFont.indexOf(item.wordsList[pIndex + 1].pinyin) > -1 ? 'noFont' : '',
  247. ]"
  248. style="text-align: left"
  249. @click.stop="
  250. viewNotes(
  251. $event,
  252. item.wordsList[pIndex + 1].pinyin,
  253. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  254. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  255. pItem.articleSentIndex,
  256. )
  257. "
  258. >{{ item.wordsList[pIndex + 1].pinyin }}</span
  259. >
  260. </span>
  261. <span
  262. v-if="
  263. item.wordsList[pIndex + 2] &&
  264. item.wordsList[pIndex + 2].chs &&
  265. (chsFhList.indexOf(item.wordsList[pIndex + 2].chs) > -1 ||
  266. NumberList.indexOf(item.wordsList[pIndex + 2].chs) > -1)
  267. "
  268. class="NNPE-words-box"
  269. >
  270. <span
  271. v-if="curQue.property.pinyin_position == 'top' && config.isShowPY && item.dhaspinyin"
  272. :class="[
  273. 'NNPE-pinyin',
  274. noFont.indexOf(item.wordsList[pIndex + 2].pinyin) > -1 ? 'noFont' : '',
  275. ]"
  276. style="text-align: left"
  277. @click.stop="
  278. viewNotes(
  279. $event,
  280. item.wordsList[pIndex + 2].pinyin,
  281. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  282. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  283. pItem.articleSentIndex,
  284. )
  285. "
  286. >{{ item.wordsList[pIndex + 2].pinyin }}</span
  287. >
  288. <span
  289. class="NNPE-chs"
  290. style="text-align: left"
  291. :class="[
  292. isPlaying &&
  293. item.timeList &&
  294. item.timeList[pItem.sentIndex] &&
  295. curTime >= item.timeList[pItem.sentIndex].bg &&
  296. curTime <= item.timeList[pItem.sentIndex].ed &&
  297. curTime
  298. ? 'active'
  299. : '',
  300. pItem.paraIndex == paraIndex && pItem.sentIndex == sentIndex ? 'overActive' : '',
  301. pItem.chstimeList &&
  302. pItem.chstimeList[pItem.leg - 1] &&
  303. curTime >= pItem.chstimeList[pItem.leg - 1].wordBg &&
  304. curQue.wordTime &&
  305. curTime <= item.timeList[pItem.sentIndex].ed
  306. ? 'wordActive'
  307. : '',
  308. ]"
  309. :style="{
  310. fontFamily: item.wordsList[pIndex + 2].config.fontFamily,
  311. height: '28px',
  312. display: 'inline-block',
  313. width: item.wordsList[pIndex + 2].chs.trim() === '' ? '6px' : '',
  314. }"
  315. @click.stop="
  316. viewNotes(
  317. $event,
  318. item.wordsList[pIndex + 2].chs,
  319. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  320. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  321. pItem.articleSentIndex,
  322. )
  323. "
  324. >{{
  325. NumberList.indexOf(item.wordsList[pIndex + 2].pinyin) == -1
  326. ? item.wordsList[pIndex + 2].chs
  327. : ''
  328. }}</span
  329. >
  330. <span
  331. v-if="curQue.property.pinyin_position == 'bottom' && config.isShowPY && item.dhaspinyin"
  332. :class="[
  333. 'NNPE-pinyin',
  334. noFont.indexOf(item.wordsList[pIndex + 2].pinyin) > -1 ? 'noFont' : '',
  335. ]"
  336. style="text-align: left"
  337. @click.stop="
  338. viewNotes(
  339. $event,
  340. item.wordsList[pIndex + 2].pinyin,
  341. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  342. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  343. pItem.articleSentIndex,
  344. )
  345. "
  346. >{{ item.wordsList[pIndex + 2].pinyin }}</span
  347. >
  348. </span>
  349. </template>
  350. <template v-else>
  351. <span
  352. v-if="curQue.property.pinyin_position == 'top' && config.isShowPY && item.dhaspinyin"
  353. class="NNPE-pinyin"
  354. :class="[
  355. pItem.chs != '“' && pItem.padding ? 'padding' : '',
  356. pItem.className ? pItem.className : '',
  357. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  358. ]"
  359. @click.stop="
  360. viewNotes(
  361. $event,
  362. pItem.pinyin,
  363. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  364. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  365. pItem.articleSentIndex,
  366. )
  367. "
  368. >{{ pItem.pinyin }}</span
  369. >
  370. <span
  371. class="NNPE-chs"
  372. :class="[
  373. item.timeList &&
  374. item.timeList[pItem.sentIndex] &&
  375. curTime >= item.timeList[pItem.sentIndex].bg &&
  376. curTime <= item.timeList[pItem.sentIndex].ed &&
  377. curTime
  378. ? 'active'
  379. : '',
  380. pItem.chs != '“' && pItem.padding && config.isShowPY ? 'padding' : '',
  381. pItem.paraIndex == paraIndex && pItem.sentIndex == sentIndex ? 'overActive' : '',
  382. ]"
  383. >
  384. <template>
  385. <span
  386. v-for="(wItem, wIndex) in pItem.leg"
  387. :key="'ci' + wIndex + pIndex + index"
  388. :class="[
  389. isPlaying &&
  390. pItem.chstimeList &&
  391. pItem.chstimeList[wIndex] &&
  392. curTime >= pItem.chstimeList[wIndex].wordBg &&
  393. curTime < item.timeList[pItem.sentIndex].ed
  394. ? 'wordActive'
  395. : '',
  396. ]"
  397. :style="{
  398. fontFamily: pItem.config.fontFamily,
  399. height: '28px',
  400. display: 'inline-block',
  401. width: pItem.chs[wIndex].trim() === '' ? '6px' : '',
  402. }"
  403. @click.stop="
  404. viewNotes(
  405. $event,
  406. pItem.chs[wIndex],
  407. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  408. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  409. pItem.articleSentIndex,
  410. )
  411. "
  412. >{{ NumberList.indexOf(pItem.pinyin) == -1 ? pItem.chs[wIndex] : '' }}</span
  413. >
  414. </template>
  415. </span>
  416. <span
  417. v-if="curQue.property.pinyin_position == 'bottom' && config.isShowPY && item.dhaspinyin"
  418. class="NNPE-pinyin"
  419. :class="[
  420. pItem.chs != '“' && pItem.padding ? 'padding' : '',
  421. pItem.className ? pItem.className : '',
  422. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  423. ]"
  424. @click.stop="
  425. viewNotes(
  426. $event,
  427. pItem.pinyin,
  428. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].bg,
  429. item.timeList && item.timeList[pItem.sentIndex] && item.timeList[pItem.sentIndex].ed,
  430. pItem.articleSentIndex,
  431. )
  432. "
  433. >{{ pItem.pinyin }}</span
  434. >
  435. </template>
  436. </template>
  437. </template>
  438. <template v-else>
  439. <span
  440. :style="{
  441. height: pItem.height + 'px',
  442. width: pItem.width + 'px',
  443. }"
  444. ></span>
  445. </template>
  446. </div>
  447. </div>
  448. <div
  449. class="multilingual-para"
  450. :class="[item.isTitle ? 'multilingual-para-center' : '']"
  451. v-if="curQue.property.multilingual_position === 'para'"
  452. >
  453. {{
  454. curQue.detail[index].multilingualTextList && curQue.detail[index].multilingualTextList[multilingual]
  455. ? curQue.detail[index].multilingualTextList[multilingual].join(' ')
  456. : ''
  457. }}
  458. </div>
  459. <img v-if="articleImg[index + 1]" :src="articleImg[index + 1]" />
  460. </div>
  461. </div>
  462. </div>
  463. </template>
  464. </template>
  465. <template v-else>
  466. <template v-if="resObj">
  467. <!-- -->
  468. <div class="NPC-sentences-list">
  469. <div
  470. v-for="(item, index) in resObj.sentList"
  471. :key="'detail' + index"
  472. :class="['NNPE-detail-box', sentIndex == index ? 'active' : '']"
  473. >
  474. <div
  475. :class="['NNPE-details']"
  476. @click="
  477. handleChangeTime(
  478. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  479. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  480. index,
  481. )
  482. "
  483. >
  484. <div
  485. v-if="item.enwords && config.isShowEN && curQue.enPosition && curQue.enPosition == 'top'"
  486. :class="['enwords', sentIndex == index ? 'wordBlank' : '']"
  487. >
  488. {{ item.enwords }}
  489. </div>
  490. <div style="overflow: hidden; clear: both"></div>
  491. <div
  492. v-for="(pItem, pIndex) in item.sentArr"
  493. :key="'wordsList' + pIndex"
  494. class="NNPE-words"
  495. :class="[
  496. pItem.chs != '“' && pItem.wordIndex == 0 ? 'textLeft' : 'textCenter',
  497. pItem.chs == '“' ? 'textRight' : '',
  498. ]"
  499. >
  500. <template v-if="!pItem.width">
  501. <template v-if="pItem.isShow">
  502. <template
  503. v-if="
  504. item.sentArr[pIndex + 1] &&
  505. item.sentArr[pIndex + 1].chs &&
  506. (chsFhList.indexOf(item.sentArr[pIndex + 1].chs) > -1 ||
  507. NumberList.indexOf(item.sentArr[pIndex + 1].chs) > -1)
  508. "
  509. >
  510. <span class="NNPE-words-box">
  511. <template v-if="curQue.property.pinyin_position == 'top'">
  512. <span
  513. v-if="config.isShowPY"
  514. class="NNPE-pinyin"
  515. :class="[
  516. pItem.className ? pItem.className : '',
  517. sentIndex == index ? 'wordBlank' : '',
  518. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  519. ]"
  520. @click.stop="
  521. viewNotes(
  522. $event,
  523. pItem.pinyin,
  524. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  525. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  526. index,
  527. )
  528. "
  529. >{{ pItem.pinyin }}</span
  530. >
  531. </template>
  532. <span
  533. class="NNPE-chs"
  534. :class="[
  535. pItem.padding && config.isShowPY ? 'padding' : '',
  536. sentIndex == index ? 'wordBlank' : '',
  537. ]"
  538. >
  539. <template>
  540. <span
  541. v-for="(wItem, wIndex) in pItem.leg"
  542. :key="'ci' + wIndex + pIndex + index"
  543. :class="[
  544. pItem.timeList[wIndex] &&
  545. curTime >= pItem.timeList[wIndex].wordBg &&
  546. curTime <= curQue.wordTime[index].ed &&
  547. curTime
  548. ? 'active'
  549. : '',
  550. sentIndex == index ? 'wordBlank' : '',
  551. ]"
  552. :style="{
  553. fontFamily: pItem.config.fontFamily,
  554. height: '28px',
  555. display: 'inline-block',
  556. width: pItem.chs[wIndex].trim() === '' ? '6px' : '',
  557. }"
  558. @click.stop="
  559. viewNotes(
  560. $event,
  561. pItem.chs[wIndex],
  562. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  563. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  564. index,
  565. )
  566. "
  567. >{{ NumberList.indexOf(pItem.pinyin) == -1 ? pItem.chs[wIndex] : '' }}</span
  568. >
  569. </template>
  570. </span>
  571. <template v-if="curQue.property.pinyin_position == 'bottom'">
  572. <span
  573. v-if="config.isShowPY"
  574. class="NNPE-pinyin"
  575. :class="[
  576. pItem.className ? pItem.className : '',
  577. sentIndex == index ? 'wordBlank' : '',
  578. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  579. ]"
  580. @click.stop="
  581. viewNotes(
  582. $event,
  583. pItem.pinyin,
  584. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  585. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  586. index,
  587. )
  588. "
  589. >{{ pItem.pinyin }}</span
  590. >
  591. </template>
  592. </span>
  593. <span class="NNPE-words-box">
  594. <template v-if="curQue.property.pinyin_position == 'top'">
  595. <span
  596. v-if="config.isShowPY"
  597. :class="[
  598. 'NNPE-pinyin',
  599. sentIndex == index ? 'wordBlank' : '',
  600. noFont.indexOf(item.sentArr[pIndex + 1].pinyin) > -1 ? 'noFont' : '',
  601. ]"
  602. style="text-align: left"
  603. @click.stop="
  604. viewNotes(
  605. $event,
  606. item.sentArr[pIndex + 1].pinyin,
  607. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  608. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  609. index,
  610. )
  611. "
  612. >{{ item.sentArr[pIndex + 1].pinyin }}</span
  613. >
  614. </template>
  615. <span class="NNPE-chs" style="text-align: left">
  616. <span
  617. :class="[
  618. pItem.timeList[pItem.leg - 1] &&
  619. curQue.wordTime &&
  620. curTime >= pItem.timeList[pItem.leg - 1].wordBg &&
  621. curTime <= curQue.wordTime[index].ed &&
  622. curTime
  623. ? 'active'
  624. : '',
  625. sentIndex == index ? 'wordBlank' : '',
  626. ]"
  627. :style="{
  628. fontFamily: item.sentArr[pIndex + 1].config.fontFamily,
  629. height: '28px',
  630. display: 'inline-block',
  631. width: item.sentArr[pIndex + 1].chs.trim() === '' ? '6px' : '',
  632. }"
  633. @click.stop="
  634. viewNotes(
  635. $event,
  636. item.sentArr[pIndex + 1].chs,
  637. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  638. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  639. index,
  640. )
  641. "
  642. >
  643. {{
  644. NumberList.indexOf(item.sentArr[pIndex + 1].pinyin) == -1
  645. ? item.sentArr[pIndex + 1].chs
  646. : ''
  647. }}</span
  648. >
  649. </span>
  650. <template v-if="curQue.property.pinyin_position == 'bottom'">
  651. <span
  652. v-if="config.isShowPY"
  653. :class="[
  654. 'NNPE-pinyin',
  655. sentIndex == index ? 'wordBlank' : '',
  656. noFont.indexOf(item.sentArr[pIndex + 1].pinyin) > -1 ? 'noFont' : '',
  657. ]"
  658. style="text-align: left"
  659. @click.stop="
  660. viewNotes(
  661. $event,
  662. item.sentArr[pIndex + 1].pinyin,
  663. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  664. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  665. index,
  666. )
  667. "
  668. >{{ item.sentArr[pIndex + 1].pinyin }}</span
  669. >
  670. </template>
  671. </span>
  672. <span
  673. v-if="
  674. item.sentArr[pIndex + 2] &&
  675. item.sentArr[pIndex + 2].chs &&
  676. chsFhList.indexOf(item.sentArr[pIndex + 2].chs) > -1
  677. "
  678. class="NNPE-words-box"
  679. >
  680. <template v-if="curQue.property.pinyin_position == 'top'">
  681. <span
  682. v-if="config.isShowPY"
  683. :class="[
  684. 'NNPE-pinyin',
  685. sentIndex == index ? 'wordBlank' : '',
  686. noFont.indexOf(item.sentArr[pIndex + 2].pinyin) > -1 ? 'noFont' : '',
  687. ]"
  688. style="text-align: left"
  689. @click.stop="
  690. viewNotes(
  691. $event,
  692. item.sentArr[pIndex + 2].pinyin,
  693. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  694. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  695. index,
  696. )
  697. "
  698. >{{ item.sentArr[pIndex + 2].pinyin }}</span
  699. >
  700. </template>
  701. <span class="NNPE-chs" style="text-align: left">
  702. <span
  703. :class="[
  704. pItem.timeList[pItem.leg - 1] &&
  705. curQue.wordTime &&
  706. curTime >= pItem.timeList[pItem.leg - 1].wordBg &&
  707. curTime <= curQue.wordTime[index].ed &&
  708. curTime
  709. ? 'active'
  710. : '',
  711. sentIndex == index ? 'wordBlank' : '',
  712. ]"
  713. :style="{
  714. fontFamily: item.sentArr[pIndex + 2].config.fontFamily,
  715. height: '28px',
  716. display: 'inline-block',
  717. width: item.sentArr[pIndex + 2].chs.trim() === '' ? '6px' : '',
  718. }"
  719. @click.stop="
  720. viewNotes(
  721. $event,
  722. item.sentArr[pIndex + 2].chs,
  723. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  724. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  725. index,
  726. )
  727. "
  728. >
  729. {{
  730. NumberList.indexOf(item.sentArr[pIndex + 2].pinyin) == -1
  731. ? item.sentArr[pIndex + 2].chs
  732. : ''
  733. }}</span
  734. >
  735. </span>
  736. <template v-if="curQue.property.pinyin_position == 'bottom'">
  737. <span
  738. v-if="config.isShowPY"
  739. :class="[
  740. 'NNPE-pinyin',
  741. sentIndex == index ? 'wordBlank' : '',
  742. noFont.indexOf(item.sentArr[pIndex + 2].pinyin) > -1 ? 'noFont' : '',
  743. ]"
  744. style="text-align: left"
  745. @click.stop="
  746. viewNotes(
  747. $event,
  748. item.sentArr[pIndex + 2].pinyin,
  749. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  750. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  751. index,
  752. )
  753. "
  754. >{{ item.sentArr[pIndex + 2].pinyin }}</span
  755. >
  756. </template>
  757. </span>
  758. </template>
  759. <template v-else>
  760. <template v-if="curQue.property.pinyin_position == 'top'">
  761. <span
  762. v-if="config.isShowPY"
  763. class="NNPE-pinyin"
  764. :class="[
  765. pItem.chs != '“' && pItem.padding ? 'padding' : '',
  766. pItem.className ? pItem.className : '',
  767. sentIndex == index ? 'wordBlank' : '',
  768. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  769. ]"
  770. @click.stop="
  771. viewNotes(
  772. $event,
  773. pItem.pinyin,
  774. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  775. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  776. index,
  777. )
  778. "
  779. >{{ pItem.pinyin }}</span
  780. >
  781. </template>
  782. <span
  783. class="NNPE-chs"
  784. :class="[
  785. pItem.chs != '“' && pItem.padding && config.isShowPY ? 'padding' : '',
  786. sentIndex == index ? 'wordBlank' : '',
  787. ]"
  788. >
  789. <template>
  790. <span
  791. v-for="(wItem, wIndex) in pItem.leg"
  792. :key="'ci' + wIndex + pIndex + index"
  793. :class="[
  794. pItem.timeList[wIndex] &&
  795. curQue.wordTime &&
  796. curQue.wordTime[index] &&
  797. curTime >= pItem.timeList[wIndex].wordBg &&
  798. curTime <= curQue.wordTime[index].ed
  799. ? 'active'
  800. : '',
  801. sentIndex == index ? 'wordBlank' : '',
  802. ]"
  803. :style="{
  804. fontFamily: pItem.config.fontFamily,
  805. height: '28px',
  806. display: 'inline-block',
  807. width: pItem.chs[wIndex].trim() === '' ? '6px' : '',
  808. }"
  809. @click.stop="
  810. viewNotes(
  811. $event,
  812. pItem.chs[wIndex],
  813. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  814. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  815. index,
  816. )
  817. "
  818. >{{ NumberList.indexOf(pItem.pinyin) == -1 ? pItem.chs[wIndex] : '' }}</span
  819. >
  820. </template>
  821. </span>
  822. <template v-if="curQue.property.pinyin_position == 'bottom'">
  823. <span
  824. v-if="config.isShowPY"
  825. class="NNPE-pinyin"
  826. :class="[
  827. pItem.chs != '“' && pItem.padding ? 'padding' : '',
  828. pItem.className ? pItem.className : '',
  829. sentIndex == index ? 'wordBlank' : '',
  830. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  831. ]"
  832. @click.stop="
  833. viewNotes(
  834. $event,
  835. pItem.pinyin,
  836. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
  837. curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
  838. index,
  839. )
  840. "
  841. >{{ pItem.pinyin }}</span
  842. >
  843. </template>
  844. </template>
  845. </template>
  846. </template>
  847. <template v-else>
  848. <span
  849. :style="{
  850. height: pItem.height + 'px',
  851. width: pItem.width + 'px',
  852. }"
  853. ></span>
  854. </template>
  855. </div>
  856. <div style="overflow: hidden; clear: both"></div>
  857. <div
  858. v-if="
  859. item.enwords &&
  860. config.isShowEN &&
  861. (!curQue.enPosition || (curQue.enPosition && curQue.enPosition == 'bottom'))
  862. "
  863. :class="['enwords', sentIndex == index ? 'wordBlank' : '']"
  864. >
  865. {{ item.enwords }}
  866. </div>
  867. </div>
  868. <div
  869. class="multilingual-para"
  870. :class="[item.isTitle ? 'multilingual-para-center' : '']"
  871. v-if="curQue.property.multilingual_position === 'para'"
  872. >
  873. {{ multilingualTextList[multilingual] ? multilingualTextList[multilingual].join(' ') : '' }}
  874. </div>
  875. </div>
  876. </div>
  877. </template>
  878. </template>
  879. <div class="multilingual" v-for="(items, indexs) in curQue.detail" :key="indexs">
  880. <div
  881. class="multilingual-para"
  882. :class="[items.isTitle ? 'multilingual-para-center' : '']"
  883. v-if="curQue.property.multilingual_position === 'all'"
  884. >
  885. {{
  886. items.multilingualTextList && items.multilingualTextList[multilingual]
  887. ? items.multilingualTextList[multilingual].join(' ')
  888. : ''
  889. }}
  890. </div>
  891. </div>
  892. <div
  893. v-if="
  894. ((curQue.mp3_list && curQue.mp3_list.length > 0 && curQue.mp3_list[0].url) ||
  895. config.isHasPY ||
  896. config.isHasEN) &&
  897. curQue.property.mp3_position === 'bottom'
  898. "
  899. class="aduioLine-box aduioLine-practice-npc aduioLine-box-bottom"
  900. >
  901. <div class="aduioLine-content">
  902. <template v-if="curQue.mp3_list && curQue.mp3_list.length > 0 && curQue.mp3_list[0].url">
  903. <AudioLine
  904. ref="audioLine"
  905. audio-id="artNormalAudio"
  906. :mp3="curQue.mp3_list[0].url"
  907. :get-cur-time="getCurTime"
  908. :duration="curQue.mp3_list[0].media_duration"
  909. :mp3-source="curQue.mp3_list[0].source"
  910. :width="colLength == 2 ? 200 : 700"
  911. :ed="ed"
  912. type="audioLine"
  913. @emptyEd="emptyEd"
  914. :attrib="attrib"
  915. />
  916. </template>
  917. </div>
  918. <div class="aduioLine-right">
  919. <SvgIcon
  920. v-if="config.isHasPY"
  921. icon-class="pin-btn"
  922. size="16"
  923. :class="['pinyin-16', config.isShowPY ? '' : 'disabled']"
  924. :style="{ color: config.isShowPY ? (attrib ? attrib.topic_color : '') : '#DCDFE6' }"
  925. @click="changePinyin"
  926. />
  927. <SvgIcon
  928. v-if="config.isHasEN"
  929. icon-class="en-btn"
  930. size="16"
  931. :class="['EN-16', config.isShowEN ? '' : 'disabled']"
  932. :style="{ color: config.isShowEN ? (attrib ? attrib.topic_color : '') : '#DCDFE6' }"
  933. @click="changeEN"
  934. />
  935. </div>
  936. </div>
  937. <template v-if="isNoteShow">
  938. <div
  939. ref="notecard"
  940. class="NNPE-noteDetail"
  941. :style="{
  942. marginLeft: windowWidth > 642 ? '-321px' : '0px',
  943. left: windowWidth > 642 ? '' : '0px',
  944. }"
  945. >
  946. <Notecard :item="curNoteCon" :change-card="changeCard" :attrib="attrib" />
  947. </div>
  948. </template>
  949. </div>
  950. </template>
  951. <script>
  952. import AudioLine from '../voice_matrix/components/AudioLine.vue';
  953. import Notecard from './components/Notecard.vue';
  954. export default {
  955. name: 'NormalModelChs',
  956. components: {
  957. AudioLine,
  958. Notecard,
  959. },
  960. props: ['curQue', 'noFont', 'config', 'NNPEAnnotationList', 'colLength', 'themeColor', 'multilingual', 'attrib'],
  961. data() {
  962. return {
  963. resArr: [],
  964. resObj: null,
  965. curTime: 0, // 单位s
  966. chsFhList: [',', '。', '”', ':', '》', '?', '!', ';', '#', '、'],
  967. enFhList: [',', '.', ';', '?', '!', ':', '>', '<'],
  968. NumberList: ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳'],
  969. newWords: ['鱼', '辩礼义'],
  970. oldHz: '',
  971. hz: '',
  972. top: 0,
  973. left: 0,
  974. articleImg: {}, // 文章图片
  975. paraIndex: -1, // 段落索引
  976. sentIndex: -1, // 句子索引
  977. ed: undefined,
  978. noteNum: '',
  979. curNoteCon: null,
  980. isNoteShow: false,
  981. oldNoteNum: '',
  982. clientY: 0,
  983. contentWidth: 732,
  984. windowWidth: window.innerWidth,
  985. };
  986. },
  987. computed: {
  988. isPlaying() {
  989. let playing = false;
  990. if (this.$refs.audioLine) {
  991. playing = this.$refs.audioLine.audio.isPlaying;
  992. }
  993. return playing;
  994. },
  995. },
  996. watch: {
  997. noteNum: {
  998. handler(val, oldVal) {
  999. let _this = this;
  1000. if (val) {
  1001. _this.handleNote(val);
  1002. }
  1003. },
  1004. // 深度观察监听
  1005. deep: true,
  1006. },
  1007. isNoteShow: {
  1008. handler(val, oldVal) {
  1009. let _this = this;
  1010. if (val) {
  1011. setTimeout(() => {
  1012. _this.cardHeight = _this.$refs.notecard.offsetHeight;
  1013. if (_this.screenHeight - _this.clientY > _this.cardHeight) {
  1014. _this.top = _this.clientY + 20;
  1015. } else {
  1016. _this.top = _this.clientY - _this.cardHeight - 30;
  1017. }
  1018. }, 50);
  1019. }
  1020. },
  1021. // 深度观察监听
  1022. deep: true,
  1023. },
  1024. curQue: {
  1025. handler(val, oldVal) {
  1026. if (val) {
  1027. this.handleData();
  1028. }
  1029. },
  1030. // 深度观察监听
  1031. deep: true,
  1032. },
  1033. },
  1034. // 生命周期 - 创建完成(可以访问当前this实例)
  1035. created() {},
  1036. // 生命周期 - 挂载完成(可以访问DOM元素)
  1037. mounted() {
  1038. if (this.curQue) {
  1039. this.handleData();
  1040. }
  1041. },
  1042. beforeCreate() {}, // 生命周期 - 创建之前
  1043. beforeMount() {}, // 生命周期 - 挂载之前
  1044. beforeUpdate() {}, // 生命周期 - 更新之前
  1045. updated() {}, // 生命周期 - 更新之后
  1046. beforeDestroy() {}, // 生命周期 - 销毁之前
  1047. destroyed() {}, // 生命周期 - 销毁完成
  1048. activated() {},
  1049. // 方法集合
  1050. methods: {
  1051. // 拼音的显示和隐藏
  1052. changePinyin() {
  1053. if (this.config.isHasPY) {
  1054. this.$emit('changeConfig', 'isShowPY');
  1055. }
  1056. },
  1057. // 英文的显示和隐藏
  1058. changeEN() {
  1059. if (this.config.isHasEN) {
  1060. this.$emit('changeConfig', 'isShowEN');
  1061. }
  1062. },
  1063. getCurTime(curTime) {
  1064. this.curTime = curTime * 1000;
  1065. this.getSentIndex(this.curTime);
  1066. },
  1067. getSentIndex(curTime) {
  1068. if (this.curQue.wordTime) {
  1069. for (let i = 0; i < this.curQue.wordTime.length; i++) {
  1070. let bg = this.curQue.wordTime[i].bg;
  1071. let ed = this.curQue.wordTime[i].ed;
  1072. if (curTime >= bg && curTime <= ed) {
  1073. this.sentIndex = i;
  1074. break;
  1075. }
  1076. }
  1077. }
  1078. },
  1079. handleData() {
  1080. let resArr = [];
  1081. let curQue = JSON.parse(JSON.stringify(this.curQue));
  1082. let wordTimeList = curQue.wordTime;
  1083. let asIndex = 0;
  1084. let dhaspinyin = false; // 每段是否有拼音
  1085. curQue.detail.forEach((dItem, dIndex) => {
  1086. dhaspinyin = false;
  1087. let paraArr = [];
  1088. if (!dItem.isTitle) {
  1089. paraArr = [
  1090. {
  1091. pinyin: '',
  1092. chs: '',
  1093. width: 20,
  1094. height: 20,
  1095. },
  1096. {
  1097. width: 20,
  1098. height: 20,
  1099. pinyin: '',
  1100. chs: '',
  1101. },
  1102. ];
  1103. }
  1104. dItem.wordsList.forEach((sItem, sIndex) => {
  1105. let sentArr = [];
  1106. sItem.forEach((wItem, wIndex) => {
  1107. let startIndex = wIndex == 0 ? 0 : sentArr[wIndex - 1].startIndex + sentArr[wIndex - 1].chs.length;
  1108. let endIndex = wIndex == 0 ? wItem.chs.length : sentArr[wIndex - 1].endIndex + wItem.chs.length;
  1109. this.mergeWordSymbol(wItem);
  1110. let obj = {
  1111. paraIndex: dIndex, // 段落索引
  1112. sentIndex: sIndex, // 在段落中句子索引
  1113. articleSentIndex: asIndex, // 在文章中句子索引
  1114. wordIndex: wIndex, // 单词的索引
  1115. pinyin:
  1116. curQue.pinyin_type === 'pinyin'
  1117. ? curQue.property.is_first_sentence_first_hz_pinyin_first_char_upper_case === 'true' && wIndex === 0
  1118. ? wItem.pinyin_up
  1119. : wItem.pinyin
  1120. : wItem.pinyin_tone,
  1121. chs: wItem.chs,
  1122. padding: true, // wItem.padding,
  1123. className: wItem.className,
  1124. isShow: wItem.isShow,
  1125. isNewWord: this.newWords.indexOf(wItem.chs) > -1,
  1126. startIndex,
  1127. endIndex,
  1128. leg: wItem.chs.length,
  1129. config: {
  1130. fontFamily: wItem.fontFamily,
  1131. },
  1132. };
  1133. if (wordTimeList && wordTimeList.length > 0) {
  1134. obj.chstimeList = wordTimeList[asIndex].wordsResultList.slice(startIndex, endIndex);
  1135. }
  1136. sentArr.push(obj);
  1137. paraArr.push(obj);
  1138. if (wIndex == sItem.length - 1) {
  1139. asIndex++;
  1140. }
  1141. if (wItem.pinyin) dhaspinyin = true;
  1142. });
  1143. });
  1144. let curSentencesLeg = dItem.sentences.length;
  1145. let startLeg = dIndex == 0 ? 0 : curQue.detail[dIndex - 1].endLeg;
  1146. let endLeg = startLeg + curSentencesLeg;
  1147. dItem.endLeg = endLeg;
  1148. let timeList = curQue.wordTime ? curQue.wordTime.slice(startLeg, endLeg) : [];
  1149. let paraObj = {
  1150. wordsList: paraArr,
  1151. timeList,
  1152. isTitle: dItem.isTitle,
  1153. dhaspinyin,
  1154. enwords: dItem.sentencesEn ? dItem.sentencesEn : [],
  1155. };
  1156. resArr.push(paraObj);
  1157. });
  1158. this.resArr = resArr;
  1159. // 循环文章图片
  1160. if (curQue.img_list) {
  1161. curQue.img_list.forEach((item) => {
  1162. this.articleImg[item.imgNumber] = item.id;
  1163. });
  1164. }
  1165. let resArrs = [];
  1166. let sentArrTotal = [];
  1167. let timeArr = [];
  1168. curQue.detail.forEach((dItem, dIndex) => {
  1169. dItem.wordsList.forEach((sItem, sIndex) => {
  1170. let sentArr = [];
  1171. sItem.forEach((wItem, wIndex) => {
  1172. let startIndex = wIndex == 0 ? 0 : sentArr[wIndex - 1].startIndex + sentArr[wIndex - 1].chs.length;
  1173. let endIndex = wIndex == 0 ? wItem.chs.length : sentArr[wIndex - 1].endIndex + wItem.chs.length;
  1174. // this.judgePad(sItem, wItem, wIndex);
  1175. this.mergeWordSymbol(wItem);
  1176. let obj = {
  1177. paraIndex: dIndex, // 段落索引
  1178. sentIndex: sIndex, // 在段落中句子索引
  1179. wordIndex: wIndex, // 单词的索引
  1180. pinyin:
  1181. curQue.pinyin_type === 'pinyin'
  1182. ? curQue.property.is_first_sentence_first_hz_pinyin_first_char_upper_case === 'true' && wIndex === 0
  1183. ? wItem.pinyin_up
  1184. : wItem.pinyin
  1185. : wItem.pinyin_tone,
  1186. chs: wItem.chs,
  1187. padding: true,
  1188. className: wItem.className,
  1189. isShow: wItem.isShow,
  1190. startIndex,
  1191. endIndex,
  1192. leg: wItem.chs.length,
  1193. timeList: [],
  1194. };
  1195. sentArr.push(obj);
  1196. });
  1197. let objs = {
  1198. sentArr,
  1199. enwords: dItem.sentencesEn && dItem.sentencesEn[sIndex] && dItem.sentencesEn[sIndex].replace(/\'/g, '’'),
  1200. };
  1201. sentArrTotal.push(sentArr);
  1202. resArrs.push(objs);
  1203. });
  1204. timeArr.push(dItem.timeList);
  1205. });
  1206. if (wordTimeList && wordTimeList.length > 0) {
  1207. this.mergeWordTime(sentArrTotal, wordTimeList);
  1208. }
  1209. let timeList = [];
  1210. timeArr.forEach((item) => {
  1211. item.forEach((aItem) => {
  1212. if (timeList.indexOf(aItem) < 0) {
  1213. timeList.push(aItem);
  1214. }
  1215. });
  1216. });
  1217. this.resObj = { sentList: resArrs, timeList };
  1218. },
  1219. mergeWordTime(resArr, wordTimeList) {
  1220. resArr.forEach((item, index) => {
  1221. let wordsResultList = wordTimeList[index].wordsResultList;
  1222. item.forEach((wItem) => {
  1223. let startIndex = wItem.startIndex;
  1224. let endIndex = wItem.endIndex;
  1225. wItem.timeList = wordsResultList.slice(startIndex, endIndex);
  1226. });
  1227. });
  1228. },
  1229. // 词和标点合一起
  1230. mergeWordSymbol(wItem) {
  1231. if (this.chsFhList.indexOf(wItem.chs) > -1 || this.NumberList.indexOf(wItem.chs) > -1) {
  1232. wItem.isShow = false;
  1233. } else {
  1234. wItem.isShow = true;
  1235. }
  1236. },
  1237. // 判断是否有padding
  1238. judgePad(sItem, wItem, curIndex) {
  1239. let leg = sItem.length;
  1240. if (curIndex < leg - 1) {
  1241. let nextIndex = curIndex + 1;
  1242. let chs = sItem[nextIndex].chs;
  1243. if (this.chsFhList.indexOf(chs) > -1 || this.chsFhList.indexOf(wItem.chs) > -1) {
  1244. wItem.padding = false;
  1245. } else {
  1246. wItem.padding = true;
  1247. }
  1248. if (this.enFhList.indexOf(wItem.pinyin) > -1) {
  1249. wItem.className = 'textLeft';
  1250. }
  1251. }
  1252. },
  1253. // 点击播放某个句子
  1254. handleChangeTime(time, ed, index) {
  1255. this.sentIndex = index;
  1256. if (time) {
  1257. this.curTime = time;
  1258. this.$refs.audioLine.onTimeupdateTime(time / 1000, true);
  1259. this.ed = ed;
  1260. }
  1261. },
  1262. emptyEd() {
  1263. this.ed = undefined;
  1264. },
  1265. // 经过每个词,高亮句子
  1266. handleMouseover(pItem) {
  1267. this.paraIndex = pItem.paraIndex;
  1268. this.sentIndex = pItem.sentIndex;
  1269. },
  1270. handleMouseleave() {
  1271. this.paraIndex = -1;
  1272. this.sentIndex = -1;
  1273. },
  1274. viewNotes(e, noteNum, time, ed, index) {
  1275. let _this = this;
  1276. let noteIndex = '';
  1277. if (_this.NumberList.indexOf(noteNum) > -1) {
  1278. for (let i = 0; i < _this.NumberList.length; i++) {
  1279. if (_this.NumberList[i] === noteNum) {
  1280. noteIndex = String(i) + '';
  1281. break;
  1282. }
  1283. }
  1284. } else {
  1285. _this.handleChangeTime(time, ed, index);
  1286. }
  1287. if (noteIndex) {
  1288. this.showNoteDetail(e, noteIndex);
  1289. }
  1290. },
  1291. showNoteDetail(e, noteNum) {
  1292. let _this = this;
  1293. // if (_this.oldNoteNum != noteNum) {
  1294. this.isNoteShow = false;
  1295. setTimeout(() => {
  1296. _this.noteNum = noteNum;
  1297. }, 50);
  1298. // }
  1299. _this.clientY = e.clientY;
  1300. let left = e.clientX;
  1301. let width = 642;
  1302. if (left - this.bodyLeft > this.contentWidth / 2) {
  1303. _this.left = 500;
  1304. } else if (left - 200 > 500) {
  1305. _this.left = 500;
  1306. } else {
  1307. _this.left = left - 200;
  1308. }
  1309. if (_this.oldNoteNum === noteNum) {
  1310. _this.handleNote(noteNum);
  1311. }
  1312. },
  1313. // 处理分词数据
  1314. handleNote(val) {
  1315. let _this = this;
  1316. _this.isNoteShow = true;
  1317. _this.oldNoteNum = val;
  1318. let noteIndex = Number(val);
  1319. if (_this.NNPEAnnotationList && _this.NNPEAnnotationList.length > 0) {
  1320. _this.curNoteCon = _this.NNPEAnnotationList[noteIndex] ? _this.NNPEAnnotationList[noteIndex] : null;
  1321. }
  1322. },
  1323. changeCard(isShow) {
  1324. let _this = this;
  1325. _this.isNoteShow = isShow;
  1326. _this.oldNoteNum = '';
  1327. _this.noteNum = '';
  1328. },
  1329. }, // 如果页面有keep-alive缓存功能,这个函数会触发
  1330. };
  1331. </script>
  1332. <style lang="scss" scoped>
  1333. //@import url(); 引入公共css类
  1334. .NNPE-ArticleView {
  1335. width: 100%;
  1336. .aduioLine-practice-npc {
  1337. display: flex;
  1338. align-items: center;
  1339. justify-content: flex-start;
  1340. .aduioLine-content {
  1341. flex: 1;
  1342. }
  1343. .aduioLine-right {
  1344. box-sizing: border-box;
  1345. display: flex;
  1346. align-items: center;
  1347. justify-content: space-between;
  1348. width: 69px;
  1349. height: 40px;
  1350. padding: 0 12px;
  1351. border-left: 1px solid rgba(0, 0, 0, 10%);
  1352. .svg-icon {
  1353. width: 16px;
  1354. height: 16px;
  1355. cursor: pointer;
  1356. }
  1357. }
  1358. }
  1359. .NPC-sentences-list {
  1360. padding: 24px 0;
  1361. color: rgba(0, 0, 0, 85%);
  1362. }
  1363. .NNPE-detail {
  1364. overflow: hidden;
  1365. clear: both;
  1366. .NNPE-words {
  1367. float: left;
  1368. &-box {
  1369. float: left;
  1370. > span {
  1371. display: block;
  1372. &.NNPE-pinyin {
  1373. height: 22px;
  1374. font-family: 'League';
  1375. font-size: 14px;
  1376. font-weight: normal;
  1377. line-height: 22px;
  1378. color: #000;
  1379. &.noFont {
  1380. font-family: initial;
  1381. }
  1382. &.textLeft {
  1383. text-align: left;
  1384. }
  1385. &.textRight {
  1386. text-align: right;
  1387. }
  1388. }
  1389. &.NNPE-chs {
  1390. display: flex;
  1391. flex-flow: wrap;
  1392. font-family: '楷体';
  1393. font-size: 20px;
  1394. line-height: 28px;
  1395. color: #000;
  1396. &.overActive {
  1397. background: rgba(0, 0, 0, 6%);
  1398. }
  1399. &.active {
  1400. background: rgba(222, 68, 68, 15%);
  1401. }
  1402. &.wordActive {
  1403. color: rgba(222, 68, 68, 100%);
  1404. }
  1405. .wordActive {
  1406. color: rgba(222, 68, 68, 100%);
  1407. }
  1408. }
  1409. &.padding {
  1410. padding: 0 3px;
  1411. }
  1412. }
  1413. }
  1414. &.textLeft {
  1415. text-align: left;
  1416. }
  1417. &.textCenter {
  1418. text-align: center;
  1419. .NNPE-chs {
  1420. justify-content: center;
  1421. }
  1422. }
  1423. &.textRight {
  1424. text-align: right;
  1425. }
  1426. > span {
  1427. display: block;
  1428. &.NNPE-pinyin {
  1429. height: 22px;
  1430. font-family: 'League';
  1431. font-size: 14px;
  1432. font-weight: normal;
  1433. line-height: 22px;
  1434. color: #000;
  1435. &.noFont {
  1436. font-family: initial;
  1437. }
  1438. &.textLeft {
  1439. text-align: left;
  1440. }
  1441. &.textRight {
  1442. text-align: right;
  1443. }
  1444. }
  1445. &.NNPE-chs {
  1446. display: flex;
  1447. flex-flow: wrap;
  1448. font-family: '楷体';
  1449. font-size: 20px;
  1450. line-height: 28px;
  1451. color: #000;
  1452. &.overActive {
  1453. background: rgba(0, 0, 0, 6%);
  1454. }
  1455. &.active {
  1456. background: rgba(222, 68, 68, 15%);
  1457. }
  1458. &.wordActive {
  1459. color: rgba(222, 68, 68, 100%);
  1460. }
  1461. .wordActive {
  1462. color: rgba(222, 68, 68, 100%);
  1463. }
  1464. }
  1465. &.padding {
  1466. padding: 0 3px;
  1467. }
  1468. }
  1469. }
  1470. &.NNPE-detail-title {
  1471. .NNPE-title {
  1472. margin: 0 auto;
  1473. }
  1474. .wordsList-box {
  1475. > div {
  1476. display: flex;
  1477. flex-flow: wrap;
  1478. justify-content: center;
  1479. }
  1480. }
  1481. }
  1482. .index {
  1483. box-sizing: border-box;
  1484. width: 48px;
  1485. padding: 8px;
  1486. text-align: right;
  1487. border-right: 1px solid rgba(0, 0, 0, 10%);
  1488. b {
  1489. font-weight: 400;
  1490. line-height: 1.5;
  1491. color: #000;
  1492. }
  1493. }
  1494. .wordsList-box {
  1495. // display: flex;
  1496. width: 100%;
  1497. padding: 6px 24px 12px;
  1498. &-left {
  1499. justify-content: flex-start;
  1500. }
  1501. &-center {
  1502. justify-content: center;
  1503. }
  1504. &-right {
  1505. justify-content: flex-end;
  1506. }
  1507. > div {
  1508. overflow: hidden;
  1509. clear: both;
  1510. }
  1511. > img {
  1512. display: block;
  1513. max-width: 100%;
  1514. margin: 8px auto;
  1515. }
  1516. }
  1517. }
  1518. .NNPE-noteDetail {
  1519. position: fixed;
  1520. top: 50%;
  1521. left: 50%;
  1522. z-index: 9999;
  1523. max-width: 100%;
  1524. margin-top: -196px;
  1525. overflow: auto;
  1526. }
  1527. .NNPE-detail-box {
  1528. box-sizing: border-box;
  1529. width: 100%;
  1530. padding: 8px 24px;
  1531. margin-bottom: 8px;
  1532. &.active {
  1533. background: rgba(222, 68, 68, 15%);
  1534. }
  1535. }
  1536. .NNPE-details {
  1537. overflow: hidden;
  1538. clear: both;
  1539. .NNPE-words {
  1540. float: left;
  1541. &-box {
  1542. float: left;
  1543. > span {
  1544. display: block;
  1545. &.NNPE-pinyin {
  1546. height: 20px;
  1547. font-family: 'League';
  1548. font-size: 14px;
  1549. font-weight: normal;
  1550. line-height: 20px;
  1551. color: rgba(0, 0, 0, 100%);
  1552. &.noFont {
  1553. font-family: initial;
  1554. }
  1555. &.textLeft {
  1556. text-align: left;
  1557. }
  1558. &.wordBlank {
  1559. color: rgba(0, 0, 0, 100%);
  1560. }
  1561. }
  1562. &.NNPE-chs {
  1563. display: flex;
  1564. flex-flow: wrap;
  1565. font-family: '楷体';
  1566. font-size: 20px;
  1567. line-height: 28px;
  1568. color: rgba(0, 0, 0, 100%);
  1569. .active {
  1570. color: #de4444;
  1571. }
  1572. &.wordBlank {
  1573. color: rgba(0, 0, 0, 100%);
  1574. }
  1575. }
  1576. // &.padding {
  1577. // padding-right: 6px;
  1578. // }
  1579. }
  1580. }
  1581. &.textLeft {
  1582. text-align: left;
  1583. }
  1584. &.textCenter {
  1585. text-align: center;
  1586. .NNPE-chs {
  1587. justify-content: center;
  1588. }
  1589. }
  1590. &.textRight {
  1591. text-align: right;
  1592. }
  1593. > span {
  1594. display: block;
  1595. &.NNPE-pinyin {
  1596. height: 20px;
  1597. font-family: 'League';
  1598. font-size: 14px;
  1599. font-weight: normal;
  1600. line-height: 20px;
  1601. color: rgba(0, 0, 0, 100%);
  1602. &.noFont {
  1603. font-family: initial;
  1604. }
  1605. &.textLeft {
  1606. text-align: left;
  1607. }
  1608. &.wordBlank {
  1609. color: rgba(0, 0, 0, 100%);
  1610. }
  1611. }
  1612. &.NNPE-chs {
  1613. display: flex;
  1614. flex-flow: wrap;
  1615. font-family: '楷体';
  1616. font-size: 20px;
  1617. line-height: 28px;
  1618. color: rgba(0, 0, 0, 100%);
  1619. .active {
  1620. color: #de4444;
  1621. }
  1622. &.wordBlank {
  1623. color: rgba(0, 0, 0, 100%);
  1624. }
  1625. }
  1626. &.padding {
  1627. padding: 0 3px;
  1628. }
  1629. }
  1630. }
  1631. }
  1632. .enwords {
  1633. padding-left: 3px;
  1634. font-family: 'Helvetica';
  1635. font-size: 14px;
  1636. font-weight: normal;
  1637. line-height: 22px;
  1638. color: rgba(0, 0, 0, 100%);
  1639. word-break: break-word;
  1640. &.wordBlank {
  1641. color: rgba(0, 0, 0, 100%);
  1642. }
  1643. }
  1644. .multilingual {
  1645. padding: 6px 24px 12px;
  1646. word-break: break-word;
  1647. }
  1648. .multilingual-para {
  1649. text-indent: 40px;
  1650. word-break: break-word;
  1651. &-center {
  1652. text-align: center;
  1653. text-indent: 0;
  1654. }
  1655. }
  1656. }
  1657. .NPC-Big-Book-preview-green {
  1658. .NNPE-ArticleView {
  1659. .NNPE-detail-box {
  1660. &.active {
  1661. background: rgba(36, 185, 158, 15%);
  1662. }
  1663. }
  1664. .NNPE-detail {
  1665. .NNPE-words {
  1666. &-box {
  1667. > span {
  1668. &.NNPE-chs {
  1669. &.active {
  1670. background: rgba(36, 185, 158, 15%);
  1671. }
  1672. &.wordActive {
  1673. color: rgba(36, 185, 158, 100%);
  1674. }
  1675. .wordActive {
  1676. color: rgba(36, 185, 158, 100%);
  1677. }
  1678. }
  1679. }
  1680. }
  1681. > span {
  1682. &.NNPE-chs {
  1683. &.active {
  1684. background: rgba(36, 185, 158, 15%);
  1685. }
  1686. &.wordActive {
  1687. color: rgba(36, 185, 158, 100%);
  1688. }
  1689. .wordActive {
  1690. color: rgba(36, 185, 158, 100%);
  1691. }
  1692. }
  1693. }
  1694. }
  1695. }
  1696. .NNPE-details {
  1697. .NNPE-words {
  1698. &-box {
  1699. > span {
  1700. &.NNPE-chs {
  1701. .active {
  1702. color: #24b99e;
  1703. }
  1704. }
  1705. }
  1706. }
  1707. > span {
  1708. &.NNPE-chs {
  1709. .active {
  1710. color: #24b99e;
  1711. }
  1712. }
  1713. }
  1714. }
  1715. }
  1716. }
  1717. }
  1718. .NPC-Big-Book-preview-brown {
  1719. .NNPE-ArticleView {
  1720. .NNPE-detail-box {
  1721. &.active {
  1722. background: rgba(189, 136, 101, 15%);
  1723. }
  1724. }
  1725. .NNPE-detail {
  1726. .NNPE-words {
  1727. &-box {
  1728. > span {
  1729. &.NNPE-chs {
  1730. &.active {
  1731. background: rgba(189, 136, 101, 15%);
  1732. }
  1733. &.wordActive {
  1734. color: rgba(189, 136, 101, 100%);
  1735. }
  1736. .wordActive {
  1737. color: rgba(189, 136, 101, 100%);
  1738. }
  1739. }
  1740. }
  1741. }
  1742. > span {
  1743. &.NNPE-chs {
  1744. &.active {
  1745. background: rgba(189, 136, 101, 15%);
  1746. }
  1747. &.wordActive {
  1748. color: rgba(189, 136, 101, 100%);
  1749. }
  1750. .wordActive {
  1751. color: rgba(189, 136, 101, 100%);
  1752. }
  1753. }
  1754. }
  1755. }
  1756. }
  1757. .NNPE-details {
  1758. .NNPE-words {
  1759. &-box {
  1760. > span {
  1761. &.NNPE-chs {
  1762. .active {
  1763. color: #bd8865;
  1764. }
  1765. }
  1766. }
  1767. }
  1768. > span {
  1769. &.NNPE-chs {
  1770. .active {
  1771. color: #bd8865;
  1772. }
  1773. }
  1774. }
  1775. }
  1776. }
  1777. }
  1778. }
  1779. </style>