AnswerModel.vue 35 KB

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