PhraseModelChs.vue 84 KB

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