AnswerModel.vue 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  1. <!-- -->
  2. <template>
  3. <div class="NNPE-ArticleView" v-if="curQue && Bookanswer">
  4. <div
  5. class="aduioLine-box"
  6. v-if="
  7. curQue.mp3_list && curQue.mp3_list.length > 0 && curQue.mp3_list[0].id
  8. "
  9. >
  10. <AudioLine
  11. audioId="'answerAudio'"
  12. :mp3="curQue.mp3_list[0].id"
  13. :getCurTime="getCurTime"
  14. ref="audioLine"
  15. />
  16. </div>
  17. <template v-if="resArr.length > 0">
  18. <div class="NPC-sentences-list">
  19. <p class="notice" v-if="curQue.notice">{{ curQue.notice }}</p>
  20. <div
  21. :class="[
  22. 'NNPE-detail',
  23. item.isTitle ? 'NNPE-detail-title' : '',
  24. item.timeList.length > 0 &&
  25. curTime >= item.timeList[0].bg &&
  26. curTime <= item.timeList[item.timeList.length - 1].ed
  27. ? 'active'
  28. : '',
  29. ]"
  30. v-for="(item, index) in resArr"
  31. :key="'detail' + index"
  32. >
  33. <div :class="['article-content', isHasRemark ? 'hasRemark' : '']">
  34. <RoleChs :curRole="item.roleDetail" :type="1" />
  35. <div class="wordsList-box">
  36. <div
  37. class="roleDetail"
  38. v-if="item.roleDetail.detail.wordsList.length > 0"
  39. >
  40. <span class="pinyin">{{
  41. item.roleDetail.detail.wordsList | handlePinyin
  42. }}</span>
  43. <span class="chs">{{
  44. item.roleDetail.detail.wordsList | handleChs
  45. }}</span>
  46. </div>
  47. <div
  48. class="para-con"
  49. :style="{ background: item.roleDetail.color.bg }"
  50. >
  51. <div
  52. class="NNPE-words"
  53. v-for="(pItem, pIndex) in item.wordsList"
  54. :key="'wordsList' + pIndex"
  55. :class="[
  56. pItem.chs != '“' && pItem.wordIndex == 0
  57. ? 'textLeft'
  58. : 'textCenter',
  59. pItem.chs == '“' ? 'textRight' : '',
  60. ]"
  61. >
  62. <template v-if="!pItem.width">
  63. <template v-if="pItem.isShow">
  64. <template
  65. v-if="
  66. item.wordsList[pIndex + 1] &&
  67. item.wordsList[pIndex + 1].chs &&
  68. chsFhList.indexOf(item.wordsList[pIndex + 1].chs) > -1
  69. "
  70. >
  71. <span class="NNPE-words-box">
  72. <span
  73. v-if="item.isHasPY > 0 && pyPosition == 'top'"
  74. class="NNPE-pinyin"
  75. :class="[
  76. pItem.className ? pItem.className : '',
  77. pItem.pinyin && noFont.indexOf(pItem.pinyin) > -1
  78. ? 'noFont'
  79. : '',
  80. ]"
  81. >{{ pItem.pinyin | handlePY }}</span
  82. >
  83. <template v-if="!pItem.isHeng">
  84. <span
  85. class="NNPE-chs"
  86. :class="[
  87. item.timeList.length > 0 &&
  88. curTime >=
  89. item.timeList[pItem.sentIndex]
  90. .wordsResultList[pItem.wordIndex].wordBg &&
  91. curTime <= item.timeList[pItem.sentIndex].ed
  92. ? 'wordActive'
  93. : '',
  94. pItem.config.underLine
  95. ? 'NNPE-chs-underline'
  96. : '',
  97. ]"
  98. >{{ pItem.chs }}</span
  99. >
  100. </template>
  101. <template v-else>
  102. <EditDiv
  103. class="answer-input"
  104. v-model="Bookanswer.input[pItem.hengIndex - 1]"
  105. :canEdit="TaskModel == 'ANSWER' ? false : true"
  106. />
  107. </template>
  108. <span
  109. v-if="item.isHasPY > 0 && pyPosition == 'bottom'"
  110. class="NNPE-pinyin"
  111. :class="[
  112. pItem.className ? pItem.className : '',
  113. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  114. ]"
  115. >{{ pItem.pinyin | handlePY }}</span
  116. >
  117. </span>
  118. <span
  119. class="NNPE-words-box"
  120. v-if="item.wordsList[pIndex + 1]"
  121. >
  122. <span
  123. v-if="item.isHasPY > 0 && pyPosition == 'top'"
  124. class="NNPE-pinyin"
  125. :class="[
  126. noFont.indexOf(
  127. item.wordsList[pIndex + 1].pinyin
  128. ) > -1
  129. ? 'noFont'
  130. : '',
  131. ]"
  132. style="text-align: left"
  133. >{{
  134. item.wordsList[pIndex + 1].pinyin | handlePY
  135. }}</span
  136. >
  137. <span
  138. class="NNPE-chs"
  139. style="text-align: left"
  140. :class="[
  141. item.timeList.length > 0 &&
  142. curTime >=
  143. item.timeList[pItem.sentIndex].wordsResultList[
  144. pItem.wordIndex
  145. ].wordBg &&
  146. curTime <= item.timeList[pItem.sentIndex].ed
  147. ? 'wordActive'
  148. : '',
  149. ]"
  150. >{{ item.wordsList[pIndex + 1].chs }}</span
  151. >
  152. <span
  153. v-if="item.isHasPY > 0 && pyPosition == 'bottom'"
  154. class="NNPE-pinyin"
  155. :class="[
  156. noFont.indexOf(
  157. item.wordsList[pIndex + 1].pinyin
  158. ) > -1
  159. ? 'noFont'
  160. : '',
  161. ]"
  162. style="text-align: left"
  163. >{{
  164. item.wordsList[pIndex + 1].pinyin | handlePY
  165. }}</span
  166. >
  167. </span>
  168. <span
  169. class="NNPE-words-box"
  170. v-if="
  171. item.wordsList[pIndex + 2] &&
  172. item.wordsList[pIndex + 2].chs &&
  173. chsFhList.indexOf(item.wordsList[pIndex + 2].chs) >
  174. -1
  175. "
  176. >
  177. <span
  178. v-if="
  179. item.isHasPY > 0 &&
  180. curQue.pyPosition == 'top' &&
  181. config.isShowPY
  182. "
  183. :class="[
  184. 'NNPE-pinyin',
  185. noFont.indexOf(
  186. item.wordsList[pIndex + 2].pinyin
  187. ) > -1
  188. ? 'noFont'
  189. : '',
  190. ]"
  191. style="text-align: left"
  192. >{{ item.wordsList[pIndex + 2].pinyin }}</span
  193. >
  194. <span
  195. class="NNPE-chs"
  196. style="text-align: left"
  197. :class="[
  198. isPlaying &&
  199. item.timeList &&
  200. item.timeList[pItem.sentIndex] &&
  201. curTime >= item.timeList[pItem.sentIndex].bg &&
  202. curTime <= item.timeList[pItem.sentIndex].ed
  203. ? 'active'
  204. : '',
  205. pItem.paraIndex == paraIndex &&
  206. pItem.sentIndex == sentIndex
  207. ? 'overActive'
  208. : '',
  209. pItem.chstimeList &&
  210. pItem.chstimeList[pItem.leg - 1] &&
  211. curTime >=
  212. pItem.chstimeList[pItem.leg - 1].wordBg &&
  213. curQue.wordTime &&
  214. curTime <= item.timeList[pItem.sentIndex].ed
  215. ? 'wordActive'
  216. : '',
  217. ]"
  218. >{{ item.wordsList[pIndex + 2].chs }}</span
  219. >
  220. <span
  221. v-if="
  222. item.isHasPY > 0 &&
  223. curQue.pyPosition == 'bottom' &&
  224. config.isShowPY
  225. "
  226. :class="[
  227. 'NNPE-pinyin',
  228. noFont.indexOf(
  229. item.wordsList[pIndex + 2].pinyin
  230. ) > -1
  231. ? 'noFont'
  232. : '',
  233. ]"
  234. style="text-align: left"
  235. >{{ item.wordsList[pIndex + 2].pinyin }}</span
  236. >
  237. </span>
  238. </template>
  239. <!--下一个元素不是标点-->
  240. <template v-else>
  241. <span
  242. v-if="item.isHasPY > 0 && pyPosition == 'top'"
  243. class="NNPE-pinyin"
  244. :class="[
  245. pItem.chs != '“' && pItem.padding ? 'padding' : '',
  246. pItem.className ? pItem.className : '',
  247. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  248. ]"
  249. >{{ pItem.pinyin | handlePY }}</span
  250. >
  251. <template v-if="!pItem.isHeng">
  252. <span
  253. v-if="pItem.chs != '#'"
  254. class="NNPE-chs"
  255. :class="[
  256. item.timeList.length > 0 &&
  257. curTime >=
  258. item.timeList[pItem.sentIndex].wordsResultList[
  259. pItem.wordIndex
  260. ].wordBg &&
  261. curTime <= item.timeList[pItem.sentIndex].ed
  262. ? 'wordActive'
  263. : '',
  264. pItem.chs != '“' && pItem.padding
  265. ? 'padding'
  266. : '',
  267. pItem.config.underLine
  268. ? 'NNPE-chs-underline'
  269. : '',
  270. ]"
  271. >{{ pItem.chs }}</span
  272. >
  273. </template>
  274. <template v-else>
  275. <EditDiv
  276. class="answer-input"
  277. v-model="Bookanswer.input[pItem.hengIndex - 1]"
  278. :canEdit="TaskModel == 'ANSWER' ? false : true"
  279. />
  280. </template>
  281. <span
  282. v-if="item.isHasPY > 0 && pyPosition == 'bottom'"
  283. class="NNPE-pinyin"
  284. :class="[
  285. pItem.chs != '“' && pItem.padding ? 'padding' : '',
  286. pItem.className ? pItem.className : '',
  287. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  288. ]"
  289. >{{ pItem.pinyin | handlePY }}</span
  290. >
  291. </template>
  292. </template>
  293. </template>
  294. <template v-else>
  295. <span
  296. :style="{
  297. height: pItem.height + 'px',
  298. width: pItem.width + 'px',
  299. }"
  300. ></span>
  301. </template>
  302. </div>
  303. <div v-if="item.enwords" class="enwords">
  304. {{ item.enwords }}
  305. </div>
  306. </div>
  307. <div class="clearFix"></div>
  308. <div class="answer-box">
  309. <div class="input-record" v-if="item.isRecord">
  310. <Soundrecord
  311. type="normal"
  312. class="normal-box"
  313. :TaskModel="TaskModel"
  314. :answerRecordList="Bookanswer.recordList[index]"
  315. :tmIndex="index"
  316. @handleWav="handleWav"
  317. />
  318. </div>
  319. <template
  320. class="input-record"
  321. v-if="
  322. curQue.checkList && curQue.checkList.indexOf('judge') > -1
  323. "
  324. >
  325. <div class="judge-box" v-if="curQue.judge[index].isJudge">
  326. <a
  327. :class="[
  328. 'right-btn',
  329. Bookanswer.judge[index] == 'right' ? 'active' : '',
  330. ]"
  331. @click="handleSelectJudge('right', index)"
  332. >
  333. <img
  334. src="../../../../assets/newImage/common/right-btn.png"
  335. />
  336. </a>
  337. <a
  338. :class="[
  339. 'error-btn',
  340. Bookanswer.judge[index] == 'error' ? 'active' : '',
  341. ]"
  342. @click="handleSelectJudge('error', index)"
  343. >
  344. <img
  345. src="../../../../assets/newImage/common/error-btn.png"
  346. />
  347. </a>
  348. </div>
  349. </template>
  350. </div>
  351. </div>
  352. </div>
  353. <div
  354. class="remarkBox remark-top"
  355. v-if="
  356. item.remarkDetail &&
  357. (item.remarkDetail.chs || item.remarkDetail.en)
  358. "
  359. >
  360. <RemarkChs :remarkDetail="item.remarkDetail" />
  361. </div>
  362. </div>
  363. <!-- <div class="dia-article-record">
  364. <Soundrecord @handleWav="handleWav" type="promax" class="luyin-box" />
  365. </div> -->
  366. </div>
  367. </template>
  368. <template v-if="paraArr.length > 0">
  369. <div class="NPC-sentences-list">
  370. <p class="notice" v-if="curQue.notice">{{ curQue.notice }}</p>
  371. <div
  372. :class="['NNPE-detail', item.isTitle ? 'NNPE-detail-title' : '']"
  373. v-for="(item, index) in paraArr"
  374. :key="'detail' + index"
  375. >
  376. <div :class="['article-content', isHasRemark ? 'hasRemark' : '']">
  377. <RoleChs :curRole="item.roleDetail" :type="1" />
  378. <div class="wordsList-box">
  379. <div
  380. class="roleDetail"
  381. v-if="item.roleDetail.detail.wordsList.length > 0"
  382. >
  383. <span class="pinyin">{{
  384. item.roleDetail.detail.wordsList | handlePinyin
  385. }}</span>
  386. <span class="chs">{{
  387. item.roleDetail.detail.wordsList | handleChs
  388. }}</span>
  389. </div>
  390. <div
  391. class="para-con"
  392. :style="{ background: item.roleDetail.color.bg }"
  393. >
  394. <div
  395. class="NNPE-words"
  396. v-for="(pItem, pIndex) in item.wordsList"
  397. :key="'wordsList' + pIndex"
  398. >
  399. <template v-if="!pItem.isHeng">
  400. <span class="NNPE-para-pinyin padding">{{
  401. pItem.con
  402. }}</span>
  403. </template>
  404. <template v-else>
  405. <EditDiv
  406. class="answer-input"
  407. v-model="Bookanswer.input[pItem.hengIndex - 1]"
  408. :canEdit="TaskModel == 'ANSWER' ? false : true"
  409. />
  410. </template>
  411. </div>
  412. <div v-if="item.enwords" class="enwords">
  413. {{ item.enwords }}
  414. </div>
  415. </div>
  416. <div class="clearFix"></div>
  417. <div class="answer-box">
  418. <div class="input-record" v-if="item.isRecord">
  419. <Soundrecord
  420. type="normal"
  421. class="normal-box"
  422. :TaskModel="TaskModel"
  423. :answerRecordList="Bookanswer.recordList[index]"
  424. :tmIndex="index"
  425. @handleWav="handleWav"
  426. />
  427. </div>
  428. <template
  429. class="input-record"
  430. v-if="
  431. curQue.checkList && curQue.checkList.indexOf('judge') > -1
  432. "
  433. >
  434. <div class="judge-box" v-if="curQue.judge[index].isJudge">
  435. <a
  436. :class="[
  437. 'right-btn',
  438. Bookanswer.judge[index] == 'right' ? 'active' : '',
  439. ]"
  440. @click="handleSelectJudge('right', index)"
  441. >
  442. <img
  443. src="../../../../assets/newImage/common/right-btn.png"
  444. />
  445. </a>
  446. <a
  447. :class="[
  448. 'error-btn',
  449. Bookanswer.judge[index] == 'error' ? 'active' : '',
  450. ]"
  451. @click="handleSelectJudge('error', index)"
  452. >
  453. <img
  454. src="../../../../assets/newImage/common/error-btn.png"
  455. />
  456. </a>
  457. </div>
  458. </template>
  459. </div>
  460. </div>
  461. </div>
  462. <div
  463. class="remarkBox remark-top"
  464. v-if="
  465. item.remarkDetail &&
  466. (item.remarkDetail.chs || item.remarkDetail.en)
  467. "
  468. >
  469. <RemarkChs :remarkDetail="item.remarkDetail" />
  470. </div>
  471. </div>
  472. <!-- <div class="dia-article-record">
  473. <Soundrecord @handleWav="handleWav" type="promax" class="luyin-box" />
  474. </div> -->
  475. </div>
  476. </template>
  477. </div>
  478. </template>
  479. <script>
  480. import { timeStrToSen } from "../../../../utils/index";
  481. import AudioLine from "../AudioLine.vue";
  482. import RoleChs from "./RoleChs.vue";
  483. import RemarkChs from "./RemarkChs.vue";
  484. import Soundrecord from "../Soundrecord.vue";
  485. import EditDiv from "../EditDiv.vue";
  486. export default {
  487. name: "DialogueNormalModelChs",
  488. props: [
  489. "curQue",
  490. "pyPosition",
  491. "colorBox",
  492. "listIndex",
  493. "Bookanswer",
  494. "TaskModel",
  495. ],
  496. components: {
  497. AudioLine,
  498. RoleChs,
  499. RemarkChs,
  500. Soundrecord,
  501. EditDiv,
  502. },
  503. filters: {
  504. handlePinyin(wordsList) {
  505. let str = "";
  506. wordsList.forEach((item, index) => {
  507. if (index < wordsList.length - 1) {
  508. str += item.pinyin + " ";
  509. } else {
  510. str += item.pinyin;
  511. }
  512. });
  513. return str;
  514. },
  515. handleChs(wordsList) {
  516. let str = "";
  517. wordsList.forEach((item, index) => {
  518. if (index < wordsList.length - 1) {
  519. str += item.chs + " ";
  520. } else {
  521. str += item.chs;
  522. }
  523. });
  524. return str;
  525. },
  526. handlePY(pinyin) {
  527. let reg = /_{2,}/g;
  528. let py = "";
  529. if (!reg.test(pinyin)) {
  530. py = pinyin;
  531. }
  532. return py;
  533. },
  534. },
  535. data() {
  536. return {
  537. resArr: [],
  538. curTime: 0, //单位s
  539. chsFhList: [",", "。", "”", ":", "》", "《", "?", "!", ";"],
  540. enFhList: [",", ".", ";", "?", "!", ":", ">", "<"],
  541. newWords: ["鱼", "辩礼义"],
  542. noFont: ["~", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "/", "_"],
  543. oldHz: "",
  544. hz: "",
  545. top: 0,
  546. left: 0,
  547. articleImg: {}, // 文章图片
  548. isHasRemark: false,
  549. paraArr: [],
  550. answer: [],
  551. hengIndex: 0,
  552. };
  553. },
  554. computed: {},
  555. watch: {},
  556. //方法集合
  557. methods: {
  558. // 判断题选择
  559. handleSelectJudge(obj, index) {
  560. let _this = this;
  561. _this.$set(_this.Bookanswer.judge, index, obj);
  562. _this.$forceUpdate();
  563. },
  564. handleWav(list, tmIndex) {
  565. tmIndex = tmIndex ? tmIndex : 0;
  566. this.$set(this.Bookanswer.recordList, tmIndex, list);
  567. },
  568. getCurTime(curTime) {
  569. this.curTime = curTime * 1000;
  570. },
  571. handleData() {
  572. let resArr = [];
  573. let reg = /_{2,}/g;
  574. let leg = this.curQue.detail.length;
  575. let curQue = JSON.parse(JSON.stringify(this.curQue));
  576. let hengIndex = 0;
  577. curQue.detail.forEach((dItem, dIndex) => {
  578. let isHasPY = 0;
  579. let isRecord = 0;
  580. let roleDetail = this.getRole(dItem);
  581. let remarkDetail = dItem.remark;
  582. if (remarkDetail && (remarkDetail.chs || remarkDetail.en)) {
  583. this.isHasRemark = true;
  584. }
  585. let paraArr = [];
  586. if (dItem.wordsList && dItem.wordsList.length > 0) {
  587. dItem.wordsList.forEach((sItem, sIndex) => {
  588. sItem.forEach((wItem, wIndex) => {
  589. this.mergeWordSymbol(wItem);
  590. if (wItem.pinyin) {
  591. isHasPY++;
  592. }
  593. let obj = {
  594. paraIndex: dIndex, //段落索引
  595. sentIndex: sIndex, //在段落中句子索引
  596. wordIndex: wIndex, //单词的索引
  597. pinyin: wItem.pinyin,
  598. chs: wItem.chs,
  599. isHeng: reg.test(wItem.chs),
  600. padding: true, //wItem.padding,
  601. className: wItem.className,
  602. isShow: wItem.isShow,
  603. isNewWord: this.newWords.indexOf(wItem.chs) > -1 ? true : false,
  604. config: {
  605. fontColor: wItem.fontColor,
  606. fontFamily: wItem.fontFamily,
  607. fontSize: wItem.fontSize,
  608. underLine: wItem.underLine,
  609. wordPadding: wItem.wordPadding,
  610. },
  611. };
  612. if (obj.isHeng) {
  613. isRecord = isRecord + 1;
  614. hengIndex = hengIndex + 1;
  615. obj.hengIndex = hengIndex;
  616. obj.answer = "";
  617. }
  618. paraArr.push(obj);
  619. });
  620. });
  621. let curSentencesLeg = dItem.sentences.length;
  622. let startLeg = dIndex == 0 ? 0 : curQue.detail[dIndex - 1].endLeg;
  623. let endLeg = startLeg + curSentencesLeg;
  624. dItem.endLeg = endLeg;
  625. let timeList = [];
  626. if (curQue.wordTime && curQue.wordTime.length > 0) {
  627. timeList = curQue.wordTime.slice(startLeg, endLeg);
  628. }
  629. let enwords =
  630. dItem.sentencesEn && dItem.sentencesEn.length > 0
  631. ? dItem.sentencesEn.join(" ")
  632. : "";
  633. let paraObj = {
  634. wordsList: paraArr,
  635. enwords: enwords,
  636. timeList: timeList,
  637. roleDetail: roleDetail,
  638. remarkDetail: remarkDetail,
  639. isRecord:
  640. isRecord > 0 ||
  641. (curQue.checkList && curQue.checkList.indexOf("record") > -1)
  642. ? true
  643. : false,
  644. isHasPY: isHasPY,
  645. };
  646. resArr.push(paraObj);
  647. }
  648. });
  649. this.resArr = resArr;
  650. // 循环文章图片
  651. if (curQue.img_list) {
  652. curQue.img_list.forEach((item) => {
  653. this.articleImg[item.imgNumber] = item.id;
  654. });
  655. }
  656. },
  657. handlePYData() {
  658. let pararArr = [];
  659. let curQue = JSON.parse(JSON.stringify(this.curQue));
  660. this.hengIndex = 0;
  661. curQue.detail.forEach((dItem, dIndex) => {
  662. let para = dItem.para;
  663. let paraObj = this.handlePara(para);
  664. let roleDetail = this.getRole(dItem);
  665. let remarkDetail = dItem.remark;
  666. if (remarkDetail && (remarkDetail.chs || remarkDetail.en)) {
  667. this.isHasRemark = true;
  668. }
  669. let obj = {
  670. wordsList: paraObj.wordsList,
  671. roleDetail: roleDetail,
  672. remarkDetail: remarkDetail,
  673. isRecord: paraObj.isRecord,
  674. };
  675. pararArr.push(obj);
  676. });
  677. this.paraArr = pararArr;
  678. },
  679. //词和标点合一起
  680. mergeWordSymbol(wItem) {
  681. if (this.chsFhList.indexOf(wItem.chs) > -1) {
  682. wItem.isShow = false;
  683. } else {
  684. wItem.isShow = true;
  685. }
  686. },
  687. //获取角色
  688. getRole(dItem) {
  689. let roleIndex = dItem.roleIndex;
  690. let resObj = null;
  691. let roleList = JSON.parse(JSON.stringify(this.curQue.roleList));
  692. for (let i = 0; i < roleList.length; i++) {
  693. let item = roleList[i];
  694. if (item.id == roleIndex) {
  695. resObj = item;
  696. resObj.color = this.colorBox[i];
  697. break;
  698. }
  699. }
  700. return resObj;
  701. },
  702. //判断是否有padding
  703. judgePad(sItem, wItem, curIndex) {
  704. let leg = sItem.length;
  705. if (curIndex < leg - 1) {
  706. let nextIndex = curIndex + 1;
  707. let chs = sItem[nextIndex].chs;
  708. if (
  709. this.chsFhList.indexOf(chs) > -1 ||
  710. this.chsFhList.indexOf(wItem.chs) > -1
  711. ) {
  712. wItem.padding = false;
  713. } else {
  714. wItem.padding = true;
  715. }
  716. if (this.enFhList.indexOf(wItem.pinyin) > -1) {
  717. wItem.className = "textLeft";
  718. }
  719. }
  720. },
  721. //转化时间
  722. handleTimeList(list) {
  723. let listRes = [];
  724. list.forEach((item) => {
  725. let res = timeStrToSen(item);
  726. listRes.push(res);
  727. });
  728. return listRes;
  729. },
  730. //点击播放某个句子
  731. handleChangeTime(time) {
  732. this.curTime = time;
  733. this.$refs.audioLine.onTimeupdateTime(time / 1000);
  734. },
  735. //处理数组
  736. handlePara(para) {
  737. para = para.trim();
  738. para = para.replace(/\s+/g, " ");
  739. para = para.replace(/_{2,}/g, "^ ");
  740. let paraArr = para.split(/\s/g);
  741. let resArr = [];
  742. paraArr.forEach((item, index) => {
  743. let obj = {
  744. isHeng: false,
  745. con: item,
  746. };
  747. if (item == "^") {
  748. obj.isHeng = true;
  749. obj.answer = "";
  750. this.hengIndex++;
  751. obj.hengIndex = this.hengIndex;
  752. }
  753. resArr.push(obj);
  754. });
  755. let isRecord = /^/g.test(para);
  756. return { wordsList: resArr, isRecord: isRecord };
  757. },
  758. },
  759. //生命周期 - 创建完成(可以访问当前this实例)
  760. created() {},
  761. //生命周期 - 挂载完成(可以访问DOM元素)
  762. mounted() {
  763. if (this.curQue) {
  764. if (this.curQue.font == "cn" || !this.curQue.font) {
  765. this.handleData();
  766. } else {
  767. this.handlePYData();
  768. }
  769. }
  770. },
  771. beforeCreate() {}, //生命周期 - 创建之前
  772. beforeMount() {}, //生命周期 - 挂载之前
  773. beforeUpdate() {}, //生命周期 - 更新之前
  774. updated() {}, //生命周期 - 更新之后
  775. beforeDestroy() {}, //生命周期 - 销毁之前
  776. destroyed() {}, //生命周期 - 销毁完成
  777. activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  778. };
  779. </script>
  780. <style lang='scss' scoped>
  781. //@import url(); 引入公共css类
  782. .NNPE-ArticleView {
  783. width: 100%;
  784. .clearFix {
  785. clear: both;
  786. overflow: hidden;
  787. }
  788. .NPC-sentences-list {
  789. .NPC-article-empty {
  790. display: flex;
  791. justify-content: flex-start;
  792. align-items: flex-start;
  793. > div {
  794. height: 24px;
  795. &.empty-left {
  796. width: 100%;
  797. box-sizing: border-box;
  798. &.hasRemark {
  799. width: 553px;
  800. box-sizing: border-box;
  801. border-right: 1px rgba(0, 0, 0, 0.1) solid;
  802. }
  803. }
  804. &.empty-right {
  805. flex: 1;
  806. }
  807. }
  808. &-bottom {
  809. > div {
  810. height: 40px;
  811. }
  812. }
  813. }
  814. .dia-article-record {
  815. width: 100%;
  816. border-top: 1px solid rgba(0, 0, 0, 0.1);
  817. .luyin-box {
  818. justify-content: start;
  819. padding: 8px 12px;
  820. height: 40px;
  821. width: 280px;
  822. justify-content: flex-start;
  823. }
  824. }
  825. }
  826. .NNPE-detail {
  827. clear: both;
  828. overflow: hidden;
  829. display: flex;
  830. justify-content: flex-start;
  831. align-items: flex-start;
  832. &.active {
  833. background: rgba(0, 0, 0, 0.06);
  834. }
  835. .article-content {
  836. width: 100%;
  837. box-sizing: border-box;
  838. padding: 8px 24px 8px 24px;
  839. display: flex;
  840. justify-content: flex-start;
  841. align-items: flex-start;
  842. &.hasRemark {
  843. width: 553px;
  844. border-right: 1px rgba(0, 0, 0, 0.1) solid;
  845. padding: 8px 0px 8px 23px;
  846. }
  847. &.paraLast {
  848. padding-bottom: 24px;
  849. }
  850. }
  851. .NNPE-words {
  852. float: left;
  853. &-box {
  854. float: left;
  855. > span {
  856. display: block;
  857. &.NNPE-pinyin {
  858. font-family: "GB-PINYINOK-B";
  859. font-weight: normal;
  860. font-size: 14px;
  861. line-height: 22px;
  862. color: #000000;
  863. height: 21px;
  864. &.noFont {
  865. font-family: initial;
  866. }
  867. &.textLeft {
  868. text-align: left;
  869. }
  870. }
  871. &.NNPE-chs {
  872. font-family: "FZJCGFKTK";
  873. font-size: 20px;
  874. line-height: 28px;
  875. color: #000000;
  876. &.active {
  877. background: rgba(60, 200, 99, 0.2);
  878. }
  879. &.wordActive {
  880. color: #de4444;
  881. }
  882. &.NNPE-chs-underline {
  883. text-decoration: underline;
  884. }
  885. }
  886. &.padding {
  887. padding: 0 3px;
  888. }
  889. }
  890. }
  891. &.textLeft {
  892. text-align: left;
  893. }
  894. &.textCenter {
  895. text-align: center;
  896. }
  897. &.textRight {
  898. text-align: right;
  899. }
  900. > span {
  901. display: block;
  902. &.NNPE-pinyin {
  903. font-family: "GB-PINYINOK-B";
  904. font-weight: normal;
  905. font-size: 14px;
  906. line-height: 22px;
  907. color: #000000;
  908. height: 21px;
  909. &.noFont {
  910. font-family: initial;
  911. }
  912. &.textLeft {
  913. text-align: left;
  914. }
  915. }
  916. &.NNPE-chs {
  917. font-family: "FZJCGFKTK";
  918. font-size: 20px;
  919. line-height: 28px;
  920. color: #000000;
  921. &.active {
  922. background: rgba(60, 200, 99, 0.2);
  923. }
  924. &.wordActive {
  925. color: #de4444;
  926. }
  927. &.NNPE-chs-underline {
  928. text-decoration: underline;
  929. }
  930. }
  931. &.padding {
  932. padding: 0 3px;
  933. }
  934. }
  935. .answer-input {
  936. min-height: 28px;
  937. box-sizing: border-box;
  938. border: 0;
  939. border-bottom: 1px #000 solid;
  940. background: 0 0;
  941. min-width: 100px;
  942. outline: 0;
  943. text-align: left;
  944. font-family: "FZJCGFKTK";
  945. font-size: 20px;
  946. padding: 0 10px;
  947. box-sizing: border-box;
  948. color: #000000;
  949. line-height: 26px;
  950. }
  951. }
  952. .enwords {
  953. font-family: "robot";
  954. font-weight: normal;
  955. font-size: 14px;
  956. line-height: 22px;
  957. color: rgba(0, 0, 0, 0.85);
  958. }
  959. &.NNPE-detail-title {
  960. .wordsList-box {
  961. > div {
  962. display: flex;
  963. justify-content: center;
  964. }
  965. }
  966. }
  967. .index {
  968. width: 48px;
  969. box-sizing: border-box;
  970. padding: 8px;
  971. text-align: right;
  972. border-right: 1px solid rgba(0, 0, 0, 0.1);
  973. b {
  974. font-weight: 400;
  975. color: #000000;
  976. line-height: 1.5;
  977. }
  978. }
  979. .wordsList-box {
  980. width: 100%;
  981. padding: 0px 24px 0px 8px;
  982. clear: both;
  983. overflow: hidden;
  984. .roleDetail {
  985. height: 36px;
  986. display: flex;
  987. justify-content: flex-start;
  988. align-items: center;
  989. .pinyin {
  990. font-family: "GB-PINYINOK-B";
  991. font-size: 14px;
  992. line-height: 22px;
  993. color: rgba(0, 0, 0, 0.85);
  994. margin-right: 4px;
  995. }
  996. .chs {
  997. font-family: "FZJCGFKTK";
  998. font-size: 16px;
  999. line-height: 24px;
  1000. color: rgba(0, 0, 0, 0.85);
  1001. }
  1002. }
  1003. > .para-con {
  1004. float: left;
  1005. border: 1px solid rgba(0, 0, 0, 0.1);
  1006. box-sizing: border-box;
  1007. padding: 8px 12px 8px 12px;
  1008. border-radius: 8px;
  1009. }
  1010. > img {
  1011. width: 100%;
  1012. display: block;
  1013. }
  1014. .input-record {
  1015. margin-right: 8px;
  1016. .mini-box {
  1017. width: 64px;
  1018. border: 1px solid rgba(0, 0, 0, 0.1);
  1019. border-radius: 8px;
  1020. padding: 0 12px;
  1021. }
  1022. .normal-box {
  1023. width: 129px;
  1024. border: 1px solid rgba(0, 0, 0, 0.1);
  1025. border-radius: 8px;
  1026. padding: 0 12px;
  1027. }
  1028. }
  1029. }
  1030. }
  1031. .remarkBox {
  1032. flex: 1;
  1033. display: flex;
  1034. align-items: center;
  1035. justify-content: center;
  1036. &.remark72 {
  1037. padding-top: 72px;
  1038. }
  1039. &.remark-top {
  1040. padding-top: 44px;
  1041. }
  1042. }
  1043. .NNPE-para-pinyin {
  1044. font-weight: normal;
  1045. font-size: 20px;
  1046. line-height: 28px;
  1047. color: #000000;
  1048. height: 28px;
  1049. }
  1050. }
  1051. .judge-box {
  1052. display: flex;
  1053. justify-content: center;
  1054. a {
  1055. width: 32px;
  1056. height: 32px;
  1057. border-radius: 8px;
  1058. border: 1px solid rgba(0, 0, 0, 0.1);
  1059. display: flex;
  1060. justify-content: center;
  1061. align-items: center;
  1062. > img {
  1063. width: 24px;
  1064. height: 24px;
  1065. }
  1066. &:hover,
  1067. &.active {
  1068. background-color: #e5fff0;
  1069. border-color: #00c850;
  1070. }
  1071. }
  1072. a.error-btn {
  1073. margin-left: 4px;
  1074. &:hover,
  1075. &.active {
  1076. background-color: #ffe5e5;
  1077. border-color: #de4444;
  1078. }
  1079. }
  1080. }
  1081. .answer-box {
  1082. display: flex;
  1083. justify-content: flex-start;
  1084. align-items: center;
  1085. margin-top: 8px;
  1086. }
  1087. </style>