PhraseModelChs.vue 86 KB

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