PhraseModelChs.vue 55 KB

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