WordModelChs.vue 66 KB

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