InnerTextSearch.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. <!-- -->
  2. <template>
  3. <div class="NNPE-ArticleView" v-if="articleInfo">
  4. <template
  5. v-if="
  6. resArr[0] &&
  7. resArr[0].wordsList[0] &&
  8. resArr[0].wordsList[0].hasOwnProperty('pno') &&
  9. resArr[0].wordsList[0].pno === 0
  10. "
  11. >
  12. <h2 :class="['NNPE-words']">
  13. <span
  14. v-for="(itemR, indexR) in resArr[0].wordsList"
  15. :key="indexR"
  16. :style="{
  17. color: colorObj.titleColor,
  18. fontSize: titleFontsize + 'px',
  19. lineHeight: titleFontsize + 8 + 'px',
  20. marginRight: itemR.tokens[9] === '' ? '' : '10px',
  21. fontWeight: '700',
  22. cursor: 'pointer',
  23. }"
  24. :class="[
  25. itemR.tokens[9] === '' ? 'marginRight' : '',
  26. itemR.marginRight ? 'marginSingleRight' : '',
  27. ]"
  28. >
  29. <!-- <template v-if="itemR.isShow"> -->
  30. <span
  31. class="NNPE-chs"
  32. :class="[
  33. itemR.type,
  34. itemR.tokens[9] === '' ? 'marginRight' : '',
  35. itemR.marginRight ? 'marginSingleRight' : '',
  36. itemR.highIndex ? 'fontWeight' : '',
  37. itemR.color ? 'wordSelected' : '',
  38. ]"
  39. :style="{
  40. background: itemR.color ? itemR.color : '',
  41. borderColor: itemR.borderColor ? itemR.borderColor : '',
  42. }"
  43. >{{ itemR.tokens[2] }}</span
  44. >
  45. <!-- <span
  46. class="NNPE-chs NNPE-chs-both"
  47. v-if="
  48. resArr[0].wordsList[indexR + 1] &&
  49. resArr[0].wordsList[indexR + 1].tokens[2] &&
  50. enFhList.indexOf(resArr[0].wordsList[indexR + 1].tokens[2]) > -1
  51. "
  52. :class="[
  53. resArr[0].wordsList[indexR + 1].type,
  54. resArr[0].wordsList[indexR + 1].tokens[8] === ''
  55. ? 'marginLeft'
  56. : '',
  57. resArr[0].wordsList[indexR + 1].marginRight
  58. ? 'marginSingleRight'
  59. : '',
  60. resArr[0].wordsList[indexR + 1].highIndex ? 'fontWeight' : '',
  61. resArr[0].wordsList[indexR + 1].color ? 'wordSelected' : '',
  62. ]"
  63. :style="{
  64. background: resArr[0].wordsList[indexR + 1].color
  65. ? resArr[0].wordsList[indexR + 1].color
  66. : '',
  67. borderColor: resArr[0].wordsList[indexR + 1].borderColor
  68. ? resArr[0].wordsList[indexR + 1].borderColor
  69. : '',
  70. }"
  71. >{{ resArr[0].wordsList[indexR + 1].tokens[2] }}</span
  72. >
  73. </template> -->
  74. <!-- {{itemR.tokens[2]}} -->
  75. </span>
  76. </h2>
  77. </template>
  78. <h2 v-else>
  79. <span
  80. :style="{
  81. color: colorObj.titleColor,
  82. fontSize: titleFontsize + 'px',
  83. lineHeight: titleFontsize + 8 + 'px',
  84. marginRight: '10px',
  85. fontWeight: '700',
  86. cursor: 'pointer',
  87. wordBreak: 'break-word',
  88. textAlign: 'center',
  89. }"
  90. >{{ articleInfo.art_title }}</span
  91. >
  92. </h2>
  93. <h6
  94. class="nnpe-article-author"
  95. :style="{
  96. color: colorObj.sourceColor,
  97. fontSize: '14px',
  98. lineHeight: '22px',
  99. fontWeight: '400',
  100. }"
  101. >
  102. {{
  103. articleInfo.art_author +
  104. " · " +
  105. articleInfo.study_phase_name +
  106. "版 · 第 " +
  107. articleInfo.iss_no +
  108. " 期 · " +
  109. articleInfo.release_date +
  110. " · " +
  111. articleInfo.chn_item +
  112. (articleInfo.page_no_in_pub ? " · P" + articleInfo.page_no_in_pub : "")
  113. }}
  114. </h6>
  115. <div class="audio-box">
  116. <div
  117. class="aduioLine-content aduioLine-box"
  118. v-if="articleInfo.art_sound_url"
  119. :style="{
  120. background: colorObj.audiobg,
  121. borderColor: colorObj.audioBorder,
  122. }"
  123. >
  124. <AudioLine
  125. audioId="artNormalAudio"
  126. :mp3="articleInfo.art_sound_url"
  127. :getCurTime="getCurTime"
  128. ref="audioLine"
  129. :mp3Source="articleInfo.sound_type === 2 ? 'tts' : 'mp3'"
  130. :colorObj="colorObj"
  131. />
  132. <svg-icon
  133. icon-class="icon-wrapper"
  134. class="wrapper"
  135. @click="fullScreen"
  136. :style="{ color: colorObj.audioBtnColor }"
  137. ></svg-icon>
  138. </div>
  139. </div>
  140. <template v-if="resArr.length > 0">
  141. <div class="table-box">
  142. <div
  143. :class="['NNPE-detail']"
  144. v-for="(item, index) in resArr"
  145. :key="'detail' + index"
  146. >
  147. <div class="wordsList-box">
  148. <div class="nnpe-sentence-box">
  149. <div
  150. v-for="(pItem, pIndex) in item.wordsList"
  151. :key="'wordsList' + pIndex"
  152. >
  153. <template v-if="pItem.pno !== 0">
  154. <!-- <template v-if="pItem.isShow"> -->
  155. <div :class="['NNPE-words']">
  156. <span
  157. class="NNPE-chs"
  158. :class="[
  159. pItem.noBefore ? 'marginLeft' : '',
  160. pItem.noAfter ? 'marginRight' : '',
  161. pItem.marginRight ? 'marginSingleRight' : '',
  162. pItem.color ? 'wordSelected' : '',
  163. ]"
  164. :style="{
  165. fontSize: wordFontsize + 'px',
  166. color: colorObj.contentColor,
  167. background: pItem.color ? pItem.color : '',
  168. borderColor: pItem.borderColor ? pItem.borderColor : '',
  169. }"
  170. >{{ pItem.tokens[2] }}</span
  171. >
  172. <!-- <span
  173. class="NNPE-chs NNPE-chs-both"
  174. v-if="
  175. item.wordsList[pIndex + 1] &&
  176. item.wordsList[pIndex + 1].tokens[2] &&
  177. enFhList.indexOf(
  178. item.wordsList[pIndex + 1].tokens[2]
  179. ) > -1
  180. "
  181. :class="[
  182. item.wordsList[pIndex + 1].tokens[8] === ''
  183. ? 'marginLeft'
  184. : '',
  185. item.wordsList[pIndex + 1].marginRight
  186. ? 'marginSingleRight'
  187. : '',
  188. item.wordsList[pIndex + 1].color
  189. ? 'wordSelected'
  190. : '',
  191. ]"
  192. :style="{
  193. fontSize: wordFontsize + 'px',
  194. color: colorObj.contentColor,
  195. background: item.wordsList[pIndex + 1].color
  196. ? item.wordsList[pIndex + 1].color
  197. : '',
  198. borderColor: item.wordsList[pIndex + 1].borderColor
  199. ? item.wordsList[pIndex + 1].borderColor
  200. : '',
  201. }"
  202. >{{ item.wordsList[pIndex + 1].tokens[2] }}</span
  203. > -->
  204. </div>
  205. <!-- </template> -->
  206. </template>
  207. </div>
  208. </div>
  209. <template v-if="articleImg && articleImg[index]">
  210. <figure
  211. v-for="(itemI, indexI) in articleImg[index]"
  212. :key="indexI"
  213. >
  214. <el-image
  215. :width="itemI.width"
  216. :height="itemI.height"
  217. :src="itemI.src"
  218. fit="contain"
  219. :preview-src-list="[itemI.src]"
  220. ></el-image>
  221. </figure>
  222. </template>
  223. </div>
  224. </div>
  225. </div>
  226. </template>
  227. <!-- <img src="../../../assets/article-img.png" style="max-width:100%;margin:24px 0;" /> -->
  228. <div class="search-box" v-if="showSearch">
  229. <div id="dragDrop" @mousedown="positionChange" class="search-show-btn">
  230. <span></span>
  231. <b>注:点击灰条后按住灰条可拖动位置</b>
  232. </div>
  233. <div class="search">
  234. <div class="select-result" @click="showSearchColorList">
  235. <span
  236. class="selectBg"
  237. :style="{ background: colorValue, borderColor: borderColorValue }"
  238. ></span>
  239. <i class="tri el-icon-arrow-down"></i>
  240. </div>
  241. <input
  242. class="searchVal"
  243. v-model="searchVal"
  244. @keyup.enter="onSearch"
  245. :style="{ color: colorValue }"
  246. @blur="searchVal = searchVal.trim()"
  247. @keydown="searchValChange"
  248. />
  249. <i class="search-icon" style="cursor: pointer" @click="onSearch"
  250. >查找</i
  251. >
  252. <ul class="searchColorList" v-if="isSCL">
  253. <li
  254. v-for="(item, index) in searchColorList"
  255. :key="'search' + index"
  256. @click="selectSearchColor(item, index)"
  257. >
  258. <span
  259. class="searchColor"
  260. :style="{ background: item, borderColor: borderColorList[index] }"
  261. ></span>
  262. </li>
  263. <li class="close" @click="closeSearchColor">关闭</li>
  264. </ul>
  265. </div>
  266. <div class="result-left-numberclose" v-if="searchWordShow">
  267. <div>
  268. <span>
  269. <span
  270. style="
  271. font-size: 12px;
  272. line-height: 20px;
  273. color: rgba(146, 156, 168, 1);
  274. "
  275. >
  276. 匹配 {{ SearchwordNumber }} 次
  277. </span>
  278. </span>
  279. <span class="resule-right-btn" @click="clearSelected('all')"
  280. ><i class="el-icon-close"></i>清除标记</span
  281. >
  282. </div>
  283. <ul class="search-list">
  284. <li
  285. v-for="(itemS, indexs) in searchResultList.slice().reverse()"
  286. :key="indexs"
  287. >
  288. <p>
  289. <span
  290. class="searchColor"
  291. :style="{ background: itemS.bg, borderColor: itemS.border }"
  292. ></span>
  293. <b>{{ itemS.text }}</b>
  294. <span>{{ itemS.number }}</span>
  295. <i>{{ itemS.percent }}%</i>
  296. <i
  297. class="el-icon-close"
  298. @click="
  299. deleteSearchList(
  300. searchResultList.length - 1 - indexs,
  301. itemS.text
  302. )
  303. "
  304. ></i>
  305. </p>
  306. <label
  307. :style="{ width: itemS.percent + '%', background: itemS.border }"
  308. ></label>
  309. </li>
  310. </ul>
  311. </div>
  312. </div>
  313. <div class="voice-full-screen" :id="'screen-' + mathNum">
  314. <Voicefullscreen
  315. v-if="isFull"
  316. :curQue="articleInfo"
  317. :sentIndex="0"
  318. :mp3="articleInfo.art_sound_url"
  319. :likeSentencelist="likeSentencelist"
  320. @exitFullscreen="exitFullscreen"
  321. @changeIsFull="changeIsFull"
  322. :likeWord="likeWord"
  323. />
  324. </div>
  325. </div>
  326. </template>
  327. <script>
  328. import AudioLine from "@/components/common/AudioLine.vue";
  329. import Voicefullscreen from "./Voicefullscreen.vue";
  330. export default {
  331. name: "ArticleView",
  332. props: [
  333. "titleFontsize",
  334. "wordFontsize",
  335. "colorObj",
  336. "articleType",
  337. "articleInfo",
  338. "likeSentencelist",
  339. "likeWord",
  340. "articleImg",
  341. ],
  342. components: {
  343. AudioLine,
  344. Voicefullscreen,
  345. },
  346. data() {
  347. return {
  348. resArr: [],
  349. curTime: 0, //单位s
  350. enFhList: [
  351. ",",
  352. ".",
  353. ";",
  354. "?",
  355. "!",
  356. ":",
  357. ">",
  358. "<",
  359. "'",
  360. "’",
  361. "n't",
  362. "n’t",
  363. "n’ts",
  364. "n‘t",
  365. "'t",
  366. "’t",
  367. "‘t",
  368. "'s",
  369. "’s",
  370. "‘s",
  371. "'m",
  372. "’m",
  373. "‘m",
  374. "'re",
  375. "’re",
  376. "‘re",
  377. "'d",
  378. "’d",
  379. "‘d",
  380. "'ve",
  381. "’ve",
  382. "‘ve",
  383. ")",
  384. "'ll",
  385. "’ll",
  386. "‘ll",
  387. "”",
  388. ],
  389. paraIndex: -1, //段落索引
  390. sentIndex: -1, // 句子索引
  391. showSearch: false,
  392. colorValue: "#F5D90A",
  393. borderColorValue: "#FEF2A4",
  394. colorIndex: 0,
  395. searchVal: "",
  396. isSCL: false,
  397. searchColorList: [
  398. "#F5D90A",
  399. "#FA934E",
  400. "#65BA75",
  401. "#3DB9CF",
  402. "#D09E72",
  403. "#99D52A",
  404. "#BE93E4",
  405. "#F2555A",
  406. "#F04F88",
  407. "#306EFF",
  408. ],
  409. borderColorList: [
  410. "#FEF2A4",
  411. "#FFDCC3",
  412. "#CEEBCF",
  413. "#C4EAEF",
  414. "#EFDDCC",
  415. "#D7F2B0",
  416. "#EDDBF9",
  417. "#EB9091",
  418. "#E58FB1",
  419. "#5E89EF",
  420. ],
  421. SearchwordNumber: 0,
  422. searchWord: [],
  423. searchWordShow: false,
  424. currentcolorValue: [],
  425. currentBorderColorValue: [],
  426. searchResultList: [], // 匹配结果list
  427. alreadySelectIndex: 0,
  428. isFull: false,
  429. mathNum: Math.random().toString(36).substr(2),
  430. };
  431. },
  432. computed: {},
  433. watch: {},
  434. //方法集合
  435. methods: {
  436. getCurTime(curTime) {
  437. this.curTime = curTime * 1000;
  438. },
  439. handleData() {
  440. let resArr = [];
  441. let articleInfo = JSON.parse(JSON.stringify(this.articleInfo));
  442. let leg =
  443. articleInfo.art_corpus_data.sentList[
  444. articleInfo.art_corpus_data.sentList.length - 1
  445. ].pno;
  446. for (let i = 0; i < leg + 1; i++) {
  447. let obj = {
  448. wordsList: [],
  449. timeList: [],
  450. };
  451. resArr.push(obj);
  452. }
  453. articleInfo.art_corpus_data.sentList.forEach((item, index) => {
  454. item.tokens.forEach((items, indexs) => {
  455. let obj = {
  456. sent_id: item.id,
  457. sno: item.sno - 1,
  458. pno: item.pno,
  459. text: item.text,
  460. tokens: items,
  461. wIndex: indexs,
  462. isShow: this.enFhList.indexOf(items[2]) == -1,
  463. marginRight: indexs === item.tokens.length - 1,
  464. noBefore: indexs !== 0 && !items[8],
  465. noAfter: !items[9],
  466. color: "",
  467. borderColor: "",
  468. };
  469. resArr[item.pno].wordsList.push(obj);
  470. });
  471. if (
  472. articleInfo.art_sound_srt_data &&
  473. articleInfo.art_sound_srt_data.sents &&
  474. articleInfo.art_sound_srt_data.sents[index]
  475. ) {
  476. resArr[item.pno].timeList.push(
  477. articleInfo.art_sound_srt_data.sents[index]
  478. );
  479. }
  480. });
  481. this.resArr = resArr;
  482. },
  483. changeShow() {
  484. this.showSearch = !this.showSearch;
  485. },
  486. showSearchColorList() {
  487. this.isSCL = !this.isSCL;
  488. },
  489. closeSearchColor() {
  490. this.isSCL = false;
  491. },
  492. selectSearchColor(item, index) {
  493. this.isSCL = false;
  494. this.colorValue = item;
  495. this.borderColorValue = this.borderColorList[index];
  496. this.colorIndex = index;
  497. },
  498. searchValChange(e) {
  499. if (this.searchVal.length == 1 && e.keyCode == 8) {
  500. if (
  501. this.colorIndex == this.alreadySelectIndex + 1 ||
  502. this.searchWord.length == 0
  503. ) {
  504. this.alreadySelectIndex = 0;
  505. return;
  506. }
  507. this.colorIndex = this.alreadySelectIndex + 1;
  508. this.colorValue = this.searchColorList[this.colorIndex];
  509. this.borderColorValue = this.borderColorList[this.colorIndex];
  510. }
  511. },
  512. onSearch() {
  513. if (!this.searchVal) {
  514. return;
  515. }
  516. this.searchWordShow = true;
  517. let index = this.searchWord.indexOf(this.searchVal.toLowerCase());
  518. if (index == -1) {
  519. this.searchWord.push(this.searchVal.toLowerCase());
  520. this.currentcolorValue.push(this.colorValue);
  521. this.currentBorderColorValue.push(this.borderColorValue);
  522. } else {
  523. // this.currentcolorValue[index] = this.colorValue;
  524. this.$set(this.currentcolorValue, index, this.colorValue);
  525. this.$set(this.currentBorderColorValue, index, this.borderColorValue);
  526. }
  527. this.type = "";
  528. this.calculateSearchwordNumber();
  529. // this.searchVal = "";
  530. },
  531. // 计算匹配个数
  532. async calculateSearchwordNumber() {
  533. let arr = [];
  534. // await this.searchWord.forEach((item) => {
  535. // this.calculateIndex(this.textContent, item).then((res) => {
  536. // arr.push(res);
  537. // });
  538. // });
  539. this.searchResultList = [];
  540. this.SearchwordNumber = 0;
  541. // 匹配高亮
  542. this.searchWord.forEach((searchItem, i) => {
  543. let SearchwordNumber = 0;
  544. this.resArr.forEach((item) => {
  545. item.wordsList.forEach((items, indexs) => {
  546. // 字符串拼接相等即为匹配相同
  547. let searchArr = searchItem.trim().replace(/\s+/g, " ").split(" ");
  548. if (
  549. items.tokens[4].toLowerCase() == searchArr[0] ||
  550. items.tokens[2].toLowerCase() == searchArr[0]
  551. ) {
  552. let mateFlag = true;
  553. searchArr.forEach((itemi, indexi) => {
  554. if (
  555. itemi.trim() ===
  556. item.wordsList[indexs + indexi].tokens[4]
  557. .toLowerCase()
  558. .trim() ||
  559. itemi.trim() ===
  560. item.wordsList[indexs + indexi].tokens[2]
  561. .toLowerCase()
  562. .trim()
  563. ) {
  564. } else {
  565. mateFlag = false;
  566. }
  567. });
  568. if (mateFlag) {
  569. SearchwordNumber++;
  570. searchArr.forEach((itemi, indexi) => {
  571. item.wordsList[indexs + indexi].color =
  572. this.currentcolorValue[i];
  573. item.wordsList[indexs + indexi].borderColor =
  574. this.currentBorderColorValue[i];
  575. });
  576. }
  577. }
  578. });
  579. });
  580. if (SearchwordNumber > 0) {
  581. this.searchResultList.push({
  582. number: SearchwordNumber,
  583. percent: (
  584. (SearchwordNumber /
  585. this.articleInfo.art_corpus_data.artStatInfo.wdc) *
  586. 100
  587. ).toFixed(2),
  588. text: searchItem,
  589. border: this.currentBorderColorValue[i],
  590. bg: this.currentcolorValue[i],
  591. });
  592. }
  593. this.SearchwordNumber = SearchwordNumber; //高亮最后一次
  594. if (SearchwordNumber > 0 && i === this.searchWord.length - 1) {
  595. this.alreadySelectIndex++;
  596. }
  597. });
  598. },
  599. // 找出对应字符的索引
  600. calculateIndex(txt, key) {
  601. return new Promise((reslove, reject) => {
  602. // 去除标点
  603. let keylength = key.length;
  604. let arr = [];
  605. for (let i = 0; i < txt.length; i++) {
  606. if (txt[i] == key[0]) {
  607. arr.push(i);
  608. }
  609. }
  610. let indexArr = [];
  611. arr.forEach((item) => {
  612. let arr = [];
  613. for (let i = 0; i < keylength; i++) {
  614. if (txt[item + i] == key[i]) {
  615. arr.push(item + i);
  616. } else {
  617. arr = [];
  618. }
  619. }
  620. if (arr.length > 0) {
  621. indexArr.push(arr);
  622. }
  623. });
  624. reslove(indexArr);
  625. });
  626. },
  627. clearSelected(all) {
  628. let _this = this;
  629. _this.type = "";
  630. _this.searchVal = "";
  631. _this.searchWord = [];
  632. _this.currentcolorValue = [];
  633. _this.currentBorderColorValue = [];
  634. _this.SearchwordNumber = 0;
  635. if (all) {
  636. this.seleLevelMapList = [];
  637. _this.searchWordShow = false;
  638. sessionStorage.setItem("tablehighlight", false);
  639. }
  640. this.colorIndex = 0;
  641. this.colorValue = this.searchColorList[this.colorIndex];
  642. this.borderColorValue = this.borderColorList[this.colorIndex];
  643. this.searchResultList = [];
  644. this.closeSearchhighlight();
  645. },
  646. // 取消搜索高亮
  647. closeSearchhighlight() {
  648. this.resArr.forEach((item) => {
  649. // item.forEach((items) => {
  650. item.wordsList.forEach((itemss) => {
  651. itemss.color = null;
  652. });
  653. // });
  654. });
  655. },
  656. deleteSearchList(index, text) {
  657. this.searchResultList.splice(index, 1);
  658. this.currentcolorValue.splice(index, 1);
  659. this.searchWord.splice(index, 1);
  660. this.currentBorderColorValue.splice(index, 1);
  661. this.resArr.forEach((item) => {
  662. item.wordsList.forEach((items) => {
  663. if (
  664. items.tokens[4].toLowerCase() == text ||
  665. items.tokens[2].toLowerCase() == text
  666. ) {
  667. items.color = "";
  668. items.borderColor = "";
  669. }
  670. });
  671. });
  672. },
  673. pauseAudio() {
  674. let audio = document.getElementsByTagName("audio");
  675. audio.forEach((item) => {
  676. item.pause();
  677. });
  678. },
  679. pauseVideo() {
  680. let video = document.getElementsByTagName("video");
  681. video.forEach((item) => {
  682. item.pause();
  683. });
  684. },
  685. //语音全屏
  686. fullScreen() {
  687. this.pauseAudio();
  688. this.pauseVideo();
  689. this.isFull = true;
  690. this.goFullscreen();
  691. },
  692. goFullscreen() {
  693. let id = "screen-" + this.mathNum;
  694. var element = document.getElementById(id);
  695. if (element.requestFullscreen) {
  696. element.requestFullscreen();
  697. } else if (element.msRequestFullscreen) {
  698. element.msRequestFullscreen();
  699. } else if (element.mozRequestFullScreen) {
  700. element.mozRequestFullScreen();
  701. } else if (element.webkitRequestFullscreen) {
  702. element.webkitRequestFullscreen();
  703. }
  704. },
  705. exitFullscreen() {
  706. this.isFull = false;
  707. if (document.exitFullscreen) {
  708. document.exitFullscreen();
  709. } else if (document.msExitFullscreen) {
  710. document.msExitFullscreen();
  711. } else if (document.mozCancelFullScreen) {
  712. document.mozCancelFullScreen();
  713. } else if (document.webkitExitFullscreen) {
  714. document.webkitExitFullscreen();
  715. }
  716. },
  717. changeIsFull() {
  718. this.isFull = false;
  719. },
  720. positionChange() {
  721. // 获取拖动时点击的元素(子div)
  722. const el = document.getElementById("dragDrop");
  723. //获取拖动时移动的元素(父div)
  724. let p_el = el.parentElement;
  725. //添加鼠标按下监听事件
  726. document.getElementById("dragDrop").addEventListener(
  727. "mousedown",
  728. function (e) {
  729. var disx = e.pageX - p_el.offsetLeft;
  730. var disy = e.pageY - p_el.offsetTop;
  731. document.onmousemove = function (e) {
  732. p_el.style.left = e.pageX - disx + "px";
  733. p_el.style.top = e.pageY - disy + "px";
  734. el.style.cursor = "grabbing";
  735. };
  736. document.onmouseup = function () {
  737. document.onmousemove = document.onmouseup = null;
  738. el.style.cursor = "grab";
  739. };
  740. },
  741. true
  742. );
  743. },
  744. },
  745. //生命周期 - 创建完成(可以访问当前this实例)
  746. created() {},
  747. //生命周期 - 挂载完成(可以访问DOM元素)
  748. mounted() {
  749. if (this.articleInfo) {
  750. this.handleData();
  751. }
  752. },
  753. beforeCreate() {}, //生命周期 - 创建之前
  754. beforeMount() {}, //生命周期 - 挂载之前
  755. beforeUpdate() {}, //生命周期 - 更新之前
  756. updated() {}, //生命周期 - 更新之后
  757. beforeDestroy() {}, //生命周期 - 销毁之前
  758. destroyed() {}, //生命周期 - 销毁完成
  759. activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  760. };
  761. </script>
  762. <style lang="scss" scoped>
  763. //@import url(); 引入公共css类
  764. .NNPE-ArticleView {
  765. width: 100%;
  766. .nnpe-article-author {
  767. margin: 24px 0;
  768. text-align: center;
  769. }
  770. h2 {
  771. display: flex;
  772. flex-flow: wrap;
  773. justify-content: center;
  774. &.sentActive {
  775. background: rgba(24, 144, 255, 0.1);
  776. }
  777. &.overActive {
  778. background: rgba(0, 0, 0, 0.06);
  779. }
  780. .wordActive {
  781. color: #175dff !important;
  782. }
  783. .wordSelected {
  784. border-radius: 4px;
  785. border: 1px solid #fef2a4;
  786. box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.12),
  787. 0px 4px 5px 0px rgba(0, 0, 0, 0.08),
  788. 0px 1px 10px 0px rgba(0, 0, 0, 0.05);
  789. }
  790. }
  791. .table-box {
  792. // background: #f7f7f7;
  793. // border-top: 1px solid rgba(0, 0, 0, 0.1);
  794. :last-child {
  795. :last-child.wordsList-box {
  796. padding-bottom: 40px;
  797. }
  798. }
  799. .wordsList-box {
  800. flex: 1;
  801. padding: 6px 0 12px 0;
  802. .nnpe-sentence-box {
  803. display: flex;
  804. flex-flow: wrap;
  805. }
  806. > img {
  807. max-width: 50%;
  808. display: block;
  809. padding: 16px 0;
  810. margin: 0 auto;
  811. }
  812. }
  813. }
  814. .NNPE-detail {
  815. clear: both;
  816. overflow: hidden;
  817. display: flex;
  818. .NNPE-words {
  819. float: left;
  820. padding: 0;
  821. &.noPadding {
  822. padding: 0;
  823. }
  824. &.sentActive {
  825. background: rgba(24, 144, 255, 0.1);
  826. }
  827. &.overActive {
  828. background: rgba(0, 0, 0, 0.06);
  829. }
  830. &.textLeft {
  831. text-align: left;
  832. }
  833. &.textCenter {
  834. text-align: center;
  835. }
  836. > span {
  837. float: left;
  838. cursor: pointer;
  839. &.NNPE-chs {
  840. // font-size: 24px;
  841. font-family: "Smartisan";
  842. line-height: 150%;
  843. color: #000000;
  844. padding: 0 3px;
  845. &.wordActive {
  846. color: #175dff !important;
  847. }
  848. &.marginRight {
  849. padding-right: 0;
  850. }
  851. &.marginLeft {
  852. padding-left: 0;
  853. }
  854. &.marginSingleRight {
  855. padding-right: 3px;
  856. }
  857. &.wordSelected {
  858. border-radius: 4px;
  859. border: 1px solid #fef2a4;
  860. box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.12),
  861. 0px 4px 5px 0px rgba(0, 0, 0, 0.08),
  862. 0px 1px 10px 0px rgba(0, 0, 0, 0.05);
  863. }
  864. }
  865. &.padding {
  866. padding: 0 3px;
  867. cursor: pointer;
  868. }
  869. }
  870. }
  871. }
  872. }
  873. .audio-box {
  874. display: flex;
  875. align-items: center;
  876. justify-content: center;
  877. }
  878. .aduioLine-box {
  879. width: 516px;
  880. height: 48px;
  881. background: #ffffff;
  882. border: 1px solid #ebebeb;
  883. border-radius: 30px;
  884. display: flex;
  885. align-items: center;
  886. padding: 8px 24px;
  887. .wrapper {
  888. width: 24px;
  889. height: 24px;
  890. flex-shrink: 0;
  891. color: #175dff;
  892. margin-left: 8px;
  893. }
  894. .Audio {
  895. width: 430px;
  896. }
  897. }
  898. .search-box {
  899. position: fixed;
  900. top: 200px;
  901. width: 298px;
  902. border-radius: 8px;
  903. border: 1px solid #e5e6eb;
  904. background: #fff;
  905. box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, 0.08),
  906. 0px 16px 24px 2px rgba(0, 0, 0, 0.04), 0px 6px 30px 5px rgba(0, 0, 0, 0.05);
  907. // min-height: 204px;
  908. right: calc((100% - 1000px) / 2);
  909. padding: 0 16px 16px;
  910. .search-show-btn {
  911. cursor: move;
  912. padding: 6px 0;
  913. span {
  914. border-radius: 4px;
  915. background: #d0d3d9;
  916. width: 48px;
  917. display: block;
  918. height: 4px;
  919. margin: 0 auto;
  920. }
  921. b {
  922. font-size: 11px;
  923. color: #d0d3d9;
  924. }
  925. }
  926. .search {
  927. position: relative;
  928. height: 40px;
  929. width: 100%;
  930. border: 1px solid #dddddd;
  931. box-sizing: border-box;
  932. padding: 7px 0;
  933. display: flex;
  934. justify-content: flex-start;
  935. align-items: center;
  936. .select-result {
  937. height: 24px;
  938. width: 57px;
  939. padding: 4px 11px;
  940. display: flex;
  941. justify-content: flex-start;
  942. align-items: center;
  943. cursor: pointer;
  944. .selectBg {
  945. width: 16px;
  946. height: 16px;
  947. background: #de4444;
  948. border-radius: 2px;
  949. border: 1px solid #fef2a4;
  950. box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.12),
  951. 0px 4px 5px 0px rgba(0, 0, 0, 0.08),
  952. 0px 1px 10px 0px rgba(0, 0, 0, 0.05);
  953. }
  954. .tri {
  955. width: 10px;
  956. height: 10px;
  957. font-size: 10px;
  958. margin-left: 4px;
  959. // background: url("../../assets/teacherdev/down-icon.png") no-repeat
  960. // left top;
  961. // background-size: 100% 100%;
  962. }
  963. }
  964. .searchVal {
  965. font-weight: bold;
  966. width: 142px;
  967. border: 0;
  968. border-left: 1px solid #dddddd;
  969. box-sizing: border-box;
  970. outline: 0;
  971. padding-left: 12px;
  972. }
  973. .search-icon {
  974. position: absolute;
  975. right: 12px;
  976. display: block;
  977. color: #175dff;
  978. font-size: 14px;
  979. font-style: normal;
  980. font-weight: 400;
  981. line-height: 22px;
  982. }
  983. .searchColorList {
  984. width: 58px;
  985. position: absolute;
  986. top: 38px;
  987. left: 0;
  988. border: 1px #d9d9d9 solid;
  989. background: #fff;
  990. list-style: none;
  991. padding: 0;
  992. margin: 0;
  993. z-index: 2;
  994. > li {
  995. width: 100%;
  996. display: flex;
  997. justify-content: center;
  998. align-items: center;
  999. padding: 8px 0;
  1000. cursor: pointer;
  1001. > span {
  1002. width: 14px;
  1003. height: 14px;
  1004. border-radius: 2px;
  1005. border: 1px solid #fef2a4;
  1006. box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.12),
  1007. 0px 4px 5px 0px rgba(0, 0, 0, 0.08),
  1008. 0px 1px 10px 0px rgba(0, 0, 0, 0.05);
  1009. }
  1010. &.close {
  1011. font-size: 12px;
  1012. border-top: 1px #d9d9d9 solid;
  1013. }
  1014. }
  1015. }
  1016. }
  1017. .result-left-numberclose {
  1018. margin-top: 16px;
  1019. font-weight: 400;
  1020. font-size: 14px;
  1021. color: #333333;
  1022. border-radius: 4px;
  1023. background: #f7f8fa;
  1024. padding: 8px;
  1025. // min-height: 126px;
  1026. > div {
  1027. display: flex;
  1028. justify-content: space-between;
  1029. }
  1030. .resule-right-btn {
  1031. display: inline-block;
  1032. border-radius: 3px;
  1033. border: 1px solid#E5E6EB;
  1034. background: #fff;
  1035. cursor: pointer;
  1036. height: 24px;
  1037. padding: 2px 8px;
  1038. color: var(--slate-10, #2f3742);
  1039. text-align: center;
  1040. font-size: 12px;
  1041. font-weight: 400;
  1042. line-height: 18px;
  1043. .el-icon-close {
  1044. margin-right: 8px;
  1045. }
  1046. }
  1047. .search-list {
  1048. width: 100%;
  1049. margin: 8px 0 0;
  1050. padding: 0;
  1051. max-height: 250px;
  1052. overflow: auto;
  1053. &::-webkit-scrollbar {
  1054. display: none;
  1055. }
  1056. li {
  1057. padding: 1px 8px;
  1058. margin: 2px 0;
  1059. border-radius: 4px;
  1060. background: #fff;
  1061. position: relative;
  1062. height: 34px;
  1063. .searchColor {
  1064. width: 12px;
  1065. height: 12px;
  1066. border-radius: 2px;
  1067. border: 1px solid rgba(255, 255, 255, 0.4);
  1068. background: #f5d90a;
  1069. box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.12),
  1070. 0px 4px 5px 0px rgba(0, 0, 0, 0.08),
  1071. 0px 1px 10px 0px rgba(0, 0, 0, 0.05);
  1072. }
  1073. p {
  1074. position: absolute;
  1075. width: 234px;
  1076. height: 34px;
  1077. left: 8px;
  1078. top: 1px;
  1079. margin: 0;
  1080. display: flex;
  1081. align-items: center;
  1082. justify-content: space-between;
  1083. z-index: 1;
  1084. }
  1085. b {
  1086. color: #2f3742;
  1087. font-size: 14px;
  1088. font-weight: 400;
  1089. line-height: 22px;
  1090. width: 77px;
  1091. }
  1092. span {
  1093. width: 20px;
  1094. text-align: right;
  1095. }
  1096. i {
  1097. text-align: right;
  1098. width: 81px;
  1099. padding: 0 4px;
  1100. margin: 0;
  1101. height: 34px;
  1102. line-height: 34px;
  1103. font-style: normal;
  1104. }
  1105. .el-icon-close {
  1106. font-size: 16px;
  1107. color: #929ca8;
  1108. cursor: pointer;
  1109. width: 16px;
  1110. height: 16px;
  1111. padding: 0;
  1112. line-height: 16px;
  1113. }
  1114. label {
  1115. position: absolute;
  1116. top: 1px;
  1117. right: 28px;
  1118. border-radius: 3px;
  1119. background: rgba(240, 192, 0, 0.16);
  1120. display: block;
  1121. height: 32px;
  1122. z-index: 0;
  1123. }
  1124. }
  1125. }
  1126. }
  1127. }
  1128. </style>