AnswerModel.vue 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  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. console.log("Normal");
  651. console.log(this.resArr);
  652. // 循环文章图片
  653. if (curQue.img_list) {
  654. curQue.img_list.forEach((item) => {
  655. this.articleImg[item.imgNumber] = item.id;
  656. });
  657. }
  658. },
  659. handlePYData() {
  660. let pararArr = [];
  661. let curQue = JSON.parse(JSON.stringify(this.curQue));
  662. this.hengIndex = 0;
  663. curQue.detail.forEach((dItem, dIndex) => {
  664. let para = dItem.para;
  665. let paraObj = this.handlePara(para);
  666. let roleDetail = this.getRole(dItem);
  667. let remarkDetail = dItem.remark;
  668. if (remarkDetail && (remarkDetail.chs || remarkDetail.en)) {
  669. this.isHasRemark = true;
  670. }
  671. let obj = {
  672. wordsList: paraObj.wordsList,
  673. roleDetail: roleDetail,
  674. remarkDetail: remarkDetail,
  675. isRecord: paraObj.isRecord,
  676. };
  677. pararArr.push(obj);
  678. });
  679. this.paraArr = pararArr;
  680. },
  681. //词和标点合一起
  682. mergeWordSymbol(wItem) {
  683. if (this.chsFhList.indexOf(wItem.chs) > -1) {
  684. wItem.isShow = false;
  685. } else {
  686. wItem.isShow = true;
  687. }
  688. },
  689. //获取角色
  690. getRole(dItem) {
  691. let roleIndex = dItem.roleIndex;
  692. let resObj = null;
  693. let roleList = JSON.parse(JSON.stringify(this.curQue.roleList));
  694. for (let i = 0; i < roleList.length; i++) {
  695. let item = roleList[i];
  696. if (item.id == roleIndex) {
  697. resObj = item;
  698. resObj.color = this.colorBox[i];
  699. break;
  700. }
  701. }
  702. return resObj;
  703. },
  704. //判断是否有padding
  705. judgePad(sItem, wItem, curIndex) {
  706. let leg = sItem.length;
  707. if (curIndex < leg - 1) {
  708. let nextIndex = curIndex + 1;
  709. let chs = sItem[nextIndex].chs;
  710. if (
  711. this.chsFhList.indexOf(chs) > -1 ||
  712. this.chsFhList.indexOf(wItem.chs) > -1
  713. ) {
  714. wItem.padding = false;
  715. } else {
  716. wItem.padding = true;
  717. }
  718. if (this.enFhList.indexOf(wItem.pinyin) > -1) {
  719. wItem.className = "textLeft";
  720. }
  721. }
  722. },
  723. //转化时间
  724. handleTimeList(list) {
  725. let listRes = [];
  726. list.forEach((item) => {
  727. let res = timeStrToSen(item);
  728. listRes.push(res);
  729. });
  730. return listRes;
  731. },
  732. //点击播放某个句子
  733. handleChangeTime(time) {
  734. this.curTime = time;
  735. this.$refs.audioLine.onTimeupdateTime(time / 1000);
  736. },
  737. //处理数组
  738. handlePara(para) {
  739. para = para.trim();
  740. para = para.replace(/\s+/g, " ");
  741. para = para.replace(/_{2,}/g, "^ ");
  742. let paraArr = para.split(/\s/g);
  743. let resArr = [];
  744. paraArr.forEach((item, index) => {
  745. let obj = {
  746. isHeng: false,
  747. con: item,
  748. };
  749. if (item == "^") {
  750. obj.isHeng = true;
  751. obj.answer = "";
  752. this.hengIndex++;
  753. obj.hengIndex = this.hengIndex;
  754. }
  755. resArr.push(obj);
  756. });
  757. let isRecord = /^/g.test(para);
  758. return { wordsList: resArr, isRecord: isRecord };
  759. },
  760. },
  761. //生命周期 - 创建完成(可以访问当前this实例)
  762. created() {},
  763. //生命周期 - 挂载完成(可以访问DOM元素)
  764. mounted() {
  765. if (this.curQue) {
  766. if (this.curQue.font == "cn" || !this.curQue.font) {
  767. this.handleData();
  768. } else {
  769. this.handlePYData();
  770. }
  771. }
  772. },
  773. beforeCreate() {}, //生命周期 - 创建之前
  774. beforeMount() {}, //生命周期 - 挂载之前
  775. beforeUpdate() {}, //生命周期 - 更新之前
  776. updated() {}, //生命周期 - 更新之后
  777. beforeDestroy() {}, //生命周期 - 销毁之前
  778. destroyed() {}, //生命周期 - 销毁完成
  779. activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  780. };
  781. </script>
  782. <style lang='scss' scoped>
  783. //@import url(); 引入公共css类
  784. .NNPE-ArticleView {
  785. width: 100%;
  786. .clearFix {
  787. clear: both;
  788. overflow: hidden;
  789. }
  790. .NPC-sentences-list {
  791. .NPC-article-empty {
  792. display: flex;
  793. justify-content: flex-start;
  794. align-items: flex-start;
  795. > div {
  796. height: 24px;
  797. &.empty-left {
  798. width: 100%;
  799. box-sizing: border-box;
  800. &.hasRemark {
  801. width: 553px;
  802. box-sizing: border-box;
  803. border-right: 1px rgba(0, 0, 0, 0.1) solid;
  804. }
  805. }
  806. &.empty-right {
  807. flex: 1;
  808. }
  809. }
  810. &-bottom {
  811. > div {
  812. height: 40px;
  813. }
  814. }
  815. }
  816. .dia-article-record {
  817. width: 100%;
  818. border-top: 1px solid rgba(0, 0, 0, 0.1);
  819. .luyin-box {
  820. justify-content: start;
  821. padding: 8px 12px;
  822. height: 40px;
  823. width: 280px;
  824. justify-content: flex-start;
  825. }
  826. }
  827. }
  828. .NNPE-detail {
  829. clear: both;
  830. overflow: hidden;
  831. display: flex;
  832. justify-content: flex-start;
  833. align-items: flex-start;
  834. &.active {
  835. background: rgba(0, 0, 0, 0.06);
  836. }
  837. .article-content {
  838. width: 100%;
  839. box-sizing: border-box;
  840. padding: 8px 24px 8px 24px;
  841. display: flex;
  842. justify-content: flex-start;
  843. align-items: flex-start;
  844. &.hasRemark {
  845. width: 553px;
  846. border-right: 1px rgba(0, 0, 0, 0.1) solid;
  847. padding: 8px 0px 8px 23px;
  848. }
  849. &.paraLast {
  850. padding-bottom: 24px;
  851. }
  852. }
  853. .NNPE-words {
  854. float: left;
  855. &-box {
  856. float: left;
  857. > span {
  858. display: block;
  859. &.NNPE-pinyin {
  860. font-family: "GB-PINYINOK-B";
  861. font-weight: normal;
  862. font-size: 14px;
  863. line-height: 22px;
  864. color: #000000;
  865. height: 21px;
  866. &.noFont {
  867. font-family: initial;
  868. }
  869. &.textLeft {
  870. text-align: left;
  871. }
  872. }
  873. &.NNPE-chs {
  874. font-family: "FZJCGFKTK";
  875. font-size: 20px;
  876. line-height: 28px;
  877. color: #000000;
  878. &.active {
  879. background: rgba(60, 200, 99, 0.2);
  880. }
  881. &.wordActive {
  882. color: #de4444;
  883. }
  884. &.NNPE-chs-underline {
  885. text-decoration: underline;
  886. }
  887. }
  888. &.padding {
  889. padding: 0 3px;
  890. }
  891. }
  892. }
  893. &.textLeft {
  894. text-align: left;
  895. }
  896. &.textCenter {
  897. text-align: center;
  898. }
  899. &.textRight {
  900. text-align: right;
  901. }
  902. > span {
  903. display: block;
  904. &.NNPE-pinyin {
  905. font-family: "GB-PINYINOK-B";
  906. font-weight: normal;
  907. font-size: 14px;
  908. line-height: 22px;
  909. color: #000000;
  910. height: 21px;
  911. &.noFont {
  912. font-family: initial;
  913. }
  914. &.textLeft {
  915. text-align: left;
  916. }
  917. }
  918. &.NNPE-chs {
  919. font-family: "FZJCGFKTK";
  920. font-size: 20px;
  921. line-height: 28px;
  922. color: #000000;
  923. &.active {
  924. background: rgba(60, 200, 99, 0.2);
  925. }
  926. &.wordActive {
  927. color: #de4444;
  928. }
  929. &.NNPE-chs-underline {
  930. text-decoration: underline;
  931. }
  932. }
  933. &.padding {
  934. padding: 0 3px;
  935. }
  936. }
  937. .answer-input {
  938. min-height: 28px;
  939. box-sizing: border-box;
  940. border: 0;
  941. border-bottom: 1px #000 solid;
  942. background: 0 0;
  943. min-width: 100px;
  944. outline: 0;
  945. text-align: left;
  946. font-family: "FZJCGFKTK";
  947. font-size: 20px;
  948. padding: 0 10px;
  949. box-sizing: border-box;
  950. color: #000000;
  951. line-height: 26px;
  952. }
  953. }
  954. .enwords {
  955. font-family: "robot";
  956. font-weight: normal;
  957. font-size: 14px;
  958. line-height: 22px;
  959. color: rgba(0, 0, 0, 0.85);
  960. }
  961. &.NNPE-detail-title {
  962. .wordsList-box {
  963. > div {
  964. display: flex;
  965. justify-content: center;
  966. }
  967. }
  968. }
  969. .index {
  970. width: 48px;
  971. box-sizing: border-box;
  972. padding: 8px;
  973. text-align: right;
  974. border-right: 1px solid rgba(0, 0, 0, 0.1);
  975. b {
  976. font-weight: 400;
  977. color: #000000;
  978. line-height: 1.5;
  979. }
  980. }
  981. .wordsList-box {
  982. width: 100%;
  983. padding: 0px 24px 0px 8px;
  984. clear: both;
  985. overflow: hidden;
  986. .roleDetail {
  987. height: 36px;
  988. display: flex;
  989. justify-content: flex-start;
  990. align-items: center;
  991. .pinyin {
  992. font-family: "GB-PINYINOK-B";
  993. font-size: 14px;
  994. line-height: 22px;
  995. color: rgba(0, 0, 0, 0.85);
  996. margin-right: 4px;
  997. }
  998. .chs {
  999. font-family: "FZJCGFKTK";
  1000. font-size: 16px;
  1001. line-height: 24px;
  1002. color: rgba(0, 0, 0, 0.85);
  1003. }
  1004. }
  1005. > .para-con {
  1006. float: left;
  1007. border: 1px solid rgba(0, 0, 0, 0.1);
  1008. box-sizing: border-box;
  1009. padding: 8px 12px 8px 12px;
  1010. border-radius: 8px;
  1011. }
  1012. > img {
  1013. width: 100%;
  1014. display: block;
  1015. }
  1016. .input-record {
  1017. margin-right: 8px;
  1018. .mini-box {
  1019. width: 64px;
  1020. border: 1px solid rgba(0, 0, 0, 0.1);
  1021. border-radius: 8px;
  1022. padding: 0 12px;
  1023. }
  1024. .normal-box {
  1025. width: 129px;
  1026. border: 1px solid rgba(0, 0, 0, 0.1);
  1027. border-radius: 8px;
  1028. padding: 0 12px;
  1029. }
  1030. }
  1031. }
  1032. }
  1033. .remarkBox {
  1034. flex: 1;
  1035. display: flex;
  1036. align-items: center;
  1037. justify-content: center;
  1038. &.remark72 {
  1039. padding-top: 72px;
  1040. }
  1041. &.remark-top {
  1042. padding-top: 44px;
  1043. }
  1044. }
  1045. .NNPE-para-pinyin {
  1046. font-weight: normal;
  1047. font-size: 20px;
  1048. line-height: 28px;
  1049. color: #000000;
  1050. height: 28px;
  1051. }
  1052. }
  1053. .judge-box {
  1054. display: flex;
  1055. justify-content: center;
  1056. a {
  1057. width: 32px;
  1058. height: 32px;
  1059. border-radius: 8px;
  1060. border: 1px solid rgba(0, 0, 0, 0.1);
  1061. display: flex;
  1062. justify-content: center;
  1063. align-items: center;
  1064. > img {
  1065. width: 24px;
  1066. height: 24px;
  1067. }
  1068. &:hover,
  1069. &.active {
  1070. background-color: #e5fff0;
  1071. border-color: #00c850;
  1072. }
  1073. }
  1074. a.error-btn {
  1075. margin-left: 4px;
  1076. &:hover,
  1077. &.active {
  1078. background-color: #ffe5e5;
  1079. border-color: #de4444;
  1080. }
  1081. }
  1082. }
  1083. .answer-box {
  1084. display: flex;
  1085. justify-content: flex-start;
  1086. align-items: center;
  1087. margin-top: 8px;
  1088. }
  1089. </style>