index.vue 27 KB

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