WordPhraseDetail.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. <template>
  2. <div class="wordDetailModule wordDetailChs">
  3. <div class="module-inner">
  4. <div class="top" v-if="data">
  5. <div class="operation">
  6. <div>
  7. <template v-if="optionRes && optionRes.length > 0">
  8. <!-- <img
  9. src="../../../../assets/icon/starline-16-normal-Black.png"
  10. alt=""
  11. v-if="!notshowNext"
  12. /> -->
  13. <img
  14. style="margin-right: 8px"
  15. src="../../assets/Left-16-normal-Black.png"
  16. alt=""
  17. @click="lastDetail"
  18. v-if="!notshowNext"
  19. />
  20. <img
  21. src="../../assets/Right-16-normal-Black.png"
  22. alt=""
  23. @click="nextDetail"
  24. v-if="!notshowNext"
  25. />
  26. </template>
  27. <img
  28. style="margin-right: 0px"
  29. @click="closeWordShow"
  30. src="../../assets/Cross-16-normal-Black.png"
  31. alt=""
  32. />
  33. </div>
  34. </div>
  35. <div class="wordDetail">
  36. <div
  37. :class="[
  38. 'bwc-Strockplay',
  39. themeColor == 'green'
  40. ? 'green-border'
  41. : themeColor == 'red'
  42. ? 'red-border'
  43. : 'brown-border',
  44. ]"
  45. >
  46. <div
  47. class="strockplay"
  48. v-for="(conItem, conindex) in data.new_word"
  49. :key="'new_word_' + conindex"
  50. >
  51. <Strockplayredline
  52. :key="conItem + detailIndex + conindex"
  53. :Book_text="conItem"
  54. :playStorkes="true"
  55. :targetDiv="'bwcHanziIntp' + conItem + detailIndex + conindex"
  56. :wordNum="data.new_word.length"
  57. :themeColor="themeColor"
  58. />
  59. <div
  60. :class="[
  61. 'bwc-line',
  62. themeColor == 'green'
  63. ? 'green-bg'
  64. : themeColor == 'red'
  65. ? 'red-bg'
  66. : 'brown-bg',
  67. ]"
  68. v-if="conindex < data.new_word.length - 1"
  69. ></div>
  70. </div>
  71. </div>
  72. <div class="wordInfor">
  73. <div class="yinpin">
  74. <span class="pinyintext"> {{ data.pinyin.toLowerCase() }}</span>
  75. <template
  76. v-if="data.mp3_list && data.mp3_list[0] && data.mp3_list[0].id"
  77. >
  78. <Audio :mp3="data.mp3_list[0].id" :themeColor="themeColor" />
  79. </template>
  80. <template v-else-if="data.mp3Url">
  81. <Audio :mp3="data.mp3Url" :themeColor="themeColor" />
  82. </template>
  83. </div>
  84. <p
  85. class="jieshu"
  86. v-for="(fy, i) in data.definition_list"
  87. :key="i"
  88. v-html="fy"
  89. ></p>
  90. </div>
  91. </div>
  92. <div class="zhedie-white">
  93. <div v-if="list1 && list1.length > 0" v-loading="loading1">
  94. <div class="topTitle">
  95. <span>本课例句({{ list1.length }})</span>
  96. <span @click="handleChangeTab('wordShow')"
  97. >{{ wordShow ? "收起" : "展开" }}
  98. <img v-if="wordShow" src="../../assets/down-black.png" alt="" />
  99. <img v-else src="../../assets/up-black.png" alt="" />
  100. </span>
  101. </div>
  102. <el-collapse-transition>
  103. <div class="liju" v-show="wordShow">
  104. <div v-for="(item, i) in list1" :key="i">
  105. <div>{{ i + 1 }}.</div>
  106. <div>
  107. <p v-html="item.res"></p>
  108. <p class="p2">
  109. 来源:{{ item.source_courseware_name_path }}
  110. </p>
  111. </div>
  112. </div>
  113. </div>
  114. </el-collapse-transition>
  115. </div>
  116. <div v-if="list2 && list2.length > 0" v-loading="loading2">
  117. <div class="topTitle">
  118. <span>本书例句({{ list2.length }})</span>
  119. <span @click="handleChangeTab('wordShow2')"
  120. >{{ wordShow2 ? "收起" : "展开" }}
  121. <img
  122. v-if="wordShow2"
  123. src="../../assets/down-black.png"
  124. alt=""
  125. />
  126. <img v-else src="../../assets/up-black.png" alt="" />
  127. </span>
  128. </div>
  129. <el-collapse-transition>
  130. <div class="liju" v-show="wordShow2">
  131. <div v-for="(item, i) in list2" :key="i">
  132. <div>{{ list1.length + i + 1 }}.</div>
  133. <div>
  134. <p v-html="item.res"></p>
  135. <p class="p2">
  136. 来源:{{ item.source_courseware_name_path }}
  137. </p>
  138. </div>
  139. </div>
  140. </div>
  141. </el-collapse-transition>
  142. </div>
  143. <div v-if="list3 && list3.length > 0" v-loading="loading3">
  144. <div class="topTitle">
  145. <span>本套教材例句({{ list3.length }})</span>
  146. <span @click="handleChangeTab('wordShow3')"
  147. >{{ wordShow3 ? "收起" : "展开" }}
  148. <img v-if="wordShow3" src="../../assets/down-black.png" />
  149. <img v-else src="../../assets/up-black.png" alt="" />
  150. </span>
  151. </div>
  152. <el-collapse-transition>
  153. <div class="liju" v-if="wordShow3">
  154. <div v-for="(item, i) in list3" :key="i">
  155. <div>{{ list1.length + list2.length + i + 1 }}.</div>
  156. <div>
  157. <p>{{ item.sentence }}</p>
  158. <p class="p2">
  159. 来源:{{ item.source_courseware_name_path }}
  160. </p>
  161. </div>
  162. </div>
  163. </div>
  164. </el-collapse-transition>
  165. </div>
  166. </div>
  167. </div>
  168. <Intp :word="data" :themeColor="themeColor" :type="type" />
  169. </div>
  170. </div>
  171. </template>
  172. <script>
  173. import Strockplayredline from "./Strockplayredline.vue";
  174. import Audio from "./AudioRed.vue";
  175. import Intp from "./Intp.vue";
  176. import { getContent } from "@/api/ajax";
  177. export default {
  178. //import引入的组件需要注入到对象中才能使用
  179. components: {
  180. Strockplayredline,
  181. Audio,
  182. Intp,
  183. },
  184. props: [
  185. "data",
  186. "changeDetailIndex",
  187. "closeWord",
  188. "detailIndex",
  189. "notshowNext",
  190. "getWordLiju",
  191. "optionRes",
  192. "themeColor",
  193. "isSuccess",
  194. "currentTreeID",
  195. "type",
  196. ],
  197. data() {
  198. //这里存放数据
  199. return {
  200. height: "",
  201. margintop: "",
  202. wordShow: true,
  203. wordShow2: true,
  204. wordShow3: true,
  205. list1: [],
  206. list2: [],
  207. list3: [],
  208. isShow: false,
  209. old_word: "",
  210. loading1: false,
  211. loading2: false,
  212. loading3: false,
  213. };
  214. },
  215. //计算属性 类似于data概念
  216. computed: {},
  217. //监控data中数据变化
  218. watch: {
  219. data: {
  220. handler: function (val, oldVal) {
  221. const _this = this;
  222. if (val) {
  223. _this.initData();
  224. }
  225. },
  226. // 深度观察监听
  227. deep: true,
  228. },
  229. },
  230. //方法集合
  231. methods: {
  232. playAudio() {},
  233. // 关闭单词详情
  234. closeWordShow() {
  235. this.closeWord(false);
  236. },
  237. // 上一个单词详情
  238. lastDetail() {
  239. if (this.detailIndex == 0) {
  240. this.$message.warning("当前已经是第一个");
  241. return;
  242. }
  243. this.changeDetailIndex("last");
  244. },
  245. // 下一个单词详情
  246. nextDetail() {
  247. let _this = this;
  248. if (_this.detailIndex == _this.optionRes.length - 1) {
  249. this.$message.warning("当前已经是最后一个了 ");
  250. return;
  251. }
  252. _this.changeDetailIndex("next");
  253. },
  254. viewIntp() {
  255. this.loading1 = true;
  256. this.loading2 = true;
  257. this.loading3 = true;
  258. let Mname =
  259. "book-courseware_manager-GetCoursewareWordExampleSentenceList";
  260. // 获取本课的 本教材的 本套的 的例句
  261. getContent(Mname, {
  262. courseware_id: this.currentTreeID, // 课件id
  263. word: this.data.new_word, //生词
  264. search_scope: 0, //检索范围0 本课件 1本教材 2本套
  265. is_contain_word_variants: false,
  266. })
  267. .then((res) => {
  268. this.loading1 = false;
  269. this.list1 = this.handleExample(res.sentence_list);
  270. console.log(this.list1);
  271. getContent(Mname, {
  272. courseware_id: this.currentTreeID, // 课件id
  273. word: this.data.new_word, //生词
  274. search_scope: 1, //检索范围0 本课件 1本教材 2本套
  275. is_contain_word_variants: false,
  276. })
  277. .then((res) => {
  278. this.loading2 = false;
  279. this.list2 = this.handleExample(res.sentence_list);
  280. getContent(Mname, {
  281. courseware_id: this.currentTreeID, // 课件id
  282. word: this.data.new_word, //生词
  283. search_scope: 2, //检索范围0 本课件 1本教材 2本套
  284. is_contain_word_variants: false,
  285. })
  286. .then((res) => {
  287. this.loading3 = false;
  288. this.list3 = this.handleExample(res.sentence_list);
  289. })
  290. .catch((err) => {
  291. this.loading3 = false;
  292. });
  293. })
  294. .catch((err) => {
  295. this.loading2 = false;
  296. });
  297. })
  298. .catch((err) => {
  299. this.loading1 = false;
  300. });
  301. },
  302. handleExample(list) {
  303. list = list.map((item, index) => {
  304. let wordIndex = null;
  305. for (let i = 0; i < item.sentence.length; i++) {
  306. if (item.sentence[i] == item.word) {
  307. wordIndex = i;
  308. }
  309. }
  310. // let b = item.begin_position;
  311. // let e = item.end_position;
  312. // let sent = item.sentence;
  313. // let part1 = sent.substring(0, b);
  314. // let part2 = sent.substring(b, e);
  315. // let part3 = sent.substring(e);
  316. let sent = item.sentence;
  317. let part1 = "";
  318. let part2 = "";
  319. let part3 = "";
  320. if (wordIndex === 0) {
  321. part1 = "";
  322. part2 = sent.substring(0, 1);
  323. part3 = sent.substring(1);
  324. } else if (wordIndex === item.sentence.length - 1) {
  325. part1 = sent.substring(0, wordIndex);
  326. part2 = sent.substring(wordIndex);
  327. part3 = "";
  328. } else {
  329. part1 = sent.substring(0, wordIndex);
  330. part2 = sent.substring(wordIndex, wordIndex + 1);
  331. part3 = sent.substring(wordIndex + 1);
  332. }
  333. // let reg = new RegExp(`${item.word}`, "g");
  334. // let result = sent.replace(
  335. // reg,
  336. // `<span style="color:#DE4444;">${item.word}</span>`
  337. // );
  338. let res =
  339. part1 + '<span style="color:#DE4444;">' + part2 + "</span>" + part3;
  340. item.res = res;
  341. return item;
  342. });
  343. return list;
  344. },
  345. initData() {
  346. console.log(this.data);
  347. this.viewIntp();
  348. // let Fathernode = document.getElementsByClassName(
  349. // "NPC-Big-Book-preview"
  350. // )[0];
  351. // if (Fathernode) {
  352. // // this.height = Fathernode.clientHeight + "px";
  353. // this.height = window.innerHeight + "px";
  354. // this.margintop = "-" + window.innerHeight / 2 + "px";
  355. // }
  356. },
  357. handleChangeTab(flag) {
  358. this[flag] = !this[flag];
  359. },
  360. },
  361. //生命周期 - 创建完成(可以访问当前this实例)
  362. created() {},
  363. //生命周期 - 挂载完成(可以访问DOM元素)
  364. mounted() {
  365. this.initData();
  366. },
  367. //生命周期-创建之前
  368. beforeCreated() {},
  369. //生命周期-挂载之前
  370. beforeMount() {},
  371. //生命周期-更新之前
  372. beforUpdate() {},
  373. //生命周期-更新之后
  374. updated() {},
  375. //生命周期-销毁之前
  376. beforeDestory() {},
  377. //生命周期-销毁完成
  378. destoryed() {},
  379. //如果页面有keep-alive缓存功能,这个函数会触发
  380. activated() {},
  381. };
  382. </script>
  383. <style lang="scss" scoped>
  384. /* @import url(); 引入css类 */
  385. .wordDetailModule {
  386. width: 100%;
  387. z-index: 999;
  388. overflow-y: scroll;
  389. .module-inner {
  390. padding: 30px 0;
  391. > div {
  392. width: 788px;
  393. margin: 0 auto;
  394. background: #ffffff;
  395. box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.15);
  396. border-radius: 8px;
  397. padding: 16px 32px 40px 32px;
  398. .operation {
  399. height: 16px;
  400. margin-bottom: 8px;
  401. div {
  402. display: flex;
  403. justify-content: flex-end;
  404. align-items: center;
  405. > :nth-child(1) {
  406. margin-right: 24px;
  407. }
  408. > :nth-child(2) {
  409. margin-right: 8px;
  410. }
  411. > :nth-child(3) {
  412. margin-right: 24px;
  413. }
  414. }
  415. img {
  416. width: 16px;
  417. height: 16px;
  418. cursor: pointer;
  419. }
  420. }
  421. }
  422. }
  423. .module-bottom {
  424. width: 788px;
  425. margin-top: 16px;
  426. }
  427. .top {
  428. padding-top: 16px;
  429. .wordDetail {
  430. width: 100%;
  431. margin-bottom: 16px;
  432. display: flex;
  433. justify-content: flex-start;
  434. align-items: flex-start;
  435. .bwc-Strockplay {
  436. display: flex;
  437. justify-content: center;
  438. align-items: center;
  439. min-width: 130px;
  440. height: 130px;
  441. margin-bottom: 16px;
  442. border-radius: 8px;
  443. box-sizing: border-box;
  444. overflow: hidden;
  445. margin-right: 37px;
  446. .strockplay {
  447. display: flex;
  448. justify-content: center;
  449. align-items: center;
  450. position: relative;
  451. .collect-icon {
  452. width: 16px;
  453. position: absolute;
  454. right: 4px;
  455. bottom: 4px;
  456. cursor: pointer;
  457. }
  458. }
  459. .bwc-line {
  460. width: 2px;
  461. height: 128px;
  462. }
  463. .red-bg {
  464. background: #ff5757;
  465. }
  466. .green-bg {
  467. background: #24b99e;
  468. }
  469. .brown-bg {
  470. background: #bd8865;
  471. }
  472. }
  473. .red-border {
  474. border: 2px solid #ff5757;
  475. }
  476. .green-border {
  477. border: 2px solid #24b99e;
  478. }
  479. .brown-border {
  480. border: 2px solid #bd8865;
  481. }
  482. .wordInfor {
  483. .yinpin {
  484. display: flex;
  485. justify-content: flex-start;
  486. align-items: center;
  487. margin-bottom: 16px;
  488. .pinyintext {
  489. font-size: 20px;
  490. line-height: 30px;
  491. color: #2c2c2c;
  492. display: flex;
  493. align-items: center;
  494. margin-right: 8px;
  495. word-break: normal;
  496. font-family: "GB-PINYINOK-B";
  497. }
  498. .content-voices {
  499. width: 16px;
  500. }
  501. }
  502. }
  503. p {
  504. margin: 0;
  505. }
  506. .word {
  507. font-weight: bold;
  508. font-size: 24px;
  509. line-height: 28px;
  510. color: #000000;
  511. }
  512. .jieshu {
  513. margin-top: 16px;
  514. font-size: 16px;
  515. line-height: 19px;
  516. color: #000000;
  517. }
  518. }
  519. .zhedie-white {
  520. width: 100%;
  521. margin: 0 auto;
  522. > div {
  523. margin-bottom: 24px;
  524. }
  525. .topTitle {
  526. width: 100%;
  527. display: flex;
  528. justify-content: space-between;
  529. padding: 0 12px;
  530. align-items: center;
  531. background: #fff !important;
  532. > :nth-child(1) {
  533. font-weight: 500;
  534. font-size: 16px;
  535. line-height: 150%;
  536. color: rgba(0, 0, 0, 0.85);
  537. }
  538. > :nth-child(2) {
  539. display: flex;
  540. align-items: center;
  541. font-weight: normal;
  542. font-size: 14px;
  543. line-height: 22px;
  544. color: rgba(0, 0, 0, 0.85);
  545. cursor: pointer;
  546. }
  547. img {
  548. width: 16px;
  549. height: 16px;
  550. margin-left: 4px;
  551. }
  552. .rotate {
  553. animation-name: firstrotate;
  554. animation-direction: 2s;
  555. animation-fill-mode: both;
  556. animation-timing-function: linear;
  557. }
  558. }
  559. .liju {
  560. padding-bottom: 16px;
  561. padding-right: 24px;
  562. background: #f7f7f7;
  563. border: 1px solid rgba(0, 0, 0, 0.1);
  564. border-top: none;
  565. border-radius: 0 0 4px 4px;
  566. > div {
  567. padding-top: 16px;
  568. margin-left: 8px;
  569. display: flex;
  570. > :nth-child(1) {
  571. text-align: right;
  572. margin-right: 6px;
  573. line-height: 24px;
  574. font-family: "FZJCGFKTK";
  575. }
  576. p {
  577. margin: 0;
  578. line-height: 24px;
  579. font-size: 16px;
  580. color: rgba(0, 0, 0, 0.85);
  581. font-family: "FZJCGFKTK";
  582. }
  583. .p2 {
  584. font-size: 12px;
  585. line-height: 20px;
  586. color: rgba(0, 0, 0, 0.85);
  587. opacity: 0.3;
  588. }
  589. }
  590. }
  591. }
  592. }
  593. .bottom {
  594. margin-top: 16px;
  595. padding-bottom: 23px;
  596. .from {
  597. // text-align: right;
  598. margin-right: 16px;
  599. font-size: 14px;
  600. line-height: 16px;
  601. color: #000000;
  602. opacity: 0.2;
  603. display: flex;
  604. justify-content: flex-end;
  605. align-items: center;
  606. img {
  607. width: 24px;
  608. margin-left: 24px;
  609. }
  610. }
  611. .wordDetail {
  612. width: 538px;
  613. margin-left: 40px;
  614. padding-bottom: 23px;
  615. border-bottom: 1px solid rgba(0, 0, 0, 0.1);
  616. p {
  617. margin: 0;
  618. }
  619. .word {
  620. font-weight: bold;
  621. font-size: 24px;
  622. line-height: 28px;
  623. color: #000000;
  624. }
  625. .yinpin {
  626. font-size: 16px;
  627. line-height: 150%;
  628. color: #000000;
  629. margin-top: 16px;
  630. display: flex;
  631. > div {
  632. height: 24px;
  633. display: flex;
  634. align-items: center;
  635. > :nth-child(1) {
  636. margin-right: 5px;
  637. }
  638. }
  639. > :nth-child(2) {
  640. margin-left: 27px;
  641. }
  642. img {
  643. margin-left: 10px;
  644. width: 24px;
  645. height: 24px;
  646. cursor: pointer;
  647. }
  648. }
  649. .jieshu {
  650. margin-top: 16px;
  651. font-size: 16px;
  652. line-height: 150%;
  653. color: #000000;
  654. display: flex;
  655. > :nth-child(1) {
  656. width: 30px;
  657. }
  658. :nth-child(2) {
  659. width: 524px;
  660. }
  661. }
  662. }
  663. }
  664. }
  665. </style>
  666. <style lang="scss">
  667. .NPC-Big-Book-preview-red {
  668. .wordDetailChs {
  669. .zhedie-white {
  670. .topTitle {
  671. height: 40px;
  672. background: #fff !important;
  673. border: 1px solid rgba(0, 0, 0, 0.1);
  674. -webkit-box-sizing: border-box;
  675. box-sizing: border-box;
  676. border-radius: 8px 8px 0px 0px;
  677. }
  678. }
  679. }
  680. }
  681. .NPC-Big-Book-preview-green {
  682. .wordDetailChs {
  683. .zhedie-white {
  684. .topTitle {
  685. height: 40px;
  686. background: #fff !important;
  687. border: 1px solid rgba(0, 0, 0, 0.1);
  688. -webkit-box-sizing: border-box;
  689. box-sizing: border-box;
  690. border-radius: 8px 8px 0px 0px;
  691. }
  692. }
  693. }
  694. }
  695. .NPC-Big-Book-preview-brown {
  696. .wordDetailChs {
  697. .zhedie-white {
  698. .topTitle {
  699. height: 40px;
  700. background: #fff !important;
  701. border: 1px solid rgba(0, 0, 0, 0.1);
  702. -webkit-box-sizing: border-box;
  703. box-sizing: border-box;
  704. border-radius: 8px 8px 0px 0px;
  705. }
  706. }
  707. }
  708. }
  709. </style>