courseView.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. <template>
  2. <div class="container">
  3. <Header />
  4. <div class="content">
  5. <div
  6. id="content-tree"
  7. :class="[
  8. fullTree ? 'content-tree-full' : 'content-tree',
  9. isPhone ? 'content-tree-phone' : '',
  10. showMenu ? '' : 'content-tree-unfold'
  11. ]"
  12. >
  13. <template v-if="isPhone">
  14. <div style="text-align: right;color: black;padding: 10px;">
  15. <i
  16. @click="toggleMenu"
  17. :class="[showMenu ? 'el-icon-s-fold' : 'el-icon-s-unfold']"
  18. ></i>
  19. </div>
  20. </template>
  21. <TreeView
  22. ref="treeView"
  23. :book-id="bookId"
  24. :change-id="changeId"
  25. :change-tree-data="changeTreeData"
  26. :current-tree-i-d="chapterId"
  27. />
  28. </div>
  29. <div
  30. id="data-screen"
  31. v-loading="loading"
  32. :class="[
  33. 'inner',
  34. fullscreen ? 'inner-full' : '',
  35. isPhone ? 'inner-phone' : ''
  36. ]"
  37. >
  38. <el-image
  39. :src="pictureUrl"
  40. fit="scale-down"
  41. class="img_url"
  42. v-if="!chapterId && pictureUrl"
  43. >
  44. <div slot="placeholder" class="image-slot">
  45. <img src="../assets/common/icon-imgloading.png" />
  46. </div>
  47. </el-image>
  48. <!-- 显示答案按钮 -->
  49. <!-- <a v-if="chapterId" :class="['answerShow',isAnswerShow?'answerShowTrue':'']" @click="handleAnswerShow">显示答案</a> -->
  50. <!-- <a class="edit-btn" @click="handleEdit">编辑</a> -->
  51. <!-- <a v-if="chapterId" :class="['answerShow']" @click="saveAnswer"
  52. >保存答案</a
  53. > -->
  54. <div v-if="chapterId" class="title-box">
  55. <img
  56. v-if="!treeFlag"
  57. src="../assets/common/icon-view-back.png"
  58. @click="treeShow"
  59. />
  60. <img
  61. v-if="!treeFlag"
  62. src="../assets/common/icon-treelist.png"
  63. @click="chooseCourseware"
  64. />
  65. <!-- <h2 class="title">{{ chapterName }}</h2> -->
  66. <!-- <el-switch
  67. v-if="!treeFlag"
  68. v-model="switchvalue"
  69. active-color="#FF9900"
  70. active-text
  71. inactive-text="生词模式"
  72. /> -->
  73. </div>
  74. <Preview
  75. ref="preview"
  76. :context="context"
  77. :que-index="queIndex"
  78. :current-tree-i-d="chapterId"
  79. :father-tree-data="FatherTreeData"
  80. :change-id="changeId"
  81. :theme-color="themeColor"
  82. :is-show-title="true"
  83. :book-answer-content="bookAnswerContent"
  84. :task-model="TaskModel"
  85. :is-show-save="false"
  86. :isAnswerItemShow="isAnswerItemShow"
  87. @finishTaskMaterial="finishTaskMaterial"
  88. />
  89. </div>
  90. <a
  91. v-if="chapterId && treeFlag && !isPhone"
  92. class="screen-full"
  93. @click="fullScreen()"
  94. />
  95. </div>
  96. </div>
  97. </template>
  98. <script>
  99. import Header from "@/components/Header.vue";
  100. import TreeView from "@/components/TreeView";
  101. import { getContent, TextbookAPI } from "@/api/ajax";
  102. import Cookies from "js-cookie";
  103. import Preview from "@/components/Adult/Preview.vue";
  104. import { getToken } from "../utils/auth";
  105. export default {
  106. name: "CourseView",
  107. components: {
  108. Header,
  109. TreeView,
  110. Preview
  111. },
  112. props: [],
  113. data() {
  114. return {
  115. bookId: "",
  116. chapterId: "",
  117. chapterName: "",
  118. fullscreen: false, // 控制全屏
  119. context: null,
  120. question: null, // 选择的模板题型
  121. queIndex: "",
  122. treeFlag: true, // tree是否显示
  123. switchvalue: true, // 生词模式
  124. isAnswerShow: false, // 是否显示答案
  125. answer: [
  126. // 假数据
  127. {
  128. table_list: [
  129. [
  130. {
  131. data: {
  132. Bookanswer: []
  133. }
  134. }
  135. ]
  136. ]
  137. }
  138. ],
  139. bookAnswerContent: "",
  140. TaskModel: "", // TEST 考试模式; PRACTICE 练习模式; ANSWER 查看答案模式; 空 预览模式
  141. category: "",
  142. FatherTreeData: null,
  143. themeColor: "",
  144. loading: false,
  145. fullTree: false, // 全屏模式下树是否显示
  146. isAnswerItemShow: false,
  147. previewType: "previewCheck",
  148. pictureUrl: "",
  149. isPhone: false, // 是否是移动端打开
  150. showMenu: true //是否展开菜单
  151. };
  152. },
  153. created() {
  154. const _this = this;
  155. const regExp = /Android|webOS|iPhone|BlackBerry|IEMobile|Opera Mini/i;
  156. this.isPhone = regExp.test(navigator.userAgent);
  157. _this.bookId = this.$route.query.bookId;
  158. // if (localStorage.getItem("Bookanswer")) {
  159. // this.TaskModel = "ANSWER";
  160. // }
  161. let userInfor = JSON.parse(getToken());
  162. if (userInfor && userInfor.user_type == "TEACHER") {
  163. _this.isAnswerItemShow = true;
  164. } else {
  165. _this.isAnswerItemShow = false;
  166. }
  167. },
  168. mounted() {},
  169. methods: {
  170. toggleMenu() {
  171. this.showMenu = !this.showMenu;
  172. },
  173. getdetail() {
  174. let MethodName = "book-book_manager-GetBookChapterStruct";
  175. let data = {
  176. book_id: this.bookId
  177. };
  178. getContent(MethodName, data).then(res => {
  179. let nodes = res.nodes;
  180. for (let i = 0; i < nodes.length; i++) {
  181. if (nodes[i].is_courseware == "true") {
  182. this.changeId(nodes[i].id, "");
  183. return false;
  184. } else {
  185. if (nodes[i].children) {
  186. let nodesC = nodes[i].children;
  187. for (let j = 0; j < nodesC.length; j++) {
  188. if (nodesC[j].is_courseware == "true") {
  189. this.changeId(nodesC[j].id, "");
  190. return false;
  191. } else {
  192. if (nodesC[j].children) {
  193. let nodesCs = nodesC[j].children;
  194. for (let l = 0; j < nodesCs.length; l++) {
  195. if (nodesCs[l].is_courseware == "true") {
  196. this.changeId(nodesCs[l].id, "");
  197. return false;
  198. }
  199. }
  200. }
  201. }
  202. }
  203. }
  204. }
  205. }
  206. });
  207. },
  208. changeTreeData(val) {
  209. this.FatherTreeData = JSON.parse(JSON.stringify(val));
  210. let nodes = this.FatherTreeData;
  211. for (let i = 0; i < nodes.length; i++) {
  212. if (nodes[i].is_courseware == "true") {
  213. this.changeId(nodes[i].id, "");
  214. return false;
  215. } else {
  216. if (nodes[i].children) {
  217. let nodesC = nodes[i].children;
  218. for (let j = 0; j < nodesC.length; j++) {
  219. if (nodesC[j].is_courseware == "true") {
  220. this.changeId(nodesC[j].id, "");
  221. return false;
  222. } else {
  223. if (nodesC[j].children) {
  224. let nodesCs = nodesC[j].children;
  225. for (let l = 0; j < nodesCs.length; l++) {
  226. if (nodesCs[l].is_courseware == "true") {
  227. this.changeId(nodesCs[l].id, "");
  228. return false;
  229. }
  230. }
  231. }
  232. }
  233. }
  234. }
  235. }
  236. }
  237. },
  238. changeId(id, name) {
  239. const _this = this;
  240. _this.chapterId = id;
  241. _this.chapterName = name;
  242. _this.isAnswerShow = false;
  243. _this.onGetData();
  244. if (!_this.treeFlag) {
  245. _this.fullTree = false;
  246. document.getElementById("content-tree").style.display = "none";
  247. }
  248. },
  249. // 点击全屏展示 隐藏tree
  250. fullScreen() {
  251. this.treeFlag = false;
  252. this.fullscreen = true;
  253. document.getElementById("content-tree").style.display = "none";
  254. },
  255. treeShow() {
  256. this.treeFlag = true;
  257. this.fullTree = false;
  258. this.fullscreen = false;
  259. document.getElementById("content-tree").style.display = "block";
  260. },
  261. // 获取预览数据
  262. onGetData() {
  263. const _this = this;
  264. _this.loading = true;
  265. _this.context = null;
  266. const MethodName = "book-courseware_manager-GetCoursewareContent_View";
  267. const data = {
  268. id: _this.chapterId
  269. };
  270. getContent(MethodName, data)
  271. .then(res => {
  272. _this.loading = false;
  273. this.category = res.category;
  274. this.themeColor = res.book_theme_color;
  275. if (res.content) {
  276. const _this = this;
  277. if (!this.category || this.category == "OC") {
  278. _this.context = {
  279. id: _this.chapterId,
  280. ui_type: JSON.parse(res.content).question
  281. ? JSON.parse(res.content).question.ui_type
  282. : "",
  283. sort_number: 1,
  284. content: JSON.parse(res.content)
  285. };
  286. } else if (this.category == "NPC") {
  287. _this.context = JSON.parse(res.content);
  288. console.log(_this.context);
  289. }
  290. } else {
  291. _this.context = null;
  292. }
  293. })
  294. .catch(() => {
  295. _this.loading = false;
  296. });
  297. },
  298. getAnswer() {
  299. // this.answer;
  300. },
  301. // 跳转编辑页面
  302. handleEdit() {
  303. const index = this.$refs.treeView.handleParentIndex().split("###");
  304. if (index.length > 1) {
  305. Cookies.set("bookIndex", index[0]);
  306. Cookies.set("bookLevel", index[1]);
  307. Cookies.set("bookNodename", index[2]);
  308. }
  309. this.$router.push("/input?bookId=" + this.bookId);
  310. },
  311. // 显示或隐藏答案
  312. handleAnswerShow() {
  313. this.isAnswerShow = !this.isAnswerShow;
  314. this.$refs.previewAnswer.bookAnswerShow(this.isAnswerShow);
  315. },
  316. // 悬浮树隐藏显示
  317. chooseCourseware() {
  318. this.fullTree = !this.fullTree;
  319. if (this.fullTree) {
  320. document.getElementById("content-tree").style.display = "block";
  321. } else {
  322. document.getElementById("content-tree").style.display = "none";
  323. }
  324. },
  325. finishTaskMaterial(data, time, rightNumber, errorNumber) {
  326. console.log("用户提交的答案:" + data);
  327. console.log("答题时间" + time);
  328. console.log("答对个数" + rightNumber);
  329. console.log("答错个数" + errorNumber);
  330. }
  331. }
  332. };
  333. </script>
  334. <style lang="scss" scoped>
  335. .container {
  336. width: 100%;
  337. min-height: 100vh;
  338. height: auto;
  339. .content {
  340. width: 100%;
  341. display: flex;
  342. justify-content: flex-start;
  343. align-items: flex-start;
  344. &-tree {
  345. width: 340px;
  346. height: 100%;
  347. overflow: auto;
  348. -webkit-overflow-scrolling: touch;
  349. padding: 20px 0px;
  350. border-right: 1px solid #d9d9d9;
  351. position: fixed;
  352. top: 0px;
  353. left: 0;
  354. transform: translate(0, 0);
  355. padding-top: 64px;
  356. z-index: 2;
  357. background: #fff;
  358. &-phone {
  359. width: 50%;
  360. }
  361. &-unfold {
  362. width: 40px;
  363. height: 90px;
  364. border: none;
  365. overflow: hidden;
  366. }
  367. }
  368. .content-tree-full {
  369. position: fixed;
  370. top: 100px;
  371. left: 152px;
  372. max-height: 588px;
  373. overflow: auto;
  374. z-index: 999;
  375. background: #fff;
  376. box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25);
  377. border-radius: 4px;
  378. }
  379. .inner {
  380. // border-left: 1px solid #d9d9d9;
  381. width: 1000px;
  382. flex: 1;
  383. margin: 0 auto;
  384. margin-left: 340px;
  385. box-sizing: border-box;
  386. padding: 20px;
  387. position: relative;
  388. background: #fff;
  389. &.inner-full {
  390. margin-left: 0;
  391. }
  392. &-phone {
  393. margin-left: 0;
  394. }
  395. .title-box {
  396. display: flex;
  397. align-items: center;
  398. margin-bottom: 12px;
  399. padding-right: 160px;
  400. position: relative;
  401. > img {
  402. width: 40px;
  403. margin-right: 16px;
  404. cursor: pointer;
  405. }
  406. }
  407. .title {
  408. font-size: 24px;
  409. margin-bottom: 20px;
  410. line-height: 40px;
  411. margin: 0;
  412. }
  413. .has-module {
  414. display: flex;
  415. justify-content: flex-start;
  416. align-items: flex-start;
  417. &-tree {
  418. width: 340px;
  419. height: 100%;
  420. overflow: auto;
  421. padding: 20px 0px;
  422. border-right: 1px solid #d9d9d9;
  423. }
  424. .inner {
  425. // border-left: 1px solid #d9d9d9;
  426. width: 1000px;
  427. flex: 1;
  428. margin: 0 auto;
  429. box-sizing: border-box;
  430. padding: 20px;
  431. position: relative;
  432. background: #fff;
  433. .title-box {
  434. display: flex;
  435. align-items: center;
  436. margin-bottom: 12px;
  437. padding-right: 160px;
  438. position: relative;
  439. > img {
  440. width: 40px;
  441. margin-right: 16px;
  442. cursor: pointer;
  443. }
  444. }
  445. .title {
  446. font-size: 24px;
  447. margin-bottom: 20px;
  448. line-height: 40px;
  449. margin: 0;
  450. }
  451. .has-module {
  452. display: flex;
  453. justify-content: flex-start;
  454. align-items: flex-start;
  455. }
  456. .edit-btn {
  457. display: inline-block;
  458. font-size: 14px;
  459. background: #ff9900;
  460. float: right;
  461. line-height: 36px;
  462. color: #fff;
  463. width: 60px;
  464. text-align: center;
  465. border-radius: 4px;
  466. }
  467. }
  468. }
  469. }
  470. .nav-list {
  471. width: 200px;
  472. height: 40px;
  473. background: rgba(49, 212, 134, 0.2);
  474. border-radius: 240px;
  475. display: flex;
  476. justify-content: flex-start;
  477. align-items: center;
  478. padding: 0;
  479. margin: 0;
  480. margin-bottom: 10px;
  481. list-style: none;
  482. > li {
  483. height: 40px;
  484. width: 100px;
  485. text-align: center;
  486. font-style: normal;
  487. font-weight: bold;
  488. font-size: 14px;
  489. line-height: 40px;
  490. color: #19b068;
  491. cursor: pointer;
  492. &.active {
  493. background: #19b068;
  494. border-radius: 240px;
  495. color: #ffffff;
  496. }
  497. }
  498. }
  499. .screen-full {
  500. position: fixed;
  501. right: 30px;
  502. bottom: 30px;
  503. width: 48px;
  504. height: 48px;
  505. background: rgba(0, 0, 0, 0.4) url("../assets/common/icon-screenFull.png")
  506. center no-repeat;
  507. background-size: 32px;
  508. }
  509. }
  510. .answerShow {
  511. position: absolute;
  512. right: 20px;
  513. top: 20px;
  514. width: 112px;
  515. height: 40px;
  516. background: #ffffff url("../assets/common/icon-eye-close.png") 16px center
  517. no-repeat;
  518. background-size: 16px;
  519. border: 1px solid rgba(44, 44, 44, 0.15);
  520. box-sizing: border-box;
  521. border-radius: 4px;
  522. font-size: 14px;
  523. line-height: 150%;
  524. color: #000000;
  525. padding: 9px 16px 9px 36px;
  526. cursor: pointer;
  527. z-index: 2;
  528. &.answerShowTrue {
  529. background: #f5f5f5 url("../assets/common/icon-eye-open.png") 16px center
  530. no-repeat;
  531. background-size: 16px;
  532. }
  533. }
  534. }
  535. .img_url {
  536. width: 1000px;
  537. height: 700px;
  538. margin: 0 auto;
  539. }
  540. </style>
  541. <style lang="scss">
  542. .title-box {
  543. .el-switch {
  544. position: absolute;
  545. top: 0;
  546. right: 0px;
  547. border: 1px solid rgba(44, 44, 44, 0.15);
  548. border-radius: 40px;
  549. height: 40px;
  550. padding: 6px 6px 6px 16px;
  551. }
  552. .el-switch__label.is-active {
  553. color: #000000;
  554. font-size: 16px;
  555. }
  556. }
  557. </style>