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

4 years ago
<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>