Newer
Older
VueSharedPrinting / src / views / selectFile.vue
hanfei on 29 Jan 2024 23 KB han
<template>
  <!--  选取资料-->
  <div class="selectFile">
    <navbar :name="name" />
    <!--    U盘打印-->
    <div class="box flex-center" v-if="name == 'U盘打印'">
      <div class="tip" style="width: 20rem;">
        <div class="title">温馨提示</div>
        <div class="content">请在右侧文件浏览区,找到待印资料文件存放的目录(文件夹),然后点选您需要打印的文件,之后按下“确认资料”按钮来提交资料。</div>
      </div>
      <div class="file">
        <div class="main" style="width: 50rem;">
          <div v-for="(item, index) in usbList" v-bind:key="index" class="li flex-start" @click="onChange(index, 'usbList',!item.sta)">
            <input type="checkbox" v-model="item.sta">
            <div class="name flex-start">{{ item.name }}</div>
          </div>
        </div>
        <div class="flex-between but">
          <div class="btn flex-center" @click="skip('argument', name)">确认资料</div>
        </div>
      </div>
    </div>
    <!--    扫描打印-->
    <div class="box flex-center" v-if="name == '扫描打印'">
      <div class="file2">
        <div class="title flex-between">已完成扫描的版面 <span :class="[{ act: smfyIndex == -1 }]" @click="onChange(-1, 'smfyIndex')">预览</span></div>
        <div class="main flex-between">
          <div class="smfyData">
            <div v-for="(item, index) in imgList" v-bind:key="index" :class="['flex-center', { act: smfyIndex == index }]" @click="onChange(index, 'smfyIndex')">
              <div class="name">{{ index + 1 }}</div>
              <span @click="onCancel(index, 'imgList')">删除</span>
            </div>
          </div>
          <img v-show="smfyIndex!=-1" :src="imgList[smfyIndex]" alt="" style="width: 25rem; height: 100%" />
          <img v-show="smfyIndex==-1" id="myCanvas" style="width: 25rem; height: 100%" />
        </div>
      </div>
      <div class="tip tip2">
        <div class="title">温馨提示</div>
        <div class="content">每次扫描前,可以按“预览”按钮来实时查看版面效果。已经扫描好的 页面显示在左边的列表中,您可以点击列表中的缩略图进行浏览核对, 不满意的页面可以点旁边的“删除”进行移除并重新扫描。如果有文件需要继续扫描,请按要求放置好资料后,按“继续扫描”。按照刚才的方法,重复扫描过程,直到完成了所有需要的页面。核对无误后,可以按“完成扫描”结束资料扫描工作。
        </div>
        <div class="flex-between but">
          <div class="btn flex-center" @click="paiz()">{{ imgList.length>0?'继续扫描':'开始扫描' }}</div>
          <div class="btn flex-center" @click="skip('argument', name)">完成扫描</div>
        </div>
      </div>
    </div>
    <!--    身份证打印-->
    <div class="box flex-center" v-if="name == '身份证打印'">
      <div class="file2 file3" style="margin-right: 20rem">
        <div class="title">请核对您的信息</div>
        <div class="card" ref="captureArea" v-if="cardInfo!=''">
          <div class="card-box2">
            <img src="../assets/card2.png" alt="身份证正面" />
            <div class="diamond">
              <div class="name">{{ cardInfo.name }}</div>
              <div class="gender flex-start">{{ cardInfo.xbmc }} <div>{{ cardInfo.mzmc }}</div></div>
              <div class="birth flex-start">
                <span>{{ cardInfo.birthday | joinYear }}</span>
                <div>{{ cardInfo.birthday | joinMonth }}</div>
                <div>{{ cardInfo.birthday | joinDay }}</div>
              </div>
              <div class="addr">{{ cardInfo.address }}</div>
              <div class="idNum">{{ cardInfo.idNum }}</div>
              <div class="avatar"><img :src="photo" alt=""></div>
            </div>
          </div>
          <div class="card-box2">
            <img src="../assets/card1.png" alt="身份证反面" />
            <div class="diamond diamond2">
              <div class="sign">{{ cardInfo.issueOrg }}</div>
              <div class="date">{{ cardInfo.effectDate | joinRq}} - {{ cardInfo.expireDate | joinRq}}</div>
            </div>
          </div>
          <div class="card-box" v-show="false">
            <img src="../assets/card2.png" alt="身份证反面" />
            <div class="card-name">{{ cardInfo.name }}</div>
            <div class="card-gender">
              {{ cardInfo.xbmc }}<span>{{ cardInfo.mzmc }}</span>
            </div>
            <div class="card-birth">
              {{ cardInfo.birthday | joinYear }}
              <span class="month">{{ cardInfo.birthday | joinMonth }}</span>
              <span class="day">{{ cardInfo.birthday | joinDay }}</span>
            </div>
            <div class="card-addr">
              {{ cardInfo.address }}
            </div>
            <div class="card-id">{{ cardInfo.idNum }}</div>
            <div class="card-avatar">
<!--              <img :src="'data:image/png;base64,'+cardInfo.photo" alt="" />-->
              <img :src="photo" alt="">
            </div>
          </div>
          <div class="card-box" v-show="false">
            <img src="../assets/card1.png"/>
            <div class="card-sign">{{ cardInfo.issueOrg  }}</div>
            <div class="card-date">
              {{ cardInfo.effectDate | joinRq}} - {{ cardInfo.expireDate | joinRq}}
            </div>
          </div>
        </div>
      </div>
      <div class="tip">
        <div class="title">温馨提示</div>
        <div class="content">身份证件信息读取成功,请您核对个人信息无误后,按“信息无误,继续”按钮进行后续操作。此时您可以取回您的身份证卡片并妥善保存。</div>
        <div class="btn flex-center" @click="skip('argument', name)">信息无误,继续</div>
      </div>
    </div>
  </div>
</template>

<script>
import navbar from "@/components/nav";
import html2canvas from "html2canvas";
import {upload2Pdf, changeIdPhotoBgc, image2Pdf} from '@/api/resultApi'
import {readUsb, readFile, readCard} from '@/api/bdResultApi'
import parseCardWzxx from "../utils/mz";
export default {
  name: 'selectFile',
  components: {
    navbar
  },
  provide() {
    return {
      title: this.tit,
      type: this.name
    }
  },
  filters: {
    joinYear(val) {
      return val.substring(0, 4)
    },
    joinMonth(val) {
      if(val.substring(4, 5)==0) {
        return val.substring(5, 6)
      }
      return val.substring(4, 6)
    },
    joinDay(val) {
      if(val.substring(6, 7)==0) {
        return val.substring(7, 8)
      }
      return val.substring(6, 8)
    },
    joinRq(val) {
      return val.substring(0, 4)+'.'+val.substring(4, 6)+'.'+val.substring(6, 8)
    }
  },
  data() {
    return {
      isChecked: true,
      tit: this.cite.modeName == 'U盘打印' ? '资料选取提交' : '资料扫描提交',
      name: this.cite.modeName,
      path: this.cite.inWebURL,
      socket: '',
      imgList: [],
      smfyIndex: -1,
      photo: '',

      UpFile: [],

      cardInfo: '',

      usbList: [],
      usbTime: ''
    };
  },
  methods: {
    async uploadImg(data, sta) {
      let _this = this
      for (let i = 0; i < data.length; i++) {
        let formData = new FormData()
        let file = data[i]
        if (sta) {
          // let dataURL = file.toDataURL('image/png')
          let name = i + '.png'
          file = _this.dataURLtoFile(file, name)
        }
        formData.append('file', file) // 使用数组语法添加多个文件
        if(this.cite.modeName=='身份证打印') {
          let res = await image2Pdf(formData)
          _this.cite.selectedFile.push(res)
          // console.log('打印文件', this.cite.selectedFile, res)
        }else{
          let res = await upload2Pdf(formData)
          _this.cite.selectedFile.push(res)
          // console.log('打印文件', this.cite.selectedFile, res)
        }
      }

    },
    async skip(href, name) {
      if (this.usbList.length > 0) {
        // 保存选中的U盘文件
        // await this.uploadImg(this.UpFile, false)
        await this.dealFile()
      } else if (this.imgList.length > 0) {
        // 保存高拍仪图片
        await this.uploadImg(this.imgList, true)
      } else if (this.cardInfo) {
        // 保存身份证图片
        await this.captureAndDownload()
      } else {
        this.cite.state = {
          name: '请选择文件打印!',
          sta: true
        }
        return
      }
      this.$router.push({
        name: href,
        params: {
          name: name
        }
      })
    },
    async captureAndDownload() {
      const captureArea = this.$refs.captureArea

      // 使用 html2canvas 将区域内容生成为图片
      console.log('html2canvas',window.devicePixelRatio)
      let sca = 0.9
      if(window.devicePixelRatio>=1) {
        sca = 0.7
      }
      const canvas = await html2canvas(captureArea, {scale: sca})

      // 将 canvas 转为图片 URL
      const dataURL = canvas.toDataURL('image/png')
      const name = 'sfz.png'
      const file = this.dataURLtoFile(dataURL, name)
      this.uploadImg([file], false)
    },
    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})
    },
    onChange(index, name, sta) {
      if (name == 'usbList') {
        this[name][index].sta = sta
      } else {
        this[name] = index
      }
    },
    onCancel(index, name) {
      if (name == 'imgList') {
        this.smfyIndex = -1
      }
      this[name].splice(index, 1)
    },
    paiz() {
      this.socket.send('Capture@2')
    },
    init: function () {
      if (typeof WebSocket === 'undefined') {
        alert('您的浏览器不支持socket')
      } else {
        // 实例化socket
        this.socket = new WebSocket(this.path)
        // 监听socket连接
        this.socket.onopen = this.open
        // 监听socket错误信息
        this.socket.onerror = this.error
        // 监听socket消息
        this.socket.onmessage = this.getMessage
      }
    },
    open: function () {
      // console.log("socket连接成功")
      this.socket.send('OpenIdCardEx@0')
      this.socket.send('OpenDevice@1')
      this.socket.send('SetResolution@2@2592@1944')
      this.socket.send('OpenVideo')
      this.socket.send('RotateRight')
      this.socket.send('Deskew')
    },
    error: function () {
      console.log('连接错误')
    },
    getMessage: function (msg) {
      if (typeof msg.data == 'string') {
        if (msg.data.indexOf('GetDevCount') == 0) {
          let s = msg.data.substring(12)
          if ('1' == s || '2' == s) {
            //如果是双摄像头 那就需要判断 s = 2;表示当前是连接了2个设备
            alert('检测到已经连接上摄像头')
          }
        } else if (msg.data.indexOf('Capture') == 0) {
          let s = msg.data.substring(8)
          if (s) {
            this.imgList.push('data:image/jpeg;base64,' + s)
          }
        } else if (msg.data.indexOf('MoveDetectEvent') == 0) {
          this.socket.send('Capture@2')
        } else if (msg.data.indexOf('IdCardEvent') == 0) {
          this.socket.send('UnFaceDetect')
        } else if (msg.data.indexOf('ReadIdCard') == 0) {
          let s = msg.data.substring(11)
          if ('1' == s) {
            this.socket.send('GetIdCardResult@||')
            this.socket.send('GetIdCardImage@2')
          }
        } else if (msg.data.indexOf('GetIdCardResult') == 0) {
          let s = msg.data.substring(16)

          let info = document.getElementById('info')
          info.value = s
        } else if (msg.data.indexOf('GetBarcode') == 0) {
          // alert(msg.data);
          let s = msg.data.substring(11)

          let info = document.getElementById('info')
          info.value = s
        } else if (msg.data.indexOf('GetIdCardImage') == 0) {
          let s = msg.data.substring(15)
          let arr = s.split('#')
          let faceImg = arr[0]

          let myimg = document.getElementById('myCanvas3')
          myimg.src = 'data:image/jpeg;base64,' + faceImg
        } else if (msg.data.indexOf('GetBase64') == 0) {
          let s = msg.data.substring(10)

          let myimg = document.getElementById('myCanvas2')
          myimg.src = 'data:image/jpeg;base64,' + s
          alert(s)
        } else if (msg.data.indexOf('GetRecognitionFromFileName') == 0) {
          let s = msg.data.substring(27)

          let info = document.getElementById('info')
          info.value = s
        } else if (msg.data.indexOf('GetOcrFromFileName') == 0) {
          let s = msg.data.substring(19)

          let info = document.getElementById('info')
          info.value = s
        } else if (msg.data.indexOf('GetDogSN') == 0) {
          let s = msg.data.substring(11)

          let info = document.getElementById('info')
          info.value = s
        }
      } else {
        let reader = new FileReader()

        reader.onload = function (msg) {
          if (msg.target.readyState == FileReader.DONE) {
            let url = msg.target.result;
            document.getElementById('myCanvas').src = url;
          }
        }

        reader.readAsDataURL(msg.data)
      }
    },
    close: function () {
      // console.log("socket已经关闭")
      this.socket.close()
      this.socket = ''
    },

    handleFileChange(event) {
      let file = event.target.files[0]
      if (file) {
        this.UpFile.push(file)
      }
    },

    // 获取身份证信息
    async sfzCard() {
      let _this = this
      let res = await readCard()
      if (res.errorMsg == 'OK') {
        // console.log(res.resultContent)
        _this.imgDeals(res.resultContent.photo)
        _this.cardInfo = parseCardWzxx(res.resultContent)

      } else {
        if(this.$route.name == 'selectFile') {
          setTimeout(() => {
            this.sfzCard()
          }, 1000)
        }
      }
    },
    // 图片处理
    imgDeals(re) {
      let file = this.dataURLtoFile('data:image/png;base64,' + re, 'sfzTx.png')
      let formData = new FormData()
      formData.append('file', file)
      formData.append('colorEnum', 'CLEAR')
      changeIdPhotoBgc(formData).then((res) => {
        console.log(res)
        this.photo = res.previewPath
      })
    },
    // 读取U盘
    readUsb() {
      let data = {
        extensions: 'pdf,doc,docx,xls,xlsx,ppt,pptx,jpg,png'
      }
      readUsb(data).then((res) => {
        // console.log(res)
        if (res) {
          if(this.UpFile.length != res.length) {
            // console.log(this.UpFile , res)
            this.UpFile = res
            this.usbList = []
            res.forEach(re =>{
              this.usbList.push({
                name: re,
                sta: false
              })
            })
          }
        } else {
          this.UpFile = []
          this.usbList = []
          this.cite.state = {
            name: '请插入U盘',
            sta: true
          }
        }
        if(this.$route.name == 'selectFile') {
          setTimeout(() =>{
            this.readUsb()
          },1000)
        }

      })
    },
    // 处理选中文件
    async dealFile() {
      let {usbList} = this
      await usbList.forEach(re =>{
        if(re.sta) {
          this.readFile(re.name)
        }
      })
    },
    async readFile(url) {
      let res = await readFile({filePath: url})
      console.log(res)

      this.cite.selectedFile.push(res.data)
    },
  },
  destroyed() {
    // 销毁监听
    if(this.socket) {
      this.close()
    }
  },
  mounted() {
    this.cite.selectedFile = []
    if (this.cite.modeName == "扫描打印") {
      this.init();
    }else if(this.cite.modeName == "身份证打印") {
      this.sfzCard()
    }else if(this.cite.modeName == "U盘打印") {
      this.readUsb()
    }
  }
}
</script>

<style scoped lang="less">
@font-face {
  font-family: 'STHeiti';//自定义字体名字
  src: url('../assets/typeface/STHeiti.ttf') format('truetype');//定义好文件的相对地址
}
@font-face {
  font-family: 'OCR';//自定义字体名字
  src: url('../assets/typeface/OCR-B-10-BT.ttf') format('truetype');//定义好文件的相对地址
}
.selectFile {
  .box {
    width: 114.06rem;
    height: 42.13rem;
    background: #ffffff;
    box-shadow: 0rem 0.31rem 0.63rem 0.06rem rgba(0, 0, 0, 0.14);
    border-radius: 1.63rem;
    margin: 0 auto;
    .tip {
      //margin-right: 15.31rem;
      width: 37rem;
      font-size: 2.25rem;
      font-weight: bold;
      color: #323232;
      line-height: 3rem;
      .title {
        font-size: 2.88rem;
        font-weight: bold;
        color: #d41212;
        line-height: 4.06rem;
      }
      .content {
        margin: 3rem auto 59px;
        text-align: center;
      }
    }
    .file {
      margin-left: 9.69rem;
      .main {
        width: 31.63rem;
        height: 26.56rem;
        background: #ffffff;
        border: 0.06rem solid #707070;
        margin: 0 auto 2.81rem;
        padding: 1rem 0;
        overflow-y: scroll;
        .li {
          padding-left: 1rem;
          .name {
            min-height: 1.8rem;
            text-align: left;
            max-width: 80%;
            margin-left: 1rem;
          }
          img {
            width: 1.3rem;
            margin-left: 1rem;
          }
        }
      }
    }
    .tip2 {
      width: 52rem;
      .but {
        .btn {
          width: 24.44rem;
          position: relative;
          input {
            position: absolute;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            opacity: 0;
          }
        }
      }
    }
    .file2 {
      margin-right: 9.69rem;
      .title {
        font-size: 2.13rem;
        font-weight: bold;
        color: #323232;
        line-height: 3rem;
        //text-align: left;
        span {
          text-decoration: underline;
          font-size: 1.5rem;
          font-weight: bold;
          color: #323232;
          line-height: 2rem;
        }
        .act {
          color: #52a39d;
        }
      }
      .main {
        width: 39.81rem;
        height: 31.31rem;
        background: #eeeeee;
        margin: 1.38rem auto 0;
      }
      .card {
        //width: 42.81rem;
        width: 20rem;
        margin: 0 10rem;
        height: 35.31rem;
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        align-items: flex-end;
        .card-box {
          width: 25rem;
          height: 15rem;
          margin-right: 5rem;
          position: relative;
          font-weight: 500;
          font-size: .9rem;
          line-height: 1rem;
          .card-title {
            padding: 1rem 0;
          }
          img {
            width: 25rem;
          }
          .card-sign {
            position: absolute;
            bottom: 2.6rem;
            left: 10.5rem;
          }
          .card-date {
            position: absolute;
            bottom: 0.5rem;
            left: 10.5rem;
          }
          .card-name {
            position: absolute;
            top: 2.2rem;
            left: 4.5rem;
          }
          .card-gender {
            position: absolute;
            top: 4.1rem;
            left: 4.5rem;
            span {
              margin-left: 5rem;
            }
          }
          .card-birth {
            position: absolute;
            top: 6.15rem;
            left: 4.5rem;
            .month {
              margin-left: 1.7rem;
            }
            .day {
              margin-left: 1.2rem;
            }
          }
          .card-addr {
            width: 11rem;
            position: absolute;
            top: 8.1rem;
            left: 4.5rem;
            text-align: left;
            line-height: 1.3rem;
          }
          .card-id {
            position: absolute;
            bottom: .8rem;
            left: 8rem;
            letter-spacing: .2rem;
          }
          .card-avatar {
            position: absolute;
            top: 3.2rem;
            right: 2rem;
            width: 7rem;
            height: 9rem;
            img {
              width: 7rem;
              height: 9rem;
              background-size: contain;
            }
          }
        }
        .card-box2 {
          position: relative;
          font-family: 'STHeiti';
          margin: 0 auto;
          img {
            width: 100%;
          }
          .diamond {
            position: absolute;
            top: 0;
            //left: 60px;
            right: 0;
            height: 100%;
            //font-size: 12px;
            text-align: left;
            left: 3.75rem;
            font-size: 0.75rem;
            .name {
              //font-size: 14px;
              font-family: 'OCR';
              //margin: 23px 0 10px;
              font-size: 0.875rem;
              margin: 1.4375rem 0 0.625rem;
            }
            .gender {
              div {
                //margin-left: 50px;
                margin-left: 3.125rem;
              }
            }
            .birth {
              //margin: 12px 0;
              margin: 0.75rem 0;
              span {
                //margin-right: 3px;
                margin-right: 0.1875rem;
              }
              div {
                //width: 20px;
                //margin-left: 11px;
                text-align: center;
                width: 1.25rem;
                margin-left: 0.6875rem;
              }
            }
            .addr {
              //width: 150px;
              //line-height: 18px;
              width: 9.375rem;
              line-height: 1.125rem;
            }
            .idNum {
              position: absolute;
              //bottom: 26px;
              //left: 46px;
              //letter-spacing: 2px;
              font-family: 'OCR';
              //font-size: 14px;
              font-weight: 600;
              bottom: 1.625rem;
              left: 2.875rem;
              letter-spacing: 0.125rem;
              font-size: 0.875rem;
            }
            .avatar {
              position: absolute;
              //right: 20px;
              //top: 40px;
              //width: 82px;
              right: 1.25rem;
              top: 2.5rem;
              width: 5.125rem;
            }
          }
          .diamond2 {
            //left: 130px;
            height: auto;
            top: auto;
            //bottom: 21px;
            left: 8.125rem;
            bottom: 1.3125rem;
            .sign {
              //margin-bottom: 14px;
              margin-bottom: 0.875rem;
            }
          }
        }
      }
    }
    .file3 {
      margin-right: 28.13rem;
      .main {
        width: 20.75rem;
        height: 28.88rem;
        border: 0.06rem solid #707070;
        margin: 1.06rem 0 0 13.38rem;
      }
    }
    .btn {
      width: 100%;
      height: 5.5rem;
      background: linear-gradient(132deg, #52a39d 0%, #a1c553 50%, #81d012 100%);
      border-radius: 1.25rem;
      font-size: 1.88rem;
      font-weight: 400;
      color: #ffffff;
      line-height: 2.63rem;
      cursor: pointer;
    }
  }
  .smfyData {
    height: 90%;
    width: 14.81rem;
    font-size: 1rem;
    font-weight: bold;
    color: #323232;
    line-height: 2rem;
    overflow: auto;
    cursor: pointer;
    .act {
      color: #52a39d;
    }
    .name {
      text-decoration: underline;
    }
    span {
      margin-left: 5rem;
    }
  }
}
</style>