浏览代码

[v1.2.20220413] CC11 選頁面插入PDF 選單 初步流程功能

Louise Lin 3 年之前
父节点
当前提交
aa7db694b1

+ 6 - 0
HiTeachCC/ClientApp/src/assets/css/Board.less

@@ -215,6 +215,12 @@
         font-weight: bold;
       }
     }
+    label.hicard-btn {
+      
+      input[type='file'] {
+        display: none;
+      }
+    }
   }
 }
 

+ 290 - 0
HiTeachCC/ClientApp/src/components/PDFInsert.vue

@@ -0,0 +1,290 @@
+<template>
+  <div class="pdfinsert">
+    <div class="pdfinsert-card">
+      <p class="pdfinsert-title">{{ '加入PDF' }}</p>
+
+      <div class="divide-wrap">
+        <div class="divide-line" />
+      </div>
+      <div class="pdfinsert-flex">
+        <div class="left-part">
+          <p>{{ currentPDFInsertFile.name }}</p>
+          <span class="left-part-title">從 </span>
+          <span class="left-part-select"
+            ><Select v-model="fromIndex" size="small">
+              <Option v-for="item in localPdfPages" :value="item" :key="'from' + item">{{ item }}</Option>
+            </Select></span
+          >
+
+          <span class="left-part-title">到</span>
+          <span class="left-part-select"
+            ><Select v-model="endIndex" size="small">
+              <Option v-for="item in localPdfPages" :value="item" :key="'End' + item" v-show="item >= fromIndex">{{ item }}</Option>
+            </Select></span
+          >
+          <p>加到目前課堂文件 第{{ this.$store.state.carouselSlide }}頁 之後</p>
+          <div class="pdfinsertbtn-group">
+            <div class="pdfinsert-btn" @click="insertPDF()">{{ $t("board['確定']") }}</div>
+            <div class="pdfinsert-btn" @click="closePDFInsert()">{{ $t("board['取消']") }}</div>
+          </div>
+        </div>
+        <div id="pdf-content" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import PDFObject from 'pdfobject' //PDF 呼叫內建預覽
+import PDFJS from 'pdfjs-dist' //PDF 渲染圖片用
+const de = require('@/utils/lib1.js')
+import enc from '@/utils/enc.js'
+
+export default {
+  name: 'PDFInsert',
+  props: ['currentPDFInsertFile'],
+  mounted() {},
+  created() {
+    //this.pdf(1)
+    this.blobinfo = JSON.parse(enc.decrypt(sessionStorage.getItem('blobConnect'), de.text))
+    console.log(this.blobinfo, 'blobsdsdsd')
+  },
+  data() {
+    return {
+      fromIndex: 1,
+      endIndex: 1,
+      localPdfPages: 0,
+      localPdfURL: '',
+      blobinfo: ''
+    }
+  },
+  watch: {
+    fromIndex(value) {
+      if (value > this.endIndex) {
+        this.endIndex = value
+      }
+    },
+    currentPDFInsertFile(value) {
+      if (value != '') {
+        // console.log(window.URL.createObjectURL(value))
+        let options = {
+          height: window.innerHeight * 0.4 + 'px',
+          width: window.innerWidth * 0.25 + 'px',
+          pdfOpenParams: {
+            navpanes: 0,
+            statusbar: 0,
+            toolbar: 1,
+            view: 'FitH',
+            pagemode: 'thumbs',
+            page: 'anchor'
+          }
+        }
+        this.localPdfURL = window.URL.createObjectURL(value)
+        let that = this
+        PDFObject.embed(this.localPdfURL, '#pdf-content', options)
+        PDFJS.disableWorker = true // due to CORS
+        PDFJS.getDocument(this.localPdfURL).then(function(pdf) {
+          that.localPdfPages = pdf.numPages
+          that.endIndex = pdf.numPages
+        })
+      }
+    }
+  },
+
+  methods: {
+    closePDFInsert() {
+      this.$store.state.showPDFInsert = false
+      this.fromIndex = 1
+    },
+    //send Img需先將圖片轉換成file
+    dataURLtoFile(dataurl, filename) {
+      const arr = dataurl.split(',')
+      const mime = arr[0].match(/:(.*?);/)[1]
+      const bstr = atob(arr[1])
+      let n = bstr.length
+      const u8arr = new Uint8Array(n)
+      while (n--) {
+        u8arr[n] = bstr.charCodeAt(n)
+      }
+      return new File([u8arr], filename, { type: mime })
+    },
+    insertPDF() {
+      //先翻頁
+      this.$parent.switchoverpdf(Number(this.$store.state.carouselSlide))
+      let that = this
+      PDFJS.disableWorker = true // due to CORS
+      PDFJS.getDocument(this.localPdfURL).then(function(pdf) {
+        let pages = []
+        let heights = []
+        let height = 0
+        let currentPage = that.fromIndex
+        let scale = 1.5
+        getPage()
+
+        function getPage() {
+          pdf.getPage(currentPage).then(function(page) {
+            let viewport = page.getViewport(scale)
+            let canvas = document.createElement('canvas')
+            let ctx = canvas.getContext('2d')
+            let renderContext = { canvasContext: ctx, viewport: viewport }
+            canvas.height = viewport.height
+            canvas.width = viewport.width
+
+            page.render(renderContext).then(async function() {
+              that.$store.state.isRenderingPDFNow = true
+
+              pages.push(ctx.getImageData(0, 0, canvas.width, canvas.height))
+              heights.push(height)
+              height += canvas.height
+
+              let pageID = that.$parent.genID()
+              let imgFile = await that.dataURLtoFile(canvas.toDataURL('images/jpeg', 0.9), `${pageID}.jpg`)
+
+              let currentIndex = that.$store.state.carouselSlide + currentPage - that.fromIndex
+              let idTypes = {
+                pageid: pageID,
+                pagetype: 'Quiz',
+                page: currentIndex
+              }
+              //序列化資料先補一個空的
+              that.$parent.saveArr.splice(currentIndex, 0, '')
+
+              //关于新加一页 数据修改
+              let originalData = JSON.parse(sessionStorage.getItem('msgBody'))
+              if (originalData) {
+                for (let i = 0; i < originalData.length; i++) {
+                  if (currentIndex + 1 <= originalData[i].page) {
+                    originalData[i].page = originalData[i].page + 1
+                  }
+                }
+              }
+              sessionStorage.setItem('msgBody', JSON.stringify(originalData))
+
+              await that.$store.state.imgArr.idArr.splice(currentIndex, 0, idTypes)
+              await that.$store.state.pdfOringinalImgsIdArr.splice(currentIndex, 0, idTypes) //存放原圖id
+              await that.$parent.uploadResourceFile(imgFile, 'ObjSrcImage').then(async res => {
+                // console.log(res, '上传Resource成功后的返回')
+                await that.$store.state.imgArr.splice(currentIndex, 0, res.url + '?' + that.blobinfo.sas_read)
+                await that.$store.state.pdfOringinalImgs.splice(currentIndex, 0, res.url + '?' + that.blobinfo.sas_read) //存放原圖連結
+              })
+              //pdf原圖連結備份在本地
+              await sessionStorage.setItem('pdfOringinalImgsIdArr', JSON.stringify(that.$store.state.pdfOringinalImgsIdArr))
+              await sessionStorage.setItem('pdfOringinalImgs', JSON.stringify(that.$store.state.pdfOringinalImgs))
+
+              if (currentPage <= that.endIndex - 1) {
+                currentPage++
+                getPage()
+              } else {
+                that.$store.state.totalpage = that.$store.state.imgArr.length
+
+                if (currentPage > that.endIndex - 1) {
+                  that.$store.state.isRenderingPDFNow = false
+                  that.closePDFInsert()
+                }
+              }
+            })
+          })
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="less">
+@import '../assets/css/color.less';
+.ivu-select-item {
+  width: 100%;
+}
+.pdfinsert {
+  position: absolute;
+  display: block;
+  width: 100%;
+  background-color: rgba(0, 0, 0, 0.8);
+  // border-radius: 5px;
+  color: black;
+  height: 100%;
+  z-index: 1002;
+  .pdfinsert-card {
+    top: 5%;
+    transition: 0.5s;
+    position: absolute;
+    left: 50%;
+    transform: translateX(-50%);
+    background-color: #ededed;
+    font-weight: bolder;
+    padding: 20px 20px 10px 20px;
+    border-radius: 5px;
+    box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
+    z-index: 102;
+    text-align: center;
+    .pdfinsert-title {
+      font-size: 20px;
+      color: #3d3d3d;
+    }
+    .textinput {
+      border-radius: 5px;
+      border: 2px solid @main-color;
+      color: black;
+      margin-top: 10px;
+      width: 100%;
+      min-height: 100px;
+      font-size: 22px;
+      padding: 10px;
+    }
+    .divide-wrap {
+      background-color: #ededed;
+      padding: 20px 0px;
+      .divide-line {
+        background-color: #ededed;
+        border-bottom: 0.5px solid rgb(192, 192, 192);
+      }
+    }
+    .pdfinsert-flex {
+      display: flex;
+      .left-part {
+        flex: 1;
+        min-width: 200px;
+        margin-right: 20px;
+        position: relative;
+        line-height: 30px;
+        .left-part-title,
+        .left-part-select {
+          display: inline-block;
+          margin: 0px 5px;
+        }
+      }
+
+      #pdf-content {
+        flex: 1;
+        width: 100%;
+        height: auto;
+        position: relative;
+        background: #999;
+      }
+    }
+
+    .pdfinsertbtn-group {
+      display: flex;
+      align-items: center;
+      position: absolute;
+      bottom: 10px;
+      width: 100%;
+      .pdfinsert-btn {
+        cursor: pointer;
+        flex: 1;
+        white-space: nowrap;
+        padding: 5px 10px;
+        margin: 10px 5px;
+        border-radius: 5px;
+        text-align: center;
+        background-color: #d8d8d8;
+        &:first-child {
+          color: white;
+          background-color: #079dda;
+        }
+      }
+    }
+  }
+}
+</style>

+ 2 - 1
HiTeachCC/ClientApp/src/store/index.js

@@ -149,7 +149,8 @@ export default new Vuex.Store({
     isShowAskCopyPage:false,
     isShowAskCopyPageIRSName:'',
     showtextInuptCard:false,
-    version: 'v1.1.20220413'
+    showPDFInsert:false,
+    version: 'v1.2.20220413'
   },
   mutations: {
   },

+ 24 - 2
HiTeachCC/ClientApp/src/views/Board.vue

@@ -1,5 +1,7 @@
 <template>
   <div class="board">
+    <!---->
+    <PDFInsert  v-show='this.$store.state.showPDFInsert' :currentPDFInsertFile='currentPDFInsertFile' />
     <!--文字輸入框介面-->
     <div class="textinput-view" v-show="this.$store.state.showtextInuptCard">
       <div class="textinput-card">
@@ -161,6 +163,14 @@
             <p>{{ $t("board['匯出PDF']") }}</p>
             <!-- <q-btn label="退出教室" size="15px" style="background: #FF0080;color: white" /> -->
           </div>
+          <label class="hicard-btn" >
+           
+            <i class="far fa-file-pdf"  style='padding:5px;font-size:40px' />
+            <p>{{ '插入PDF' }}</p>
+            <input @click="resetpdfUploader()"  ref="pdfUploader" type="file" id="addpdfFile" accept=".pdf" @change="openPDFInsert" />
+         
+           
+          </label>
           <div class="closebtn" @click="closeHi"><img src="@/statics/iconsvg/interaction/Close.svg" class="q-icon" /></div>
         </div>
       </q-card>
@@ -331,6 +341,8 @@ import BaseTimer from '../components/Tools/BaseTimer.vue'
 import BasePick from '../components/Tools/BasePick.vue'
 import TurnTable from '../components/Tools/turnTable.vue'
 import TextPicker from '../components/ColorPop/TextPicker.vue'
+import PDFInsert from '../components/PDFInsert.vue'
+
 import PDFJS from 'pdfjs-dist'
 import RenderContent from '../assets/test/test.json'
 import { jsPDF } from 'jspdf'
@@ -363,7 +375,8 @@ export default {
     BasePick,
     TurnTable,
     QRCode,
-    TextPicker
+    TextPicker,
+    PDFInsert
   },
   data() {
     return {
@@ -577,10 +590,19 @@ export default {
       limitClientHint: false,
       isShowAskPasteWhichPage: false, //詢問要貼本頁或新增到一頁空白頁貼回,
       showScreenNote: true,
-      currentAddTextValue: '' //文字框加入
+      currentAddTextValue: '', //文字框加入
+      currentPDFInsertFile:''
     }
   },
   methods: {
+    resetpdfUploader(){
+      this.$refs.pdfUploader.value = ''
+      this.currentPDFInsertFile=''
+    },
+    openPDFInsert(e){
+       this.$store.state.showPDFInsert=true
+       this.currentPDFInsertFile=e.target.files[0]
+    },
     addTextBox() {
       this.$store.state.showtextInuptCard = false
       document.body.classList.remove('cursor-fdj')

+ 5 - 0
package-lock.json

@@ -117,6 +117,11 @@
       "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.10.377.tgz",
       "integrity": "sha512-i0jRShtvgfsVQUNCoFYH4SVhPO3U0yhtiFLfZ0RR0B+68N+Vnwq+8B3cjWjLEwWGh8wg1XQ/sYMYKUlHn/Qpsw=="
     },
+    "pdfobject": {
+      "version": "2.2.7",
+      "resolved": "https://registry.npmjs.org/pdfobject/-/pdfobject-2.2.7.tgz",
+      "integrity": "sha512-9ptX0XNCtpYz0hNWz6j/1O4rvJkcPR2rct3UDBhs8ZEosOO67dCEAu4VpBvVJ64SMh8Mrn9pWWODnyLjgFQYgg=="
+    },
     "qr-code-styling": {
       "version": "1.6.0-rc.1",
       "resolved": "https://registry.npmjs.org/qr-code-styling/-/qr-code-styling-1.6.0-rc.1.tgz",