index.vue 27 KB

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