vuex项目扫码枪收款

一. 扫码枪工作原理

扫码枪会将扫到的数据带入到获取焦点的输入框中,并且触发输入框的enter回车事件

1.页面上要有一个输入框,并且是获取焦点状态,当然它是隐藏的看不到,我是把宽高设置为0,然后加上回车事件。

<el-input ref="barCodeInput" v-model="barCode" size="small" @keyup.enter.native="payCode"></el-input>  

2.获取焦点的方法

Vue.nextTick(() => {
    this.$refs["barCodeInput"].focus();
});  

3.执行回车事件

payCode(){
     //这里进行扫码枪扫码后的操作,调后台接口     
}

 

二、 项目使用实际代码  

因为产品要求是不能展示出扫码枪的输入框的,所以使用的input 的hidden属性隐藏了输入框,监听onkeyup事件处理

代码如下:

扫码枪组件代码:

scannerTipDialog.vue
<template>
  /* 点开这个弹框的时候,提示需要扫码,待扫码input获取到数据后,则会自动关闭弹框,将数据传送给上一级做处理*/
  <el-dialog
    custom-class="jpark-center-mgr"
    title="支付提示"
    :visible.sync="dialogVisible"
    :before-close="handleClose"
    width="30%"
    append-to-body
    :close-on-click-modal="false">
    <div class="text">
      <span>请使用扫码枪完成支付!</span>
    </div>
    <!-- <el-input style="display: none;" width="50px" ref="barCodeInput" v-model="barCode" size="small" @keyup.native="payCode"></el-input>   -->
    <input ref="barCodeInput" v-model="barCode" style="width:500px;" type="text" hidden  placeholder="">
    
  </el-dialog>
</template>
<script>
export default {
  name: "ScannerTipDialog",
  props: {
    scannerDialogVisible: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      dialogVisible: true,
      loading: false,
      barCode: '', //扫码枪获取到的值
      regexRules: [
        {
          regex: /^(10|11|12|13|14|15|16|17|18|19)[0-9]{16,17}/,
          value: "WX",
        },
        {
          regex: /^(25|26|27|28|29|30)[0-9]{14,22}/,
          value: "ZFB",
        }
      ],
      delay: 200,
      _start: null
    };
  },
  mounted() {
    let _this = this
    this.$nextTick(() => {
      _this.$refs["barCodeInput"].focus();
      document.onkeydown = function(event) {
        console.log('event', event)
        let result = _this.barCode || '';
        let _start = _this._start || new Date();
        let now = new Date();
        // if ((now.getTime() - _start.getTime()) > _this.delay) {
        //   _start = now;
        //   result = '';
        // }
        let bizCode = String.fromCharCode(event.keyCode);
        // console.log('bizCode', bizCode)
        if (event.code == "Enter") {
          let type = _this.initRegexRules(_this.barCode)
          console.log('获取到的值',_this.barCode, type)
          _this.$emit('getScanCode',_this.barCode, type)
        }
        result += bizCode
        _this.barCode = result
        _this._start = _start
      };
    })
    
    
  },
  destroyed () {
    document.onkeydown = null
  },
  methods: {
    initRegexRules(v) {
      let atype = this.regexRules.filter(item => item.regex.test(v))
      if (atype.length) {
        return atype[0].value
      } else {
        return 'UNKNOW'
      }
      
    },
    handleClose() {
      this.$emit('closeScanner')
      this.dialogVisible = false
      document.onkeydown = null
    },
    
  },
  watch: {
    
  },
};
</script>
<style lang="scss" scoped>
.text {
  text-align: center;
  font-size: 17px;
  font-weight: 700;
}  
</style> 

父组件处理数据代码:

html:

<scanner-tip-dialog v-if="isShowScanner" ref="scannerTipDialog" @getScanCode="getScanCode" @closeScanner="closeScanner"/>

data () {
    isShowScanner: false, // 方便每次打开扫码枪弹框的时候会重新挂载,获取焦点
}

methods: {
    getScanCode (code,type) {
              console.log('扫码得到的数据',code,type)
              this.isShowScanner = false
              this.dialogLoading = true
              this.open({code, type})
            },
    closeScanner () {
              this.isShowScanner = false
            },

 /*
下面是事件处理函数,通过promise避免了回调地狱,可供以后写代码参考
promise 返回的reject() 数据处理都会被catch捕获到,展示出错误信息
promise 返回的resolve() 数据处理都会被try捕获到,函数继续往下执行
*/
async open(scanner){
                var payMode = null
                var order = null
                try {

                    //2. 查询对应的支付编号
                    payMode = await this.getPayModeByType(scanner.type)
                    console.log('==>>payMode', payMode)

                    // 3. 支付订单 
                    order = await this.payOrder(scanner)
                    console.log('==>>order', order)

                    // 4. 开卡
                    let open = await this.handleOpen(order)
                    this.dialogLoading = false
                    console.log('==>>handleOpen', open)
                   
                } catch(error){
                    this.dialogLoading = false;
                    console.log('==>>error', error)
                    if(error.code == this.errorTypes.scannerError.code) {
                        // 扫码枪扫描失败
                        this.$message({
                            type: 'error',
                            message: '扫码枪扫描失败,请重新提交并扫码'
                        })
                    } else if(error.code == this.errorTypes.payModeError.code){
                        // 获取支付方式失败
                        this.$message({
                            type: 'error',
                            message: '订单支付类型获取失败,请更换支付方式'
                        })
                    } else if(error.code == this.errorTypes.serverError.code){
                        // 订单支付失败
                        this.$message({
                            type: 'error',
                            message: '订单支付失败,请重新扫码'
                        })
                    } else if(error.code == this.errorTypes.payOrderError.code){
                        // 订单支付失败 需要反查
                        let param = {
                            subsystemCode: this.model.subsystemCode,
                            orderNum: error.outTradeNo
                        }
                        try{
                            let orderStatus = await this.queryOrderStatus(param)
                            console.log("===>orderStatus",orderStatus)
                            let open = await this.handleOpen(order)
                            console.log('==>>handleOpen', open)
                        } catch(e){
                            console.log('==>>e', e)
                            this.handleOpenFailed()
                        }
                    } else if(error.code == this.errorTypes.openMonthCardError.code){
                        // 月卡开卡失败处理
                        this.handleOpenFailed()
                    }
                }
            },
// 订单状态反查
            queryOrderStatus(param){
                let that = this
                return new Promise((resolve, reject) => {
                    getOrderStatus(param).then(res => {
                        if(res.respCode == 'success' 
                        && res.respData ){
                            if(res.respData.resultCode == 0){
                                if(res.respData.attributes && res.respData.attributes.tradeState == 'SUCCESS'){
                                    that.model.orderId = res.respData.attributes.orderNo
                                    resolve(res.respData)
                                } else {
                                    let e = Object.assign({}, this.errorTypes.payOrderError, {orderNo: res.respData.attributes.orderNo})
                                    reject(e)
                                }
                            } else {
                                reject(this.errorTypes.serverError)
                            }
                        } else {
                            reject(this.errorTypes.serverError)
                        }
                    }).catch(err => {
                        reject(this.errorTypes.serverError)
                    })
                })
            },
// 获取对用的支付方式
            getPayModeByType(type){
                return new Promise((resolve, reject) => {
                    getPayMode(type).then(res => {
                        this.tempPayMode = res.respData.itemKey
                        resolve(res.respData)
                    }).catch(e => {
                        reject(this.errorTypes.payModeError)
                    })
                })
                
            },
// 月卡开卡失败处理
            handleOpenFailed(){
                // 判断是否使用扫码枪支付
                if (this.payMode == this.offlinePay.itemKey){
                    this.model.payMode = this.tempPayMode
                }
                handleOpenPayFailed(this.model).then(res => {
                    var msg = "月卡开卡失败,请稍后重试";
                    this.$message({
                        message: msg,
                        type: "success",
                        duration: 5000
                    });
                    this.cancel()
                }).catch(err => {
                    this.$message({
                        type: 'warning',
                        message: '系统错误,请稍后再试'
                    })
                })
            },
//支付订单
            payOrder(scanner){
                let that = this
                return new Promise((resolve, reject) => {
                     // 获取车牌号码
                    let carNos = that.model.personCars.map(e => {
                      return e.carNo
                    }).join(',')
                    that.orderParam.carNo = carNos
                    that.orderParam.subsystemCode = that.model.subsystemCode
                    that.orderParam.ysMoney = that.model.ysMoney
                    that.orderParam.ssMoney = that.model.ssMoney
                    that.orderParam.newBeginTime = that.model.beginTime
                    that.orderParam.newEndTime = that.model.endTime
                    that.orderParam.authCode = scanner.code
                    that.orderParam.payChannel = scanner.type
                    payParkServiceOrder(that.orderParam).then(res => {
                        if(res.respCode == 'success' 
                        && res.respData){ //需要细分失败类型
                            that.orderParam.id = res.respData.id
                            that.orderParam.outTradeNo = res.respData.outTradeNo
                            if(res.respData.payStatus == '1'){
                                that.model.orderId = res.respData.outTradeNo
                                resolve(res.respData)
                            } else if(res.respData.payStatus == '0'){
                                let e = Object.assign({}, this.errorTypes.payOrderError, {outTradeNo: res.respData.outTradeNo})
                                reject(e)
                            } else if(res.respData.payStatus == '-2'){
                                reject(this.errorTypes.serverError)
                            }
                        } else {
                            reject(this.errorTypes.serverError)
                        }
                    }).catch(err => {
                        reject(this.errorTypes.serverError)
                    })
                })
            },  
                  
}    

 

参考:

基于VUE的插件,实现无需输入框得情况下网页监听扫码枪扫码结果

 

本地测试html文件:

<!DOCTYPE html>
<html>
<head>
    <title>扫码枪测试demo</title>
</head>
<body>
<div>
 <!--hidden 可以先去掉来测试扫码枪-->
  <input id="inputData" style="width:500px;" type="text" hidden value="" placeholder="请输入优惠券码/扫描优惠券码" onBlur="blur" onkeyup="getDetail()">
</div>
<script type="text/javascript">
  let msg = ''
  window.onload = function () {
    let oInput = document.querySelector('#inputData')
    let b = '1111';
    let _this = this; 
    // oInput.value = b;
    oInput.focus()
    document.onkeydown = function(event) {
      console.log('event', event)
      if (event.keyCode != 13) {
        var bizCode = String.fromCharCode(event.keyCode);
        console.log('bizCode', bizCode)
        if (event.keyCode >= 48 && event.keyCode <= 122) {
          b = b + bizCode;
        }
      } else {
        b = "";
      }
      _this.msg = b;
      if (event.code == "Enter") {
        console.log('获取到的值',oInput.value)
      }
    };
    
  }
  function getDetail (data) {
    console.log('获取到的数据', msg)
  }
  
  
</script>
</body>
</html>

 

hidden
posted @ 2022-03-31 11:26  front-gl  阅读(1305)  评论(0编辑  收藏  举报