wangfukang 14 hours ago
parent
commit
bbce6f265b
  1. BIN
      components/kk-printer/empty-icon.png
  2. 469
      components/kk-printer/index.vue

BIN
components/kk-printer/empty-icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

469
components/kk-printer/index.vue

@ -24,10 +24,10 @@
</view> </view>
<view class="" v-else> <view class="" v-else>
<view class="kk-devices-item" v-for="(item,index) in devicesList" :key="index" <view class="kk-devices-item" v-for="(item,index) in devicesList" :key="index"
@tap="lianejieshebei(item.deviceId)"> @tap="lianejieshebei(item.deviceId, { device: item })">
<view class="name" style="color:#000;display: flex;flex-direction: column;"> <view class="name" style="color:#000;display: flex;flex-direction: column;">
<text>设备名称</text> <text>{{item.isCached?'上次连接:':'设备名称:'}}</text>
<text>{{item.name?item.name:'未命名'}}</text> <text>{{item.name || item.localName || '未命名'}}</text>
</view> </view>
<!-- <view class="rssi"> <!-- <view class="rssi">
<text>信号强度</text> <text>信号强度</text>
@ -72,7 +72,15 @@
writeId: '', writeId: '',
readId: '', readId: '',
iosNo: false, iosNo: false,
deviceType: 'ios' deviceType: 'ios',
searchTimer: null,
connectTimer: null,
printFinishTimer: null,
isListeningBluetoothDeviceFound: false,
bluetoothDeviceFoundHandler: null,
currentDevice: null,
writeFailing: false,
isWriting: false
} }
}, },
props: { props: {
@ -112,14 +120,195 @@
beforeDestroy() { beforeDestroy() {
this.stopSearchBtnTap(); this.stopSearchBtnTap();
this.clearTimers();
if (wx.offBluetoothDeviceFound && this.bluetoothDeviceFoundHandler) {
wx.offBluetoothDeviceFound(this.bluetoothDeviceFoundHandler);
}
}, },
methods: { methods: {
doNothing() { doNothing() {
return; return;
}, },
clearTimers() {
clearTimeout(this.searchTimer);
clearTimeout(this.connectTimer);
clearTimeout(this.printFinishTimer);
this.searchTimer = null;
this.connectTimer = null;
this.printFinishTimer = null;
},
showToast(title) {
if (this.tui && this.tui.toast) {
this.tui.toast(title);
return;
}
uni.showToast({
title,
icon: 'none'
});
},
getCachedPrinter() {
let printer = uni.getStorageSync('printerDevice') || {};
if (typeof printer == 'string') {
try {
printer = JSON.parse(printer);
} catch (e) {
printer = {};
}
}
const deviceId = uni.getStorageSync('deviceId') || printer.deviceId;
if (!deviceId) {
return null;
}
return {
...printer,
deviceId,
name: printer.name || printer.localName || uni.getStorageSync('printerName') || '上次连接的打印机',
localName: printer.localName || printer.name || '',
isCached: true
};
},
savePrinterCache(device, serviceId, characteristicId) {
const deviceName = device.name || device.localName || '上次连接的打印机';
uni.setStorageSync('deviceId', device.deviceId);
uni.setStorageSync('serviceId', serviceId);
uni.setStorageSync('characteristicId', characteristicId);
uni.setStorageSync('printerName', deviceName);
uni.setStorageSync('printerDevice', {
deviceId: device.deviceId,
name: deviceName,
localName: device.localName || device.name || '',
updatedAt: Date.now()
});
},
clearPrinterConnectionCache() {
uni.removeStorageSync('deviceId');
uni.removeStorageSync('serviceId');
uni.removeStorageSync('characteristicId');
},
addCachedDeviceToList() {
const cachedPrinter = this.getCachedPrinter();
if (cachedPrinter) {
this.addDevice(cachedPrinter, true);
}
},
addDevice(device, isCached = false) {
if (!device || !device.deviceId) {
return;
}
const deviceName = device.name || device.localName || '';
if (!deviceName && !isCached) {
return;
}
const cachedPrinter = this.getCachedPrinter();
const sameCachedName = cachedPrinter && deviceName && (
deviceName == cachedPrinter.name || deviceName == cachedPrinter.localName
);
const normalizedDevice = {
...device,
name: deviceName || '上次连接的打印机',
localName: device.localName || device.name || '',
isCached: isCached || sameCachedName
};
let index = this.devicesList.findIndex(item => item.deviceId == normalizedDevice.deviceId);
if (index == -1 && normalizedDevice.isCached) {
index = this.devicesList.findIndex(item => item.isCached);
}
if (index > -1) {
const mergedDevice = {
...this.devicesList[index],
...normalizedDevice,
isCached: this.devicesList[index].isCached || normalizedDevice.isCached
};
if (mergedDevice.isCached && deviceName) {
uni.setStorageSync('printerName', deviceName);
uni.setStorageSync('printerDevice', {
deviceId: mergedDevice.deviceId,
name: deviceName,
localName: mergedDevice.localName || deviceName,
updatedAt: Date.now()
});
}
this.$set(this.devicesList, index, mergedDevice);
return;
}
if (normalizedDevice.isCached) {
this.devicesList.unshift(normalizedDevice);
} else {
this.devicesList.push(normalizedDevice);
}
},
listenBluetoothDevices() {
if (this.isListeningBluetoothDeviceFound) {
return;
}
this.isListeningBluetoothDeviceFound = true;
this.bluetoothDeviceFoundHandler = (res4) => {
(res4.devices || []).forEach((device) => {
this.addDevice(device);
});
};
wx.onBluetoothDeviceFound(this.bluetoothDeviceFoundHandler);
},
refreshBluetoothDevices() {
wx.getBluetoothDevices({
success: (res) => {
(res.devices || []).forEach((device) => {
this.addDevice(device);
});
}
});
},
startSearchTimeout() {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.isSearching = false;
this.stopSearchBtnTap();
uni.hideLoading();
if (this.devicesList.length <= 0) {
this.showToast('未搜索到打印机,请确认打印机已开机并靠近手机');
}
}, 12000);
},
closeCurrentConnection(delay = 0, deviceId = '') {
deviceId = deviceId || uni.getStorageSync('deviceId') || (this.currentDevice && this.currentDevice.deviceId);
if (!deviceId) {
return;
}
setTimeout(() => {
wx.closeBLEConnection({
deviceId,
success() {},
fail() {}
});
}, delay);
},
fallbackToSearch(message) {
clearTimeout(this.connectTimer);
this.closeCurrentConnection();
uni.hideLoading();
this.isPrinting = false;
this.isShowSearch = true;
this.clearPrinterConnectionCache();
if (message) {
this.showToast(message);
}
if (!this.isSearching) {
this.sousuo({
autoConnectCache: false,
keepList: true
});
}
},
// //
handlePrintTap() { handlePrintTap() {
let that = this let that = this
if (that.isPrinting) {
return;
}
that.clearTimers();
that.isPrinting = true;
that.writeFailing = false;
uni.showLoading({ uni.showLoading({
mask: true, mask: true,
title: '打印中...' title: '打印中...'
@ -135,7 +324,9 @@
wx.openBluetoothAdapter({ //111 wx.openBluetoothAdapter({ //111
mode: 'central', mode: 'central',
success: (res2) => { success: (res2) => {
that.sousuo() that.sousuo({
autoConnectCache: true
})
}, },
fail: (res) => { fail: (res) => {
@ -147,26 +338,34 @@
mask: true mask: true
}) })
} else { } else {
that.tui.toast('连接失败,请重启蓝牙或删除小程序重新进入-1') that.showToast('连接失败,请重启蓝牙或删除小程序重新进入-1')
that.isShowSearch = true that.isShowSearch = true
} }
setTimeout(res => { that.isPrinting = false;
uni.hideLoading(); uni.hideLoading();
}, 2000)
} }
}) })
}, },
// //
sousuo() { sousuo(options = {}) {
let that = this; let that = this;
this.devicesList = [] if (!options.keepList) {
this.devicesList = []
}
this.addCachedDeviceToList();
this.listenBluetoothDevices();
this.isSearching = true;
wx.startBluetoothDevicesDiscovery({ //222 wx.startBluetoothDevicesDiscovery({ //222
allowDuplicatesKey: false,
success(res3) { success(res3) {
that.jiantingshebei() that.refreshBluetoothDevices()
that.startSearchTimeout()
that.jiantingshebei(options.autoConnectCache === true)
}, },
fail(err) { fail(err) {
that.tui.toast('连接失败,请重启蓝牙或删除小程序重新进入-2',err) that.isSearching = false;
that.showToast('连接失败,请重启蓝牙或删除小程序重新进入-2')
wx.closeBLEConnection({ wx.closeBLEConnection({
deviceId: uni.getStorageSync('deviceId'), deviceId: uni.getStorageSync('deviceId'),
@ -183,52 +382,64 @@
} }
}) })
uni.removeStorageSync('deviceId') that.clearPrinterConnectionCache()
that.handlePrintTap()
that.isShowSearch = true that.isShowSearch = true
setTimeout(res => { that.isPrinting = false;
uni.hideLoading(); uni.hideLoading();
}, 2000)
} }
}) })
}, },
// //
stopSearchBtnTap() { stopSearchBtnTap() {
wx.stopBluetoothDevicesDiscovery() clearTimeout(this.searchTimer);
this.searchTimer = null;
this.isSearching = false;
wx.stopBluetoothDevicesDiscovery({
success() {},
fail() {}
})
}, },
/** /**
* jiantingshebei方法判断缓存中有没有deviceId等数据的时候 * jiantingshebei方法判断缓存中有没有deviceId等数据的时候
* 直接拿到缓存中的deviceId等直接请求 wx.createBLEConnection * 直接拿到缓存中的deviceId等直接请求 wx.createBLEConnection
* 没有才会调用 wx.onBluetoothDeviceFound 搜索 * 没有才会调用 wx.onBluetoothDeviceFound 搜索
*/ */
jiantingshebei() { jiantingshebei(autoConnectCache = true) {
let that = this; let that = this;
if (uni.getStorageSync('deviceId')) { const cachedPrinter = that.getCachedPrinter();
if (autoConnectCache && cachedPrinter && cachedPrinter.deviceId) {
// that.huoqufuwu(uni.getStorageSync('deviceId')) // that.huoqufuwu(uni.getStorageSync('deviceId'))
that.lianejieshebei(uni.getStorageSync('deviceId')) that.lianejieshebei(cachedPrinter.deviceId, {
device: cachedPrinter,
isCached: true
})
} else { } else {
uni.hideLoading(); uni.hideLoading();
that.isShowSearch = true that.isShowSearch = true
//
wx.onBluetoothDeviceFound((res4) => { //333
res4.devices.forEach((device) => {
if (!device.name && !device.localName) {
return
}
that.devicesList.push(device)
})
})
} }
}, },
lianejieshebei(deviceId) { lianejieshebei(deviceId, options = {}) {
let that = this; let that = this;
const retryCount = options.retryCount || 0;
const device = options.device || that.devicesList.find(item => item.deviceId == deviceId) || that.getCachedPrinter() || {
deviceId,
name: '上次连接的打印机'
};
that.currentDevice = device;
that.isPrinting = true;
uni.showLoading({ uni.showLoading({
mask: true, mask: true,
title: '加载中...' title: '连接打印机...'
}); });
let timerId = setTimeout(() => { clearTimeout(that.connectTimer);
let finished = false;
that.connectTimer = setTimeout(() => {
if (finished) {
return;
}
finished = true;
wx.closeBLEConnection({ wx.closeBLEConnection({
deviceId: deviceId, deviceId: deviceId,
success(res2) { success(res2) {
@ -237,37 +448,49 @@
} }
}) })
wx.closeBluetoothAdapter({ that.fallbackToSearch('上次连接的打印机连接超时,请从列表重新选择')
success(res) {
},fail(err2){
}
})
uni.removeStorageSync('deviceId')
that.handlePrintTap()
that.isShowSearch = true
return return
}, 5000); }, 8000);
// //
wx.createBLEConnection({ //555 wx.createBLEConnection({ //555
deviceId: deviceId, // deviceId deviceId: deviceId, // deviceId
success: () => { success: () => {
// //
clearTimeout(timerId); if (finished) {
return;
}
finished = true;
clearTimeout(that.connectTimer);
that.isShowSearch = false that.isShowSearch = false
that.stopSearchBtnTap();
that.huoqufuwu(deviceId) that.huoqufuwu(deviceId)
}, },
fail: (res) => { fail: (res) => {
if (finished) {
clearTimeout(timerId); return;
}
finished = true;
clearTimeout(that.connectTimer);
if(res.errno == '1509007'){ if(res.errno == '1509007'){
that.huoqufuwu(deviceId) that.huoqufuwu(deviceId)
return;
} }
if(res.errno == '1509003'){ if((res.errno == '1509003' || res.errCode == 10003) && retryCount < 1){
that.lianejieshebei(deviceId) wx.closeBLEConnection({
deviceId,
success() {},
fail() {}
});
setTimeout(() => {
that.lianejieshebei(deviceId, {
...options,
retryCount: retryCount + 1
});
}, 500);
return;
} }
that.fallbackToSearch(options.isCached ? '上次连接的打印机连接失败,请从列表重新选择' : '打印机连接失败,请重新选择设备')
} }
}) })
}, },
@ -277,62 +500,56 @@
wx.getBLEDeviceServices({ //666 wx.getBLEDeviceServices({ //666
deviceId: deviceId, // deviceId deviceId: deviceId, // deviceId
success: (res5) => { success: (res5) => {
that.duxietezhengzhi(deviceId, res5) if (!res5.services || res5.services.length <= 0) {
that.fallbackToSearch('未找到打印机服务,请重新选择设备')
return;
}
that.duxietezhengzhi(deviceId, res5.services, 0)
}, },
fail: (res) => { fail: (res) => {
that.tui.toast('连接失败,请重启蓝牙或删除小程序重新进入-4',res) that.showToast('连接失败,请重启蓝牙或删除小程序重新进入-4')
wx.closeBLEConnection({ wx.closeBLEConnection({
deviceId: uni.getStorageSync('deviceId'), deviceId: deviceId,
success(res1) { success(res1) {
} }
}) })
uni.removeStorageSync('deviceId') that.fallbackToSearch()
that.sousuo()
that.isShowSearch = true
setTimeout(res => {
uni.hideLoading();
}, 2000)
} }
}) })
}, },
duxietezhengzhi(deviceId, res5) { duxietezhengzhi(deviceId, services, index = 0) {
let that = this; let that = this;
if (!services || index >= services.length) {
that.fallbackToSearch('未找到可写入的打印机服务,请重新选择设备')
return;
}
const serviceId = services[index].uuid;
// //
wx.getBLEDeviceCharacteristics({ //777 wx.getBLEDeviceCharacteristics({ //777
deviceId: deviceId, // deviceId deviceId: deviceId, // deviceId
serviceId: res5.services[0].uuid, // serviceId: serviceId, //
success: (res6) => { success: (res6) => {
for (let i = 0; i < res6.characteristics.length; i++) { const characteristics = res6.characteristics || [];
let item = res6.characteristics[i] const notifyItem = characteristics.find(item => item.properties && (item.properties.notify || item.properties.indicate));
that.startNoticeBle(deviceId, res5.services[0].uuid, res6.characteristics[2].uuid) const writeItem = characteristics.find(item => item.properties && (item.properties.write || item.properties.writeNoResponse));
if (item.properties.write) { // if (writeItem) { //
if (notifyItem) {
uni.setStorageSync('deviceId', deviceId); that.startNoticeBle(deviceId, serviceId, notifyItem.uuid)
uni.setStorageSync('serviceId', res5.services[0].uuid);
uni.setStorageSync('characteristicId', item.uuid);
that.xierushuju()
return;
} }
that.savePrinterCache({
...that.currentDevice,
deviceId
}, serviceId, writeItem.uuid);
that.xierushuju()
return;
} }
that.duxietezhengzhi(deviceId, services, index + 1)
}, },
fail: (res) => { fail: (res) => {
that.tui.toast('连接失败,请重启蓝牙或删除小程序重新进入-5',res) that.duxietezhengzhi(deviceId, services, index + 1)
wx.closeBLEConnection({
deviceId: uni.getStorageSync('deviceId'),
success(res) {
}
})
uni.removeStorageSync('deviceId')
that.sousuo()
that.isShowSearch = true
setTimeout(res => {
uni.hideLoading();
}, 2000)
} }
}) })
}, },
@ -361,17 +578,10 @@
_this.bleData = _this.ab2hex(res.value) _this.bleData = _this.ab2hex(res.value)
console.log('返回值是什么',_this.bleData) console.log('返回值是什么',_this.bleData)
uni.hideLoading() if (_this.isWriting) {
setTimeout(res=>{ return;
uni.closeBLEConnection({ }
deviceId: uni.getStorageSync('deviceId'), _this.finishPrint()
success(res) {
},
fail(err) {}
})
},_this.picWaitTime)
}) })
}, },
@ -406,51 +616,86 @@
const delay = that.deviceType == 'android' ? 20 : 180; const delay = that.deviceType == 'android' ? 20 : 180;
let buffer = gbk.strToGBKByte(dataStr) let buffer = gbk.strToGBKByte(dataStr)
if (!buffer || buffer.byteLength <= 0) {
that.finishPrint();
that.showToast('暂无打印内容');
return;
}
if(dataStr.indexOf('EG ') != -1){ if(dataStr.indexOf('EG ') != -1){
that.picWaitTime = buffer.byteLength + 200 that.picWaitTime = buffer.byteLength + 200
} }
const chunks = [];
for (let i = 0, j = 0, length = buffer.byteLength; i < length; i += maxChunk, j++) { 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); let subPackage = buffer.slice(i, i + maxChunk <= length ? (i + maxChunk) : length);
setTimeout(that._writeBLECharacteristicValue, j * delay, subPackage); chunks.push(subPackage);
} }
that.isWriting = true;
that.writeChunks(chunks, 0, delay);
}) })
return; return;
}, },
_writeBLECharacteristicValue(buffer) { writeChunks(chunks, index, delay) {
let that = this; if (this.writeFailing) {
return;
}
if (index >= chunks.length) {
this.isWriting = false;
this.finishPrint();
return;
}
this._writeBLECharacteristicValue(chunks[index], () => {
setTimeout(() => {
this.writeChunks(chunks, index + 1, delay);
}, delay);
}, (res) => {
this.handleWriteFail(res);
});
},
_writeBLECharacteristicValue(buffer, success, fail) {
wx.writeBLECharacteristicValue({ wx.writeBLECharacteristicValue({
deviceId: uni.getStorageSync('deviceId'), deviceId: uni.getStorageSync('deviceId'),
serviceId: uni.getStorageSync('serviceId'), serviceId: uni.getStorageSync('serviceId'),
characteristicId: uni.getStorageSync('characteristicId'), characteristicId: uni.getStorageSync('characteristicId'),
value: buffer, value: buffer,
success(res) { success(res) {
success && success(res);
}, },
fail(res) { fail(res) {
wx.closeBLEConnection({ fail && fail(res);
deviceId: uni.getStorageSync('deviceId'),
success(res) {
}
})
if (uni.getStorageSync('deviceId')) {
// that.xierushuju()
} else {
that.jiantingshebei()
}
uni.hideLoading();
} }
}) })
}, },
handleWriteFail(res) {
this.writeFailing = true;
this.isWriting = false;
this.closeCurrentConnection();
this.fallbackToSearch('打印数据发送失败,请重新选择打印机后再试');
},
finishPrint() {
if (!this.isPrinting && !uni.getStorageSync('deviceId')) {
return;
}
clearTimeout(this.printFinishTimer);
uni.hideLoading();
this.isPrinting = false;
this.isWriting = false;
this.writeFailing = false;
this.printFinishTimer = setTimeout(() => {
this.closeCurrentConnection();
this.picWaitTime = 0;
}, this.picWaitTime || 300);
},
handleSearchClose() { handleSearchClose() {
this.stopSearchBtnTap();
wx.closeBluetoothAdapter({ wx.closeBluetoothAdapter({
success(res) { success(res) {
} }
}) })
this.isShowSearch = false this.isShowSearch = false
this.isPrinting = false
} }
} }
} }

Loading…
Cancel
Save