平板端快衣店
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.
 
 
 
 
 

597 lines
16 KiB

<template>
<view class="kk-printer">
<view class="kk-printer-btn" @tap="handlePrintTap" style="color:#FFF;">
{{isPrinting?printingText:defaultText}}
</view>
<view class="kk-shadow" :class="isShowSearch?'show':''" @tap="handleSearchClose">
<view class="kk-modal" @tap.stop="doNothing">
<view class="kk-search-device">
<!-- <view class="kk-filter-wrap">
<view class="filter-title">根据SRRI过滤设备</view>
<slider @change="handleSRRIChange" max='-20' min='-100' value="-95" show-value/>
</view>
<view class="kk-filter-wrap">
<view class="filter-title">根据蓝牙名过滤</view>
<input type="text" placeholder-class="kk-placeholder-class" placeholder="请输入蓝牙名字或设备ID搜索" v-model="filterName" />
</view> -->
<view class="kk-btn-wrap">
<view class="kk-btn-item confirm-btn" @tap="searchBtnTap" v-if="!isSearching">
搜索设备
</view>
<view class="kk-btn-item confirm-btn" v-else>
搜索中...
</view>
<view class="kk-btn-item" @tap="stopSearchBtnTap">
停止搜索
</view>
</view>
<view class="kk-devices-wrap">
<view class="empty-wrap" v-if="filterDeviceList.length <= 0">
<view class="empty-icon"></view>
<view class="empty-text">无可搜索到的设备</view>
</view>
<view class="" v-else>
<view class="kk-devices-item" v-for="(item,index) in filterDeviceList" :key="index"
@tap="handleConnectDevice(item)">
<view class="name" style="color:#000;">
<text>设备名称:</text>
<text>{{item.name?item.name:'未命名'}}</text>
</view>
<view class="rssi">
<text>信号强度:</text>
<text>({{Math.max(0, item.RSSI + 100)}}%)</text>
</view>
<!-- <view class="deviceid">
<text>设备ID:</text>
<text>{{item.deviceId}}</text>
</view>
<view class="advmac" v-if="item.advMac">
<text>advMac:</text>
<text>{{item.advMac}}</text>
</view> -->
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import gbk from '@/components/kk-printer/utils/printUtil-GBK.js';
import * as blesdk from './utils/bluetoolth';
import util from './utils/util.js';
export default {
data() {
return {
//是否正在打印
isPrinting: false,
//是否正在搜索设备
isSearching: false,
//是否显示蓝牙列表
isShowSearch: false,
//按蓝牙名过滤
filterName: '',
//按信号过滤
filterRSSI: -95,
//设备列表
devicesList: [],
//连接的设备ID
deviceId: '',
//根据设备ID获取的服务
services: '',
//获取特征值时返回的三要素
serviceId: '',
writeId: '',
readId: '',
iosNo: false,
deviceType: 'ios'
}
},
props: {
//按钮默认文字
defaultText: {
type: String,
default: '打印'
},
//按钮打印中的文字
printingText: {
type: String,
default: '打印中...'
},
bufferData: {
type: Array,
require: true
},
roomcode: {
type: String,
require: true
},
CustName: {
type: String,
require: true
},
roomid: {
type: String,
require: true
}
},
computed: {
mapFilterRSSI() {
return (0 - this.filterRSSI)
},
filterDeviceList() {
let devices = this.devicesList;
let name = this.filterName;
let rssi = this.filterRSSI;
//按RSSI过滤
let filterDevices1 = devices.filter((item) => {
return item.RSSI > rssi
})
// 按名字过滤
let filterDevices2
if (name != '') {
filterDevices2 = filterDevices1.filter((item) => {
return (item.name.indexOf(name) >= 0 || item.deviceId.indexOf(name) >= 0)
})
} else {
filterDevices2 = filterDevices1
}
// 根据广播数据提取MAC地址
for (let i = 0; i < filterDevices2.length; i++) {
if (filterDevices2[i].hasOwnProperty('advertisData')) {
if (filterDevices2[i].advertisData.byteLength == 8) {
filterDevices2[i].advMac = util.buf2hex(filterDevices2[i].advertisData.slice(2, 7));
}
}
}
return filterDevices2
}
},
mounted() {
},
onLoad() {
uni.getSystemInfoSync({
success: function(res) {
this.deviceType = res.osName
console.log('设备类型', res.osName)
}
});
},
beforeDestroy() {
this.stopSearchBtnTap();
},
methods: {
doNothing() {
return;
},
//点击打印按钮
handlePrintTap() {
let that = this
// 初始化蓝牙模块
wx.openBluetoothAdapter({ //111
mode: 'central',
success: (res2) => {
console.log('初始化蓝牙模块', res2)
that.sousuo()
},
fail: (res) => {
that.tui.toast('初始化失败', res)
}
})
},
// 开始搜索附近的蓝牙外围设备
sousuo() {
let that = this;
wx.startBluetoothDevicesDiscovery({ //222
success(res3) {
console.log('获取设备成功', res3)
that.jiantingshebei()
},
fail(err) {
that.tui.toast('获取设备失败', res)
}
})
},
/**
* jiantingshebei方法,判断缓存中有没有deviceId等数据的时候,
* 有: 直接拿到缓存中的deviceId等,直接请求 wx.createBLEConnection
* 没有:才会调用 wx.onBluetoothDeviceFound 搜索
*/
jiantingshebei() {
let that = this;
if (uni.getStorageSync('deviceId')) {
that.lianejieshebei(uni.getStorageSync('deviceId'))
} else {
// 监听扫描到新设备事件
wx.onBluetoothDeviceFound((res4) => { //333
console.log('监听新设备列表,拿到想要的就自动停止', res4)
res4.devices.forEach((device) => {
if (device.name == 'QR380A-6824_Ble') { //搜索到需要的设备
// 找到要搜索的设备后,及时停止扫描
wx.stopBluetoothDevicesDiscovery() //444
that.lianejieshebei(device.deviceId);
}
})
})
}
},
lianejieshebei(deviceId) {
let that = this;
// 连接设备
wx.createBLEConnection({ //555
deviceId: deviceId, // 搜索到设备的 deviceId
success: () => {
console.log('连接设备成功')
that.huoqufuwu(deviceId)
},
fail: (res) => {
that.tui.toast('连接设备失败', res)
}
})
},
huoqufuwu(deviceId) {
let that = this;
//获取服务
wx.getBLEDeviceServices({ //666
deviceId: deviceId, // 搜索到设备的 deviceId
success: (res5) => {
console.log('获取服务成功', res5)
that.duxietezhengzhi(deviceId, res5)
},
fail: (res) => {
that.tui.toast('获取服务失败', res)
}
})
},
duxietezhengzhi(deviceId, res5) {
let that = this;
//读写特征值
wx.getBLEDeviceCharacteristics({ //777
deviceId: deviceId, // 搜索到设备的 deviceId
serviceId: res5.services[0].uuid, // 上一步中找到的某个服务
success: (res6) => {
console.log('读写特征值成功', res6)
that.xierushuju(deviceId, res5, res6)
},
fail: (res) => {
that.tui.toast('读写特征值失败', res)
}
})
},
xierushuju(deviceId, res5, res6) {
let that = this;
uni.setStorageSync('deviceId', deviceId);
uni.setStorageSync('serviceId', res5.services[0].uuid);
uni.setStorageSync('characteristicId', item.uuid);
//写入数据
for (let i = 0; i < res6.characteristics.length; i++) {
let item = res6.characteristics[i]
if (item.properties.write) { // 该特征值可写
console.log('该特征值可写')
if (this.defaultText == '打印小票') {
that.$emit('onPrintSmall');
} else if (this.defaultText == '确认打印') {
that.$emit('goPrint');
} else {
that.$emit('onPrint');
}
console.log('查看数据是否正确', this.bufferData)
let buffer = gbk.strToGBKByte(data)
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._writeBLECharacteristicValue, j * delay, subPackage);
}
// that.$nextTick(()=>{
// for(var m=0;m<that.bufferData.length;m++){
// // if(m > 0){
// // console.log('打印前',that.bufferData[m])
// // setTimeout(res=> {
// // var data = that.bufferData[m]
// // let buffer = gbk.strToGBKByte(data)
// // let opt = {
// // deviceId: deviceId,
// // serviceId: res5.services[0].uuid,
// // value:buffer,
// // characteristicId:item.uuid,
// // lasterSuccess: that.onPrintSuccess,
// // onceLength: that.deviceType == 'android'?20:180 //ios 180 安卓 20
// // }
// // blesdk.sendDataToDevice(opt);
// // },3000 * m)
// // }else{
// console.log('打印前',that.bufferData[m])
// var data = that.bufferData[m]
// var buffer = gbk.strToGBKByte(that.bufferData[m])
// var opt = {
// deviceId: deviceId,
// serviceId: res5.services[0].uuid,
// value:buffer,
// characteristicId:item.uuid,
// lasterSuccess: that.onPrintSuccess,
// onceLength: 20 //ios 180 安卓 20
// }
// blesdk.sendDataToDevice(opt);
// // }
// }
// })
// return;
}
}
},
_writeBLECharacteristicValue(buffer) {
wx.writeBLECharacteristicValue({
deviceId:uni.getStorageSync('deviceId'),
serviceId: uni.getStorageSync('serviceId'),
characteristicId: uni.getStorageSync('characteristicId'),
value: buffer,
success(res) {
console.log('writeBLECharacteristicValue success', res)
},
fail(res) {
console.log('writeBLECharacteristicValue fail', res)
}
})
},
onGetDevice(res) {
this.devicesList = res;
},
handleSearchClose() {
this.isShowSearch = false
},
handleSRRIChange(e) {
this.filterRSSI = e.detail.value
},
//开始搜索设备
searchBtnTap() {
blesdk.startBluetoothDevicesDiscovery();
this.isSearching = true;
blesdk.onfindBlueDevices(this.onGetDevice)
},
//停止搜索设备
stopSearchBtnTap() {
blesdk.stopBlueDevicesDiscovery();
this.isSearching = false;
},
//点击连接设备
handleConnectDevice(device) {
let deviceId = device.deviceId;
let name = device.name;
this.deviceId = deviceId;
uni.setStorageSync('deviceId', deviceId);
uni.onBLEConnectionStateChange(function(res) {
if (res.connected) {
// plus.nativeUI.toast('设备'+ res.deviceId + '已连接',{
// verticalAlign:'center'
// })
} else {
// plus.nativeUI.toast('设备'+ res.deviceId + '已断开连接',{
// verticalAlign:'center'
// })
}
})
blesdk.createBLEConnection(deviceId, this.onConnectSuccess, this.onConnectFail);
this.devicesList == []
},
onConnectSuccess(res) {
this.stopSearchBtnTap()
uni.setStorageSync('ok', true)
blesdk.getBLEDeviceServices(this.deviceId, this.onGetServicesSuccess, this.onGetServicesFail);
},
onConnectFail(err) {
blesdk.closeBLEConnection(uni.getStorageSync('deviceId'));
this.isShowSearch = true
uni.removeStorageSync('deviceId')
uni.removeStorageSync('serviceId')
uni.removeStorageSync('writeId')
uni.removeStorageSync('readId')
// uni.
},
onGetServicesSuccess(res) {
this.services = res.serviceId;
blesdk.getDeviceCharacteristics(uni.getStorageSync('deviceId') ? uni.getStorageSync('deviceId') : this
.deviceId, uni.getStorageSync('services') ? uni.getStorageSync('services') : this.services, this
.onGetCharacterSuccess, this.onGetCharacterFail);
},
onGetServicesFail(err) {},
onGetCharacterSuccess(res) {
this.serviceId = res.serviceId;
this.writeId = res.writeId;
this.readId = res.readId;
uni.setStorageSync('serviceId', res.serviceId)
uni.setStorageSync('writeId', res.writeId)
uni.setStorageSync('readId', res.readId)
this.isShowSearch = false;
this.handlePrintTap()
},
onGetCharacterFail(err) {
},
onPrintSuccess() {
console.log("打印完成22222")
this.isPrinting = false;
this.$u.route('/pages/toll/toll', {
roomcode: this.roomcode,
CustName: this.CustName,
id: this.roomid
})
this.$emit('onPrintSuccess')
},
onPrintFail() {
this.isPrinting = false;
}
}
}
</script>
<style lang="scss" scoped>
.kk-printer {
&-btn {
width: 100%;
height: 100%;
}
.kk-shadow {
display: none;
&.show {
display: block;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.4);
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
.kk-modal {
width: 680upx;
height: 80%;
padding: 24upx;
box-sizing: border-box;
overflow-y: auto;
border-radius: 20upx;
background: #ffffff;
display: flex;
justify-content: center;
align-items: center;
.kk-search-device {
width: 100%;
height: 100%;
.kk-filter-wrap {
width: 100%;
height: 160upx;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
.filter-title {
line-height: 70upx;
font-size: 30upx;
color: #999999;
}
&>slider {
width: 90%;
height: 90upx;
}
&>input {
padding: 0 20upx;
box-sizing: border-box;
border-radius: 10upx;
height: 90upx;
width: 100%;
border: 1upx solid #ebebeb;
}
}
.kk-btn-wrap {
width: 100%;
height: 140upx;
display: flex;
justify-content: space-between;
align-items: center;
&>view {
flex: 1 1 auto;
height: 100upx;
line-height: 100upx;
border-radius: 16upx;
text-align: center;
color: #ffffff;
&.confirm-btn {
background: #007AFF;
margin-right: 30upx;
}
&:nth-last-child(1) {
background: #DD524D;
}
}
}
.kk-devices-wrap {
height: calc(100% - 460upx);
overflow-y: auto;
padding: 10upx 20upx;
box-sizing: border-box;
border: 1upx solid #ebebeb;
box-sizing: border-box;
border-radius: 20upx;
.empty-wrap {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.empty-icon {
width: 268upx;
height: 240upx;
background-size: 100% 100%;
margin-bottom: 26upx;
}
.empty-text {
width: 100%;
line-height: 50upx;
font-size: 30upx;
text-align: center;
color: #999999;
}
}
.kk-devices-item {
width: 100%;
border-bottom: 1upx solid #ebebeb;
padding: 10upx 0;
box-sizing: border-box;
z-index: 500;
&:nth-last-child(1) {
border-bottom: none;
}
&>view {
width: 100%;
font-size: 30upx;
}
}
}
}
}
}
}
}
.kk-placeholder-class {
font-size: 30upx;
color: #999999;
}
</style>