WordModelChs.vue 63 KB

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