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

本文涉及的产品
可视分析地图(DataV-Atlas),3 个项目,100M 存储空间
简介: 低代码可视化-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>


相关实践学习
DataV Board用户界面概览
本实验带领用户熟悉DataV Board这款可视化产品的用户界面
阿里云实时数仓实战 - 项目介绍及架构设计
课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3&nbsp;)前置知识要求 &nbsp; 课程大纲 第一章&nbsp;了解数据仓库概念 初步了解数据仓库是干什么的 第二章&nbsp;按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章&nbsp;数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章&nbsp;采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章&nbsp;用户行为数据仓库 严格按照企业的标准开发 第六章&nbsp;搭建业务数仓理论基础和对表的分类同步 第七章&nbsp;业务数仓的搭建&nbsp; 业务行为数仓效果图&nbsp;&nbsp;
目录
相关文章
|
1月前
|
数据可视化 前端开发 UED
低代码可视化-Uniapp Cascader级联选择器-代码生成器
Cascader级联选择器是一种常用的UI组件,适用于从具有层级关系的数据中进行选择,如省市区选择、公司层级选择等。它通过分组多列展示选项,支持多级分类、联动选择、搜索与过滤等功能。组件具备自定义样式、禁用选项、清空选项等特性,广泛应用于电商、企业内部系统等场景。代码示例展示了其详细的实现和调用方法。
43 7
低代码可视化-Uniapp Cascader级联选择器-代码生成器
|
2月前
|
数据可视化 API
低代码可视化-uniapp购物车页面-代码生成器
低代码可视化-uniapp购物车页面-代码生成器
53 1
|
2月前
|
移动开发 编解码 数据可视化
低代码可视化-uniapp SliderRange区间组件-代码生成器
SliderRange区间组件是一种用户界面元素,允许用户通过拖动滑块选择数值范围。组件支持微信小程序、H5和App,具有高度可定制性、响应式设计和多种事件处理功能。适用于价格筛选、音量调节等场景。代码实现包括滑动区域、滑块、事件处理等部分,支持可视化配置步长、颜色等属性。使用时需注意选择合适步长、提供清晰标签和考虑无障碍设计。
39 0
|
2月前
|
小程序 数据可视化 API
低代码可视化-uniapp商城首页小程序-代码生成器
低代码可视化-uniapp商城首页小程序-代码生成器
31 0
|
2月前
|
JSON 数据可视化 JavaScript
低代码可视化-uniapp响应式数据data-代码生成器
低代码可视化-uniapp响应式数据data-代码生成器
42 0
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的房屋租赁App的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的房屋租赁App的详细设计和实现(源码+lw+部署文档+讲解等)
131 7
基于SpringBoot+Vue+uniapp的房屋租赁App的详细设计和实现(源码+lw+部署文档+讲解等)
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的汉服交易小程序的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的汉服交易小程序的详细设计和实现(源码+lw+部署文档+讲解等)
67 7
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的宠物医院微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的宠物医院微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
87 7
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的武汉市公交路线查询系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的武汉市公交路线查询系统的详细设计和实现(源码+lw+部署文档+讲解等)
117 7
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的旅游攻略系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的旅游攻略系统的详细设计和实现(源码+lw+部署文档+讲解等)
120 7