index.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  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" 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. // if (!this.isJudgingRightWrong) {
  323. // let userAnswer = JSON.parse(JSON.stringify(_this.userAnswer));
  324. // _this.$set(this.data, 'Bookanswer', userAnswer);
  325. // }
  326. _this.$nextTick(() => {
  327. _this.bodyLeft = _this.$refs.ArticleViewbody.getBoundingClientRect().left;
  328. });
  329. for (let i = 0; i < this.data.detail.length; i++) {
  330. let enStr = this.data.detail[i].sentencesEn ? this.data.detail[i].sentencesEn.join('') : '';
  331. if (enStr) {
  332. this.config.isShowEN = false;
  333. this.config.isHasEN = true;
  334. }
  335. let pinyin = this.handleObj(this.data.detail[i].wordsList);
  336. if (pinyin && this.isEnable(this.data.property.view_pinyin)) {
  337. this.config.isShowPY = true;
  338. this.config.isHasPY = true;
  339. }
  340. if (enStr && pinyin) {
  341. break;
  342. }
  343. }
  344. }
  345. },
  346. deep: true,
  347. immediate: true,
  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.data.mp3_list && this.data.mp3_list.length > 0) {
  509. this.data.mp3_list[0].url = this.data.mp3_list[0].temporary_url;
  510. // GetFileURLMap({ file_id_list: [this.data.mp3_list[0].file_id] }).then(({ url_map }) => {
  511. // this.data.mp3_list[0].url = url_map[this.data.mp3_list[0].file_id];
  512. // });
  513. }
  514. this.NNPENewWordList = (
  515. this.data.new_word_list_other_component_input ? this.data.new_word_list_other_component_input : []
  516. )
  517. .concat(
  518. this.data.new_word_list && this.data.new_word_list.new_word_list ? this.data.new_word_list.new_word_list : [],
  519. )
  520. .concat(
  521. this.data.other_word_list && this.data.other_word_list.new_word_list
  522. ? this.data.other_word_list.new_word_list
  523. : [],
  524. );
  525. this.NNPEAnnotationList = this.data.notes_list && this.data.notes_list.option ? this.data.notes_list.option : [];
  526. let resArr = [];
  527. let sentArrTotal = [];
  528. let timeArr = [];
  529. let curQue = JSON.parse(JSON.stringify(this.data));
  530. let wordTimeList = curQue.wordTime;
  531. let dhaspinyin = false; // 每段是否有拼音
  532. let dhaspinyinArr = [];
  533. curQue.detail.forEach((dItem, dIndex) => {
  534. dhaspinyin = false;
  535. dItem.wordsList.forEach((sItem, sIndex) => {
  536. let sentArr = [];
  537. let sentence = dItem.sentences[sIndex];
  538. sItem.forEach((wItem, wIndex) => {
  539. let startIndex = wIndex === 0 ? 0 : sentArr[wIndex - 1].startIndex + sentArr[wIndex - 1].chs.length;
  540. let endIndex = wIndex === 0 ? wItem.chs.length : sentArr[wIndex - 1].endIndex + wItem.chs.length;
  541. // this.judgePad(sItem, wItem, wIndex);
  542. this.mergeWordSymbol(wItem);
  543. let words = '';
  544. if (this.newWordList.length > 0) {
  545. if (!this.highWords) {
  546. this.findLightWord(wItem, wIndex, sentence, sItem);
  547. words = this.highWords ? this.highWords.words : '';
  548. } else if (wIndex > this.highWords.endIndex - 1) {
  549. this.highWords = null;
  550. this.findLightWord(wItem, wIndex, sentence, sItem);
  551. words = this.highWords ? this.highWords.words : '';
  552. } else {
  553. words = this.highWords ? this.highWords.words : '';
  554. }
  555. }
  556. let obj = {
  557. paraIndex: dIndex, // 段落索引
  558. sentIndex: sIndex, // 在段落中句子索引
  559. wordIndex: wIndex, // 单词的索引
  560. pinyin: wItem.pinyin,
  561. chs: wItem.chs,
  562. padding: true,
  563. className: wItem.className,
  564. isShow: wItem.isShow,
  565. startIndex,
  566. endIndex,
  567. leg: wItem.chs.length,
  568. timeList: [],
  569. words,
  570. config: {
  571. fontFamily: wItem.fontFamily,
  572. },
  573. };
  574. sentArr.push(obj);
  575. if (wItem.pinyin) dhaspinyin = true;
  576. });
  577. let objs = {
  578. sentArr,
  579. enwords: dItem.sentencesEn && dItem.sentencesEn[sIndex] && dItem.sentencesEn[sIndex].replace(/'/g, '’'),
  580. };
  581. sentArrTotal.push(sentArr);
  582. resArr.push(objs);
  583. });
  584. timeArr.push(dItem.timeList);
  585. if (this.isEnable(curQue.property.view_pinyin)) {
  586. dhaspinyinArr.push(dhaspinyin);
  587. }
  588. });
  589. if (wordTimeList && wordTimeList.length > 0) {
  590. this.mergeWordTime(sentArrTotal, wordTimeList);
  591. }
  592. let timeList = [];
  593. timeArr.forEach((item) => {
  594. item.forEach((aItem) => {
  595. if (timeList.indexOf(aItem) < 0) {
  596. timeList.push(aItem);
  597. }
  598. });
  599. });
  600. this.resObj = {
  601. sentList: resArr,
  602. timeList,
  603. dhaspinyinArr,
  604. };
  605. },
  606. mergeWordTime(resArr, wordTimeList) {
  607. resArr.forEach((item, index) => {
  608. let wordsResultList = wordTimeList[index].wordsResultList;
  609. item.forEach((wItem) => {
  610. let startIndex = wItem.startIndex;
  611. let endIndex = wItem.endIndex;
  612. wItem.timeList = wordsResultList.slice(startIndex, endIndex);
  613. });
  614. });
  615. },
  616. findLightWord(wItem, startIndex, sentence, sItem) {
  617. let endIndex = 0;
  618. let words = '';
  619. this.newWordList.forEach((item) => {
  620. if (item.length === 1) {
  621. if (item === wItem.chs && !wItem.banLight) {
  622. words = wItem.chs;
  623. endIndex = startIndex + 1;
  624. }
  625. } else if (item[0] === wItem.chs && sentence.indexOf(item) > -1) {
  626. let index = null;
  627. let chsStr = '';
  628. for (let i = startIndex; i < sItem.length + 1; i++) {
  629. index = i;
  630. if (chsStr.length === item.length) {
  631. break;
  632. } else {
  633. chsStr += sItem[i] ? sItem[i].chs : '';
  634. }
  635. }
  636. if (chsStr === item && !wItem.banLight) {
  637. words = item;
  638. endIndex = index;
  639. }
  640. } else if (wItem.new_word && wItem.new_word === item && !wItem.banLight) {
  641. words = item;
  642. endIndex = startIndex + 1;
  643. }
  644. });
  645. if (words) {
  646. this.highWords = { words, endIndex };
  647. } else {
  648. this.highWords = null;
  649. }
  650. },
  651. // 词和标点合一起
  652. mergeWordSymbol(wItem) {
  653. if (this.chsFhList.indexOf(wItem.chs) > -1) {
  654. wItem.isShow = false;
  655. } else {
  656. wItem.isShow = true;
  657. }
  658. },
  659. handleWav(list, tmIndex) {
  660. let i = tmIndex || 0;
  661. this.data.Bookanswer.practiceModel[i] = {
  662. recordList: [],
  663. };
  664. this.$set(this.data.Bookanswer.practiceModel[i], 'recordList', list);
  665. },
  666. handleNewword() {
  667. let NewWordList = [];
  668. this.NNPENewWordList.forEach((wItem) => {
  669. // item.forEach((wItem) => {
  670. if (wItem.new_word) {
  671. NewWordList.push(wItem.new_word);
  672. } else if (wItem.detail && wItem.detail.sentence) {
  673. NewWordList.push(wItem.detail.sentence);
  674. }
  675. // });
  676. });
  677. this.newWordList = JSON.parse(JSON.stringify(NewWordList));
  678. },
  679. },
  680. };
  681. </script>
  682. <style lang="scss" scoped>
  683. @use '@/styles/mixin.scss' as *;
  684. .article-preview {
  685. @include preview-base;
  686. .main {
  687. display: grid;
  688. row-gap: 24px;
  689. align-items: center;
  690. }
  691. .NPC-ArticleView {
  692. width: 100%;
  693. .ArticleView-full {
  694. position: absolute;
  695. top: 0;
  696. left: 0;
  697. z-index: 1;
  698. font-size: 16px;
  699. font-weight: bold;
  700. line-height: 24px;
  701. color: #000;
  702. cursor: pointer;
  703. // background: url('@/assets/full-screen-red.png') left center no-repeat;
  704. // background-size: 20px 20px;
  705. }
  706. .ArticleView-header {
  707. position: relative;
  708. display: flex;
  709. align-items: center;
  710. justify-content: space-between;
  711. height: 24px;
  712. margin-bottom: 16px;
  713. .left {
  714. display: flex;
  715. align-items: center;
  716. justify-content: center;
  717. // padding-left: 24px;
  718. font-size: 16px;
  719. font-weight: bold;
  720. line-height: 24px;
  721. cursor: pointer;
  722. // background: url('@/assets/wbfx-icon.png') left center no-repeat;
  723. // background-size: 20px;
  724. img {
  725. width: 20px;
  726. height: 20px;
  727. margin-right: 4px;
  728. }
  729. }
  730. .right {
  731. display: flex;
  732. gap: 24px;
  733. a {
  734. display: flex;
  735. gap: 4px;
  736. align-items: center;
  737. color: rgba(0, 0, 0, 65%);
  738. cursor: pointer;
  739. }
  740. }
  741. .setting-fontsize {
  742. display: flex;
  743. margin-left: 24px;
  744. a {
  745. box-sizing: border-box;
  746. display: block;
  747. width: 24px;
  748. height: 24px;
  749. border: 1px solid rgba(0, 0, 0, 10%);
  750. border-radius: 4px;
  751. }
  752. img {
  753. width: 100%;
  754. }
  755. > img {
  756. width: 24px;
  757. margin: 0 8px;
  758. }
  759. }
  760. }
  761. .ArticleView-body {
  762. box-sizing: border-box;
  763. background: #fff;
  764. border: 1px solid rgba(0, 0, 0, 10%);
  765. border-radius: 8px;
  766. .aduioLine-box {
  767. width: 100%;
  768. border-bottom: 1px solid rgba(0, 0, 0, 10%);
  769. &-bottom {
  770. border-top: 1px solid rgba(0, 0, 0, 10%);
  771. border-bottom: none;
  772. }
  773. }
  774. }
  775. }
  776. }
  777. </style>
  778. <style lang="scss">
  779. .NPC-ArticleView {
  780. .ArticleView-header {
  781. .el-switch {
  782. margin-left: 24px;
  783. }
  784. .el-switch__core {
  785. width: 44px !important;
  786. height: 24px;
  787. border-radius: 20px;
  788. }
  789. .el-switch__core::after {
  790. top: 3px;
  791. left: 3px;
  792. }
  793. .el-switch.is-checked .el-switch__core::after {
  794. left: 100%;
  795. margin-left: -19px;
  796. }
  797. .el-switch__label {
  798. color: #000;
  799. }
  800. .el-switch__label.is-active {
  801. color: rgba($color: #000, $alpha: 30%);
  802. }
  803. .el-switch__label--left {
  804. margin-right: 8px;
  805. }
  806. }
  807. .pinyin-16 {
  808. cursor: pointer;
  809. // background: url('@/assets/icon/pinyin-16-normal-red.png') no-repeat left top;
  810. // background-size: 100% 100%;
  811. // &.disabled {
  812. // background: url('@/assets/icon/pinyin-16-disable-Black.png') no-repeat left top;
  813. // background-size: 100% 100%;
  814. // }
  815. }
  816. .EN-16 {
  817. cursor: pointer;
  818. // background: url('@/assets/icon/EN-16-normal-red.png') no-repeat left top;
  819. // background-size: 100% 100%;
  820. // &.disabled {
  821. // background: url('@/assets/icon/EN-16-disable-Black.png') no-repeat left top;
  822. // background-size: 100% 100%;
  823. // }
  824. }
  825. }
  826. .ArticleView-body {
  827. .aduioLine-box {
  828. width: 100%;
  829. border-bottom: 1px solid rgba(0, 0, 0, 10%);
  830. &-bottom {
  831. border-top: 1px solid rgba(0, 0, 0, 10%);
  832. border-bottom: none;
  833. }
  834. }
  835. .el-slider {
  836. flex: 1;
  837. width: auto !important;
  838. }
  839. }
  840. </style>