PhraseModelChs.vue 80 KB

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