NormalModelChs.vue 67 KB

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