• 【vue+蓝牙扫码枪】实现扫码录入发票信息,光标自动聚焦,列表中连续录入


    上周给了我一把扫码枪,给了份说明书,说了一下如何开机,关机和连蓝牙

    然后关于扫码枪的就没了

    虽然没有搞过,但是搜一搜文章,了解了解,也是能搞出来的。

    借鉴了这篇文章,感兴趣的可以戳这里,扫码枪【1】:vue中扫码枪的运用

    博主说的挺明了的,扫码枪扫出来的信息会在有光标的输入框内显示,并且扫码枪自己做了一件事,就是扫码完成后自动触发input输入框的enter(键盘回车)事件

    所以我们要做两件事,第一:让鼠标自动聚焦到输入框;第二:在回车事件中处理数据

    我手上的应该就是普通的扫码枪,关于扫码枪的说明书,上面有很多条形码,主要说说我用到了哪些

    首先开机需要按下扳机3秒,会听到开机声音

    蓝牙usb接口要插在电脑上,然后扫“蓝牙键盘模式”条形码,链接蓝牙。

    蓝牙连完注意有一个坑,我之前不知道,花了很多时间再找哪里出了问题

    当我正常扫码的时候,输入框内会把扫到的信息都展示出来,但就是不触发enter键盘回车事件,一直在排查代码问题,最后才发现,说明书上有个“添加回车”条形码,这个也要扫一下

    不用扫码枪的时候要扫“关机”条形码

    注意点说完了,下面开始贴代码

    我的需求是在一个弹窗里有扫码枪按钮和一个列表,列表里可以连续扫码录入,初次点“扫码枪”按钮新增一行并自动聚焦,扫完后再自动新增一行并自动聚焦,当点确认的时候把列表数据给后台,处理完后自动在页面的列表上新增我们扫出来的数据。

    1、点扫码枪按钮,在列表内新增一条并自动聚焦

     <el-button
            class="UpButton ml5"
            size="mini"
            type="primary"
            title="扫码枪"
            icon="el-icon-full-screen"
            @click="openScanner"
            >扫码枪
          </el-button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
      <el-table
          ref="elTable"
          class="mt5"
          style="margin-top: 0px"
          :height="462"
          border
          :header-cell-style="{
            'text-align': 'center',
            'background-color': '#f8f8f9',
          }"
          :data="totalHandList"
        >
          <el-table-column
            align="center"
            :show-overflow-tooltip="true"
            prop="name"
            label="xxx"
            width="200"
          >     
            <template slot-scope="scope">
                  <el-input
                class="input_scanner"
                v-model="scope.row.code"
                @keyup.enter.native="inputDown(scope.row)"
                :ref="'Input_' + scope.$index"
              ></el-input>        
            </template>
          </el-table-column>
             </el-table>
         <div class="scanner_text">
          <p>提示:扫描后,数据会自动显示在上方,请将输入法切换至英文状态下!</p>
          <p>支持增值税普通发票、增值税电子普通发票!</p>
        </div>        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    注:因为还有其他设备共用这个弹窗,所以我用了计算属性,当切换到其他设备时,要删掉在扫码枪时多增的那条空白数据

      data() {
        return {
          //动态高度
          screenHeight: "",
          scannerList: [], //扫码枪数据源
          falseList: [], //假数据   
        };
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注:计算属性不需要在data中定义,后期删除的时候也不能删totalHandList,而是要去删除原数组
    handFileList是其他硬件要绑的数组,可忽略

      computed: {
        totalHandList() {
          return [...this.handFileList, ...this.scannerList, ...this.falseList];
        },
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
        // 打开扫码枪
        openScanner() {
          this.scannerFlag = true;//不重要
          this.$emit("closeScann", 1);//触发父组件事件,不重要
          if (this.falseList.length > 0) return;//防止点扫码枪重复新增
          this.falseList.push({
            name: "",
            percentage: 0,
            invoiceDate: "",
            invoiceCode: "",
            invoiceNumber: "",
            seller: "",
            pretaxAmount: "",
            total: "",
            flag: "scanner",
            code: "",
          });
          //给最后一行加光标
          this.$nextTick(() => {
            this.$refs["Input_" + (this.totalHandList.length - 1)].focus();
          });
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2、处理键盘回车事件,给input绑定好事件后,这个事件是扫码枪自动触发的
    增值税电子专用发票当扫二维码的时候,可以扫出五大项,发票代码,发票号码,发票日期、校验码和不含税金额,并且除了这五项,还会有类型,可以区分是哪种发票的类型,这个要具体看情况,不清楚是不是通用的。五大项的排序位置是固定的,所以我这里是按顺序截取

     // 扫码枪自动开启enter事件
        async inputDown(row) {
          row.dealcode = row.code.split(",");     
          row.invoiceType = row.dealcode[1];
          row.invoiceCode = row.dealcode[2];
          row.invoiceNumber = row.dealcode[3];
          row.pretaxAmount = row.dealcode[4];
          row.invoiceDate = this.isYmd(row.dealcode[5]);
          row.checkCode = row.dealcode[6].substring(
            row.dealcode[6].length - 6,
            row.dealcode[6].length
          ); 
          let obj = {
            invoiceType: row.invoiceType,
            invoiceCode: row.invoiceCode,
            invoiceNumber: row.invoiceNumber,
            pretaxAmount: row.pretaxAmount,
            invoiceDate: row.invoiceDate,
            checkCode: row.checkCode,
          };
          const data = await checkScanner(obj);
          if (data.code == 200) {
            if (data.invoiceIndex.ocrResult == "重复录入") {
              this.$message.warning(
                `${data.invoiceIndex.ocrResult}!${data.invoiceIndex.ocrResultCreatName}已经录入!`
              );
              this.falseList[0].code = "";
            } else {
              this.scannerList.push({
                name: "",      
                percentage: 100,
                response: {
                  msg: data.invoiceIndex.ocrResult,
                  invoiceIndex: data.invoiceIndex,
                },
              });
              this.falseList[0] = {
                name: "",
                percentage: 0,
                invoiceDate: "",
                invoiceCode: "",
                invoiceNumber: "",
                seller: "",
                pretaxAmount: "",
                total: "",      
                flag: "scanner",
                code: "",
              };
              this.inputblur();
            }
          }
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    说下日期处理,我们拿到的发票日期是这样的,‘20221125’,要处理成‘2022-11-25’

       // 处理日期格式
        isYmd(date) {
          if (!date) return this.$message.warning("请将输入法切换至英文状态下!");
    
          var partten = /(\d{4})(\d{2})(\d{2})/;
          var formateDate = date.replace(partten, "$1-$2-$3");
          return formateDate;
        },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
        // 输入框失焦
        inputblur() {
          this.$nextTick(() => {
            this.$refs["Input_" + (this.totalHandList.length - 1)].focus();
          });
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、删除,对原数组进行删除

        /** 删除 */
        handleDelete(row, index) {      
          if (row.uid) {
            this.handFileList = this.handFileList.filter((item) => {
              return item.uid !== row.uid;
            });
          }
          this.scannerList = this.scannerList.filter((item) => {
            return (
              item.response.invoiceIndex.invoiceNumber !==
              row.response.invoiceIndex.invoiceNumber
            );
          });
          this.falseList = [];
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    应该没啥落的了,有问题,欢迎沟通

  • 相关阅读:
    Centos部署Docker
    线程间通信(生产者和消费者案例)
    java计算机毕业设计-数字相册管理系统-源程序+mysql+系统+lw文档+远程调试
    Postgresql中yacc语法树冲突解决方法(shift/reduce conflicts)
    Docker入门
    [附源码]Python计算机毕业设计Django酒店物联网平台系统
    基于移动互联网的订餐APP系统设计与实现
    [附源码]JAVA毕业设计高校心理咨询预约系统(系统+LW)
    AI图书推荐:用ChatGPT按需DIY定制来赚钱
    浏览器的缓存机制 优点 缺点 协商缓存和强缓存 浏览器缓存过程 如何判断强缓存是否过期
  • 原文地址:https://blog.csdn.net/weixin_49668076/article/details/127976351