From 8b592ade95ab9ae8f4b04d7504794b7dca0fcde3 Mon Sep 17 00:00:00 2001 From: whycq <10027870+whycq@user.noreply.gitee.com> Date: 星期二, 25 四月 2023 18:34:04 +0800 Subject: [PATCH] # --- pages/print/print.vue | 452 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 405 insertions(+), 47 deletions(-) diff --git a/pages/print/print.vue b/pages/print/print.vue index ec0a463..c61ef22 100644 --- a/pages/print/print.vue +++ b/pages/print/print.vue @@ -1,58 +1,416 @@ <template> - <view> - <button @click="connectBluetooth">connect</button> + <!-- 钃濈墮鎵撳嵃椤甸潰 --> + <view class="page"> + <button @click="openBluetoothAdapter">閲嶆柊鏌ヨ</button> + <view class="title"> + 鍙繛鎺ョ殑钃濈墮璁惧鍒楄〃锛� + <text style="color: red;font-size:22rpx;">(閮ㄥ垎鏈哄瀷闇�瑕佹墦寮�GPS瀹氫綅鏈嶅姟)</text> + </view> + <view class="list"> + <view class="item" v-for="(item, i) in devices" :key="i"> + <!-- 璁惧鍚嶇О --> + <text>{{ item.name }}</text> + <!-- 杩炴帴鐘舵�� --> + <view class="right"> + <view class="font-color-3" @click="createBLEConnection(item)" v-show="!item.isShowConnect">杩炴帴璁惧</view> + <view class="font-color-3" v-show="item.isShowConnect">宸茶繛鎺�</view> + </view> + </view> + <!-- v-if="devices.length" --> + <button @click="writeBLECharacteristicValue">寮�濮嬫墦鍗�</button> + <!-- <button :class="isDisabled || isConnected ? 'submit disabled' : 'submit'" @click="writeBLECharacteristicValue" :disabled="isDisabled || isConnected">寮�濮嬫墦鍗�</button> --> + <view class="no-devices" v-if="!devices.length">鏈悳绱㈠埌钃濈墮璁惧</view> + </view> </view> </template> <script> - export default { - data() { - return { +const LAST_CONNECTED_DEVICE = 'last_connected_device'; +import PrinterJobs from '../../static/js/printerjobs'; +import printerUtil from '../../static/js/printerutil'; - } - }, - methods: { - connectBluetooth() { - let that = this - uni.openBluetoothAdapter({ - success(res) { - console.log(res) - uni.getBluetoothAdapterState({ - success(res) { - console.log(res); - if (!res.discovering) { - uni.startBluetoothDevicesDiscovery({ - success(res) { - console.log(res); - uni.onBluetoothDeviceFound(devices => { - console.log('寮�濮嬬洃鍚鎵惧埌鏂拌澶囩殑浜嬩欢'); - // this.$set(this.disabled, 3, false); - uni.getBluetoothDevices({ - success: res => { - this.newDeviceLoad = false; - console.log('鑾峰彇钃濈墮璁惧鎴愬姛:' + res.errMsg); - // console.log(JSON.stringify(res)) - }, - }); - }); - }, - fail(err) { - console.log(); - } - }) - } - } - }) - }, - }) - // 鐩戝惉钃濈墮璁惧鍒楄〃 - - }, - +function inArray(arr, key, val) { + for (let i = 0; i < arr.length; i++) { + if (arr[i][key] === val) { + return i; } } + return -1; +} + +// ArrayBuffer杞�16杩涘害瀛楃涓茬ず渚� +function ab2hex(buffer) { + const hexArr = Array.prototype.map.call(new Uint8Array(buffer), function(bit) { + return ('00' + bit.toString(16)).slice(-2); + }); + return hexArr.join(','); +} + +function str2ab(str) { + // Convert str to ArrayBuff and write to printer + let buffer = new ArrayBuffer(str.length); + let dataView = new DataView(buffer); + for (let i = 0; i < str.length; i++) { + dataView.setUint8(i, str.charAt(i).charCodeAt(0)); + } + return buffer; +} + +export default { + name: 'print', + components: {}, + props: {}, + data() { + return { + devices: [], + connected: false, + isConnected: true, + name: '', + deviceId: null + }; + }, + onLoad() {}, + onShow() {}, + created() {}, + mounted() { + this.openBluetoothAdapter(); + }, + methods: { + // 鍒濆鍖栬摑鐗� + openBluetoothAdapter() { + console.log('鍒濆鍖栬摑鐗欐ā鍧� openBluetoothAdapter'); + if (!uni.openBluetoothAdapter) { + console.log('寰俊鐗堟湰杩囦綆'); + uni.showModal({ + title: '鎻愮ず', + content: '褰撳墠寰俊鐗堟湰杩囦綆锛屾棤娉曚娇鐢ㄨ鍔熻兘锛岃鍗囩骇鍒版渶鏂板井淇$増鏈悗閲嶈瘯銆�' + }); + return; + } + uni.showLoading({ + title: '寮�濮嬫悳绱㈣摑鐗欒澶�' + }); + // uni.hideLoading(); + uni.openBluetoothAdapter({ + success: res => { + console.log('鍒濆鍖栨垚鍔無penBluetoothAdapter success', res); + uni.hideLoading(); + // 鎼滃闄勮繎鐨勮摑鐗� + this.startBluetoothDevicesDiscovery(); + }, + fail: res => { + console.log('鍒濆鍖栧け璐penBluetoothAdapter fail', res); + // uni.showModal({ + // content: res.errMsg, + // showCancel: false + // }); + uni.hideLoading(); + if (res.errCode === 10001) { + // 褰撳墠钃濈墮閫傞厤鍣ㄤ笉鍙敤 + uni.showModal({ + title: '閿欒', + content: '鏈壘鍒拌摑鐗欒澶�, 璇锋墦寮�钃濈墮鍚庨噸璇曘��', + showCancel: false + }); + // 鐩戝惉钃濈墮閫傞厤鍣ㄧ姸鎬佸彉鍖栦簨浠� + uni.onBluetoothAdapterStateChange(res => { + console.log('鐩戝惉钃濈墮閫傞厤鍣ㄧ姸鎬� onBluetoothAdapterStateChange', res); + // available锛氳摑鐗欓�傞厤鍣ㄦ槸鍚﹀彲鐢� + if (res.available) { + // 鍙栨秷鐩戝惉锛屽惁鍒檚topBluetoothDevicesDiscovery鍚庝粛浼氱户缁Е鍙憃nBluetoothAdapterStateChange锛� + // 瀵艰嚧鍐嶆璋冪敤startBluetoothDevicesDiscovery + // uni.onBluetoothAdapterStateChange(() => {}); + // 寮�濮嬫悳瀵婚檮杩戠殑钃濈墮澶栧洿璁惧 + this.startBluetoothDevicesDiscovery(); + } + }); + } + } + }); + }, + // 寮�濮嬫悳瀵婚檮杩戠殑钃濈墮澶栧洿璁惧 + startBluetoothDevicesDiscovery() { + console.log('寮�濮嬫悳瀵婚檮杩戠殑钃濈墮璁惧'); + uni.startBluetoothDevicesDiscovery({ + allowDuplicatesKey: false, + interval: 0, + success: res => { + console.log('鎼滃闄勮繎鐨勮摑鐗欏鍥磋澶� startBluetoothDevicesDiscovery success111', res); + // 鐩戝惉瀵绘壘鍒版柊璁惧鐨勪簨浠� + this.onBluetoothDeviceFound(); + }, + fail: res => { + console.log('鎼滃闄勮繎鐨勮摑鐗欏鍥磋澶� startBluetoothDevicesDiscovery fail', res); + uni.hideLoading(); + } + }); + }, + // 鐩戝惉瀵绘壘鍒版柊璁惧鐨勪簨浠� + onBluetoothDeviceFound() { + console.log('杩涘叆鏌ヨ璁惧'); + uni.onBluetoothDeviceFound(res => { + console.log('瀵绘壘璁惧', res.devices); + res.devices.forEach(device => { + if (!device.name && !device.localName) { + return; + } + const foundDevices = this.devices; + // 鍦ㄦ暟缁勪腑鏌ユ壘鎸囧畾鍊硷紝骞惰繑鍥炲畠鐨勭储寮曞�硷紙濡傛灉娌℃湁鎵惧埌锛屽垯杩斿洖-1锛� + const idx = inArray(foundDevices, 'deviceId', device.deviceId); + const data = {}; + if (idx === -1) { + this.$set(this.devices, `${foundDevices.length}`, device); + } else { + this.$set(this.devices, `${idx}`, device); + } + console.log('鎼滅储缁撴灉', this.devices); + uni.hideLoading(); + }); + }); + }, + + // this.devices鏄摑鐗欒澶囧垪琛紝娓叉煋鍒伴〉闈㈡樉绀虹偣鍑绘墽琛岃摑鐗欒繛鎺� + // 鐐瑰嚮閾炬帴钃濈墮 + createBLEConnection(e) { + console.log('鐐瑰嚮杩炴帴钃濈墮', e); + const deviceId = e.deviceId; + const name = e.name; + this._createBLEConnection(deviceId, name); + }, + + _createBLEConnection(deviceId, name) { + // this.$myToast('杩炴帴璁惧涓�', 'loading'); + // 杩炴帴浣庡姛鑰楄摑鐗欒澶� + uni.createBLEConnection({ + deviceId, // 鐢ㄤ簬鍖哄垎璁惧鐨� id + success: () => { + console.log('杩炴帴钃濈墮鎺ュ彛璋冪敤鎴愬姛 createBLEConnection success', this.devices); + this.devices.forEach((item, index) => { + this.$set(this.devices[index], 'isShowConnect', false); + if (item.deviceId === deviceId) { + this.$set(this.devices[index], 'isShowConnect', true); + } + }); + this.$myToast('璁惧杩炴帴鎴愬姛', 'success'); + + this.connected = true; + this.isConnected = false; + this.name = name; + this.deviceId = deviceId; + // 鑾峰彇钃濈墮璁惧鎵�鏈夋湇鍔�(service) + this.getBLEDeviceServices(deviceId); + // 鏈�鍚庤繛鎺ヨ澶� + uni.setStorage({ + key: LAST_CONNECTED_DEVICE, + data: name + ':' + deviceId + }); + }, + complete() { + uni.hideLoading(); + }, + fail: res => { + // 杩炴帴钃濈墮鎺ュ彛璋冪敤澶辫触 + console.log('杩炴帴钃濈墮鎺ュ彛璋冪敤澶辫触 createBLEConnection fail', res); + uni.showModal({ + title: this.$t('wechat.w227'), + content: '钃濈墮杩炴帴澶辫触', + showCancel: false + }); + } + }); + // 宸茬粡鎵惧埌闇�瑕佺殑钃濈墮璁惧,鍋滄鎼滃闄勮繎鐨勮摑鐗欏鍥磋澶� + this.stopBluetoothDevicesDiscovery(); + }, + // 鑾峰彇钃濈墮璁惧鎵�鏈夋湇鍔�(service) + getBLEDeviceServices(deviceId) { + uni.getBLEDeviceServices({ + deviceId, + success: res => { + console.log('鑾峰彇钃濈墮璁惧鎵�鏈夋湇鍔� getBLEDeviceServices', res); + for (let i = 0; i < res.services.length; i++) { + if (res.services[i].isPrimary) { + this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid); + return; + } + } + } + }); + }, + stopBluetoothDevicesDiscovery() { + uni.stopBluetoothDevicesDiscovery({ + complete: () => { + // console.log('stopBluetoothDevicesDiscovery') + this._discoveryStarted = false; + } + }); + }, + /* + 鑾峰彇钃濈墮璁惧鏌愪釜鏈嶅姟涓墍鏈夌壒寰佸��(characteristic) + characteristic: + uuid:钃濈墮璁惧鐗瑰緛鍊肩殑 uuid + properties:璇ョ壒寰佸�兼敮鎸佺殑鎿嶄綔绫诲瀷 + */ + getBLEDeviceCharacteristics(deviceId, serviceId) { + uni.getBLEDeviceCharacteristics({ + // 杩欓噷鐨� deviceId 闇�瑕佸凡缁忛�氳繃 createBLEConnection 涓庡搴旇澶囧缓绔嬮摼鎺� + deviceId, + // 杩欓噷鐨� serviceId(钃濈墮鏈嶅姟 uuid) 闇�瑕佸湪 getBLEDeviceServices 鎺ュ彛涓幏鍙� + serviceId, + success: res => { + console.log('鐗瑰緛鍊煎彉鍖� getBLEDeviceCharacteristics success', res.characteristics); + // 杩欓噷浼氬瓨鍦ㄧ壒寰佸�兼槸鏀寔write锛屽啓鍏ユ垚鍔熶絾鏄病鏈変换浣曞弽搴旂殑鎯呭喌 + // 鍙兘涓�涓釜鍘昏瘯 + // characteristics锛氳澶囨湇鍔″垪琛� + for (let i = 0; i < res.characteristics.length; i++) { + const item = res.characteristics[i]; + // if (item.properties.read) { + // uni.readBLECharacteristicValue({ + // deviceId, + // serviceId, + // characteristicId: item.uuid + // }) + // } + + if (item.properties.write) { + this.canWrite = true; + this._deviceId = deviceId; + this._serviceId = serviceId; + this._characteristicId = item.uuid; + } + + if (item.properties.notify || item.properties.indicate) { + uni.notifyBLECharacteristicValueChange({ + deviceId, + serviceId, + characteristicId: item.uuid, + state: true + }); + } + + if (item.properties.write) { + this.canWrite = true; + this._deviceId = deviceId; + this._serviceId = serviceId; + this._characteristicId = item.uuid; + } + + if (item.properties.notify || item.properties.indicate) { + uni.notifyBLECharacteristicValueChange({ + deviceId, + serviceId, + characteristicId: item.uuid, + state: true + }); + } + } + }, + fail(res) { + console.error('鐗瑰緛鍊煎彉鍖� getBLEDeviceCharacteristics', res); + } + }); + }, + + // 钃濈墮杩炴帴鎴愬姛鍚庣偣鍑绘墦鍗帮紝鎵撳嵃鏁版嵁 + // 鐐瑰嚮鎵撳嵃锛氬啓鍏ユ暟鎹紙鏍规嵁椤圭洰闇�瑕佹墦鍗板唴瀹规潵瀹炵幇锛� + writeBLECharacteristicValue() { + console.log('鍐欐暟鎹�'); + let printerJobs = new PrinterJobs(); + // 瑕佹墦鍗扮殑淇℃伅 + printerJobs + .setAlign('ct') + .setSize(2, 2) + .print('璁板綍鎶ュ憡') + .setSize(0, 0) + .print() + .setAlign('lt'); + // 鎵撳嵃 + printerJobs.print(printerUtil.fillLine()); + // 缁撳熬 + printerJobs + .println() + .print('绛惧悕') + .println() + .println(); + + let buffer = printerJobs.buffer(); + // console.log('ArrayBuffer', 'length: ' + buffer.byteLength, ' hex: ' + ab2hex(buffer)); + // 1.骞惰璋冪敤澶氭浼氬瓨鍦ㄥ啓澶辫触鐨勫彲鑳芥�� + // 2.寤鸿姣忔鍐欏叆涓嶈秴杩�20瀛楄妭 + // 鍒嗗寘澶勭悊锛屽欢鏃惰皟鐢� + const maxChunk = 20; + const delay = 40; + console.log(111111); + 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); + // subPackage锛氬弬鏁� + setTimeout(this._writeBLECharacteristicValue, j * delay, subPackage); + } + + console.log(22222); + }, + // 鍚戜綆鍔熻�楄摑鐗欒澶囩壒寰佸�间腑鍐欏叆浜岃繘鍒舵暟鎹�傛敞鎰忥細蹇呴』璁惧鐨勭壒寰佸�兼敮鎸� write 鎵嶅彲浠ユ垚鍔熻皟鐢ㄣ�� + _writeBLECharacteristicValue(buffer) { + console.log('鍐欏叆鏁版嵁'); + uni.writeBLECharacteristicValue({ + deviceId: this._deviceId, // 钃濈墮璁惧 id + serviceId: this._serviceId, // 钃濈墮鐗瑰緛鍊煎搴旀湇鍔$殑 uuid + characteristicId: this._characteristicId, // 钃濈墮鐗瑰緛鍊肩殑 uuid + value: buffer, // 钃濈墮璁惧鐗瑰緛鍊煎搴旂殑浜岃繘鍒跺�� + success(res) { + console.log('writeBLECharacteristicValue success', res); + }, + fail(res) { + console.log('writeBLECharacteristicValue fail', res); + } + }); + } + } +}; </script> -<style> +<style scoped lang="scss"> +.page { + margin: 20rpx; + color: #323232; + background-color: #f5f9ff; + height: 100vh; +} +.title { + font-weight: 600; + margin: 20rpx 0rpx; +} +.list { + .item { + display: flex; + justify-content: space-between; + padding: 10rpx 20rpx; + height: 60rpx; + line-height: 60rpx; + background-color: #ffffff; + margin-bottom: 4rpx; + } -</style> + .right { + } + .no-devices { + height: 400rpx; + font-size: 32rpx; + line-height: 400rpx; + text-align: center; + color: #969696; + } +} + +.font-color-3 { + color: #1a8cff; +} + +.submit { + background-color: #4d88ff !important; + color: #f5f9ff !important; +} + +.disabled { + background-color: #66b1ff !important; +} +</style> \ No newline at end of file -- Gitblit v1.9.1