index.vue 28 KB

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