【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>
  <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>        

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

  data() {
    return {
      //动态高度
      screenHeight: "",
      scannerList: [], //扫码枪数据源
      falseList: [], //假数据   
    };
  },

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

  computed: {
    totalHandList() {
      return [...this.handFileList, ...this.scannerList, ...this.falseList];
    },
  },
    // 打开扫码枪
    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();
      });
    },

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();
        }
      }
    },

说下日期处理,我们拿到的发票日期是这样的,‘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;
    },

    // 输入框失焦
    inputblur() {
      this.$nextTick(() => {
        this.$refs["Input_" + (this.totalHandList.length - 1)].focus();
      });
    },

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 = [];
    },

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

你可能感兴趣的:(vue,vue.js,bash,git)