浏览代码

fix: 实现查看课件的功能,规范课件类型,停用课件使用时间

chillqi 3 年之前
父节点
当前提交
447e5b3eb8

文件差异内容过多而无法显示
+ 187 - 164
package-lock.json


+ 13 - 0
package.json

@@ -15,14 +15,26 @@
     "core-js": "^3.6.5",
     "echarts": "^4.8.0",
     "element-plus": "^1.0.2-beta.71",
+    "pdfjs-dist": "^2.0.943",
     "pdfmake": "^0.2.6",
+    "react": "^18.2.0",
     "react-pdf": "^6.0.3",
     "resize-detector": "^0.3.0",
     "vue": "^3.1.0",
+    "vue-pdf-embed": "^1.1.5",
+    "vue-pdf-preview": "^0.0.3",
+    "vue-pdf-signature": "^4.2.7",
     "vue-router": "^4.0.12",
+    "vue3-pdfjs": "^0.1.6",
     "vuex": "^4.0.2"
   },
   "devDependencies": {
+    "@babel/core": "^7.20.2",
+    "@babel/plugin-proposal-class-properties": "^7.18.6",
+    "@babel/plugin-transform-runtime": "^7.19.6",
+    "@babel/preset-env": "^7.20.2",
+    "@babel/preset-react": "^7.18.6",
+    "@babel/runtime": "^7.20.1",
     "@vue/cli-plugin-babel": "~4.5.0",
     "@vue/cli-plugin-eslint": "~4.5.0",
     "@vue/cli-plugin-router": "^4.5.15",
@@ -30,6 +42,7 @@
     "@vue/cli-service": "~4.5.0",
     "@vue/compiler-sfc": "^3.0.0",
     "babel-eslint": "^10.1.0",
+    "babel-loader": "^8.3.0",
     "eslint": "^6.7.2",
     "eslint-plugin-vue": "^7.0.0",
     "file-loader": "^6.2.0",

+ 13 - 11
src/api/courseWare.js

@@ -31,22 +31,24 @@ function downloadCourseWare(id) {
     );
 }
 
-const host = process.env.NODE_ENV === "development" ? "http://localhost:8080" : "";
-const slideUrl = host + "/api/slide";
-const useSlideServer = postfix => postfix ? slideUrl + postfix : slideUrl;
+// const host = process.env.NODE_ENV === "development" ? "http://localhost:8080" : "";
+// const slideUrl = host + "/api/slide";
+// const useSlideServer = postfix => postfix ? slideUrl + postfix : slideUrl;
 
 // 获取课件的文件链接
-function getSlideUrl ({ slideId }) {
-    return axios
-        .get(useSlideServer("/" + slideId + "/url"))
-        .then(res => res.data);
+function getSlideUrl (slideId) {
+    // return axios
+    //     .get(useSlideServer("/" + slideId + "/url"))
+    //     .then(res => res.data);
+    return axios.get(`${prefix}/getSlideUrl`, {params: {slideId}});
 }
 
 // 获取某个具体课件的信息
-function getSlideInfo ({ slideId }) {
-    return axios
-        .get(useSlideServer("/" + slideId))
-        .then(res => res.data);
+function getSlideInfo (slideId) {
+    // return axios
+    //     .get(useSlideServer("/" + slideId))
+    //     .then(res => res.data);
+    return axios.get(`${prefix}/getSlideInfo`, {params: {slideId}});
 }
 
 function checkCourseWareNameUnique(courseId, name) {

+ 93 - 92
src/components/Basic/CButton.vue

@@ -1,95 +1,96 @@
-<!--<template>-->
-<!--  <button class="c-button" :style="style" :class="classList" @click="$emit('click')">-->
-<!--    <c-icon :bold="!noBold" :right="6" :left="-4" v-if="icon" class="icon" :size="20">{{icon}}</c-icon>-->
-<!--    <slot></slot>-->
-<!--  </button>-->
-<!--</template>-->
-
-<!--<script>-->
-<!--import CIcon from "@/components/Basic/CIcon";-->
-
-<!--export default {-->
-<!--  components: { CIcon },-->
-<!--  // props: ['icon', 'noClickWarn']-->
-<!--  props: {-->
-<!--    icon: {-->
-<!--      type: String,-->
-<!--      default: null-->
-<!--    },-->
-<!--    noClickWarn: {-->
-<!--      type: Boolean,-->
-<!--      default: false-->
-<!--    },-->
-<!--    theme: {-->
-<!--      type: String,-->
-<!--      default: "normal"-->
-<!--    },-->
-<!--    // 背景透明的按钮-->
-<!--    text: {-->
-<!--      type: Boolean,-->
-<!--      default: false-->
-<!--    },-->
-<!--    // 使用白色字体、深色背景的最显眼按钮,优先级大于 text-->
-<!--    standout: {-->
-<!--      type: Boolean,-->
-<!--      default: false-->
-<!--    },-->
-<!--    // 占满宽度-->
-<!--    block: {-->
-<!--      type: Boolean,-->
-<!--      default: false-->
-<!--    },-->
-<!--    small: {-->
-<!--      type: Boolean,-->
-<!--      default: false-->
-<!--    },-->
-<!--    large: {-->
-<!--      type: Boolean,-->
-<!--      default: false-->
-<!--    },-->
-<!--    // 去掉涟漪效果-->
-<!--    noRipple: {-->
-<!--      type: Boolean,-->
-<!--      default: false-->
-<!--    },-->
-<!--    noBold: {-->
-<!--      type: Boolean,-->
-<!--      default: false-->
-<!--    },-->
-<!--    left: {-->
-<!--      type: Number,-->
-<!--      default: 0-->
-<!--    },-->
-<!--    right: {-->
-<!--      type: Number,-->
-<!--      default: 0-->
-<!--    }-->
-<!--  },-->
-<!--  computed: {-->
-<!--    style () {-->
-<!--      return {-->
-<!--        marginRight: this.right ? this.right + "px" : null,-->
-<!--        marginLeft: this.left ? this.left + "px" : null-->
-<!--      };-->
-<!--    },-->
-<!--    classList () {-->
-<!--      return [-->
-<!--        this.standout-->
-<!--          ? (this.theme ? "c-button-standout&#45;&#45;" + this.theme : "c-button-standout&#45;&#45;normal")-->
-<!--          : (-->
-<!--            this.text-->
-<!--              ? (this.theme ? "c-button-text&#45;&#45;" + this.theme : "c-button-text&#45;&#45;normal")-->
-<!--              : (this.theme ? "c-button&#45;&#45;" + this.theme : "c-button&#45;&#45;normal")-->
-<!--          ),-->
-<!--        this.large ? "c-button&#45;&#45;large" : "",-->
-<!--        this.small ? "c-button&#45;&#45;small" : "",-->
-<!--        this.noClickWarn ? "c-button&#45;&#45;disabled" : "",-->
-<!--        this.block ? "c-button&#45;&#45;block" : ""-->
-<!--      ];-->
-<!--    }-->
-<!--  }-->
-<!--};-->
-<!--</script>-->
+<template>
+    <el-button></el-button>
+    <!--  <button class="c-button" :style="style" :class="classList" @click="$emit('click')">-->
+    <!--    <c-icon :bold="!noBold" :right="6" :left="-4" v-if="icon" class="icon" :size="20">{{icon}}</c-icon>-->
+    <!--    <slot></slot>-->
+    <!--  </button>-->
+</template>
+
+<script>
+    // import CIcon from "@/components/Basic/CIcon";
+    //
+    // export default {
+    //   components: { CIcon },
+    //   // props: ['icon', 'noClickWarn']
+    //   props: {
+    //     icon: {
+    //       type: String,
+    //       default: null
+    //     },
+    //     noClickWarn: {
+    //       type: Boolean,
+    //       default: false
+    //     },
+    //     theme: {
+    //       type: String,
+    //       default: "normal"
+    //     },
+    //     // 背景透明的按钮
+    //     text: {
+    //       type: Boolean,
+    //       default: false
+    //     },
+    //     // 使用白色字体、深色背景的最显眼按钮,优先级大于 text
+    //     standout: {
+    //       type: Boolean,
+    //       default: false
+    //     },
+    //     // 占满宽度
+    //     block: {
+    //       type: Boolean,
+    //       default: false
+    //     },
+    //     small: {
+    //       type: Boolean,
+    //       default: false
+    //     },
+    //     large: {
+    //       type: Boolean,
+    //       default: false
+    //     },
+    //     // 去掉涟漪效果
+    //     noRipple: {
+    //       type: Boolean,
+    //       default: false
+    //     },
+    //     noBold: {
+    //       type: Boolean,
+    //       default: false
+    //     },
+    //     left: {
+    //       type: Number,
+    //       default: 0
+    //     },
+    //     right: {
+    //       type: Number,
+    //       default: 0
+    //     }
+    //   },
+    //   computed: {
+    //     style () {
+    //       return {
+    //         marginRight: this.right ? this.right + "px" : null,
+    //         marginLeft: this.left ? this.left + "px" : null
+    //       };
+    //     },
+    //     classList () {
+    //       return [
+    //         this.standout
+    //           ? (this.theme ? "c-button-standout--" + this.theme : "c-button-standout--normal")
+    //           : (
+    //             this.text
+    //               ? (this.theme ? "c-button-text--" + this.theme : "c-button-text--normal")
+    //               : (this.theme ? "c-button--" + this.theme : "c-button--normal")
+    //           ),
+    //         this.large ? "c-button--large" : "",
+    //         this.small ? "c-button--small" : "",
+    //         this.noClickWarn ? "c-button--disabled" : "",
+    //         this.block ? "c-button--block" : ""
+    //       ];
+    //     }
+    //   }
+    // };
+</script>
 
 <!--<style lang="scss" scoped>-->
 <!--@import "src/style/theme.scss";-->

+ 60 - 58
src/components/Basic/CIcon.vue

@@ -1,62 +1,63 @@
-<!--<template>-->
-<!--  <i class="c-icons c-icon" :class="classList" :style="style">-->
-<!--    <slot></slot>-->
-<!--  </i>-->
-<!--</template>-->
+<template>
+  <i></i>
+  <!--  <i class="c-icons c-icon" :class="classList" :style="style">-->
+  <!--    <slot></slot>-->
+  <!--  </i>-->
+</template>
 
-<!--<script>-->
-<!--export default {-->
-<!--  props: {-->
-<!--    bold: {-->
-<!--      type: Boolean,-->
-<!--      default: false-->
-<!--    },-->
-
-<!--    // icon 大小-->
-<!--    size: {-->
-<!--      type: Number,-->
-<!--      default: 0-->
-<!--    },-->
-
-<!--    // 可以直接传入 6 位颜色值,将覆盖 theme 设置的颜色-->
-<!--    color: {-->
-<!--      type: String,-->
-<!--      default: ""-->
-<!--    },-->
-
-<!--    theme: {-->
-<!--      type: String,-->
-<!--      default: "normal"-->
-<!--    },-->
-
-<!--    right: {-->
-<!--      type: Number,-->
-<!--      default: 0-->
-<!--    },-->
-
-<!--    left: {-->
-<!--      type: Number,-->
-<!--      default: 0-->
-<!--    }-->
-<!--  },-->
-<!--  computed: {-->
-<!--    classList () {-->
-<!--      return [-->
-<!--        this.bold ? "bold" : "",-->
-<!--        this.theme ? "c-icon&#45;&#45;" + this.theme : ""-->
-<!--      ];-->
-<!--    },-->
-<!--    style () {-->
-<!--      return {-->
-<!--        fontSize: this.size ? this.size + "px" : null,-->
-<!--        marginRight: this.right ? this.right + "px" : null,-->
-<!--        marginLeft: this.left ? this.left + "px" : null,-->
-<!--        color: this.color || null-->
-<!--      };-->
-<!--    }-->
-<!--  }-->
-<!--};-->
-<!--</script>-->
+<script>
+  // export default {
+  //   props: {
+  //     bold: {
+  //       type: Boolean,
+  //       default: false
+  //     },
+  //
+  //     // icon 大小
+  //     size: {
+  //       type: Number,
+  //       default: 0
+  //     },
+  //
+  //     // 可以直接传入 6 位颜色值,将覆盖 theme 设置的颜色
+  //     color: {
+  //       type: String,
+  //       default: ""
+  //     },
+  //
+  //     theme: {
+  //       type: String,
+  //       default: "normal"
+  //     },
+  //
+  //     right: {
+  //       type: Number,
+  //       default: 0
+  //     },
+  //
+  //     left: {
+  //       type: Number,
+  //       default: 0
+  //     }
+  //   },
+  //   computed: {
+  //     classList () {
+  //       return [
+  //         this.bold ? "bold" : "",
+  //         this.theme ? "c-icon--" + this.theme : ""
+  //       ];
+  //     },
+  //     style () {
+  //       return {
+  //         fontSize: this.size ? this.size + "px" : null,
+  //         marginRight: this.right ? this.right + "px" : null,
+  //         marginLeft: this.left ? this.left + "px" : null,
+  //         color: this.color || null
+  //       };
+  //     }
+  //   }
+  // };
+</script>
 
 <!--<style lang="scss" scoped>-->
 <!-- @import "src/style/set-theme.scss";-->
@@ -76,3 +77,4 @@
 
 <!--@include setTheme-->
 <!--</style>-->
+

+ 30 - 28
src/components/Basic/CInput.vue

@@ -1,32 +1,34 @@
-<!--<template>-->
-<!--  <component-->
-<!--    class="c-input"-->
-<!--    :required="required"-->
-<!--    :is="textarea ? 'textarea' : 'input'"-->
-<!--    :type="type ? type : 'text'"-->
-<!--    :placeholder="placeholder"-->
-<!--    :value="value"-->
-<!--    :maxlength="maxlength ? maxlength : null"-->
-<!--    @input="$emit('input', $event.target.value)"-->
-<!--  />-->
-<!--</template>-->
+<template>
+    <el-button></el-button>
+    <!--  <component-->
+    <!--    class="c-input"-->
+    <!--    :required="required"-->
+    <!--    :is="textarea ? 'textarea' : 'input'"-->
+    <!--    :type="type ? type : 'text'"-->
+    <!--    :placeholder="placeholder"-->
+    <!--    :value="value"-->
+    <!--    :maxlength="maxlength ? maxlength : null"-->
+    <!--    @input="$emit('input', $event.target.value)"-->
+    <!--  />-->
+</template>
+
+<script>
+    // export default {
+    //   model: {
+    //     prop: "value",
+    //     event: "input"
+    //   },
+    //   props: {
+    //     value: [String, Number],
+    //     placeholder: String,
+    //     textarea: Boolean,
+    //     type: String,
+    //     maxlength: Number,
+    //     required: Boolean
+    //   }
+    // };
+</script>
 
-<!--<script>-->
-<!--export default {-->
-<!--  model: {-->
-<!--    prop: "value",-->
-<!--    event: "input"-->
-<!--  },-->
-<!--  props: {-->
-<!--    value: [String, Number],-->
-<!--    placeholder: String,-->
-<!--    textarea: Boolean,-->
-<!--    type: String,-->
-<!--    maxlength: Number,-->
-<!--    required: Boolean-->
-<!--  }-->
-<!--};-->
-<!--</script>-->
 <!--<style lang="scss" scoped>-->
 <!--@import "src/style/theme.scss";-->
 

+ 21 - 20
src/components/Basic/CTag.vue

@@ -1,24 +1,25 @@
-<!--<template>-->
-<!--  <div class="c-tag" :class="classList">-->
-<!--    <slot></slot>-->
-<!--  </div>-->
-<!--</template>-->
+<template>
+    <el-tag></el-tag>
+    <!--  <div class="c-tag" :class="classList">-->
+    <!--    <slot></slot>-->
+    <!--  </div>-->
+</template>
 
-<!--<script>-->
-<!--export default {-->
-<!--  props: {-->
-<!--    theme: {-->
-<!--      type: String,-->
-<!--      default: "normal"-->
-<!--    }-->
-<!--  },-->
-<!--  computed: {-->
-<!--    classList () {-->
-<!--      return [this.theme ? "c-tag&#45;&#45;" + this.theme : ""];-->
-<!--    }-->
-<!--  }-->
-<!--};-->
-<!--</script>-->
+<script>
+    // export default {
+    //   props: {
+    //     theme: {
+    //       type: String,
+    //       default: "normal"
+    //     }
+    //   },
+    //   computed: {
+    //     classList () {
+    //       return [this.theme ? "c-tag--" + this.theme : ""];
+    //     }
+    //   }
+    // };
+</script>
 
 <!--<style lang="scss" scoped>-->
 <!--@import "src/style/set-theme.scss";-->

+ 61 - 59
src/components/Basic/IconButton.vue

@@ -1,63 +1,64 @@
-<!--<template>-->
-<!--  <div class="icon-button" :class="classList" :title="title ? title : ''" @click="$emit('click')" :style="style">-->
-<!--    <c-icon :theme="theme" :bold="!noBold" :size="size ? size / 1.4 - 4 : 26">-->
-<!--      <slot></slot>-->
-<!--    </c-icon>-->
-<!--    <ripple :color="theme"></ripple>-->
-<!--  </div>-->
-<!--</template>-->
+<template>
+  <el-button></el-button>
+  <!--  <div class="icon-button" :class="classList" :title="title ? title : ''" @click="$emit('click')" :style="style">-->
+  <!--    <c-icon :theme="theme" :bold="!noBold" :size="size ? size / 1.4 - 4 : 26">-->
+  <!--      <slot></slot>-->
+  <!--    </c-icon>-->
+  <!--    <ripple :color="theme"></ripple>-->
+  <!--  </div>-->
+</template>
 
-<!--<script>-->
-<!--import CIcon from "@/components/Basic/CIcon";-->
-<!--import Ripple from "@/components/Basic/Ripple";-->
-
-<!--export default {-->
-<!--  components: { Ripple, CIcon },-->
-<!--  // props: ['title', 'ripple', 'small']-->
-<!--  props: {-->
-<!--    title: {-->
-<!--      type: String,-->
-<!--      default: "按钮"-->
-<!--    },-->
-
-<!--    // 可以直接传入 6 位颜色值,将覆盖 theme 设置的颜色-->
-<!--    color: {-->
-<!--      type: String,-->
-<!--      default: ""-->
-<!--    },-->
-
-<!--    // 这个值需要在下方 scss 中有相应的定义,否则无效-->
-<!--    theme: {-->
-<!--      type: String,-->
-<!--      default: "normal"-->
-<!--    },-->
-
-<!--    noBold: {-->
-<!--      type: Boolean,-->
-<!--      default: false-->
-<!--    },-->
-
-<!--    // icon button 大小-->
-<!--    size: Number,-->
-<!--    left: Number,-->
-<!--    right: Number-->
-<!--  },-->
-<!--  computed: {-->
-<!--    classList () {-->
-<!--      return [this.theme ? "icon-button&#45;&#45;" + this.theme : ""];-->
-<!--    },-->
-<!--    style () {-->
-<!--      return {-->
-<!--        color: this.color.match(/^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/) ? this.color : "",-->
-<!--        width: this.size ? this.size + "px" : null,-->
-<!--        height: this.size ? this.size + "px" : null,-->
-<!--        marginLeft: this.left ? this.left + "px" : null,-->
-<!--        marginRight: this.right ? this.right + "px" : null-->
-<!--      };-->
-<!--    }-->
-<!--  }-->
-<!--};-->
-<!--</script>-->
+<script>
+  // import CIcon from "@/components/Basic/CIcon";
+  // import Ripple from "@/components/Basic/Ripple";
+  //
+  // export default {
+  //   components: { Ripple, CIcon },
+  //   // props: ['title', 'ripple', 'small']
+  //   props: {
+  //     title: {
+  //       type: String,
+  //       default: "按钮"
+  //     },
+  //
+  //     // 可以直接传入 6 位颜色值,将覆盖 theme 设置的颜色
+  //     color: {
+  //       type: String,
+  //       default: ""
+  //     },
+  //
+  //     // 这个值需要在下方 scss 中有相应的定义,否则无效
+  //     theme: {
+  //       type: String,
+  //       default: "normal"
+  //     },
+  //
+  //     noBold: {
+  //       type: Boolean,
+  //       default: false
+  //     },
+  //
+  //     // icon button 大小
+  //     size: Number,
+  //     left: Number,
+  //     right: Number
+  //   },
+  //   computed: {
+  //     classList () {
+  //       return [this.theme ? "icon-button--" + this.theme : ""];
+  //     },
+  //     style () {
+  //       return {
+  //         color: this.color.match(/^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/) ? this.color : "",
+  //         width: this.size ? this.size + "px" : null,
+  //         height: this.size ? this.size + "px" : null,
+  //         marginLeft: this.left ? this.left + "px" : null,
+  //         marginRight: this.right ? this.right + "px" : null
+  //       };
+  //     }
+  //   }
+  // };
+</script>
 
 <!--<style lang="scss" scoped>-->
 <!--@import "src/style/theme.scss";-->
@@ -106,3 +107,4 @@
 
 <!--@include setTheme()-->
 <!--</style>-->
+

+ 29 - 28
src/components/Basic/Ripple.vue

@@ -1,32 +1,33 @@
-<!--<template>-->
-<!--  <div class="ripple-wrapper" :class="color || ''">-->
-<!--    <div class="ripple" @click="handleRipple" :class="className" :style="size ? `width: ${size}px; height: ${size}px;` : ''">-->
-<!--    </div>-->
-<!--    <div class="background"></div>-->
-<!--  </div>-->
-<!--</template>-->
+<template>
+  <el-tag></el-tag>
+  <!--  <div class="ripple-wrapper" :class="color || ''">-->
+  <!--    <div class="ripple" @click="handleRipple" :class="className" :style="size ? `width: ${size}px; height: ${size}px;` : ''">-->
+  <!--    </div>-->
+  <!--    <div class="background"></div>-->
+  <!--  </div>-->
+</template>
 
-<!--<script>-->
-<!--export default {-->
-<!--  props: ["size", "color"],-->
-<!--  data () {-->
-<!--    return {-->
-<!--      className: "hide"-->
-<!--    };-->
-<!--  },-->
-<!--  methods: {-->
-<!--    handleRipple () {-->
-<!--      this.className = "";-->
-<!--      this.$nextTick(() => {-->
-<!--        this.className = "show";-->
-<!--        setTimeout(() => {-->
-<!--          this.className = "";-->
-<!--        }, 500);-->
-<!--      });-->
-<!--    }-->
-<!--  }-->
-<!--};-->
-<!--</script>-->
+<script>
+  // export default {
+  //   props: ["size", "color"],
+  //   data () {
+  //     return {
+  //       className: "hide"
+  //     };
+  //   },
+  //   methods: {
+  //     handleRipple () {
+  //       this.className = "";
+  //       this.$nextTick(() => {
+  //         this.className = "show";
+  //         setTimeout(() => {
+  //           this.className = "";
+  //         }, 500);
+  //       });
+  //     }
+  //   }
+  // };
+</script>
 
 <!--<style lang="scss" scoped>-->
 <!--@import "src/style/theme.scss";-->

+ 1 - 0
src/components/CourseCard.vue

@@ -43,6 +43,7 @@ export default {
   },
   computed: {
     imageUrl() {
+      console.log(this.courseVO.imageUrl);
       return this.courseVO.imageUrl === null ? this.noImgUrl : this.courseVO.imageUrl + "?t=" + Date.now().valueOf();
     },
     title() {

+ 94 - 90
src/components/PDF/Pdf.vue

@@ -1,99 +1,103 @@
-<!--<template>-->
+<template>
+  <button></button>
 <!--  <div class="pdf">-->
 <!--    <canvas class="pdf pdf-canvas" id="pdf-canvas" :class="classList"></canvas>-->
-<!--    <div v-if="loading" class="loading">加载中...</div>-->
-<!--    <fade-transition>-->
-<!--      <div v-if="focus" class="focus-mask">禁用快捷键中...<br>点击空白出退出</div>-->
-<!--    </fade-transition>-->
+<!--&lt;!&ndash;    <div v-if="loading" class="loading">加载中...</div>&ndash;&gt;-->
+<!--&lt;!&ndash;    <fade-transition>&ndash;&gt;-->
+<!--&lt;!&ndash;      <div v-if="focus" class="focus-mask">禁用快捷键中...<br>点击空白出退出</div>&ndash;&gt;-->
+<!--&lt;!&ndash;    </fade-transition>&ndash;&gt;-->
 <!--  </div>-->
-<!--</template>-->
+</template>
 
-<!--<script>-->
-<!--import pdfjs from "@/utils/pdf";-->
-<!--import { mapState } from "vuex";-->
-<!--import { SET_TOTAL_PAGES } from "@/store/types/pdf-types";-->
-<!--import FadeTransition from "@/animations/FadeTransition";-->
-
-<!--export default {-->
-<!--  components: { FadeTransition },-->
-<!--  data () {-->
-<!--    return {-->
-<!--      loading: true-->
-<!--    };-->
-<!--  },-->
-<!--  mounted () {-->
-<!--    console.log("hhh");-->
-<!--    this.loading = true;-->
-<!--    this._canvas = document.getElementById("pdf-canvas");-->
-<!--    this._context = this._canvas.getContext("2d");-->
-
-<!--    // Default size-->
-<!--    this._canvas.height = 1080;-->
-<!--    this._canvas.width = 1440;-->
-
-<!--    console.log(this.src);-->
-<!--    if (this.src) {-->
-<!--      this.load(this.src);-->
-<!--    } else {-->
-<!--      // ! 1秒后重试-->
-<!--      setTimeout(() => {-->
-<!--        this.load(this.src);-->
-<!--      }, 1000);-->
-<!--    }-->
-<!--  },-->
-<!--  computed: {-->
-<!--    ...mapState({-->
-<!--      src: state => state.pdf.src,-->
-<!--      showDiscussion: state => state.pdf.showDiscussion,-->
-<!--      currentPage: state => state.pdf.currentPage,-->
-<!--      screenShot: state => state.pdf.screenShot,-->
-<!--      focus: state => state.pdf.focus-->
-<!--    }),-->
-<!--    classList () {-->
-<!--      return {-->
-<!--        "full-size": !this.showDiscussion-->
-<!--      };-->
-<!--    }-->
-<!--  },-->
-<!--  watch: {-->
-<!--    currentPage () {-->
-<!--      this.showPage();-->
-<!--    }-->
-<!--  },-->
-<!--  methods: {-->
-<!--    load (src) {-->
-<!--      const loadingTask = pdfjs.getDocument(src);-->
-<!--      loadingTask.promise.then(pdf => {-->
-<!--        this.loading = false;-->
-<!--        this._pdf = pdf;-->
-<!--        this.$store.commit(SET_TOTAL_PAGES, { totalPages: pdf.numPages });-->
-<!--        this.showPage();-->
-<!--      });-->
-<!--    },-->
-<!--    showPage () {-->
-<!--      this._pdf && this._pdf.getPage(this.currentPage || 1).then(page => {-->
-<!--        const scale = 2.5;-->
-<!--        const viewport = page.getViewport({ scale: scale });-->
-
-<!--        this._canvas.height = viewport.height;-->
-<!--        this._canvas.width = viewport.width;-->
-
-<!--        const renderContext = {-->
-<!--          canvasContext: this._context,-->
-<!--          viewport: viewport-->
-<!--        };-->
-<!--        page.render(renderContext);-->
-<!--      }).catch(() => {-->
-<!--        console.log("PDF 当前页解析错误");-->
-<!--        //this.$setInfoMessage('PDF 当前页解析错误')-->
-<!--      });-->
-<!--    }-->
-<!--  }-->
-<!--};-->
-<!--</script>-->
+<script>
+// import { mapState } from "vuex";
+// import { SET_TOTAL_PAGES } from "@/store/types/pdf-types";
+// import FadeTransition from "@/animations/FadeTransition";
+//
+// const pdfJS = require("pdfjs-dist");
+// pdfJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry");
+//
+// export default {
+//   data() {
+//     return {
+//       loading: true,
+//     };
+//   },
+//   mounted() {
+//     this.loading = true;
+//     this._canvas = document.getElementById("pdf-canvas");
+//     this._context = this._canvas.getContext("2d");
+//
+//     // Default size
+//     this._canvas.height = 1080;
+//     this._canvas.width = 1440;
+//
+//     // if (this.src) {
+//     //   console.log(this.src);
+//     //   this.load(this.src);
+//     // } else {
+//     //   // ! 1秒后重试
+//     //   setTimeout(() => {
+//     //     //this.load(this.src);
+//     //   }, 1000);
+//     // }
+//     console.log(this.src);
+//     this.load(this.src);
+//   },
+//   computed: {
+//     ...mapState({
+//       src: state => state.pdf.src,
+//       showDiscussion: state => state.pdf.showDiscussion,
+//       currentPage: state => state.pdf.currentPage,
+//       screenShot: state => state.pdf.screenShot,
+//       focus: state => state.pdf.focus
+//     }),
+//     classList() {
+//       return {
+//         "full-size": !this.showDiscussion
+//       };
+//     }
+//   },
+//   watch: {
+//     currentPage() {
+//       this.showPage();
+//     }
+//   },
+//   methods: {
+//     load(src) {
+//       console.log(src);
+//       const loadingTask = pdfJS.getDocument(src);
+//       loadingTask.promise.then(pdf => {
+//         this.loading = false;
+//         this._pdf = pdf;
+//         this.$store.commit(SET_TOTAL_PAGES, {totalPages: pdf.numPages});
+//         this.showPage();
+//       });
+//     },
+//     showPage() {
+//       this._pdf && this._pdf.getPage(this.currentPage || 1).then(page => {
+//         const scale = 2.5;
+//         const viewport = page.getViewport({scale: scale});
+//
+//         this._canvas.height = viewport.height;
+//         this._canvas.width = viewport.width;
+//
+//         const renderContext = {
+//           canvasContext: this._context,
+//           viewport: viewport
+//         };
+//         page.render(renderContext);
+//       }).catch(() => {
+//         console.log("PDF 当前页解析错误");
+//         //this.$setInfoMessage('PDF 当前页解析错误')
+//       });
+//     }
+//   },
+// };
+</script>
 
 <!--<style lang="scss" scoped>-->
-<!--@import 'src/style/theme.scss';-->
+<!--@import 'src/style/set-theme.scss';-->
 
 <!--.pdf {-->
 <!--  z-index: -1;-->

+ 63 - 62
src/components/PDF/PdfController.vue

@@ -1,4 +1,5 @@
-<!--<template>-->
+<template>
+  <button></button>
 <!--  <div class="pdf-controller" style="margin-top: 5%">-->
 <!--    <div class="actions" :class="hide ? 'hide-actions' : ''">-->
 <!--      <a :href="src">-->
@@ -17,69 +18,69 @@
 <!--      <i class="el-icon-arrow-down"/>-->
 <!--    </icon-button>-->
 <!--  </div>-->
-<!--</template>-->
-
-<!--<script>-->
-<!--import IconButton from "@/components/Basic/IconButton";-->
-<!--import { NEXT_PAGE, PREVIOUS_PAGE, SET_CURRENT_PAGE, TOGGLE_SHOW_DISCUSSION } from "@/store/types/pdf-types";-->
-<!--import { mapState } from "vuex";-->
-<!--import CInput from "@/components/Basic/CInput";-->
-<!--import { isEmpty } from "@/utils/types";-->
-
-<!--export default {-->
-<!--  components: { CInput, IconButton },-->
-<!--  data () {-->
-<!--    return {-->
-<!--      pageMarked: false,-->
-<!--      toPage: "",-->
-<!--      hide: false-->
-<!--    };-->
-<!--  },-->
-<!--  computed: {-->
-<!--    ...mapState({-->
-<!--      showDiscussion: state => state.pdf.showDiscussion,-->
-<!--      src: state => state.pdf.src,-->
-<!--      totalPages: state => state.pdf.totalPages,-->
-<!--      currentPage: state => state.pdf.currentPage-->
-<!--    })-->
-<!--  },-->
-<!--  methods: {-->
-<!--    handleDiscussionShowState () {-->
-<!--      this.$store.commit(TOGGLE_SHOW_DISCUSSION);-->
-<!--    },-->
-<!--    handlePrevious () {-->
-<!--      this.$store.commit(PREVIOUS_PAGE);-->
-<!--    },-->
-<!--    handleNext () {-->
-<!--      this.$store.commit(NEXT_PAGE);-->
-<!--    },-->
-<!--    handleToPage (value) {-->
-<!--      if (isEmpty(value) || value === "" || value === 0) {-->
-<!--        return;-->
-<!--      }-->
-<!--      value = typeof value === typeof "" ? parseInt(value) : value;-->
-<!--      if (value > this.totalPages) {-->
-<!--        console.log("超过最大页数,已跳到最后一页");-->
-<!--        this.$store.commit(SET_CURRENT_PAGE, { currentPage: this.totalPages });-->
-<!--      } else if (value <= 0) {-->
-<!--        console.log("超过最小页数,已跳到第一页");-->
-<!--        this.$store.commit(SET_CURRENT_PAGE, { currentPage: 1 });-->
-<!--      } else {-->
-<!--        this.$store.commit(SET_CURRENT_PAGE, { currentPage: value });-->
-<!--      }-->
-<!--    },-->
-<!--    handleHide () {-->
-<!--      this.hide = !this.hide;-->
-<!--    }-->
-<!--    // handleScreenShot () {-->
-<!--    //   this.$store.commit(SET_SCREEN_SHOT)-->
-<!--    // }-->
-<!--  }-->
-<!--};-->
-<!--</script>-->
+</template>
+
+<script>
+// import IconButton from "@/components/Basic/IconButton";
+// import { NEXT_PAGE, PREVIOUS_PAGE, SET_CURRENT_PAGE, TOGGLE_SHOW_DISCUSSION } from "@/store/types/pdf-types";
+// import { mapState } from "vuex";
+// import CInput from "@/components/Basic/CInput";
+// import { isEmpty } from "@/utils/types";
+//
+// export default {
+//   components: { CInput, IconButton },
+//   data () {
+//     return {
+//       pageMarked: false,
+//       toPage: "",
+//       hide: false
+//     };
+//   },
+//   computed: {
+//     ...mapState({
+//       showDiscussion: state => state.pdf.showDiscussion,
+//       src: state => state.pdf.src,
+//       totalPages: state => state.pdf.totalPages,
+//       currentPage: state => state.pdf.currentPage
+//     })
+//   },
+//   methods: {
+//     handleDiscussionShowState () {
+//       this.$store.commit(TOGGLE_SHOW_DISCUSSION);
+//     },
+//     handlePrevious () {
+//       this.$store.commit(PREVIOUS_PAGE);
+//     },
+//     handleNext () {
+//       this.$store.commit(NEXT_PAGE);
+//     },
+//     handleToPage (value) {
+//       if (isEmpty(value) || value === "" || value === 0) {
+//         return;
+//       }
+//       value = typeof value === typeof "" ? parseInt(value) : value;
+//       if (value > this.totalPages) {
+//         console.log("超过最大页数,已跳到最后一页");
+//         this.$store.commit(SET_CURRENT_PAGE, { currentPage: this.totalPages });
+//       } else if (value <= 0) {
+//         console.log("超过最小页数,已跳到第一页");
+//         this.$store.commit(SET_CURRENT_PAGE, { currentPage: 1 });
+//       } else {
+//         this.$store.commit(SET_CURRENT_PAGE, { currentPage: value });
+//       }
+//     },
+//     handleHide () {
+//       this.hide = !this.hide;
+//     }
+//     // handleScreenShot () {
+//     //   this.$store.commit(SET_SCREEN_SHOT)
+//     // }
+//   }
+// };
+</script>
 
 <!--<style lang="scss" scoped>-->
-<!--@import 'src/style/theme.scss';-->
+<!--//@import 'src/style/set-theme.scss';-->
 
 <!--.pdf-controller {-->
 <!--  position: fixed;-->

+ 206 - 24
src/components/PDF/PdfViewer.vue

@@ -1,29 +1,211 @@
-<!--<template>-->
-<!--  <div>-->
+<template>
+  <div>
+<!--    <canvas class="pdf pdf-canvas" id="pdf-canvas" :class="classList"></canvas>-->
+
+<!--    <input type="file" ref="fielinput" @change="uploadFile" />-->
+<!--    <div class="canvas-container">-->
+<!--      <canvas ref="myCanvas" class="pdf-container"> </canvas>-->
+<!--    </div>-->
+<!--    <div class="pagination-wrapper">-->
+<!--      <button @click="clickPre">上一页</button>-->
+<!--      <span>第{{ pageNo }} / {{ pdfPageNumber }}页</span>-->
+<!--      <button @click="clickNext">下一页</button>-->
+<!--    </div>-->
+
 <!--    <pdf></pdf>-->
 <!--    <pdf-controller></pdf-controller>-->
-<!--  </div>-->
-<!--</template>-->
-
-<!--<script>-->
-<!--import Pdf from "@/components/PDF/Pdf";-->
-<!--import PdfController from "@/components/PDF/PdfController";-->
-<!--export default {-->
-<!--  components: { PdfController, Pdf },-->
-<!--  props: ["src", "discussion"],-->
-<!--  data () {-->
-<!--    return {-->
-<!--      currentPage: 1,-->
-<!--      fullSize: !this.discussion-->
-<!--    };-->
-<!--  },-->
-<!--  watch: {-->
-<!--    discussion (newValue) {-->
-<!--      this.fullSize = !newValue;-->
-<!--    }-->
-<!--  }-->
-<!--};-->
-<!--</script>-->
+  </div>
+</template>
+
+<script>
+// import Pdf from "@/components/PDF/Pdf";
+// // import PdfController from "@/components/PDF/PdfController";
+//
+// export default {
+//   components: {
+//     // PdfController,
+//     Pdf },
+//   props: ["src"],
+//   data () {
+//     return {
+//       currentPage: 1,
+//       fullSize: !this.discussion
+//     };
+//   },
+//   watch: {
+//     discussion (newValue) {
+//       this.fullSize = !newValue;
+//     }
+//   }
+// };
+//
+
+
+// import { mapState } from "vuex";
+// import { SET_TOTAL_PAGES } from "@/store/types/pdf-types";
+// import FadeTransition from "@/animations/FadeTransition";
+
+// const pdfJS = require("pdfjs-dist");
+// pdfJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry");
+
+// export default {
+//   data() {
+//     return {
+//       loading: true,
+//     };
+//   },
+//   mounted() {
+//     this.loading = true;
+//     this._canvas = document.getElementById("pdf-canvas");
+//     this._context = this._canvas.getContext("2d");
+//
+//     // Default size
+//     this._canvas.height = 1080;
+//     this._canvas.width = 1440;
+//
+//     if (this.src) {
+//       this.load(this.src);
+//     } else {
+//       // ! 1秒后重试
+//       setTimeout(() => {
+//         this.load(this.src);
+//       }, 1000);
+//     }
+//   },
+//   computed: {
+//     ...mapState({
+//       src: state => state.pdf.src,
+//       showDiscussion: state => state.pdf.showDiscussion,
+//       currentPage: state => state.pdf.currentPage,
+//       screenShot: state => state.pdf.screenShot,
+//       focus: state => state.pdf.focus
+//     }),
+//     classList() {
+//       return {
+//         "full-size": !this.showDiscussion
+//       };
+//     }
+//   },
+//   watch: {
+//     currentPage() {
+//       this.showPage();
+//     }
+//   },
+//   methods: {
+//     load(src) {
+//       console.log(pdfJS);
+//       const loadingTask = pdfJS.getDocument(src);
+//       loadingTask.promise.then(pdf => {
+//         this.loading = false;
+//         this._pdf = pdf;
+//         this.$store.commit(SET_TOTAL_PAGES, {totalPages: pdf.numPages});
+//         this.showPage();
+//       });
+//     },
+//     showPage() {
+//       this._pdf && this._pdf.getPage(this.currentPage || 1).then(page => {
+//         const scale = 2.5;
+//         const viewport = page.getViewport({scale: scale});
+//
+//         this._canvas.height = viewport.height;
+//         this._canvas.width = viewport.width;
+//
+//         const renderContext = {
+//           canvasContext: this._context,
+//           viewport: viewport
+//         };
+//         page.render(renderContext);
+//       }).catch(() => {
+//         console.log("PDF 当前页解析错误");
+//         //this.$setInfoMessage('PDF 当前页解析错误')
+//       });
+//     }
+//   },
+// };
+
+// export default {
+//   mounted() {},
+//   data() {
+//     return {
+//       pageNo: null,
+//       pdfPageNumber: null,
+//       pdfTotalPages: 1,
+//       renderingPage: false,
+//       pdfData: null, // PDF的base64
+//       scale: 1, // 缩放值
+//     };
+//   },
+//   methods: {
+//     uploadFile() {
+//       let inputDom = this.$refs.fielinput;
+//       let file = inputDom.files[0];
+//       let reader = new FileReader();
+//       reader.readAsDataURL(file);
+//       reader.onload = () => {
+//         let data = atob(
+//                 reader.result.substring(reader.result.indexOf(",") + 1)
+//         );
+//         this.loadPdfData(data);
+//       };
+//     },
+//     loadPdfData(data) {
+//       console.log(pdfJS);
+//       // 引入pdf.js的字体
+//       let CMAP_URL = "https://unpkg.com/pdfjs-dist@2.0.943/cmaps/";
+//       //读取base64的pdf流文件
+//       this.pdfData = pdfJS.getDocument({
+//         data: data, // PDF base64编码
+//         cMapUrl: CMAP_URL,
+//         cMapPacked: true,
+//       });
+//       console.log(this.pdfData);
+//       this.renderPage(1);
+//       // this.renderScrollPdf();
+//     },
+//
+//     // 根据页码渲染相应的PDF
+//     renderPage(num) {
+//       this.renderingPage = true;
+//       this.pdfData.promise.then((pdf) => {
+//         this.pdfPageNumber = pdf.numPages;
+//
+//         pdf.getPage(num).then((page) => {
+//           // 获取DOM中为预览PDF准备好的canvasDOM对象
+//           let canvas = this.$refs.myCanvas;
+//           let viewport = page.getViewport(this.scale);
+//           canvas.height = viewport.height;
+//           canvas.width = viewport.width;
+//
+//           let ctx = canvas.getContext("2d");
+//           let renderContext = {
+//             canvasContext: ctx,
+//             viewport: viewport,
+//           };
+//           page.render(renderContext).then(() => {
+//             this.renderingPage = false;
+//             this.pageNo = num;
+//           });
+//         });
+//       });
+//     },
+//     clickPre() {
+//       if (!this.renderingPage && this.pageNo && this.pageNo > 1) {
+//         this.renderPage(this.pageNo - 1);
+//       }
+//     },
+//     clickNext() {
+//       if (
+//               !this.renderingPage &&
+//               this.pdfPageNumber &&
+//               this.pageNo &&
+//               this.pageNo < this.pdfPageNumber
+//       ) {
+//         this.renderPage(this.pageNo + 1);
+//       }
+//     },
+//   },
+// };
+</script>
 
 <!--<style lang="scss" scoped>-->
 <!--</style>-->

+ 176 - 175
src/components/PDF/PointerCanvas.vue

@@ -1,181 +1,182 @@
-<!--<template>-->
+<template>
 <!--  <canvas :width="width" :height="height" class="pointer-canvas" ref="pointerCanvas" @click="handleFocus">-->
 <!--  </canvas>-->
-<!--</template>-->
+  <div></div>
+</template>
 
-<!--<script>-->
-<!--import { mapState } from "vuex";-->
-<!--import { USE_FOCUS } from "@/store/types/pdf-types";-->
-
-<!--export default {-->
-<!--  name: "PointerCanvas",-->
-<!--  props: {-->
-<!--    noPointer: Boolean,-->
-<!--    noBox: Boolean-->
-<!--  },-->
-<!--  data () {-->
-<!--    return {-->
-<!--      points: [],-->
-<!--      disablePointer: false,-->
-<!--      width: window.innerWidth,-->
-<!--      height: document.documentElement.clientHeight,-->
-<!--      rects: [],-->
-<!--      drawingRect: {},-->
-<!--      poped: [],-->
-<!--      // 为了突破30fps限制(应该与chrome优化机制有关),往数组中多放入冗余数字,以让动画更流畅-->
-<!--      overrate: 4-->
-<!--    };-->
-<!--  },-->
-<!--  computed: {-->
-<!--    pointerActive () {-->
-<!--      return this.width > 500 && !this.noPointer && !this.disablePointer;-->
-<!--    },-->
-<!--    ...mapState({-->
-<!--      currentPage: state => state.pdf.currentPage-->
-<!--    })-->
-<!--  },-->
-<!--  watch: {-->
-<!--    currentPage () {-->
-<!--      this.rects = [];-->
-<!--      this.poped = [];-->
-<!--      this.drawingRect = {};-->
-<!--      this.renderer();-->
-<!--    }-->
-<!--  },-->
-<!--  mounted () {-->
-<!--    this._canvas = this.$refs.pointerCanvas;-->
-<!--    this._ctx = this._canvas.getContext("2d");-->
-
-<!--    window.addEventListener("resize", this.handleResize);-->
-<!--    this._canvas.addEventListener("mousemove", this.handleMouseMove);-->
-<!--    this._canvas.addEventListener("mousedown", this.handleMouseDown);-->
-<!--    this._canvas.addEventListener("mouseup", this.handleMouseUp);-->
-<!--    this._interval = setInterval(this.shiftPoints, 1000 / 90);-->
-<!--  },-->
-<!--  unmounted () {-->
-<!--    clearInterval(this._interval);-->
-<!--    window.removeEventListener("resize", this.handleResize);-->
-<!--    this._canvas.removeEventListener("mousemove", this.handleMouseMove);-->
-<!--    this._canvas.removeEventListener("mousedown", this.handleMouseDown);-->
-<!--    this._canvas.removeEventListener("mouseup", this.handleMouseUp);-->
-<!--  },-->
-<!--  methods: {-->
-<!--    handleResize () {-->
-<!--      this.width = window.innerWidth;-->
-<!--      this.height = document.documentElement.clientHeight;-->
-<!--      this.renderer();-->
-<!--    },-->
-<!--    handleMouseMove (e) {-->
-<!--      if (this.pointerActive) {-->
-<!--        const { x, y } = this.points[this.points.length - 1] ?? { x: 0, y: 0 };-->
-<!--        if (this.points.length === 0 || Math.abs(x - e.clientX) > 8 || Math.abs(y - e.clientY) > 8) {-->
-<!--          [...Array(this.overrate)].forEach(_ => this.points.unshift({ x: e.clientX, y: e.clientY }));-->
-<!--          if (this.points.length > 100) {-->
-<!--            [...Array(this.overrate)].forEach(_ => this.points.pop());-->
-<!--          }-->
-<!--        }-->
-<!--      }-->
-<!--    },-->
-<!--    shiftPoints () {-->
-<!--      if (this.points.length > 34) {-->
-<!--        this.points.pop();-->
-<!--      }-->
-<!--      if (this.points.length > 0) {-->
-<!--        this.points.pop();-->
-<!--        requestAnimationFrame(() => {-->
-<!--          this.renderer();-->
-<!--        });-->
-<!--      }-->
-<!--    },-->
-<!--    handleMouseDown (e) {-->
-<!--      if (!this.noBox) {-->
-<!--        this.disablePointer = true;-->
-<!--        this.drawingRect.begin = { x: e.clientX, y: e.clientY };-->
-
-<!--        this._canvas.addEventListener("mousemove", this.handleBoxMouseMove);-->
-<!--      }-->
-<!--    },-->
-<!--    handleBoxMouseMove (e) {-->
-<!--      this.drawingRect.end = { x: e.clientX, y: e.clientY };-->
-<!--      requestAnimationFrame(() => {-->
-<!--        this.renderer();-->
-<!--      });-->
-<!--    },-->
-<!--    handleMouseUp (e) {-->
-<!--      if (!this.noBox) {-->
-<!--        if (this.drawingRect.begin && this.drawingRect.end) {-->
-<!--          this.rects.push(this.drawingRect);-->
-<!--          this.poped = [];-->
-<!--        }-->
-<!--        this._canvas.removeEventListener("mousemove", this.handleBoxMouseMove);-->
-<!--        this.disablePointer = false;-->
-<!--        this.renderer();-->
-<!--        this.drawingRect = {};-->
-<!--      }-->
-<!--    },-->
-<!--    renderer () {-->
-<!--      this._ctx.clearRect(0, 0, 2000, 2000);-->
-
-<!--      // 框选-->
-<!--      this._ctx.lineWidth = 4;-->
-<!--      this._ctx.lineJoin = "round";-->
-<!--      this._ctx.strokeStyle = "rgba(85, 136, 229, 1)";-->
-<!--      this._ctx.fillStyle = "rgba(85, 136, 229, .05)";-->
-<!--      this.rects.forEach(rect => {-->
-<!--        if (rect) {-->
-<!--          this._ctx.beginPath();-->
-<!--          this._ctx.rect(rect.begin.x, rect.begin.y, rect.end.x - rect.begin.x, rect.end.y - rect.begin.y);-->
-<!--          this._ctx.closePath();-->
-<!--          this._ctx.fill();-->
-<!--          this._ctx.stroke();-->
-<!--        }-->
-<!--      });-->
-<!--      if (this.drawingRect.begin && this.drawingRect.end) {-->
-<!--        this._ctx.beginPath();-->
-<!--        this._ctx.rect(-->
-<!--          this.drawingRect.begin.x,-->
-<!--          this.drawingRect.begin.y,-->
-<!--          this.drawingRect.end.x - this.drawingRect.begin.x,-->
-<!--          this.drawingRect.end.y - this.drawingRect.begin.y-->
-<!--        );-->
-<!--        this._ctx.closePath();-->
-<!--        this._ctx.fill();-->
-<!--        this._ctx.stroke();-->
-<!--      }-->
-
-<!--      // 线条-->
-<!--      this._ctx.strokeStyle = "rgba(211, 47, 47, .2)";-->
-<!--      this._ctx.beginPath();-->
-<!--      const length = this.points.length;-->
-<!--      this.points.forEach((point, index) => {-->
-<!--        if (index % this.overrate) {-->
-<!--          this._ctx.lineTo(point.x, point.y);-->
-<!--          this._ctx.lineWidth = (length - index + 4) / (2 * this.overrate);-->
-<!--          this._ctx.stroke();-->
-<!--        }-->
-<!--      });-->
-<!--      this._ctx.closePath();-->
-<!--    },-->
-<!--    handleFocus () {-->
-<!--      this.$store.commit(USE_FOCUS);-->
-<!--    },-->
-<!--    cleanCanvas () {-->
-<!--      this.rects = [];-->
-<!--      this.renderer();-->
-<!--    },-->
-<!--    undo () {-->
-<!--      const rect = this.rects.pop();-->
-<!--      rect && this.poped.push(rect);-->
-<!--      rect && this.renderer();-->
-<!--    },-->
-<!--    redo () {-->
-<!--      const rect = this.poped.pop();-->
-<!--      rect && this.rects.push(rect);-->
-<!--      rect && this.renderer();-->
-<!--    }-->
-<!--  }-->
-<!--};-->
-<!--</script>-->
+<script>
+// import { mapState } from "vuex";
+// import { USE_FOCUS } from "@/store/types/pdf-types";
+//
+// export default {
+//   name: "PointerCanvas",
+//   props: {
+//     noPointer: Boolean,
+//     noBox: Boolean
+//   },
+//   data () {
+//     return {
+//       points: [],
+//       disablePointer: false,
+//       width: window.innerWidth,
+//       height: document.documentElement.clientHeight,
+//       rects: [],
+//       drawingRect: {},
+//       poped: [],
+//       // 为了突破30fps限制(应该与chrome优化机制有关),往数组中多放入冗余数字,以让动画更流畅
+//       overrate: 4
+//     };
+//   },
+//   computed: {
+//     pointerActive () {
+//       return this.width > 500 && !this.noPointer && !this.disablePointer;
+//     },
+//     ...mapState({
+//       currentPage: state => state.pdf.currentPage
+//     })
+//   },
+//   watch: {
+//     currentPage () {
+//       this.rects = [];
+//       this.poped = [];
+//       this.drawingRect = {};
+//       this.renderer();
+//     }
+//   },
+//   mounted () {
+//     this._canvas = this.$refs.pointerCanvas;
+//     this._ctx = this._canvas.getContext("2d");
+//
+//     window.addEventListener("resize", this.handleResize);
+//     this._canvas.addEventListener("mousemove", this.handleMouseMove);
+//     this._canvas.addEventListener("mousedown", this.handleMouseDown);
+//     this._canvas.addEventListener("mouseup", this.handleMouseUp);
+//     this._interval = setInterval(this.shiftPoints, 1000 / 90);
+//   },
+//   unmounted () {
+//     clearInterval(this._interval);
+//     window.removeEventListener("resize", this.handleResize);
+//     this._canvas.removeEventListener("mousemove", this.handleMouseMove);
+//     this._canvas.removeEventListener("mousedown", this.handleMouseDown);
+//     this._canvas.removeEventListener("mouseup", this.handleMouseUp);
+//   },
+//   methods: {
+//     handleResize () {
+//       this.width = window.innerWidth;
+//       this.height = document.documentElement.clientHeight;
+//       this.renderer();
+//     },
+//     handleMouseMove (e) {
+//       if (this.pointerActive) {
+//         const { x, y } = this.points[this.points.length - 1] ?? { x: 0, y: 0 };
+//         if (this.points.length === 0 || Math.abs(x - e.clientX) > 8 || Math.abs(y - e.clientY) > 8) {
+//           [...Array(this.overrate)].forEach(_ => this.points.unshift({ x: e.clientX, y: e.clientY }));
+//           if (this.points.length > 100) {
+//             [...Array(this.overrate)].forEach(_ => this.points.pop());
+//           }
+//         }
+//       }
+//     },
+//     shiftPoints () {
+//       if (this.points.length > 34) {
+//         this.points.pop();
+//       }
+//       if (this.points.length > 0) {
+//         this.points.pop();
+//         requestAnimationFrame(() => {
+//           this.renderer();
+//         });
+//       }
+//     },
+//     handleMouseDown (e) {
+//       if (!this.noBox) {
+//         this.disablePointer = true;
+//         this.drawingRect.begin = { x: e.clientX, y: e.clientY };
+//
+//         this._canvas.addEventListener("mousemove", this.handleBoxMouseMove);
+//       }
+//     },
+//     handleBoxMouseMove (e) {
+//       this.drawingRect.end = { x: e.clientX, y: e.clientY };
+//       requestAnimationFrame(() => {
+//         this.renderer();
+//       });
+//     },
+//     handleMouseUp (e) {
+//       if (!this.noBox) {
+//         if (this.drawingRect.begin && this.drawingRect.end) {
+//           this.rects.push(this.drawingRect);
+//           this.poped = [];
+//         }
+//         this._canvas.removeEventListener("mousemove", this.handleBoxMouseMove);
+//         this.disablePointer = false;
+//         this.renderer();
+//         this.drawingRect = {};
+//       }
+//     },
+//     renderer () {
+//       this._ctx.clearRect(0, 0, 2000, 2000);
+//
+//       // 框选
+//       this._ctx.lineWidth = 4;
+//       this._ctx.lineJoin = "round";
+//       this._ctx.strokeStyle = "rgba(85, 136, 229, 1)";
+//       this._ctx.fillStyle = "rgba(85, 136, 229, .05)";
+//       this.rects.forEach(rect => {
+//         if (rect) {
+//           this._ctx.beginPath();
+//           this._ctx.rect(rect.begin.x, rect.begin.y, rect.end.x - rect.begin.x, rect.end.y - rect.begin.y);
+//           this._ctx.closePath();
+//           this._ctx.fill();
+//           this._ctx.stroke();
+//         }
+//       });
+//       if (this.drawingRect.begin && this.drawingRect.end) {
+//         this._ctx.beginPath();
+//         this._ctx.rect(
+//           this.drawingRect.begin.x,
+//           this.drawingRect.begin.y,
+//           this.drawingRect.end.x - this.drawingRect.begin.x,
+//           this.drawingRect.end.y - this.drawingRect.begin.y
+//         );
+//         this._ctx.closePath();
+//         this._ctx.fill();
+//         this._ctx.stroke();
+//       }
+//
+//       // 线条
+//       this._ctx.strokeStyle = "rgba(211, 47, 47, .2)";
+//       this._ctx.beginPath();
+//       const length = this.points.length;
+//       this.points.forEach((point, index) => {
+//         if (index % this.overrate) {
+//           this._ctx.lineTo(point.x, point.y);
+//           this._ctx.lineWidth = (length - index + 4) / (2 * this.overrate);
+//           this._ctx.stroke();
+//         }
+//       });
+//       this._ctx.closePath();
+//     },
+//     handleFocus () {
+//       this.$store.commit(USE_FOCUS);
+//     },
+//     cleanCanvas () {
+//       this.rects = [];
+//       this.renderer();
+//     },
+//     undo () {
+//       const rect = this.rects.pop();
+//       rect && this.poped.push(rect);
+//       rect && this.renderer();
+//     },
+//     redo () {
+//       const rect = this.poped.pop();
+//       rect && this.rects.push(rect);
+//       rect && this.renderer();
+//     }
+//   }
+// };
+</script>
 
 <!--<style lang="scss" scoped>-->
 

+ 21 - 6
src/utils/pdf.js

@@ -1,10 +1,25 @@
-import pdfjs from "pdfjs";
+// import pdfjs from "pdfjs-dist";
+//
+// // import pdfMake from "pdfmake/build/pdfmake";
+// // import pdfFonts from "pdfmake/build/vfs_fonts";
+// // import { Document, Page, pdfjs } from "react-pdf";
+// // pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/@2.16.105/pdf.worker.js`;
+//
+// pdfjs.GlobalWorkerOptions.workerSrc = "node_modules/pdfjs-dist/build/pdf.worker.js";
+// // // pdfjs.GlobalWorkerOptions.workerSrc = "https://cdn.jsdelivr.net/npm/pdfjs-dist@3.0.279/build/pdf.worker.min.js";
+// // pdfjs.GlobalWorkerOptions.workerSrc = "https://cdn.jsdelivr.net/npm/pdfjs-dist@2.16.105/build/pdf.worker.js";
+//
+// export default pdfjs;
 
-import pdfMake from "pdfmake/build/pdfmake";
-import pdfFonts from "pdfmake/build/vfs_fonts";
-//import { Document, Page, pdfjs } from "react-pdf";
-//pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
 
-pdfjs.GlobalWorkerOptions.workerSrc = "https://cdn.jsdelivr.net/npm/pdfjs-dist@3.0.279/build/pdf.worker.min.js";
+//import pdfjs from "pdfjs";
+
+//pdfjs.GlobalWorkerOptions.workerSrc = "D:\\Desktop\\seecoder\\SEEC-Portal-Front\\node_modules\\pdfjs-dist\\build\\pdf.worker.js";
+
+
+const pdfjs = await import("pdfjs-dist/build/pdf");
+const pdfjsWorker = await import("pdfjs-dist/build/pdf.worker.entry");
+
+pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
 
 export default pdfjs;

+ 180 - 74
src/views/CoursePage/tabs/CoursewareTab.vue

@@ -1,17 +1,28 @@
 <template>
   <div class="courseware-tab">
-    <el-button @click="uploadDialogVisible = true" type="primary" plain>添加课件</el-button>
-    <el-dialog v-model="uploadDialogVisible" :before-close="handleFormCancel" :width="700">
+      <el-row>
+          <el-col :span="3.5">
+              <el-button
+                      @click="uploadDialogVisible = true"
+                      type="primary"
+                      icon="el-icon-circle-plus-outline"
+                      plain>新建</el-button>
+          </el-col>
+          <el-col :span="15">
+              <span style="font-size: smaller; position: absolute; bottom: 25%">(支持拓展名:.pdf .ppt .pptx .doc .docx .xls .jpg .jpeg .png,单次只可上传一个文件)</span>
+          </el-col>
+      </el-row>
+      <el-dialog v-model="uploadDialogVisible" :before-close="handleFormCancel" :width="700">
       <el-form ref="formRef" :model="form"  label-width="100px">
 <!--          :rules="formRules"-->
-          <el-form-item label="使用时间" required>
-              <el-select v-model="form.useTime" placeholder="时间">
-                  <el-option key="1" label="课前" value="BEFORE_CLASS"></el-option>
-                  <el-option key="2" label="课中" value="IN_CLASS"></el-option>
-                  <el-option key="3" label="课后" value="AFTER_CLASS"></el-option>
-                  <el-option key="4" label="期末" value="FINISH_CLASS"></el-option>
-              </el-select>
-          </el-form-item>
+<!--          <el-form-item label="使用时间" required>-->
+<!--              <el-select v-model="form.useTime" placeholder="时间">-->
+<!--                  <el-option key="1" label="课前" value="BEFORE_CLASS"></el-option>-->
+<!--                  <el-option key="2" label="课中" value="IN_CLASS"></el-option>-->
+<!--                  <el-option key="3" label="课后" value="AFTER_CLASS"></el-option>-->
+<!--                  <el-option key="4" label="期末" value="FINISH_CLASS"></el-option>-->
+<!--              </el-select>-->
+<!--          </el-form-item>-->
 
           <el-form-item label="使用类型" required>
               <el-select v-model="form.useMethod" placeholder="类型">
@@ -27,8 +38,14 @@
                   action=""
                   class="upload-demo"
                   :auto-upload="false"
-                  :show-file-list="false">
-                  <el-button plain type="primary" class="tabs-function-button">上传文件<i class="el-icon-upload"></i></el-button>(请选择单个文件)
+                  :show-file-list="false"
+              >
+                  <el-button
+                      plain
+                      type="primary"
+                      class="tabs-function-button"
+                      icon="el-icon-upload"
+                        >上传文件</el-button>(请选择单个文件)
               </el-upload>
               <el-tag
                       v-if="isUnique"
@@ -53,15 +70,15 @@
       <el-table-column
         prop="name"
         label="文件名"
-        width="220">
+        width="240">
           <template #default="scope">
             <el-icon v-if="scope.row['courseWareVO'].useMethod === 'SCAN'" style="color: #337ecc" class="myicon"><Reading /></el-icon>
             <el-icon v-if="scope.row['courseWareVO'].useMethod === 'ATTACHMENT'" style="color: green" class="myicon"><Paperclip /></el-icon>
             {{scope.row["courseWareVO"].name}}
-            <el-tag v-if="scope.row['courseWareVO'].useTime === 'BEFORE_CLASS'" type="success" class="mytag" size="mini"> {{getUseTimeTransition(scope.row["courseWareVO"].useTime)}} </el-tag>
-            <el-tag v-else-if="scope.row['courseWareVO'].useTime === 'IN_CLASS'" type="warning" class="mytag" size="mini"> {{getUseTimeTransition(scope.row["courseWareVO"].useTime)}} </el-tag>
-            <el-tag v-else-if="scope.row['courseWareVO'].useTime === 'AFTER_CLASS'" class="mytag" size="mini"> {{getUseTimeTransition(scope.row["courseWareVO"].useTime)}} </el-tag>
-            <el-tag v-else type="danger" class="mytag" size="mini"> {{getUseTimeTransition(scope.row["courseWareVO"].useTime)}} </el-tag>
+<!--            <el-tag v-if="scope.row['courseWareVO'].useTime === 'BEFORE_CLASS'" type="success" class="mytag" size="mini"> {{getUseTimeTransition(scope.row["courseWareVO"].useTime)}} </el-tag>-->
+<!--            <el-tag v-else-if="scope.row['courseWareVO'].useTime === 'IN_CLASS'" type="warning" class="mytag" size="mini"> {{getUseTimeTransition(scope.row["courseWareVO"].useTime)}} </el-tag>-->
+<!--            <el-tag v-else-if="scope.row['courseWareVO'].useTime === 'AFTER_CLASS'" class="mytag" size="mini"> {{getUseTimeTransition(scope.row["courseWareVO"].useTime)}} </el-tag>-->
+<!--            <el-tag v-else type="danger" class="mytag" size="mini"> {{getUseTimeTransition(scope.row["courseWareVO"].useTime)}} </el-tag>-->
           </template>
       </el-table-column>
       <el-table-column
@@ -69,13 +86,13 @@
         label="文件大小"
         width="100">
           <template #default="scope">
-            <span>{{scope.row["courseWareVO"].size}} KB</span>
+            {{getSizeTransition(scope.row["courseWareVO"].size)}}
           </template>
       </el-table-column>
       <el-table-column
         prop="created_time"
         label="上传时间"
-        width="180">
+        width="160">
           <template #default="scope">
             {{timestampToTime(scope.row["courseWareVO"].createdTime)}}
           </template>
@@ -85,8 +102,16 @@
         label="操作"
         width="220">
           <template #default="scope">
-            <el-button v-if="scope.row['courseWareVO'].useMethod === 'SCAN'"
-                       size="mini" type="primary" @click="handleCheck(scope.row['courseWareVO'].id)" plain style="margin-right: 5px">查看</el-button>
+            <a :href="scope.row['courseWareVO'].fileUrl" v-if="isPdfOrPicture(scope.row['courseWareVO'].name) === 'OTHER'">
+              <el-button v-if="scope.row['courseWareVO'].useMethod === 'SCAN'"
+                       size="mini" type="primary" plain style="margin-right: 5px">预览</el-button>
+            </a>
+            <el-button v-if="scope.row['courseWareVO'].useMethod === 'SCAN' && isPdfOrPicture(scope.row['courseWareVO'].name) === 'PDF'"
+                 @click="handleCheck(scope.row['courseWareVO'].fileUrl)"
+                   size="mini" type="primary" plain style="margin-right: 5px">预览</el-button>
+            <el-button v-if="scope.row['courseWareVO'].useMethod === 'SCAN' && isPdfOrPicture(scope.row['courseWareVO'].name) === 'PICTURE'"
+                 @click="handleCheckPicture(scope.row['courseWareVO'])"
+                 size="mini" type="primary" plain style="margin-right: 5px">预览</el-button>
             <a :href="scope.row['courseWareVO'].fileUrl">
               <el-button size="mini" type="success" plain style="margin-right: 5px">下载</el-button>
             </a>
@@ -95,6 +120,21 @@
           </template>
       </el-table-column>
     </el-table>
+      <el-dialog
+              v-model = "pictureDialogVisible"
+              width = "80%"
+              :before-close = "handleClosePicture"
+      >
+          <img :src="pictureUrl" alt="" style="width: 100%" class="image" />
+<!--          <el-image style="width: 100px; height: 100px" :src="getPictureUrl" />-->
+          <template #footer>
+      <span class="dialog-footer">
+        <el-button type="primary" @click="pictureDialogVisible = false" plain>
+          关闭
+        </el-button>
+      </span>
+          </template>
+      </el-dialog>
   </div>
 </template>
 
@@ -124,7 +164,10 @@ export default {
       fileList: [],
       fileEntryList: [],
       uploadDialogVisible: false,
+      pictureDialogVisible: false,
       isUnique: false,
+      pictureUrl: null,
+      pictureName: null,
       fileNameTags: [],
       tag: null,
       num: 0,
@@ -134,7 +177,7 @@ export default {
     // isCreator(senderId) {
     //   return Number(senderId) === Number(this.$store.state.user.id);
     // },
-},
+  },
   mounted() {
       this.init();
   },
@@ -150,6 +193,26 @@ export default {
     timestampToTime: portal.functions.timestampToTime,
 
     async handleChange(file, fileList) {
+        const fileType = file.name.substring(file.name.indexOf(".") + 1);
+        console.log(this.form.useMethod + " + " + file.name.substring(file.name.indexOf(".") + 1));
+        if (!(fileType === "pdf" || fileType === "ppt" || fileType === "pptx" || fileType === "xls"
+            || fileType === "doc" || fileType === "docx" || fileType === "png" || fileType === "jpeg" || fileType === "jpg")) {
+            this.$message({
+                message: "该文件类型不属于支持的课件类型",
+                type: "error"
+            });
+            return;
+        }
+        // if (this.form.useMethod === "SCAN") {
+        //     if (!(fileType === "pdf" || fileType === "ppt" || fileType === "pptx" || fileType === "xls"
+        //         || fileType === "doc" || fileType === "docx" || fileType === "txt")) {
+        //         this.$message({
+        //             message: "该文件类型不属于支持的可浏览课件类型",
+        //             type: "error"
+        //         });
+        //         return;
+        //     }
+        // }
         if (this.num === 1) {
             this.$message({
                 message: "一次只能选择上传一个课件",
@@ -159,14 +222,10 @@ export default {
         }
         this.file = file;
         this.fileList = fileList;
+        console.log(this.file.raw.type);
         const isNameUnique = (await this.$apis.checkCourseWareNameUnique(this.courseId, this.file.name)).data.data;
         if (!isNameUnique) {
             console.log("notunique");
-            // await ElMessageBox.alert("该课程下已存在同名课件", "提示", {
-            //     confirmButtonText: "重新选择",
-            //     type: "warning",
-            //     center: true,
-            // });
             this.$message({
                 message: "该课程下已存在同名课件",
                 type: "error"
@@ -184,7 +243,7 @@ export default {
                 type: "error"
             });
         } else {
-            const fileUrl = (await this.$apis.uploadCourseWareFile(this.file.name, this.fileList[0].raw)).data.data;
+            const fileUrl = (await this.$apis.uploadCourseWareFile(this.courseId + "/" + this.file.name, this.fileList[0].raw)).data.data;
             this.$message({
                 message: "上传课件成功",
                 type: "success"
@@ -195,7 +254,7 @@ export default {
                 senderId: this.$store.state.user.id,
                 courseId: this.courseId,
                 createdTime: new Date(),
-                useTime: this.form.useTime,
+                useTime: "BEFORE_CLASS",
                 useMethod: this.form.useMethod,
                 fileUrl: fileUrl,
             }).then(async () => {
@@ -203,6 +262,7 @@ export default {
             });
             this.uploadDialogVisible = false;
             this.isUnique = false;
+            this.num = 0;
         }
     },
 
@@ -265,16 +325,28 @@ export default {
             });
     },
 
-    handleCheck(id) {
-        console.log("check" + id);
-        this.$router.push({ name: "courseWare", params: { courseWareId: id, page: "1"} });
+    handleCheck(fileUrl) {
+        console.log("check" + fileUrl);
+        //this.$router.push({ name: "courseWare", params: { courseWareId: id, page: "1"} });
+        window.open(fileUrl);
     },
 
-    // handleExceed(files) {
-    //     console.log(files);
-    //     ElMessage.error("一次只能上传一个文件");
-    //     this.fileList = null;
-    // },
+    handleCheckPicture(courseWareVO) {
+        this.pictureDialogVisible = true;
+        this.pictureUrl = courseWareVO.fileUrl;
+        this.pictureName = courseWareVO.name;
+    },
+
+    isPdfOrPicture(name) {
+        const fileType = name.substring(name.indexOf(".") + 1);
+        if (fileType === "pdf") {
+            return "PDF";
+        } else if (fileType === "png" || fileType === "jpg" || fileType === "jpeg") {
+            return "PICTURE";
+        } else {
+            return "OTHER";
+        }
+    },
 
     getUseTimeTransition(useTime) {
       switch (useTime) {
@@ -289,46 +361,80 @@ export default {
       }
     },
 
-    getUseTimeColor(useTime) {
-      switch (useTime) {
-          case "BEFORE_CLASS":
-              return "green";
-          case "IN_CLASS":
-              return "orange";
-          case "AFTER_CLASS":
-              return "blue";
-          case "FINISH_CLASS":
-              return "red";
-      }
+    getSizeTransition(size) {
+    if (size < 1000000) {
+        return (size * 1.0 / 1000).toFixed(2) + " MB";
+    } else {
+        return (size * 1.0 / 1000000).toFixed(2) + " GB";
+    }
+    },
+
+    handleClosePicture() {
+      ElMessageBox.confirm("Are you sure to close this dialog?")
+          .then(() => {
+              this.pictureDialogVisible = false;
+          });
     },
 
+    Previewf(file) {
+      console.log(file);
+      // window.open(file.response)
+      if (file) {
+          const addTypeArray = file.name.split(".");
+          const addType = addTypeArray[addTypeArray.length - 1];
+          console.log(addType);
+          if (addType === "pdf") {
+              let routeData = this.$router.resolve({
+                  path: "/insurancePdf",
+                  query: { url: file.response, showBack: false },
+              });
+              window.open(routeData.href, "_blank");
+          }
+          //".rar, .zip, .doc, .docx, .xls, .txt, .pdf, .jpg,  .png, .jpeg,"
+          else if (addType === "doc" || addType === "docx" || addType === "xls") {
+              window.open(
+                  "http://view.officeapps.live.com/op/view.aspx?src=" + file.response
+              );
+          } else if (addType === "txt") {
+              window.open(file.response);
+          } else if (["png", "jpg", "jpeg"].includes(addType)) {
+              window.open(file.response);
+          } else if (addType === "rar" || addType === "zip") {
+              this.$message({
+                  message: "该文件类型暂不支持预览",
+                  type: "warning",
+              });
+              return false;
+          }
+      }
+    }
 
-      // handleDownload(id) {
-      //   this.$apis.downloadCourseWare(id, {responseType: "blob"})
-      //       .then((res) => {
-      //       let data = res.data;
-      //       console.log(data);
-      //       if(!data){
-      //           return;
-      //       }
-      //       let fileName = res.headers["content-disposition"].split(";")[1];
-      //       console.log(fileName);
-      //       //构造a标签 通过a标签来下载
-      //       let url = window.URL.createObjectURL(new Blob([data]));
-      //       let a = document.createElement("a");
-      //       a.style.display = "none";
-      //       a.href = url;
-      //       //此处的download是a标签的内容,固定写法,不是后台api接口
-      //       a.setAttribute("download",fileName);
-      //       document.body.appendChild(a);
-      //       //点击下载
-      //       a.click();
-      //       // 下载完成移除元素
-      //       document.body.removeChild(a);
-      //       // 释放掉blob对象
-      //       window.URL.revokeObjectURL(url);
-      //   });
-      // }
+    // handleDownload(id) {
+    //   this.$apis.downloadCourseWare(id, {responseType: "blob"})
+    //       .then((res) => {
+    //       let data = res.data;
+    //       console.log(data);
+    //       if(!data){
+    //           return;
+    //       }
+    //       let fileName = res.headers["content-disposition"].split(";")[1];
+    //       console.log(fileName);
+    //       //构造a标签 通过a标签来下载
+    //       let url = window.URL.createObjectURL(new Blob([data]));
+    //       let a = document.createElement("a");
+    //       a.style.display = "none";
+    //       a.href = url;
+    //       //此处的download是a标签的内容,固定写法,不是后台api接口
+    //       a.setAttribute("download",fileName);
+    //       document.body.appendChild(a);
+    //       //点击下载
+    //       a.click();
+    //       // 下载完成移除元素
+    //       document.body.removeChild(a);
+    //       // 释放掉blob对象
+    //       window.URL.revokeObjectURL(url);
+    //   });
+    // }
 
     // handleDownloadFileIconClick(url) {
     // },

+ 214 - 184
src/views/CourseWarePage/CourseWarePage.vue

@@ -1,201 +1,231 @@
 <template>
 <el-row id="manage-page-body">
-    <el-col :span="3">
-        <el-menu background-color="#f8f9fb" default-active="1" style="position: fixed;"
-                 @select="handleSelect">
-            <el-menu-item index="0">
-                <el-icon>
-                    <Back/>
-                </el-icon>
-                <span style="padding-left: 20px">返回首页</span>
-            </el-menu-item>
-            <el-menu-item index="1">
-                <el-icon>
-                    <Document/>
-                </el-icon>
-                <span style="padding-left: 20px">全部课程</span>
-            </el-menu-item>
-        </el-menu>
-    </el-col>
-    <el-col :span="1"/>
-    <el-col :span="18">
-        <div class="pdf-reader">
-            <pdf-viewer></pdf-viewer>
-            <pointer-canvas ref="pointerCanvas" :no-pointer="!pointer" :no-box="!box"></pointer-canvas>
-            <div class="pointer-actions">
-                <c-button text :theme="pointer ? 'red' : ''" @click="pointer = !pointer">
-                    <i class="el-icon-edit"/> 指针</c-button>
-                <c-button text :left="8" :theme="box ? 'blue' : ''" @click="box = !box">
-                    <i class="el-icon-crop"/> 框选</c-button>
-                <c-button text :left="8" theme="orange" @click="cleanCanvas">
-                    <i class="el-icon-refresh-left"/> 清除</c-button>
-            </div>
-        </div>
-    </el-col>
+<!--    <div class="pdf-reader">-->
+<!--        <el-button type="info" circle @click="this.$router.go(-1)" class="mybuttton"><el-icon class="myicon"><Back /></el-icon></el-button>-->
+<!--        <div class="container">-->
+<!--            <iframe :src="pdfurl" width="100%" height="100%"></iframe>-->
+<!--        </div>-->
+
+<!--        <img :src="imageUrl" alt="" class="image">-->
+<!--        <canvas class="pdf pdf-canvas" id="pdf-canvas"></canvas>-->
+
+<!--        <pdf-viewer></pdf-viewer>-->
+<!--        <pointer-canvas ref="pointerCanvas" :no-pointer="!pointer" :no-box="!box"></pointer-canvas>-->
+<!--        <div class="pointer-actions">-->
+<!--            <c-button text :theme="pointer ? 'red' : ''" @click="pointer = !pointer">-->
+<!--                <i class="el-icon-edit"/> 指针</c-button>-->
+<!--            <c-button text :left="8" :theme="box ? 'blue' : ''" @click="box = !box">-->
+<!--                <i class="el-icon-crop"/> 框选</c-button>-->
+<!--            <c-button text :left="8" theme="orange" @click="cleanCanvas">-->
+<!--                <i class="el-icon-refresh-left"/> 清除</c-button>-->
+<!--        </div>-->
+<!--    </div>-->
 </el-row>
 
 </template>
 
 <script>
-import PdfViewer from "@/components/PDF/PdfViewer";
-import { mapState } from "vuex";
-import {
-    FOCUS_ON_INPUT,
-    NEXT_PAGE,
-    PREVIOUS_PAGE,
-    RESET, SET_CURRENT_PAGE,
-    SET_SRC,
-    TOGGLE_SHOW_DISCUSSION,
-    USE_FOCUS
-} from "@/store/types/pdf-types";
-import PointerCanvas from "@/components/PDF/PointerCanvas";
-import CButton from "@/components/Basic/CButton";
-
-export default {
-    components: {CButton, PointerCanvas, PdfViewer},
-    computed: {
-        ...mapState({
-            src: state => state.pdf.src,
-            focus: state => state.pdf.focus
-        })
-    },
-    data () {
-        return {
-            pointer: false,
-            box: false,
-            slide: {}
-        };
-    },
-    mounted () {
-        console.log("coursewarepage");
-        this.$store.commit(RESET);
-        let { page } = this.$route.params;
-        if (page) {
-            this.$store.commit(SET_CURRENT_PAGE, { currentPage: parseInt(page) });
-        }
-        const _slideId = this.$route.params.slideId;
-        this.$apis.getSlideInfo({ slideId: _slideId }).then(res => {
-            this.slide = res;
-        }).catch(err => {
-            //this.$setErrorMessage(err.response.data.msg)
-        });
-        this.$apis.getSlideUrl({ slideId: _slideId }).then(res => {
-            console.log(this.$apis.getSlideUrl({ slideId: _slideId }));
-            this.$store.commit(SET_SRC, { src: res });
-        }).catch(err => {
-            //this.$setErrorMessage('获取课件链接的过程中:' + err.response.data.msg)
-        });
-        window.addEventListener("keydown", this.handleKey);
-    },
-    beforeUnmount () {
-        window.removeEventListener("keydown", this.handleKey);
-    },
-    methods: {
-        handleSelect(index) {
-            if (index === "0") {
-                this.$router.push("portal");
-            }
-            if (index === "1") {
-                document.getElementById("app").scrollIntoView({behavior: "smooth"});
-            }
-        },
-        handleKey (e) {
-            if (e.key === "Enter") {
-                !this.showDiscussion && this.$store.commit(TOGGLE_SHOW_DISCUSSION);
-                !this.focus && this.$store.commit(FOCUS_ON_INPUT);
-                return;
-            }
-            if (e.key === "Escape") {
-                if (this.focus) {
-                    this.$store.commit(USE_FOCUS);
-                } else {
-                    this.$store.commit(TOGGLE_SHOW_DISCUSSION);
-                }
-                return;
-            }
-            if (!this.showDiscussion || !this.focus) {
-                switch (e.key) {
-                    case "ArrowDown":
-                    case "ArrowRight":
-                    case "s":
-                    case "d":
-                    case " ":
-                        this.$store.commit(NEXT_PAGE);
-                        break;
-                    case "ArrowUp":
-                    case "ArrowLeft":
-                    case "w":
-                    case "a":
-                        this.$store.commit(PREVIOUS_PAGE);
-                        break;
-                    case "c":
-                        this.cleanCanvas();
-                        break;
-                    case "q":
-                    case "z":
-                        this.$refs.pointerCanvas.undo();
-                        break;
-                    case "e":
-                    case "y":
-                        this.$refs.pointerCanvas.redo();
-                        break;
-                    case "[":
-                    case "b":
-                        this.box = !this.box;
-                        break;
-                    case "p":
-                    case "v":
-                        this.pointer = !this.pointer;
-                        break;
-                }
-            }
-        },
-        cleanCanvas () {
-            this.$refs.pointerCanvas.cleanCanvas();
-        }
-    },
-};
+// import PdfViewer from "@/components/PDF/PdfViewer";
+// import { mapState } from "vuex";
+// import {
+//     FOCUS_ON_INPUT,
+//     NEXT_PAGE,
+//     PREVIOUS_PAGE,
+//     RESET, SET_CURRENT_PAGE,
+//     SET_SRC,
+//     TOGGLE_SHOW_DISCUSSION,
+//     USE_FOCUS
+// } from "@/store/types/pdf-types";
+// import PointerCanvas from "@/components/PDF/PointerCanvas";
+// import CButton from "@/components/Basic/CButton";
+// import { SET_TOTAL_PAGES } from "@/store/types/pdf-types";
+// import FadeTransition from "@/animations/FadeTransition";
+//
+// const pdfJS = require("pdfjs-dist");
+// pdfJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry");
+//
+// export default {
+//     components: {
+//      //   CButton,
+//      //   PointerCanvas,
+//     //   PdfViewer
+//     },
+//     computed: {
+//         ...mapState({
+//             src: state => state.pdf.src,
+//             focus: state => state.pdf.focus,
+//             currentPage: state => state.pdf.currentPage,
+//             screenShot: state => state.pdf.screenShot,
+//         }),
+//         imageUrl() {
+//             //return "https://seec-portal.oss-cn-hangzhou.aliyuncs.com/1/1bc3ed2e423eec0.jpg" + "?t=" + Date.now().valueOf();
+//             return "https://seec-portal.oss-cn-hangzhou.aliyuncs.com/1/8610161.jpg";
+//         },
+//     },
+//     data () {
+//         return {
+//             pdfurl:"",
+//             courseWare: {}
+//         };
+//     },
+//     watch: {
+//         currentPage() {
+//             this.showPage();
+//         }
+//     },
+//     async mounted() {
+//         console.log("coursewarepage");
+//         console.log(this.$route.params.courseWareId);
+//         this.$store.commit(RESET);
+//         let {page} = this.$route.params.page;
+//         if (page) {
+//             this.$store.commit(SET_CURRENT_PAGE, {currentPage: parseInt(page)});
+//         }
+//         this.courseWare = (await this.$apis.getSlideInfo(this.$route.params.courseWareId)).data.data;
+//         this.pdfurl = (await this.$apis.getSlideUrl(this.$route.params.courseWareId)).data.data;
+//         this.$store.commit(SET_SRC, {src: this.pdfurl});
+//         window.addEventListener("keydown", this.handleKey);
+//
+//         this._canvas = document.getElementById("pdf-canvas");
+//         this._context = this._canvas.getContext("2d");
+//
+//         this.load(this.pdfurl);
+//     },
+//     beforeUnmount () {
+//         window.removeEventListener("keydown", this.handleKey);
+//     },
+//     methods: {
+//         handleKey (e) {
+//             if (e.key === "Enter") {
+//                 !this.showDiscussion && this.$store.commit(TOGGLE_SHOW_DISCUSSION);
+//                 !this.focus && this.$store.commit(FOCUS_ON_INPUT);
+//                 return;
+//             }
+//             if (e.key === "Escape") {
+//                 if (this.focus) {
+//                     this.$store.commit(USE_FOCUS);
+//                 } else {
+//                     this.$store.commit(TOGGLE_SHOW_DISCUSSION);
+//                 }
+//                 return;
+//             }
+//             if (!this.showDiscussion || !this.focus) {
+//                 switch (e.key) {
+//                     case "ArrowDown":
+//                     case "ArrowRight":
+//                     case "s":
+//                     case "d":
+//                     case " ":
+//                         this.$store.commit(NEXT_PAGE);
+//                         break;
+//                     case "ArrowUp":
+//                     case "ArrowLeft":
+//                     case "w":
+//                     case "a":
+//                         this.$store.commit(PREVIOUS_PAGE);
+//                         break;
+//                     case "c":
+//                         this.cleanCanvas();
+//                         break;
+//                     case "q":
+//                     case "z":
+//                         this.$refs.pointerCanvas.undo();
+//                         break;
+//                     case "e":
+//                     case "y":
+//                         this.$refs.pointerCanvas.redo();
+//                         break;
+//                     case "[":
+//                     case "b":
+//                         this.box = !this.box;
+//                         break;
+//                     case "p":
+//                     case "v":
+//                         this.pointer = !this.pointer;
+//                         break;
+//                 }
+//             }
+//         },
+//         load(src) {
+//             console.log("load:" + src.substring(48));
+//             const loadingTask = pdfJS.getDocument("/api/slide" + src.substring(48));
+//             loadingTask.promise.then(pdf => {
+//                 this.loading = false;
+//                 this._pdf = pdf;
+//                 this.$store.commit(SET_TOTAL_PAGES, {totalPages: pdf.numPages});
+//                 this.showPage();
+//             });
+//         },
+//         showPage() {
+//             this._pdf && this._pdf.getPage(this.currentPage || 1).then(page => {
+//                 const scale = 2.5;
+//                 const viewport = page.getViewport({scale: scale});
+//
+//                 this._canvas.height = viewport.height;
+//                 this._canvas.width = viewport.width;
+//
+//                 const renderContext = {
+//                     canvasContext: this._context,
+//                     viewport: viewport
+//                 };
+//                 page.render(renderContext);
+//             }).catch(() => {
+//                 console.log("PDF 当前页解析错误");
+//                 //this.$setInfoMessage('PDF 当前页解析错误')
+//             });
+//         }
+//     },
+// };
 
 
 </script>
 
-<style lang="scss" scoped>
-    .pdf-reader {
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        min-height: 100vh;
-    }
+<!--<style lang="scss" scoped>-->
+<!--    .pdf-reader {-->
+<!--        display: flex;-->
+<!--        align-items: center;-->
+<!--        justify-content: center;-->
+<!--        min-height: 100vh;-->
+<!--    }-->
+
+<!--    .mybuttton {-->
+<!--        position: absolute;-->
+<!--        left: 16px;-->
+<!--        top: 16px;-->
+<!--        background-color: rgba(160, 180, 200, .1);-->
+<!--        color: #7a8a9a;-->
+<!--        align-items: center;-->
+<!--        justify-content: center;-->
+<!--        padding: 8px;-->
+<!--        width: 44px;-->
+<!--        height: 44px;-->
+<!--        &:hover {-->
+<!--            background-color: rgba(218, 234, 250, 0.67);-->
+<!--        }-->
+<!--    }-->
+
+<!--    .myicon {-->
+<!--        font-size: 25px;-->
+<!--    }-->
 
-    .icon-button {
-        z-index: 2;
-        position: absolute;
-        left: 16px;
-        top: 16px;
-        background-color: rgba(218, 234, 250, 0.4);
-        backdrop-filter: saturate(150%) blur(20px);
+<!--    .show-discussion, .hide-discussion {-->
+<!--        transition: .2s;-->
+<!--    }-->
 
-        &:hover {
-            background-color: rgba(218, 234, 250, 0.67);
-        }
-    }
+<!--    .hide-discussion {-->
+<!--        transform: translateY(100%);-->
+<!--        opacity: 0;-->
+<!--    }-->
 
-    .show-discussion, .hide-discussion {
-        transition: .2s;
-    }
+<!--    .pointer-actions {-->
+<!--        position: fixed;-->
+<!--        left: 6px;-->
+<!--        bottom: 8px;-->
 
-    .hide-discussion {
-        transform: translateY(100%);
-        opacity: 0;
-    }
+<!--        .c-button {-->
+<!--            background-color: white;-->
+<!--        }-->
+<!--    }-->
+<!--</style>-->
 
-    .pointer-actions {
-        position: fixed;
-        left: 6px;
-        bottom: 8px;
 
-        .c-button {
-            background-color: white;
-        }
-    }
-</style>

+ 9 - 9
vue.config.js

@@ -5,12 +5,12 @@ module.exports = {
   publicPath: process.env.BASE_URL,
   chainWebpack: config => {
     config
-      .plugin("html")
-      .tap(args => {
-        // NOTE 确定系统正式名称
-        args[0].title = "SEEC门户系统";
-        return args;
-      });
+        .plugin("html")
+        .tap(args => {
+          // NOTE 确定系统正式名称
+          args[0].title = "SEEC门户系统";
+          return args;
+        });
   },
   css: {
     loaderOptions: {
@@ -33,8 +33,8 @@ module.exports = {
       port: 8000,
     },
     plugins: process.env.NODE_ENV === "development" ?
-      [
-        new WebpackBar(),
-      ] : []
+        [
+          new WebpackBar(),
+        ] : []
   },
 };

文件差异内容过多而无法显示
+ 412 - 379
yarn.lock


部分文件因为文件数量过多而无法显示