低代码可视化-uniapp蓝牙标签打印-代码生成器

简介: 低代码可视化-uniapp蓝牙标签打印-代码生成器

蓝牙标签打印

蓝牙标签打印技术结合了蓝牙通信与标签打印的功能,为用户提供了一种便捷、高效的打印解决方案。以下是对蓝牙标签打印的详细解析:


蓝牙标签打印机的特点

无线连接:蓝牙标签打印机最大的亮点在于其无线连接方式。用户可以通过蓝牙轻松地将手机、平板电脑或电脑与打印机连接,无需复杂的网络设置或线缆连接,极大地提高了使用的便捷性。

兼容性强:蓝牙标签打印机通常支持多种操作系统和设备,包括安卓、iOS以及Windows等,满足不同用户的需求。

便携小巧:许多蓝牙标签打印机设计得小巧轻便,便于携带,用户可以随时随地进行打印操作。

功能多样:除了基本的文本打印外,蓝牙标签打印机还支持打印条形码、二维码、图片等,广泛应用于物流、仓储、零售、医疗等行业。

蓝牙标签打印机的应用场景


物流管理:在快递、物流行业中,蓝牙标签打印机可以快速打印出运单、标签等,提高包裹的分拣和配送效率。

仓储管理:在仓库中,蓝牙标签打印机可以打印出货物标签、货架标签等,帮助工作人员快速识别和定位货物。

零售管理:在超市、便利店等零售场所,蓝牙标签打印机可以打印出价格标签、促销标签等,方便商品管理和顾客选购。

医疗管理:在医疗行业中,蓝牙标签打印机可以打印出药品标签、患者信息标签等,确保医疗过程的安全和准确。

蓝牙标签打印的优势

提高效率:无线连接和便携设计使得蓝牙标签打印机可以在任何需要的地方进行打印操作,大大提高了工作效率。

降低成本:相比于传统的有线打印方式,蓝牙标签打印机减少了线缆和设备的投入成本,同时降低了维护成本。

增强灵活性:蓝牙标签打印机支持多种打印格式和内容,可以根据实际需求进行灵活调整和优化。

打印核心代码

打印核心代码基于网上资源自己进行了二次开发,兼容了uniapp。

print.js核心代码

import tsc from './tsc.js';
import esc from './esc.js';
 
// 打印程序begin---------------------------------
/**
 * android 6.0以上需授权地理位置权限
 */
var checkPemission = function(that) {
  var systemInfo = uni.getSystemInfoSync();
  var platform = systemInfo.platform;
  if (platform == "ios") {
    getBluetoothDevices(that)
  } else if (platform == "android") {
    let system = systemInfo.system;
    let system_no = system.replace('android', '');
    system_no = system.replace('Android', '');
    if (Number(system_no) > 5) {
      uni.getSetting({
        success: function(res) {
          if (!res.authSetting['scope.userLocation']) {
            uni.authorize({
              scope: 'scope.userLocation',
              complete: function(res) {
                getBluetoothDevices(that)
              }
            })
          } else {
            getBluetoothDevices(that)
          }
        }
      })
    }
  }
}
 
/**
 * 获取蓝牙设备信息
 */
var getBluetoothDevices = function(that) {
  console.log("start search")
  uni.showLoading({
    title: '搜索中',
  })
  that.setData({
    isScanning: true
  })
  uni.startBluetoothDevicesDiscovery({
    success: function(res) {
      setTimeout(function() {
        uni.getBluetoothDevices({
          success: function(res) {
            var devices = []
            var num = 0
            for (var i = 0; i < res.devices.length; ++i) {
              if (res.devices[i].name != "未知设备") {
                devices[num] = res.devices[i]
                num++
              }
            }
            that.setData({
              devicesList: devices,
              isScanning: false
            })
            uni.hideLoading()
            uni.stopPullDownRefresh()
          },
        })
      }, 3000)
    },
  })
}
 
/**
 * 开始连接蓝牙设置
 */
var connectBluetoothSettings = function(app, that) {
  let deviceId = that.deviceId;
  uni.stopBluetoothDevicesDiscovery({
    success: function(res) {
      //console.log(res)
    },
  })
  that.setData({
    serviceId: 0,
    writeCharacter: false,
    readCharacter: false,
    notifyCharacter: false
  })
  uni.showLoading({
    title: '正在连接',
  })
  uni.createBLEConnection({
    deviceId: deviceId,
    success: function(res) {
      app.globalData.bluetoothDeviceId = deviceId
      getBLEDeviceServices(app, that);
      uni.showLoading({
        title: '连接好可以打印',
      })
    },
    fail: function(e) {
      uni.showModal({
        title: '提示',
        content: '连接失败',
      })
      uni.hideLoading()
    },
    complete: function(e) {
      //console.log(e)
    }
  })
}
 
/**
 * 获取蓝牙设备所有服务
 */
var getBLEDeviceServices = function(app, that) {
  console.log(app.globalData.bluetoothDeviceId)
  uni.getBLEDeviceServices({
    deviceId: app.globalData.bluetoothDeviceId,
    success: function(res) {
      that.setData({
        services: res.services
      })
      getBLEDeviceCharacteristics(app, that)
    },
    fail: function(e) {
      console.log(e)
    },
    complete: function(e) {
      //console.log(e)
    }
  })
}
 
/**
 * 获取蓝牙设备某个服务中所有特征值
 */
var getBLEDeviceCharacteristics = function(app, that) {
  var list = that.services
  var num = that.serviceId
  var write = that.writeCharacter
  var read = that.readCharacter
  var notify = that.notifyCharacter
  uni.getBLEDeviceCharacteristics({
    deviceId: app.globalData.bluetoothDeviceId,
    serviceId: list[num].uuid,
    success: function(res) {
      for (var i = 0; i < res.characteristics.length; ++i) {
        var properties = res.characteristics[i].properties
        var item = res.characteristics[i].uuid
        if (!notify) {
          if (properties.notify) {
            app.globalData.notifyCharaterId = item
            app.globalData.notifyServiceId = list[num].uuid
            notify = true
          }
        }
        if (!write) {
          if (properties.write) {
            app.globalData.writeCharaterId = item
            app.globalData.writeServiceId = list[num].uuid
            write = true
          }
        }
        if (!read) {
          if (properties.read) {
            app.globalData.readCharaterId = item
            app.globalData.readServiceId = list[num].uuid
            read = true
          }
        }
      }
      if (!write || !notify || !read) {
        num++
        that.setData({
          writeCharacter: write,
          readCharacter: read,
          notifyCharacter: notify,
          serviceId: num
        })
        if (num == list.length) {
          uni.showModal({
            title: '提示',
            content: '找不到该读写的特征值',
          })
        } else {
          getBLEDeviceCharacteristics(app, that)
        }
      } else {
        notifyBLECharacteristicValueChange(app)
      }
    },
    fail: function(e) {
      console.log(e)
    },
    complete: function(e) {
      //console.log("write:" + app.globalData.writeCharaterId)
      //console.log("read:" + app.globalData.readCharaterId)
      //console.log("notify:" + app.globalData.notifyCharaterId)
    }
  })
}
 
/**
 * 启用低功耗蓝牙设备特征值变化时的 notify 功能
 */
var notifyBLECharacteristicValueChange = function(app) {
  //console.log("deviceId:" + app.globalData.bluetoothDeviceId)
  //console.log("serviceId:" + app.globalData.notifyServiceId)
  //console.log("notifyCharaterId:" + app.globalData.notifyCharaterId)
  uni.hideLoading();
  uni.notifyBLECharacteristicValueChange({
    deviceId: app.globalData.bluetoothDeviceId,
    serviceId: app.globalData.notifyServiceId,
    characteristicId: app.globalData.notifyCharaterId,
    state: true,
    success: function(res) {
      uni.onBLECharacteristicValueChange(function(r) {
        //console.log('onBLECharacteristicValueChange=', r);
      })
    },
    fail: function(e) {
      console.log('fail', e)
    },
    complete: function(e) {
      //console.log('complete', e)
    }
  })
}
 
/**
 * 标签模式
 */
var labelTest = function(app, that) {
  var command = tsc.jpPrinter.createNew()
  command.setSize(70, 50) //纸宽度70,高度50
  command.setGap(0)
  command.setCls() //需要设置这个,不然内容和上一次重复
  // 10起始位置,10行距,TSS24.BF2字体,1字与字之间的间距,1字体大小,最后一个打印内容
  command.setText(10, 10, "TSS24.BF2", 2, 2, 'DIY可视化蓝牙打印')
  command.setText(10, 70, "TSS24.BF2", 1, 1, '联系人:邓志锋')
  command.setText(10, 110, "TSS24.BF2", 1, 1, '网址:diygw.com')
  command.setText(10, 150, "TSS24.BF2", 1, 1, '电话:15655555555')
  //command.setText(10, 40, "TSS24.BF2", 1, 2, "蓝牙热敏标签打印测试2")
  command.setPagePrint()
  prepareSend(app, that, command.getData())
}
 
// 打印标签
var printLabel = function(app, that) {
  var command = tsc.jpPrinter.createNew()
  command.setSpeed(0)
  command.setSize(that.form.width, that.form.height) //纸宽度,高度
  command.setGap(0)
  command.setCls() //需要设置这个,不然内容和上一次重复
  // 10起始位置,TSS24.BF2字体,1字与字之间的间距,1字体大小,一行行增加40高度打印
  // 打印位置
  let y = 0;
  let content = that.form.content
  for (let i = 0; i < content.length; i++) {
    command.setText(10, y, "TSS24.BF2", content[i].scale, content[i].scale, content[i].text)
    y = y + 40
  }
  command.setPagePrint()
  prepareSend(app, that, command.getData())
}
 
/**
 * 准备发送数据
 */
var prepareSend = function(app, that, buff) {
  //console.log('buff', buff)
  var time = that.oneTimeData
  var looptime = parseInt(buff.length / time);
  var lastData = parseInt(buff.length % time);
  that.setData({
    looptime: looptime + 1,
    lastData: lastData,
    currentTime: 1,
  })
  Send(app, that, buff)
}
 
/**
 * 查询打印机状态
 */
var queryPrinterStatus = function() {
  var command = esc.jpPrinter.Query();
  command.getRealtimeStatusTransmission(1);
  this.setData({
    returnResult: "查询成功"
  })
}
 
/**
 * 分包发送
 */
var Send = function(app, that, buff) {
  var currentTime = that.currentTime;
  var loopTime = that.looptime;
  var lastData = that.lastData;
  var onTimeData = that.oneTimeData;
  var printNum = that.printNum; //打印多少份
  var currentPrint = that.currentPrint;
  var buf
  var dataView
  if (currentTime < loopTime) {
    buf = new ArrayBuffer(onTimeData)
    dataView = new DataView(buf)
    for (var i = 0; i < onTimeData; ++i) {
      dataView.setUint8(i, buff[(currentTime - 1) * onTimeData + i])
    }
  } else {
    buf = new ArrayBuffer(lastData)
    dataView = new DataView(buf)
    for (var i = 0; i < lastData; ++i) {
      dataView.setUint8(i, buff[(currentTime - 1) * onTimeData + i])
    }
  }
  console.log("第" + currentTime + "次发送数据大小为:" + buf.byteLength);
  console.log("deviceId:" + app.globalData.bluetoothDeviceId)
  console.log("serviceId:" + app.globalData.writeServiceId)
  console.log("characteristicId:" + app.globalData.writeCharaterId)
  uni.writeBLECharacteristicValue({
    deviceId: app.globalData.bluetoothDeviceId,
    serviceId: app.globalData.writeServiceId,
    characteristicId: app.globalData.writeCharaterId,
    value: buf,
    success: function(res) {
      console.log('写入成功', res)
    },
    fail: function(e) {
      console.error('写入失败', e)
    },
    complete: function() {
      currentTime++
      if (currentTime <= loopTime) {
        that.setData({
          currentTime: currentTime
        })
        Send(app, that, buff)
      } else {
        if (currentPrint == printNum) {
          that.setData({
            looptime: 0,
            lastData: 0,
            currentTime: 1,
            isReceiptSend: false,
            isLabelSend: false,
            currentPrint: 1
          })
        } else {
          currentPrint++
          that.setData({
            currentPrint: currentPrint,
            currentTime: 1,
          })
          console.log("开始打印")
          Send(app, that, buff)
        }
      }
      //console.log('打印完成')
    }
  })
}
 
/**
 * 蓝牙搜索
 */
var searchBluetooth = function(that) {
  //判断蓝牙是否打开
  if(uni.openBluetoothAdapter){
    uni.openBluetoothAdapter({
      success: function(res) {
        uni.getBluetoothAdapterState({
          success: function(res) {
            if (res.available) {
              if (res.discovering) {
                uni.stopBluetoothDevicesDiscovery({
                  success: function(res) {
                    //console.log(res)
                  }
                })
              }
              checkPemission(that)
            } else {
              uni.showModal({
                title: '提示',
                content: '请开启手机蓝牙后再试',
              })
            }
          },
        })
      },
      fail: function() {
        uni.showModal({
          title: '提示',
          content: '蓝牙初始化失败,请打开蓝牙',
        })
      }
    })
  }else{
    that.showToast('只支持APP或小程序')
  }
  
}
// -end---------------------------------
 
var print = {
  searchBluetooth: searchBluetooth,
  connectBluetoothSettings: connectBluetoothSettings,
  labelTest: labelTest,
  printLabel: printLabel
}
export default print;


tsc.js核心代码

 
import encode from './encoding.js';
var jpPrinter = {
  createNew: function () {
    var jpPrinter = {};
    var data = "";
    var command = []
 
    jpPrinter.name = "标签模式";
 
    jpPrinter.init = function () { };
 
    jpPrinter.addCommand = function (content) {  //将指令转成数组装起
      var code = new encode.TextEncoder(
        'gb18030', {
          NONSTANDARD_allowLegacyEncoding: true
        }).encode(content)
      for (var i = 0; i < code.length; ++i) {
        command.push(code[i])
      }
    }
 
    jpPrinter.setSize = function (pageWidght, pageHeight) { //设置页面大小
      data = "SIZE " + pageWidght.toString() + " mm" + "," + pageHeight.toString() + " mm" + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setSpeed = function (printSpeed) { //设置打印机速度
      data = "SPEED " + printSpeed.toString() + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setDensity = function (printDensity) { //设置打印机浓度
      data = "DENSITY " + printDensity.toString() + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setGap = function (printGap) { //传感器
      data = "GAP " + printGap.toString() + " mm\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setCountry = function (country) { //选择国际字符集
      /*
      001:USA
      002:French
      003:Latin America
      034:Spanish
      039:Italian
      044:United Kingdom
      046:Swedish
      047:Norwegian
      049:German
       */
      data = "COUNTRY " + country + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setCodepage = function (codepage) { //选择国际代码页
      /*
      8-bit codepage 字符集代表
      437:United States
      850:Multilingual
      852:Slavic
      860:Portuguese
      863:Canadian/French
      865:Nordic
      Windows code page
      1250:Central Europe
      1252:Latin I
      1253:Greek
      1254:Turkish
      以下代码页仅限于 12×24 dot 英数字体
      WestEurope:WestEurope
      Greek:Greek
      Hebrew:Hebrew
      EastEurope:EastEurope
      Iran:Iran
      IranII:IranII
      Latvian:Latvian
      Arabic:Arabic
      Vietnam:Vietnam
      Uygur:Uygur
      Thai:Thai
      1252:Latin I
      1257:WPC1257
      1251:WPC1251
      866:Cyrillic
      858:PC858
      747:PC747
      864:PC864
      1001:PC100
      */
      data = "CODEPAGE " + codepage + "\r\n";
      jpPrinter.addCommand(data)
    }
 
    jpPrinter.setCls = function () { //清除打印机缓存
      data = "CLS" + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setFeed = function (feed) { //将纸向前推出n
      data = "FEED " + feed + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setBackFeed = function (backup) { //将纸向后回拉n
      data = "BACKFEED " + backup + "\r\n";
      jpPrinter.addCommand(data)
    }
 
    jpPrinter.setDirection = function (direction) { //设置打印方向,参考编程手册  
      data = "DIRECTION " + direction + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setReference = function (x, y) { //设置坐标原点,与打印方向有关
      data = "REFERENCE " + x + "," + y + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setFromfeed = function () { //根据Size进一张标签纸
      data = "FORMFEED \r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setHome = function () { //根据Size找到下一张标签纸的位置
      data = "HOME \r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setSound = function (level, interval) { //控制蜂鸣器
      data = "SOUND " + level + "," + interval + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setLimitfeed = function (limit) { // 检测垂直间距
      data = "LIMITFEED " + limit + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setBar = function (x, y, width, height) { //绘制线条
      data = "BAR " + x + "," + y + "," + width + "," + height + "\r\n"
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setBox = function (x_start, y_start, x_end, y_end, thickness) { //绘制方框
      data = "BOX " + x_start + "," + y_start + "," + x_end + "," + y_end + "," + thickness + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setErase = function (x_start, y_start, x_width, y_height) { //清除指定区域的数据
      data = "ERASE " + x_start + "," + y_start + "," + x_width + "," + y_height + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setReverse = function (x_start, y_start, x_width, y_height) { //将指定的区域反相打印
      data = "REVERSE " + x_start + "," + y_start + "," + x_width + "," + y_height + "\r\n";
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setText = function (x, y, font, x_, y_, str) { //打印文字
      data = "TEXT " + x + "," + y + ",\"" + font + "\"," + 0 + "," + x_ + "," + y_ + "," + "\"" + str + "\"\r\n"
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setQR = function (x, y, level, width, mode, content) { //打印二维码
      data = "QRCODE " + x + "," + y + "," + level + "," + width + "," + mode + "," + 0 + ",\"" + content + "\"\r\n"
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setBar = function (x, y, codetype, height, readable, narrow, wide, content) { //打印条形码
      data = "BARCODE " + x + "," + y + ",\"" + codetype + "\"," + height + "," + readable + "," + 0 + "," + narrow + "," + wide + ",\"" + content + "\"\r\n"
      jpPrinter.addCommand(data)
    };
 
    jpPrinter.setBitmap = function (x, y, mode, res) {  //添加图片,res为画布参数
      console.log(res)
      var width = parseInt((res.width + 7) / 8 * 8 / 8)
      var height = res.height;
      var time = 1;
      var temp = res.data.length - width * 32;
      var pointList = []
      console.log(width + "--" + height)
      data = "BITMAP " + x + "," + y + "," + width + "," + height + "," + mode + ","
      jpPrinter.addCommand(data)
      for (var i = 0; i < height; ++i) {
        console.log(temp)
        for (var j = 0; j < width; ++j) {
          for (var k = 0; k < 32; k += 4) {
            if (res.data[temp] == 0 && res.data[temp + 1] == 0 && res.data[temp + 2] == 0 && res.data[temp + 3] == 0) {
              pointList.push(1)
            } else {
              pointList.push(0)
            }
            temp += 4
          }
        }
        time++
        temp = res.data.length - width * 32 * time
      }
      for (var i = 0; i < pointList.length; i += 8) {
        var p = pointList[i] * 128 + pointList[i + 1] * 64 + pointList[i + 2] * 32 + pointList[i + 3] * 16 + pointList[i + 4] * 8 + pointList[i + 5] * 4 + pointList[i + 6] * 2 + pointList[i + 7]
        command.push(p)
      }
    }
 
    jpPrinter.setPagePrint = function () { //打印页面
      data = "PRINT 1,1\r\n"
      jpPrinter.addCommand(data)
    };
    //获取打印数据
    jpPrinter.getData = function () {
      return command;
    };
    return jpPrinter;
  }
};
 
var tsc={
  jpPrinter
}
export default tsc;

页面调用

<template>
  <view class="container container329843">
    <button @tap="navigateTo" data-type="searchBluetoothFunction" class="diygw-col-24 btn-clz diygw-btn-default">搜索打印机</button>
    <text class="diygw-col-24 text-clz"> 如果是微信小程序,请前往微信官方公众平台设置隐私协议 </text>
    <u-form-item labelWidth="auto" class="diygw-col-24" v-if="devicesList.length > 0" label="选择打印机" labelPosition="top" prop="deviceId">
      <diy-checkbox class="diygw-col-24" col="12" mode="radio" valueField="deviceId" labelField="name" v-model="deviceId" :list="devicesList" @change="changeDeviceId"> </diy-checkbox>
    </u-form-item>
    <u-form-item labelAlign="justify" class="diygw-col-24" label="打印份数" prop="printNum">
      <u-input :focus="printNumFocus" placeholder="请输入打印份数" v-model="printNum" type="number"></u-input>
    </u-form-item>
    <u-form :model="form" :rules="formRules" :errorType="['message', 'toast']" ref="formRef" class="flex diygw-form diygw-col-24">
      <view class="flex flex-wrap diygw-col-24">
        <u-form-item labelAlign="justify" class="diygw-col-12" label="标签宽度" prop="width">
          <u-input :focus="formData.widthFocus" placeholder="请输入宽度" v-model="form.width" type="number"></u-input>
        </u-form-item>
        <u-form-item labelAlign="justify" class="diygw-col-12" label="标签高度" prop="height">
          <u-input :focus="formData.heightFocus" placeholder="请输入宽度" v-model="form.height" type="number"></u-input>
        </u-form-item>
      </view>
      <view class="flex flex-wrap diygw-col-24">
        <view class="diygw-col-24" v-for="(contentItem, contentIndex) in form.content" :key="contentIndex">
          <u-form class="diygw-col-24" :model="form.content[contentIndex]" :errorType="['message', 'toast']" ref="contentRef" :rules="contentItemRules">
            <view class="flex flex-wrap diygw-col-24 flex1-clz">
              <u-form-item labelAlign="justify" class="diygw-col-24" label="放大倍数" prop="scale">
                <u-input :focus="formData.contentItemDatas[contentIndex].scaleFocus" placeholder="请输入宽度" v-model="contentItem.scale" type="number"></u-input>
              </u-form-item>
              <u-form-item labelAlign="justify" class="diygw-col-24" label="打印内容" prop="text">
                <u-input :focus="formData.contentItemDatas[contentIndex].textFocus" placeholder="请输入宽度" v-model="contentItem.text"></u-input>
              </u-form-item>
            </view>
          </u-form>
          <view class="formcontenttools flex justify-end">
            <button @tap="upContentItem" :data-index="contentIndex" class="diygw-btn flex-sub radius margin-xs">
              <text class="button-icon diy-icon-fold"></text>
            </button>
            <button @tap="downContentItem" :data-index="contentIndex" class="diygw-btn flex-sub radius margin-xs">
              <text class="button-icon diy-icon-unfold"></text>
            </button>
            <button @tap="addContentItem" :data-index="contentIndex" class="diygw-btn flex-sub radius margin-xs">
              <text class="button-icon diy-icon-add"></text>
            </button>
            <button @tap="delContentItem" :data-index="contentIndex" class="diygw-btn flex-sub radius margin-xs">
              <text class="button-icon diy-icon-close"></text>
            </button>
          </view>
        </view>
      </view>
    </u-form>
    <button @tap="navigateTo" data-type="printFunction" class="diygw-col-24 prt-clz diygw-btn-default">开始打印</button>
    <view class="clearfix"></view>
  </view>
</template>
 
<script>
  import print from '@/common/print/print.js';
  export default {
    data() {
      return {
        //用户全局信息
        userInfo: {},
        //页面传参
        globalOption: {},
        //自定义全局变量
        globalData: {},
        devicesList: [],
        services: [],
        serviceId: 0,
        writeCharacter: false,
        readCharacter: false,
        notifyCharacter: false,
        isScanning: false,
        looptime: 0,
        currentTime: 1,
        lastData: 0,
        oneTimeData: 20,
        returnResult: 'returnResult',
        currentPrint: 1,
        isReceiptSend: false,
        isLabelSend: true,
        deviceId: '',
        printNumFocus: false,
        printNum: 1,
        form: {
          width: 40,
          height: 70,
          content: []
        },
        formRules: {},
        contentItem: {
          scale: 1,
          text: 'DIYGW可视化蓝牙打印'
        },
        contentItemData: {
          scaleFocus: false,
          textFocus: false
        },
        formData: {
          widthFocus: false,
          heightFocus: false,
          contentItemDatas: []
        },
        contentItemRules: {}
      };
    },
    onShow() {
      this.setCurrentPage(this);
    },
    onLoad(option) {
      this.setCurrentPage(this);
      if (option) {
        this.setData({
          globalOption: this.getOption(option)
        });
      }
 
      this.init();
    },
    onReady() {
      this.$refs.formRef?.setRules(this.formRules);
      this.initContentData();
    },
    methods: {
      async init() {
        await this.initResetform();
      },
      // 搜索打印机 自定义方法
      async searchBluetoothFunction(param) {
        let thiz = this;
        print.searchBluetooth(this);
      },
 
      // 打印 自定义方法
      async printFunction(param) {
        let thiz = this;
        if (!this.deviceId) {
          this.navigateTo({
            type: 'tip',
            tip: '请选择打印机'
          });
          return;
        }
        print.printLabel(getApp(), this);
      },
 
      // 连接打印 自定义方法
      async connectFunction(param) {
        let thiz = this;
        print.connectBluetoothSettings(getApp(), this);
      },
      changeDeviceId(evt) {
        this.navigateTo({ type: 'connectFunction' });
      },
      //初始化显示子表单数据条数
      initContentData() {
        for (let i = 0; i < 1; i++) {
          this.form.content.push(JSON.parse(JSON.stringify(this.contentItem)));
          this.formData.contentItemDatas.push(JSON.parse(JSON.stringify(this.contentItemData)));
        }
        this.initContentValid();
      },
      //子表单验证
      initContentValid() {
        this.$nextTick(() => {
          this.$refs['contentRef']?.forEach((subform) => {
            subform.setRules(this.contentItemRules);
          });
        });
      },
      //上移子表单
      upContentItem(evt) {
        let { index } = evt.currentTarget.dataset;
        if (index == 0) {
          this.navigateTo({
            type: 'tip',
            tip: '已经是第一个'
          });
          return false;
        }
        this.form.content[index] = this.form.content.splice(index - 1, 1, this.form.content[index])[0];
        this.formData.contentItemDatas[index] = this.formData.contentItemDatas.splice(index - 1, 1, this.formData.contentItemDatas[index])[0];
        this.initContentValid();
      },
      //下移子表单
      downContentItem(evt) {
        let { index } = evt.currentTarget.dataset;
        if (index == this.form.content.length - 1) {
          this.navigateTo({
            type: 'tip',
            tip: '已经是最后一个'
          });
          return false;
        }
        this.form.content[index] = this.form.content.splice(index + 1, 1, this.form.content[index])[0];
        this.formData.contentItemDatas[index] = this.formData.contentItemDatas.splice(index + 1, 1, this.formData.contentItemDatas[index])[0];
        this.initContentValid();
      },
      //删除子表单
      delContentItem(evt) {
        if (this.form.content.length == 1) {
          this.showToast('不能小于1个');
          return;
        }
        let { index } = evt.currentTarget.dataset;
        this.form.content.splice(index, 1);
        this.formData.contentItemDatas.splice(index, 1);
        this.initContentValid();
      },
      //增加子表单
      addContentItem() {
        this.form.content.push(JSON.parse(JSON.stringify(this.contentItem)));
        this.formData.contentItemDatas.push(JSON.parse(JSON.stringify(this.contentItemData)));
        this.initContentValid();
      },
      //验证所有的子表单
      checkContentValid() {
        let flag = true;
        this.$refs['contentRef']?.forEach((subform) => {
          subform.validate((valid) => {
            if (!valid) {
              flag = false;
              return false;
            }
          });
        });
        return flag;
      },
      initResetform() {
        this.initform = JSON.stringify(this.form);
        //如果想给表单默认初始值,其中row为某一行数据也可能是API返回的结果集,然后给到this.form
        //this.form = this.$tools.changeRowToForm(row,this.form)
      },
      resetForm() {
        this.form = JSON.parse(this.initform);
      },
 
      async submitForm(e) {
        this.$refs.formRef?.setRules(this.formRules);
 
        this.initContentValid();
        this.$nextTick(async () => {
          let contentvalid = await this.checkContentValid();
          let valid = await this.$refs.formRef.validate();
          if (valid && contentvalid) {
            //保存数据
            let param = this.form;
            let header = {
              'Content-Type': 'application/json'
            };
            let url = '';
            if (!url) {
              this.showToast('请先配置表单提交地址', 'none');
              return false;
            }
 
            let res = await this.$http.post(url, param, header, 'json');
 
            if (res.code == 200) {
              this.showToast(res.msg, 'success');
            } else {
              this.showModal(res.msg, '提示', false);
            }
          } else {
            console.log('验证失败');
          }
        });
      }
    }
  };
</script>
 
<style lang="scss" scoped>
  .btn-clz {
    padding-top: 20rpx;
    border-bottom-left-radius: 120rpx;
    color: #fff;
    padding-left: 20rpx;
    padding-bottom: 20rpx;
    border-top-right-radius: 120rpx;
    margin-right: 30rpx;
    background-color: #07c160;
    margin-left: 30rpx;
    overflow: hidden;
    width: calc(100% - 30rpx - 30rpx) !important;
    border-top-left-radius: 120rpx;
    margin-top: 20rpx;
    border-bottom-right-radius: 120rpx;
    margin-bottom: 20rpx;
    text-align: center;
    padding-right: 20rpx;
  }
  .text-clz {
    border-bottom-left-radius: 120rpx;
    overflow: hidden;
    border-top-left-radius: 120rpx;
    border-top-right-radius: 120rpx;
    border-bottom-right-radius: 120rpx;
    text-align: center;
  }
  .formcontenttools {
    position: absolute;
    z-index: 1;
    right: 0rpx;
    top: 0rpx;
  }
  .formcontenttools .diygw-btn {
    padding: 5px;
    height: auto;
    flex: inherit;
    border-radius: 20px;
  }
  .flex1-clz {
    border: 2rpx solid #eee;
    padding-top: 10rpx;
    border-bottom-left-radius: 12rpx;
    padding-left: 10rpx;
    padding-bottom: 10rpx;
    border-top-right-radius: 12rpx;
    margin-right: 20rpx;
    margin-left: 20rpx;
    overflow: hidden;
    width: calc(100% - 20rpx - 20rpx) !important;
    border-top-left-radius: 12rpx;
    margin-top: 10rpx;
    border-bottom-right-radius: 12rpx;
    margin-bottom: 10rpx;
    padding-right: 10rpx;
  }
  .prt-clz {
    padding-top: 20rpx;
    border-bottom-left-radius: 120rpx;
    color: #fff;
    padding-left: 20rpx;
    padding-bottom: 20rpx;
    border-top-right-radius: 120rpx;
    margin-right: 30rpx;
    background-color: #07c160;
    margin-left: 30rpx;
    overflow: hidden;
    width: calc(100% - 30rpx - 30rpx) !important;
    border-top-left-radius: 120rpx;
    margin-top: 20rpx;
    border-bottom-right-radius: 120rpx;
    margin-bottom: 20rpx;
    text-align: center;
    padding-right: 20rpx;
  }
  .container329843 {
  }
</style>


目录
相关文章
|
2天前
|
编解码 Java 程序员
写代码还有专业的编程显示器?
写代码已经十个年头了, 一直都是习惯直接用一台Mac电脑写代码 偶尔接一个显示器, 但是可能因为公司配的显示器不怎么样, 还要接转接头 搞得桌面杂乱无章,分辨率也低,感觉屏幕还是Mac自带的看着舒服
|
4天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1540 5
|
1月前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
7天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
581 22
|
4天前
|
存储 SQL 关系型数据库
彻底搞懂InnoDB的MVCC多版本并发控制
本文详细介绍了InnoDB存储引擎中的两种并发控制方法:MVCC(多版本并发控制)和LBCC(基于锁的并发控制)。MVCC通过记录版本信息和使用快照读取机制,实现了高并发下的读写操作,而LBCC则通过加锁机制控制并发访问。文章深入探讨了MVCC的工作原理,包括插入、删除、修改流程及查询过程中的快照读取机制。通过多个案例演示了不同隔离级别下MVCC的具体表现,并解释了事务ID的分配和管理方式。最后,对比了四种隔离级别的性能特点,帮助读者理解如何根据具体需求选择合适的隔离级别以优化数据库性能。
201 3
|
10天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
11天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
580 5
|
23天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
7天前
|
XML 安全 Java
【Maven】依赖管理,Maven仓库,Maven核心功能
【Maven】依赖管理,Maven仓库,Maven核心功能
233 3
|
9天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
327 2