PhraseModelChs.vue 81 KB

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