dusenyao 1 år sedan
förälder
incheckning
59afe9f867

+ 3 - 0
src/icons/svg/courseware/menu-2.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M3 4H21V6H3V4ZM3 11H15V13H3V11ZM3 18H21V20H3V18Z" fill="white"/>
+</svg>

+ 10 - 8
src/icons/svg/courseware/menu.svg

@@ -1,10 +1,12 @@
 <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-<g clip-path="url(#clip0_271_9197)">
-<path d="M5.33333 2.66536H14V3.9987H5.33333V2.66536ZM2 2.33203H4V4.33203H2V2.33203ZM2 6.9987H4V8.9987H2V6.9987ZM2 11.6654H4V13.6654H2V11.6654ZM5.33333 7.33203H14V8.66536H5.33333V7.33203ZM5.33333 11.9987H14V13.332H5.33333V11.9987Z" fill="black"/>
-</g>
-<defs>
-<clipPath id="clip0_271_9197">
-<rect width="16" height="16" fill="white"/>
-</clipPath>
-</defs>
+  <g clip-path="url(#clip0_271_9197)">
+    <path
+      d="M5.33333 2.66536H14V3.9987H5.33333V2.66536ZM2 2.33203H4V4.33203H2V2.33203ZM2 6.9987H4V8.9987H2V6.9987ZM2 11.6654H4V13.6654H2V11.6654ZM5.33333 7.33203H14V8.66536H5.33333V7.33203ZM5.33333 11.9987H14V13.332H5.33333V11.9987Z"
+      fill="black" />
+  </g>
+  <defs>
+    <clipPath id="clip0_271_9197">
+      <rect width="16" height="16" fill="white" />
+    </clipPath>
+  </defs>
 </svg>

+ 2 - 8
src/router/modules/courseware.js

@@ -18,14 +18,8 @@ const CoursewareModulePage = {
  * 课件预览组件
  */
 const PreviewPage = {
-  path: '/preview',
-  component: DEFAULT,
-  children: [
-    {
-      path: 'courseware/:book_id',
-      component: () => import('@/views/book/courseware/preview/index.vue'),
-    },
-  ],
+  path: '/preview/courseware/:book_id',
+  component: () => import('@/views/book/courseware/preview/index.vue'),
 };
 
 export default [CoursewareModulePage, PreviewPage];

+ 1 - 1
src/views/book/chapter.vue

@@ -7,7 +7,7 @@
           <span>{{ getCatalogueName() }}</span>
         </div>
         <el-popover v-model="visibleStatus" placement="bottom" trigger="click">
-          <CatalogueTree :nodes="nodes" @selectNode="selectNode" />
+          <CatalogueTree :nodes="nodes" />
 
           <span slot="reference" class="pointer"><SvgIcon icon-class="menu" /> 目录</span>
         </el-popover>

+ 6 - 2
src/views/book/components/catalogueTree.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="node-wrapper">
-    <div v-for="node in nodes" :key="node.id" class="node">
+    <div v-for="node in nodes" :key="node.id" :class="['node', { active: getCurChaterId() === node.id }]">
       <div
         :class="['node-name', { content: node.is_leaf_chapter === 'true' }]"
         @click="handleSelectNode(node.is_leaf_chapter, node.id)"
@@ -15,7 +15,7 @@
 <script>
 export default {
   name: 'CatalogueTree',
-  inject: ['selectNode'],
+  inject: ['selectNode', 'getCurChaterId'],
   props: {
     nodes: {
       type: Array,
@@ -36,6 +36,10 @@ export default {
 
 <style lang="scss" scoped>
 .node {
+  &.active {
+    background-color: #f3f3f3;
+  }
+
   &-name {
     padding-bottom: 4px;
 

+ 111 - 32
src/views/book/courseware/preview/index.vue

@@ -1,23 +1,33 @@
 <template>
   <div class="preview">
-    <div></div>
-    <div>
-      <div
-        class="content"
-        :style="[
-          {
-            backgroundImage: data.background_image_url ? `url(${data.background_image_url})` : '',
-            backgroundSize: data.background_image_url
-              ? `${data.background_position.width}% ${data.background_position.height}%`
-              : '',
-            backgroundPosition: data.background_image_url
-              ? `${data.background_position.left}% ${data.background_position.top}%`
-              : '',
-          },
-        ]"
-      >
-        <div></div>
+    <div class="menu">
+      <div class="title">目录</div>
+      <CatalogueTree :nodes="nodes" />
+    </div>
+
+    <div class="content-wrapper">
+      <div class="exit">
+        <el-button icon="el-icon-close" @click="goBack">退出预览</el-button>
       </div>
+      <main class="content">
+        <span class="content-title">
+          <SvgIcon icon-class="menu-2" size="24" />
+        </span>
+        <div
+          class="courserware"
+          :style="[
+            {
+              backgroundImage: data.background_image_url ? `url(${data.background_image_url})` : '',
+              backgroundSize: data.background_image_url
+                ? `${data.background_position.width}% ${data.background_position.height}%`
+                : '',
+              backgroundPosition: data.background_image_url
+                ? `${data.background_position.left}% ${data.background_position.top}%`
+                : '',
+            },
+          ]"
+        ></div>
+      </main>
     </div>
   </div>
 </template>
@@ -25,14 +35,25 @@
 <script>
 import { GetCoursewareContent, GetBookChapterStruct, GetCoursewareList_Chapter } from '@/api/book';
 
+import CatalogueTree from '@/views/book/components/catalogueTree.vue';
+
 export default {
   name: 'PreviewPage',
+  components: {
+    CatalogueTree,
+  },
+  provide() {
+    return {
+      selectNode: this.selectNode,
+      getCurChaterId: () => this.curChapterId,
+    };
+  },
   data() {
     const { chapter_id } = this.$route.query;
     return {
       book_id: this.$route.params.book_id,
       chapter_id,
-      curChaterId: chapter_id,
+      curChapterId: chapter_id,
       data: {
         background_image_url: '',
         background_position: {
@@ -85,6 +106,11 @@ export default {
     setCurPosition(id) {
       this.curPosition = this.findNodeIndexById(this.nodes, id);
     },
+    selectNode(id) {
+      this.setCurPosition(id);
+      this.getCoursewareList_Chapter(id);
+      this.curChapterId = id;
+    },
     getCoursewareList_Chapter(chapter_id) {
       GetCoursewareList_Chapter({ chapter_id }).then(({ courseware_list }) => {
         this.courseware_list = courseware_list ?? [];
@@ -101,24 +127,77 @@ export default {
 
 <style lang="scss" scoped>
 .preview {
-  .content {
-    display: flex;
-    flex-direction: column;
-    row-gap: 6px;
-    width: 100%;
-    min-height: calc(100% - 56px);
+  display: flex;
+  height: 100%;
+
+  .menu {
+    width: 240px;
     padding: 24px;
+    overflow: auto;
     background-color: #fff;
-    background-repeat: no-repeat;
-    border-radius: 4px;
 
-    .row {
-      display: grid;
-      row-gap: 16px;
-      align-items: start;
+    .title {
+      margin-bottom: 16px;
+      font-weight: bold;
+    }
+
+    :deep .node {
+      &-name {
+        height: 38px;
+        line-height: 38px;
+
+        &.content {
+          padding-left: 16px;
+          font-size: 14px;
+          border-bottom: 1px solid $border-color;
+        }
+      }
+
+      .node {
+        padding-left: 20px;
+        margin-left: 0;
+      }
+    }
+  }
+
+  .content-wrapper {
+    flex: 1;
+    padding: 24px 60px;
+    background: url('~@/assets/mask_group.png') repeat 0 0;
+
+    .exit {
+      display: flex;
+      justify-content: flex-end;
+      margin-bottom: 24px;
+
+      .el-button {
+        height: 40px;
+        font-size: 16px;
+        font-weight: bold;
+        border-width: 0;
+        box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 8%);
+      }
+    }
+
+    .content {
+      background-color: #fff;
+      border: 3px solid #f44444;
+      border-radius: 16px;
+
+      &-title {
+        display: inline-block;
+        min-width: 280px;
+        height: 64px;
+        padding: 18px 24px;
+        font-size: 20px;
+        color: #fff;
+        background-color: #f44444;
+        border-top-left-radius: 12px;
+        border-bottom-right-radius: 16px;
+      }
 
-      .col {
-        display: grid;
+      .courserware {
+        padding: 24px;
       }
     }
   }