index.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div class="article-preview" :style="[getAreaStyle(), getComponentStyle()]">
  4. <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
  5. <div class="main">
  6. <div class="NPC-ArticleView NPC-ArticleView-container">
  7. <div class="ArticleView-header">
  8. <a class="ArticleView-full" title="黑板模式" @click="fullScreen">
  9. <svg-icon
  10. icon-class="icon-full"
  11. size="24"
  12. :style="{
  13. color: data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
  14. }"
  15. />
  16. </a>
  17. <div>
  18. <!-- v-if="
  19. (tokenData && tokenData.popedom_code_list && tokenData.popedom_code_list.indexOf(2100001) != -1) ||
  20. (tokenData && tokenData.user_type === 'APP')
  21. " -->
  22. <div class="left" :style="{ marginLeft: '40px', cursor: 'pointer' }" title="文本分析" @click="submit">
  23. <!-- <img src="@/assets/wbfx-icon.png" alt="" /> -->
  24. <svg-icon
  25. icon-class="icon-wbfx"
  26. size="24"
  27. :style="{
  28. color: data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
  29. }"
  30. />
  31. </div>
  32. </div>
  33. <div class="right">
  34. <!-- <template v-if="data.property.is_enable_new_word === 'true'">
  35. <el-switch
  36. v-model="showPhrases"
  37. style="display: block"
  38. :active-color="bookInfo.theme_color"
  39. inactive-color="rgba(0,0,0,0.1)"
  40. active-text=""
  41. inactive-text="本课生词"
  42. @change="handleSwitchChange('showPractice', 'showWord')"
  43. />
  44. </template>
  45. <template v-if="data.property.is_enable_read === 'true'">
  46. <el-switch
  47. v-model="showPractice"
  48. style="display: block"
  49. :active-color="bookInfo.theme_color"
  50. inactive-color="rgba(0,0,0,0.1)"
  51. active-text=""
  52. inactive-text="语音练习"
  53. @change="handleSwitchChange('showPhrases', 'showWord')"
  54. />
  55. </template>
  56. <template v-if="data.property.is_enable_word === 'true'">
  57. <el-switch
  58. v-model="showWord"
  59. style="display: block"
  60. :active-color="bookInfo.theme_color"
  61. inactive-color="rgba(0,0,0,0.1)"
  62. active-text=""
  63. inactive-text="取词"
  64. @change="handleSwitchChange('showPhrases', 'showPractice')"
  65. />
  66. </template> -->
  67. <a
  68. v-if="data.property.is_enable_new_word === 'true'"
  69. :style="{
  70. color:
  71. showPhrases && data.unified_attrib && data.unified_attrib.topic_color
  72. ? data.unified_attrib.topic_color
  73. : '',
  74. }"
  75. title="本课生词"
  76. @click="handleSwitchChange('showPractice', 'showWord', 'showPhrases')"
  77. >
  78. <svg-icon icon-class="icon-article-ci" size="24" />
  79. </a>
  80. <a
  81. v-if="data.property.is_enable_read === 'true'"
  82. :style="{
  83. color:
  84. showPractice && data.unified_attrib && data.unified_attrib.topic_color
  85. ? data.unified_attrib.topic_color
  86. : '',
  87. }"
  88. title="语音练习"
  89. @click="handleSwitchChange('showPhrases', 'showWord', 'showPractice')"
  90. >
  91. <svg-icon icon-class="icon-article-practice" size="24" />
  92. </a>
  93. <a
  94. v-if="data.property.is_enable_word === 'true'"
  95. :style="{
  96. color:
  97. showWord && data.unified_attrib && data.unified_attrib.topic_color
  98. ? data.unified_attrib.topic_color
  99. : '',
  100. }"
  101. title="取词模式"
  102. @click="handleSwitchChange('showPhrases', 'showPractice', 'showWord')"
  103. >
  104. <svg-icon icon-class="icon-article-phrase" size="24" />
  105. </a>
  106. </div>
  107. </div>
  108. <div ref="ArticleViewbody" class="ArticleView-body">
  109. <NormalModelChs
  110. v-if="!showPhrases && !showPractice && !showWord"
  111. :cur-que="data"
  112. :title-fontsize="titleFontsize"
  113. :word-fontsize="wordFontsize"
  114. :body-left="bodyLeft"
  115. :body-width="bodyWidth"
  116. :attrib="data.unified_attrib"
  117. :is-mobile="isMobile"
  118. :no-font="noFont"
  119. :config="config"
  120. :NNPEAnnotationList="NNPEAnnotationList"
  121. :col-length="colLength"
  122. :multilingual="showLang && getLang() ? getLang() : ''"
  123. @changeConfig="changeConfig"
  124. />
  125. <PhraseModel
  126. v-if="showPhrases"
  127. :cur-que="data"
  128. :title-fontsize="titleFontsize"
  129. :word-fontsize="wordFontsize"
  130. :NNPENewWordList="NNPENewWordList"
  131. :attrib="data.unified_attrib"
  132. :is-mobile="isMobile"
  133. :no-font="noFont"
  134. :body-left="bodyLeft"
  135. :config="config"
  136. :TaskModel="isJudgingRightWrong ? 'ANSWER' : ''"
  137. :NNPEAnnotationList="NNPEAnnotationList"
  138. :col-length="colLength"
  139. :NpcNewWordMp3="NpcNewWordMp3"
  140. :multilingual="showLang && getLang() ? getLang() : ''"
  141. @changeConfig="changeConfig"
  142. />
  143. <Practice
  144. v-if="showPractice"
  145. :cur-que="data"
  146. :title-fontsize="titleFontsize"
  147. :word-fontsize="wordFontsize"
  148. :attrib="data.unified_attrib"
  149. :is-mobile="isMobile"
  150. :no-font="noFont"
  151. :NNPENewWordList="NNPENewWordList"
  152. :NNPEAnnotationList="NNPEAnnotationList"
  153. :config="config"
  154. :TaskModel="isJudgingRightWrong ? 'ANSWER' : ''"
  155. :col-length="colLength"
  156. :NpcNewWordMp3="NpcNewWordMp3"
  157. :is-full="isFull"
  158. :multilingual="showLang && getLang() ? getLang() : ''"
  159. @changeConfig="changeConfig"
  160. />
  161. <WordModel
  162. v-if="showWord"
  163. :cur-que="data"
  164. :title-fontsize="titleFontsize"
  165. :word-fontsize="wordFontsize"
  166. :body-left="bodyLeft"
  167. :body-width="bodyWidth"
  168. :NNPENewWordList="NNPENewWordList"
  169. :attrib="data.unified_attrib"
  170. :is-mobile="isMobile"
  171. :no-font="noFont"
  172. :config="config"
  173. :TaskModel="isJudgingRightWrong ? 'ANSWER' : ''"
  174. :col-length="colLength"
  175. :multilingual="showLang && getLang() ? getLang() : ''"
  176. @changeConfig="changeConfig"
  177. />
  178. </div>
  179. <div :id="'screen-' + mathNum" class="voice-full-screen">
  180. <Voicefullscreen
  181. v-if="isFull && resObj"
  182. :theme-color="bookInfo.theme_color"
  183. :cur-que="data"
  184. :sent-list="resObj.sentList"
  185. :sent-index="0"
  186. :mp3="data.mp3_list && data.mp3_list[0] ? data.mp3_list[0].url : ''"
  187. :no-font="noFont"
  188. :NNPENewWordList="NNPENewWordList"
  189. :NNPEAnnotationList="NNPEAnnotationList"
  190. :is-full="isFull"
  191. :config="config"
  192. :TaskModel="isJudgingRightWrong ? 'ANSWER' : ''"
  193. :NpcNewWordMp3="NpcNewWordMp3"
  194. :attrib="data.unified_attrib"
  195. :is-mobile="isMobile"
  196. @handleWav="handleWav"
  197. @changePinyin="changePinyins"
  198. @changeEN="changeENs"
  199. @exitFullscreen="exitFullscreen"
  200. @changeIsFull="changeIsFull"
  201. />
  202. </div>
  203. </div>
  204. <template
  205. v-if="data.new_word_list && data.new_word_list.new_word_list && data.new_word_list.new_word_list.length > 0"
  206. >
  207. <NewWordPreview :new-data="data.new_word_list" :is-mobile="isMobile" />
  208. </template>
  209. <template
  210. v-if="
  211. data.other_word_list && data.other_word_list.new_word_list && data.other_word_list.new_word_list.length > 0
  212. "
  213. >
  214. <NewWordPreview :new-data="data.other_word_list" :is-mobile="isMobile" />
  215. </template>
  216. <template v-if="data.notes_list && data.notes_list.option && data.notes_list.option.length > 0">
  217. <NotesPreview :notes-data="data.notes_list" :is-mobile="isMobile" />
  218. </template>
  219. </div>
  220. </div>
  221. </template>
  222. <script>
  223. import { getArticleData } from '@/views/book/courseware/data/dialogueArticle';
  224. import PreviewMixin from '../common/PreviewMixin';
  225. import PhraseModel from './PhraseModelChs.vue';
  226. import NormalModelChs from './NormalModelChs.vue';
  227. import Practice from './Practicechs.vue'; // 语音练习模式
  228. import WordModel from './WordModelChs.vue'; // 语音练习模式
  229. import Voicefullscreen from '../article/Voicefullscreen.vue';
  230. import { getToken } from '@/utils/auth';
  231. import { GetFileURLMap } from '@/api/app';
  232. import { analysSubmit, getSysConfig } from '@/api/article';
  233. import NewWordPreview from '../new_word/NewWordPreview.vue';
  234. import NotesPreview from '../notes/NotesPreview.vue';
  235. export default {
  236. name: 'DialogueArticlePreview',
  237. components: {
  238. NormalModelChs,
  239. Practice,
  240. WordModel,
  241. PhraseModel,
  242. Voicefullscreen,
  243. NewWordPreview,
  244. NotesPreview,
  245. },
  246. mixins: [PreviewMixin],
  247. inject: ['bookInfo'],
  248. props: ['isMobile'],
  249. data() {
  250. return {
  251. data: getArticleData(),
  252. showPreview: true, // 全文预览
  253. showPhrases: false, // 显示单词和短语
  254. showPractice: false, // 语音练习
  255. showWord: false, // 取词
  256. titleFontsize: 20, // 标题字号初始值
  257. wordFontsize: 16, // 文章内容字号初始值
  258. bodyLeft: 0,
  259. bodyWidth: 0,
  260. noFont: ['~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '/'],
  261. config: {
  262. isShowEN: false,
  263. isHasEN: false,
  264. isShowPY: false,
  265. isHasPY: false,
  266. },
  267. userAnswer: {
  268. normalModel: {
  269. recordList: [],
  270. },
  271. writeModel: {}, // 生词/取词模式
  272. practiceModel: {}, // 练习模式
  273. wordModel: {
  274. recordList: [],
  275. },
  276. },
  277. tokenData: getToken(),
  278. mathNum: Math.random().toString(36).substr(2),
  279. isFull: false,
  280. resObj: null,
  281. chsFhList: [',', '。', '”', ':', '》', '?', '!', ';', '、'],
  282. highWords: null,
  283. highWordsArr: [],
  284. highIndex: 0,
  285. newWordList: [],
  286. NNPEAnnotationList: [],
  287. NNPENewWordList: [],
  288. NpcNewWordMp3: [],
  289. colLength: 1,
  290. multilingualTextList: {},
  291. analyser_url: '',
  292. };
  293. },
  294. computed: {},
  295. watch: {
  296. showLang: {
  297. handler(val) {
  298. if (val) {
  299. this.data.multilingual.forEach((item) => {
  300. let trans_arr = item.translation ? item.translation.split('\n') : [];
  301. this.data.detail.forEach((items) => {
  302. let items_trans_arr = [];
  303. if (items && !items.hasOwnProperty('multilingualTextList')) {
  304. this.$set(items, 'multilingualTextList', {});
  305. }
  306. if (items.para) {
  307. items_trans_arr = trans_arr.splice(0, items.sentences.length);
  308. }
  309. this.$set(items.multilingualTextList, item.type, items_trans_arr);
  310. });
  311. });
  312. }
  313. },
  314. deep: true,
  315. immediate: true,
  316. },
  317. 'data.detail.length': {
  318. handler(val) {
  319. if (val) {
  320. this.handleData();
  321. let _this = this;
  322. _this.$nextTick(() => {
  323. _this.bodyLeft = _this.$refs.ArticleViewbody.getBoundingClientRect().left;
  324. });
  325. for (let i = 0; i < this.data.detail.length; i++) {
  326. let enStr = this.data.detail[i].sentencesEn ? this.data.detail[i].sentencesEn.join('') : '';
  327. if (enStr) {
  328. this.config.isShowEN = false;
  329. this.config.isHasEN = true;
  330. }
  331. let pinyin = this.handleObj(this.data.detail[i].wordsList);
  332. if (pinyin && this.isEnable(this.data.property.view_pinyin)) {
  333. this.config.isShowPY = true;
  334. this.config.isHasPY = true;
  335. }
  336. if (enStr && pinyin) {
  337. break;
  338. }
  339. }
  340. }
  341. },
  342. deep: true,
  343. immediate: true,
  344. },
  345. isJudgingRightWrong(val) {
  346. if (!val) return;
  347. this.data.Bookanswer = this.answer.answer_list;
  348. },
  349. },
  350. created() {},
  351. methods: {
  352. changeConfig(obj) {
  353. this.config[obj] = !this.config[obj];
  354. },
  355. changeIsFull() {
  356. this.isFull = false;
  357. },
  358. // 拼音的显示和隐藏
  359. changePinyins() {
  360. if (this.config.isHasPY) {
  361. this.changeConfig('isShowPY');
  362. }
  363. },
  364. // 英文的显示和隐藏
  365. changeENs() {
  366. if (this.config.isHasEN) {
  367. this.changeConfig('isShowEN');
  368. }
  369. },
  370. // 处理字体大小
  371. handleFontsize(symbol) {
  372. if (symbol === '+') {
  373. if (this.wordFontsize < 24) {
  374. this.titleFontsize += 2;
  375. this.wordFontsize += 2;
  376. }
  377. } else if (symbol === '-') {
  378. if (this.wordFontsize > 12) {
  379. this.titleFontsize -= 2;
  380. this.wordFontsize -= 2;
  381. }
  382. }
  383. },
  384. // 切换开关
  385. handleSwitchChange(obj1, obj2, obj3) {
  386. this[obj1] = false;
  387. this[obj2] = false;
  388. this[obj3] = !this[obj3];
  389. this.showPreview = false;
  390. },
  391. handleObj(list) {
  392. let pinyin = '';
  393. list.forEach((item) => {
  394. item.forEach((items) => {
  395. if (items.pinyin) pinyin += items.pinyin;
  396. });
  397. });
  398. return pinyin;
  399. },
  400. submit() {
  401. let access_token =
  402. this.tokenData && this.tokenData.gcls_sys_session_info ? this.tokenData.gcls_sys_session_info.access_token : '';
  403. let loading = this.$loading({
  404. lock: true,
  405. text: 'Loading',
  406. spinner: 'el-icon-loading',
  407. background: 'rgba(0, 0, 0, 0.7)',
  408. });
  409. getSysConfig()
  410. .then((ress) => {
  411. let content = '';
  412. this.data.detail.forEach((item) => {
  413. content += `${item.para}\n`;
  414. });
  415. analysSubmit({
  416. app_user_id: '',
  417. text: content,
  418. })
  419. .then((res) => {
  420. window.open(
  421. `${ress.text_analyser_page_address}GCLS-TC/#/textanalysis/Result?id=${res.record.id}&type=文本分析&AccessToken=${access_token}`,
  422. );
  423. loading.close();
  424. })
  425. .catch((res) => {
  426. loading.close();
  427. });
  428. })
  429. .catch((res) => {
  430. loading.close();
  431. });
  432. },
  433. // 语音全屏
  434. fullScreen() {
  435. this.pauseAudio();
  436. this.pauseVideo();
  437. this.isFull = true;
  438. this.goFullscreen();
  439. },
  440. pauseAudio() {
  441. let audio = document.getElementsByTagName('audio');
  442. if (audio && audio.length > 0 && window.location.href.indexOf('GCLS-Learn') === -1 && audio.forEach) {
  443. audio.forEach((item) => {
  444. item.pause();
  445. });
  446. }
  447. },
  448. pauseVideo() {
  449. let video = document.getElementsByTagName('video');
  450. if (video && video.length > 0 && window.location.href.indexOf('GCLS-Learn') === -1 && video.forEach) {
  451. video.forEach((item) => {
  452. item.pause();
  453. });
  454. }
  455. },
  456. goFullscreen() {
  457. let id = `screen-${this.mathNum}`;
  458. let element = document.getElementById(id);
  459. if (element.requestFullscreen) {
  460. element.requestFullscreen();
  461. } else if (element.msRequestFullscreen) {
  462. element.msRequestFullscreen();
  463. } else if (element.mozRequestFullScreen) {
  464. element.mozRequestFullScreen();
  465. } else if (element.webkitRequestFullscreen) {
  466. element.webkitRequestFullscreen();
  467. }
  468. },
  469. exitFullscreen() {
  470. this.isFull = false;
  471. if (document.exitFullscreen) {
  472. document.exitFullscreen();
  473. } else if (document.msExitFullscreen) {
  474. document.msExitFullscreen();
  475. } else if (document.mozCancelFullScreen) {
  476. document.mozCancelFullScreen();
  477. } else if (document.webkitExitFullscreen) {
  478. document.webkitExitFullscreen();
  479. }
  480. },
  481. handleData() {
  482. if (this.data.new_word_list) {
  483. this.$set(this.data.new_word_list, 'unified_attrib', this.data.unified_attrib);
  484. }
  485. if (this.data.other_word_list) {
  486. this.$set(this.data.other_word_list, 'unified_attrib', this.data.unified_attrib);
  487. }
  488. if (this.data.notes_list) {
  489. this.$set(this.data.notes_list, 'unified_attrib', this.data.unified_attrib);
  490. }
  491. if (this.showLang) {
  492. this.data.multilingual.forEach((item) => {
  493. let trans_arr = item.translation ? item.translation.split('\n') : [];
  494. this.data.detail.forEach((items) => {
  495. let items_trans_arr = [];
  496. if (!items.hasOwnProperty('multilingualTextList')) {
  497. this.$set(items, 'multilingualTextList', {});
  498. }
  499. if (items.para) {
  500. items_trans_arr = trans_arr.splice(0, items.sentences.length);
  501. }
  502. this.$set(items.multilingualTextList, item.type, items_trans_arr);
  503. });
  504. });
  505. }
  506. let userAnswer = JSON.parse(JSON.stringify(this.userAnswer));
  507. this.$set(this.data, 'Bookanswer', userAnswer);
  508. if (!this.isJudgingRightWrong) {
  509. this.answer.answer_list = this.data.Bookanswer;
  510. }
  511. if (this.data.mp3_list && this.data.mp3_list.length > 0) {
  512. this.data.mp3_list[0].url = this.data.mp3_list[0].temporary_url;
  513. // GetFileURLMap({ file_id_list: [this.data.mp3_list[0].file_id] }).then(({ url_map }) => {
  514. // this.data.mp3_list[0].url = url_map[this.data.mp3_list[0].file_id];
  515. // });
  516. }
  517. this.NNPENewWordList = (
  518. this.data.new_word_list_other_component_input ? this.data.new_word_list_other_component_input : []
  519. )
  520. .concat(
  521. this.data.new_word_list && this.data.new_word_list.new_word_list ? this.data.new_word_list.new_word_list : [],
  522. )
  523. .concat(
  524. this.data.other_word_list && this.data.other_word_list.new_word_list
  525. ? this.data.other_word_list.new_word_list
  526. : [],
  527. );
  528. this.NNPEAnnotationList = this.data.notes_list && this.data.notes_list.option ? this.data.notes_list.option : [];
  529. let resArr = [];
  530. let sentArrTotal = [];
  531. let timeArr = [];
  532. let curQue = JSON.parse(JSON.stringify(this.data));
  533. let wordTimeList = curQue.wordTime;
  534. let dhaspinyin = false; // 每段是否有拼音
  535. let dhaspinyinArr = [];
  536. curQue.detail.forEach((dItem, dIndex) => {
  537. dhaspinyin = false;
  538. dItem.wordsList.forEach((sItem, sIndex) => {
  539. let sentArr = [];
  540. let sentence = dItem.sentences[sIndex];
  541. sItem.forEach((wItem, wIndex) => {
  542. let startIndex = wIndex === 0 ? 0 : sentArr[wIndex - 1].startIndex + sentArr[wIndex - 1].chs.length;
  543. let endIndex = wIndex === 0 ? wItem.chs.length : sentArr[wIndex - 1].endIndex + wItem.chs.length;
  544. // this.judgePad(sItem, wItem, wIndex);
  545. this.mergeWordSymbol(wItem);
  546. let words = '';
  547. if (this.newWordList.length > 0) {
  548. if (!this.highWords) {
  549. this.findLightWord(wItem, wIndex, sentence, sItem);
  550. words = this.highWords ? this.highWords.words : '';
  551. } else if (wIndex > this.highWords.endIndex - 1) {
  552. this.highWords = null;
  553. this.findLightWord(wItem, wIndex, sentence, sItem);
  554. words = this.highWords ? this.highWords.words : '';
  555. } else {
  556. words = this.highWords ? this.highWords.words : '';
  557. }
  558. }
  559. let obj = {
  560. paraIndex: dIndex, // 段落索引
  561. sentIndex: sIndex, // 在段落中句子索引
  562. wordIndex: wIndex, // 单词的索引
  563. pinyin: wItem.pinyin,
  564. chs: wItem.chs,
  565. padding: true,
  566. className: wItem.className,
  567. isShow: wItem.isShow,
  568. startIndex,
  569. endIndex,
  570. leg: wItem.chs.length,
  571. timeList: [],
  572. words,
  573. config: {
  574. fontFamily: wItem.fontFamily,
  575. color: wItem.color,
  576. textDecoration: wItem.textDecoration,
  577. border: wItem.border,
  578. fontWeight: wItem.fontWeight,
  579. },
  580. matchWords: wItem.matchWords,
  581. matchNotes: wItem.matchNotes,
  582. img: wItem.img,
  583. imgPosition: wItem.imgPosition,
  584. };
  585. sentArr.push(obj);
  586. if (wItem.pinyin) dhaspinyin = true;
  587. });
  588. let objs = {
  589. sentArr,
  590. enwords: dItem.sentencesEn && dItem.sentencesEn[sIndex] && dItem.sentencesEn[sIndex].replace(/'/g, '’'),
  591. };
  592. sentArrTotal.push(sentArr);
  593. resArr.push(objs);
  594. });
  595. timeArr.push(dItem.timeList);
  596. if (this.isEnable(curQue.property.view_pinyin)) {
  597. dhaspinyinArr.push(dhaspinyin);
  598. }
  599. });
  600. if (wordTimeList && wordTimeList.length > 0) {
  601. this.mergeWordTime(sentArrTotal, wordTimeList);
  602. }
  603. let timeList = [];
  604. timeArr.forEach((item) => {
  605. item.forEach((aItem) => {
  606. if (timeList.indexOf(aItem) < 0) {
  607. timeList.push(aItem);
  608. }
  609. });
  610. });
  611. this.resObj = {
  612. sentList: resArr,
  613. timeList,
  614. dhaspinyinArr,
  615. };
  616. },
  617. mergeWordTime(resArr, wordTimeList) {
  618. resArr.forEach((item, index) => {
  619. let wordsResultList = wordTimeList[index].wordsResultList;
  620. item.forEach((wItem) => {
  621. let startIndex = wItem.startIndex;
  622. let endIndex = wItem.endIndex;
  623. wItem.timeList = wordsResultList.slice(startIndex, endIndex);
  624. });
  625. });
  626. },
  627. findLightWord(wItem, startIndex, sentence, sItem) {
  628. let endIndex = 0;
  629. let words = '';
  630. this.newWordList.forEach((item) => {
  631. if (item.length === 1) {
  632. if (item === wItem.chs && !wItem.banLight) {
  633. words = wItem.chs;
  634. endIndex = startIndex + 1;
  635. }
  636. } else if (item[0] === wItem.chs && sentence.indexOf(item) > -1) {
  637. let index = null;
  638. let chsStr = '';
  639. for (let i = startIndex; i < sItem.length + 1; i++) {
  640. index = i;
  641. if (chsStr.length === item.length) {
  642. break;
  643. } else {
  644. chsStr += sItem[i] ? sItem[i].chs : '';
  645. }
  646. }
  647. if (chsStr === item && !wItem.banLight) {
  648. words = item;
  649. endIndex = index;
  650. }
  651. } else if (wItem.new_word && wItem.new_word === item && !wItem.banLight) {
  652. words = item;
  653. endIndex = startIndex + 1;
  654. }
  655. });
  656. if (words) {
  657. this.highWords = { words, endIndex };
  658. } else {
  659. this.highWords = null;
  660. }
  661. },
  662. // 词和标点合一起
  663. mergeWordSymbol(wItem) {
  664. if (this.chsFhList.indexOf(wItem.chs) > -1) {
  665. wItem.isShow = false;
  666. } else {
  667. wItem.isShow = true;
  668. }
  669. },
  670. handleWav(list, tmIndex) {
  671. let i = tmIndex || 0;
  672. this.data.Bookanswer.practiceModel[i] = {
  673. recordList: [],
  674. };
  675. this.$set(this.data.Bookanswer.practiceModel[i], 'recordList', list);
  676. },
  677. handleNewword() {
  678. let NewWordList = [];
  679. this.NNPENewWordList.forEach((wItem) => {
  680. // item.forEach((wItem) => {
  681. if (wItem.new_word) {
  682. NewWordList.push(wItem.new_word);
  683. } else if (wItem.detail && wItem.detail.sentence) {
  684. NewWordList.push(wItem.detail.sentence);
  685. }
  686. // });
  687. });
  688. this.newWordList = JSON.parse(JSON.stringify(NewWordList));
  689. },
  690. },
  691. };
  692. </script>
  693. <style lang="scss" scoped>
  694. @use '@/styles/mixin.scss' as *;
  695. .article-preview {
  696. @include preview-base;
  697. .main {
  698. display: grid;
  699. row-gap: 24px;
  700. align-items: center;
  701. }
  702. .NPC-ArticleView {
  703. width: 100%;
  704. .ArticleView-full {
  705. position: absolute;
  706. top: 0;
  707. left: 0;
  708. z-index: 1;
  709. font-size: 16px;
  710. font-weight: bold;
  711. line-height: 24px;
  712. color: #000;
  713. cursor: pointer;
  714. // background: url('@/assets/full-screen-red.png') left center no-repeat;
  715. // background-size: 20px 20px;
  716. }
  717. .ArticleView-header {
  718. position: relative;
  719. display: flex;
  720. align-items: center;
  721. justify-content: space-between;
  722. height: 24px;
  723. margin-bottom: 16px;
  724. .left {
  725. display: flex;
  726. align-items: center;
  727. justify-content: center;
  728. // padding-left: 24px;
  729. font-size: 16px;
  730. font-weight: bold;
  731. line-height: 24px;
  732. cursor: pointer;
  733. // background: url('@/assets/wbfx-icon.png') left center no-repeat;
  734. // background-size: 20px;
  735. img {
  736. width: 20px;
  737. height: 20px;
  738. margin-right: 4px;
  739. }
  740. }
  741. .right {
  742. display: flex;
  743. gap: 24px;
  744. a {
  745. display: flex;
  746. gap: 4px;
  747. align-items: center;
  748. color: rgba(0, 0, 0, 65%);
  749. cursor: pointer;
  750. }
  751. }
  752. .setting-fontsize {
  753. display: flex;
  754. margin-left: 24px;
  755. a {
  756. box-sizing: border-box;
  757. display: block;
  758. width: 24px;
  759. height: 24px;
  760. border: 1px solid rgba(0, 0, 0, 10%);
  761. border-radius: 4px;
  762. }
  763. img {
  764. width: 100%;
  765. }
  766. > img {
  767. width: 24px;
  768. margin: 0 8px;
  769. }
  770. }
  771. }
  772. .ArticleView-body {
  773. box-sizing: border-box;
  774. background: #fff;
  775. border: 1px solid rgba(0, 0, 0, 10%);
  776. border-radius: 4px;
  777. .aduioLine-box {
  778. width: 100%;
  779. border-bottom: 1px solid rgba(0, 0, 0, 10%);
  780. &-bottom {
  781. border-top: 1px solid rgba(0, 0, 0, 10%);
  782. border-bottom: none;
  783. }
  784. }
  785. }
  786. }
  787. }
  788. </style>
  789. <style lang="scss">
  790. .NPC-ArticleView {
  791. .ArticleView-header {
  792. .el-switch {
  793. margin-left: 24px;
  794. }
  795. .el-switch__core {
  796. width: 44px !important;
  797. height: 24px;
  798. border-radius: 20px;
  799. }
  800. .el-switch__core::after {
  801. top: 3px;
  802. left: 3px;
  803. }
  804. .el-switch.is-checked .el-switch__core::after {
  805. left: 100%;
  806. margin-left: -19px;
  807. }
  808. .el-switch__label {
  809. color: #000;
  810. }
  811. .el-switch__label.is-active {
  812. color: rgba($color: #000, $alpha: 30%);
  813. }
  814. .el-switch__label--left {
  815. margin-right: 8px;
  816. }
  817. }
  818. .pinyin-16 {
  819. cursor: pointer;
  820. // background: url('@/assets/icon/pinyin-16-normal-red.png') no-repeat left top;
  821. // background-size: 100% 100%;
  822. // &.disabled {
  823. // background: url('@/assets/icon/pinyin-16-disable-Black.png') no-repeat left top;
  824. // background-size: 100% 100%;
  825. // }
  826. }
  827. .EN-16 {
  828. cursor: pointer;
  829. // background: url('@/assets/icon/EN-16-normal-red.png') no-repeat left top;
  830. // background-size: 100% 100%;
  831. // &.disabled {
  832. // background: url('@/assets/icon/EN-16-disable-Black.png') no-repeat left top;
  833. // background-size: 100% 100%;
  834. // }
  835. }
  836. }
  837. .ArticleView-body {
  838. .aduioLine-box {
  839. width: 100%;
  840. border-bottom: 1px solid rgba(0, 0, 0, 10%);
  841. &-bottom {
  842. border-top: 1px solid rgba(0, 0, 0, 10%);
  843. border-bottom: none;
  844. }
  845. }
  846. .el-slider {
  847. flex: 1;
  848. width: auto !important;
  849. }
  850. }
  851. </style>