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