eventsource realizes mobile phone uploading and computer receiving

eventsource supports the server to actively push information to the client; it does not support two-way push.
//The process is that the PC side clicks the scan button to request a unique id, uses the id and other required parameters to generate a QR code through an interface and returns it to the front desk, and the front desk gets the QR code data and displays it to the user and opens it at the same time eventsource service (the backend will check whether there is a record corresponding to this id in a table according to this id every once in a while, if there is, it will be pushed to the front desk, if not, it will continue to check after a while), mobile phone scanning jumps to an upload file page, after the mobile phone uploads, submit the required data to the backend, and the backend will generate a record with the data and this unique id for source interface query;

<template>
  <div style="margin-left:10px;width:50%;">
      <p style="line-height:40px"><el-button type="primary" class="smallbtn" style="font-size: 12px;" @click="getcode">扫描上传</el-button></p>
      <el-dialog title="扫描上传" :close-on-click-modal="false"  :modal="false" id="code_dialog" center @close='setCodedata' :visible.sync="code_dialog" width="800px">
        <p style="text-align:center"><img :src="codeImg" alt="" style="margin:0 auto"></p>
        <span slot="footer" class="dialog-footer" style="padding:0 24px;">
          <el-button style="width:120px;" ref="closebtn" @click="closecode">关闭</el-button>
        </span>
      </el-dialog>
      <ul>
        <li v-for="(item,index) in sendFileArr" :key="index">
          <span class="l_span" :title="item.fileName">{
   
   { item.fileName }}</span>  <span class="delbt" @click="del(index)" style="font-size:12px;margin-left:20px;cursor:pointer">删除</span>
        </li>
      </ul>
  </div>
</template>

<script>
import {mapState, mapGetters} from 'vuex'
export default {
  props:['filetypeArr','uploadurl','clearfn','htref'], //
  data () {
    return {
        code_dialog:false,
        codeImg:'',
        openbool:false,
        sendFileArr:[]
    }
  },

  components: {},
  watch:{  
  //这里通过弹窗开启关闭时更改值,来置空组件数据
    clearfn:function(val){
       this.sendFileArr=[]
       this.$emit('sendsuccess',[])
    }
  },
  computed: {
    userId:function(){
      return localStorage.getItem('session_id')||''
    }
  },

  methods: {
    // 获取唯一id
    getcodeid(){
      return new Promise((resolve,reject)=>{
        this.axios.post('xxxxxx').then(res=>{
           if(res.data.code===200){
              resolve(res.data.data.codeid)
           }else{
              this.$message.error('获取二维码失败')   //生成不了id就不去生成二维码了
           }
        }).catch(err=>{
           this.$message.error('获取二维码失败')
        })
      })
    },
    setCodedata(){
      this.codeImg=''
    },
    // 获取二维码图片
    async getcode(){
        if(typeof EventSource==='undefined'){
          this.$message.error('当前浏览器不支持手机传送数据到电脑功能,请更换浏览器或者使用电脑上传')
          return
        } 
        let codeid=await this.getcodeid()
       //如果参数是汉字类对象数组,这么写:encodeURIComponent(encodeURIComponent(JSON.stringify(sendtypeArr)))
        this.axios.get(`xxxxx?a=xxxx}`, {
              responseType: 'arraybuffer' // 指定返回数据的格式为blob   
            }
          ).then(res => {
           //拼成src
            this.codeImg = 'data:image/png;base64,' + btoa(new Uint8Array(res.data).reduce((data, byte) => data + String.fromCharCode(byte), ''))
            this.code_dialog=true
            this.opensource(codeid)
          }).catch(err => {
            this.$message.error('获取二维码失败')
          })
    },
    // 开启eventsource  // 
    opensource(codeid){
        this.openbool=true
        let that=this
        //因为需要在点击页面某个按钮来关闭接收服务,直接在这里申明变量的话在其他方法中访问不到,所有把source实例挂到了当前方法的内部属性,这里的this.opensource就是我们当前定义的methods方法名
        this.opensource.source = new EventSource(`${this.api.basePath}/Api/contract/uploadmessage/getDate?codeid=${codeid}&bookNumber=${this.bookNumber}&token=${this.userId}`)
        this.opensource.source.onopen = function (event) { // 与服务器连接成功回调
          console.log('成功与服务器连接')
        }
        this.opensource.source.onmessage = function (event) { // 监听未命名事件
          console.log('接收到数据')
          if(event.data){
            that.openbool=false
            that.$emit('sendsuccess',JSON.parse(event.data))
            that.sendFileArr=JSON.parse(event.data)
            that.closecode()
            that.opensource.source.close()
            console.log('服务器连接关闭')
          } 
        }
        this.opensource.source.onerror = function (error) { // 监听错误
          console.log('错误')
        }
        // console.log(this.opensource.source.readyState) //服务状态,可查看eventsource api
    },
    // 关闭弹窗 关闭eventsource
    closecode:function(){
        // console.log(this.opensource.source.readyState)
        // 如果已接收到数据,直接关闭弹窗
        if(!this.openbool){
          this.code_dialog=false
          return
        }
        // 服务正在开启 则openbool改成false  关闭服务 关闭弹窗
        this.$confirm('确定要关闭吗',{
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'}).then(()=>{
            // console.log(this.opensource.source.close)
            this.opensource.source.close()
            this.opensource.source=null
            this.openbool=false
            this.code_dialog=false
        }).catch(()=>{
          this.$message.success('已取消')
        })
    },
    del(index){   //可删除
      this.sendFileArr.splice(index,1)
      this.$emit('sendsuccess',this.sendFileArr)
    }
  },

  mounted(){

  }

}
</script>
<style lang='scss' scoped>
ul{
  width:100%;
  margin-left:10px;
  // margin-top:10px;
  li{
    display:flex;
    justify-content: space-between;
    align-items: center;
    line-height:26px;
    margin-top:5px;
    .l_span{
      width:80%;
      overflow: hidden;
      text-overflow:ellipsis;
      white-space: nowrap;
    }
    
  }
  li:nth-of-type(1){
    margin-top:10px
  }
  li:hover{
      background-color: #F5F7FA;
    .delbt{
      color:#409EFF
    }  
  }

}
</style>

Guess you like

Origin blog.csdn.net/weixin_43392545/article/details/105933550