You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

323 lines
8.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<!--
1.手机蓝牙打开
2.微信也许访问蓝牙和位置信息
3.重启蓝牙设备
4.不行的时候,删掉手机中蓝牙,重新链接
-->
<view class="content">
<button size="mini" type="primary" @tap="startBluetoothDeviceDiscovery"></button>
<button size="mini" type="warn" @tap="stopBluetoothDevicesDiscovery"></button>
<button type="primary" @tap="pickUpOnce"></button>
<scroll-view class="device_list" scroll-y="true" show-scrollbar="true">
<radio-group>
<view v-for="(item,index) in devicesList" :key="index" class="device_item" v-if="item.name.length>0">
<view style="font-size: 32rpx; color: #333;">
<radio :value="item.deviceId" @tap="select_deviceId(item)" />{{item.name }}</view>
<view style="font-size: 20rpx">信号强度: {{item.RSSI}}dBm ({{Math.max(100+item.RSSI,0)}}%)</view>
<view style="font-size: 20rpx">deviceId: {{item.deviceId}}</view>
<view style="font-size: 20rpx">Service数量: {{item.advertisServiceUUIDs.length || 0}}</view>
<radio-group v-if="deviceId===item.deviceId">
<view v-for="(service,service_index) in serviceList" :key="service_index" style="font-size: 20rpx">
<radio style="transform:scale(0.7)" :value="service.uuid" @tap="select_service(service)" />{{service.uuid }}
</view>
</radio-group>
</view>
</radio-group>
</scroll-view>
<canvas canvas-id="shareCanvas" style="width: 240px; height: 240px;"></canvas>
</view>
</template>
<script>
import PrinterJobs from '@/common/print/printerjobs.js'
import printerUtil from '@/common/print/printerutil.js'
import util from '@/common/print/util.js'
import drawQrcode from '@/common/print/weapp.qrcode.esm.js'
import Bluetooth from '@/common/print/bluetooth.js'
let bluetooth = new Bluetooth();
export default {
components: {},
data() {
return {
isOpenBle: false, //是否已经打开蓝牙默认为false
devicesList: [], //设备列表
serviceList: [], //服务列表
deviceId: "", //选中的deviceId
canvas_width: 240,
canvas_height: 240,
}
},
//页面卸载是关闭蓝牙链接
onUnload() {
bluetooth.closeBLEConnection();
bluetooth.closeBluetoothAdapter();
},
//页面打开,获取位置,打开蓝牙链接
onLoad() {
uni.getLocation({
type: 'wgs84',
success: function(res) {
console.log('当前位置的经度:' + res.longitude);
console.log('当前位置的纬度:' + res.latitude);
}
});
bluetooth.openBluetoothAdapter();
},
methods: {
//搜索周边设备
startBluetoothDeviceDiscovery() {
uni.showLoading({
title: '蓝牙搜索中'
})
let self = this;
self.devicesList = [];
setTimeout(() => {
uni.startBluetoothDevicesDiscovery({
success: res => {
uni.onBluetoothDeviceFound(devices => {
console.log("发现设备: " + JSON.stringify(devices));
//不重复,就添加到devicesList中,
if (!self.devicesList.some(item => {
return item.deviceId === devices.devices[0].deviceId
})) {
self.devicesList.push(devices.devices[0])
}
});
},
fail: res => {
uni.hideLoading();
self.showToast(`搜索设备失败` + JSON.stringify(err));
}
})
}, 200)
},
//停止搜索蓝牙设备
stopBluetoothDevicesDiscovery() {
uni.hideLoading();
bluetooth.stopBluetoothDevicesDiscovery();
},
//选中设备
async select_deviceId(item) {
this.deviceId = item.deviceId;
bluetooth.deviceId = item.deviceId;
uni.setStorageSync('deviceId', bluetooth.deviceId);
this.serviceList = [];
try {
//1.链接设备
let result = await bluetooth.createBLEConnection();
//2.寻找服务
let result2 = await bluetooth.getBLEDeviceServices();
console.log("获取服务: " + JSON.stringify(result2));
this.serviceList = result2;
} catch (e) {
//TODO handle the exception
console.log("e: " + JSON.stringify(e));
}
},
//选中服务
async select_service(res) {
bluetooth.serviceId = res.uuid;
uni.setStorageSync('serviceId', res.uuid);
try {
let result = await bluetooth.getBLEDeviceCharacteristics();
} catch (e) {
//TODO handle the exception
console.log("e: " + JSON.stringify(e));
}
},
//打印一次
pickUpOnce() {
bluetooth.notifyBLECharacteristicValue();
let self = this;
setTimeout(() => {
self.writeBLECharacteristicValue();
}, 500);
},
//写入控制命令
async writeBLECharacteristicValue() {
let Qrcode_res = await this.get_Qrcode();
console.log(Qrcode_res);
let printerJobs = new PrinterJobs();
printerJobs
.print(util.formatTime(new Date()))
.print(printerUtil.fillLine())
.setAlign('ct')
.setSize(2, 2)
.print('#20外卖')
.setSize(1, 1)
.print('切尔西Chelsea')
.setSize(2, 2)
.print('在线支付(已支付)')
.setSize(1, 1)
.print('订单号5415221202244734')
.print('下单时间:' + util.formatTime(new Date()))
.setAlign('lt')
.print(printerUtil.fillAround('一号口袋'))
.print(printerUtil.inline('意大利茄汁一面 * 1', '15'))
.print(printerUtil.fillAround('其他'))
.print('餐盒费1')
.print('[赠送康师傅冰红茶] * 1')
.print(printerUtil.fillLine())
.setAlign('rt')
.print('原价¥16')
.print('总价¥16')
.setAlign('lt')
.print(printerUtil.fillLine())
.print('备注')
.print("无")
.print(printerUtil.fillLine())
.printQrcode(Qrcode_res)
.println()
;
//console.log(printerJobs);
let buffer = printerJobs.buffer();
this.printbuffs(buffer);
},
printbuffs(buffer) {
// 1.并行调用多次会存在写失败的可能性
// 2.建议每次写入不超过20字节
// 分包处理,延时调用
const maxChunk = 20;
const delay = 20;
for (let i = 0, j = 0, length = buffer.byteLength; i < length; i += maxChunk, j++) {
let subPackage = buffer.slice(i, i + maxChunk <= length ? (i + maxChunk) : length);
setTimeout(this.printbuff, j * delay, subPackage);
}
},
printbuff(buffer) {
bluetooth.writeBLECharacteristicValue(buffer);
},
get_Qrcode() {
let self = this;
return new Promise((resolve, reject) => {
const ctx = uni.createCanvasContext('shareCanvas');
console.log(self.canvas_width);
ctx.clearRect(0, 0, self.canvas_width, self.canvas_height);
drawQrcode({
canvasId: 'shareCanvas',
text: String('xiaonibaba.com'),
width: self.canvas_width,
height: self.canvas_height,
callback(e) {
setTimeout(() => {
console.log(self.canvas_width);
// 获取图片数据
uni.canvasGetImageData({
canvasId: 'shareCanvas',
x: 0,
y: 0,
width: self.canvas_width,
height: self.canvas_height,
success(res) {
resolve(util.zip_image(res));
}
})
}, 1000);
}
});
});
},
}
}
</script>
<style>
.content {}
page {
color: #333;
}
button {
margin: 10upx;
}
.devices_summary {
margin-top: 5rpx;
padding: 20rpx;
font-size: 30rpx;
}
.device_list {
margin: 5rpx 20rpx 5rpx 20rpx;
border: 1rpx solid #ddd;
border-radius: 10rpx;
background-color: #FdFdFd;
min-height: 0rpx;
max-height: 400rpx;
width: 700rpx;
}
.device_item {
border-bottom: 1rpx solid #ddd;
padding: 20rpx;
color: #666;
}
.device_item_hover {
background-color: rgba(0, 0, 0, .1);
}
.connected_info {
position: fixed;
bottom: 0;
width: 100%;
background-color: #F0F0F0;
padding: 10px;
padding-bottom: 20px;
margin-bottom: env(safe-area-inset-bottom);
font-size: 14px;
min-height: 100px;
box-shadow: 0px 0px 3px 0px;
}
.connected_info .operation {
position: absolute;
display: inline-block;
right: 30px;
}
</style>