<template>
	<view class="content">
		<view class="cz-box" @click="toWork">
			<view :class="loading?'turn':''">
				<u-image width="100rpx" height="100rpx" src="/static/chengzhong.png"></u-image>
				<view class="tits">投放称重</view>
			</view>
		</view>
		<view class="bindDev" @click="toInit">
			{{statusStr}}
		</view>
		<view class="devList">
			<view v-for="item in deviceList" :key="item.deviceId">
				<view class="names">
					<view>{{item.name}}</view>
					<view class="texts">MAC：{{item.deviceId}}</view>
				</view>
				<view class="btns" @click="connectBlue(item)" v-if="!connectStatus">点击连接</view>
				<view class="btns" @click="closeBlue" v-else>断开连接</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				deviceList:[], // 设备列表
				deviceId: '',
				connectedDeviceId: '',
				services: [],
				readsId:'',
				writeId:'',
				notifyServicweId: '',
				writeDatas: '',
				balanceData: '',
				hexstr: '',
				statusStr: '绑定电子秤',
				connectStatus: false ,// 设备连接状态
				loading: false ,// 正在连接
			}
		},
		onShow() {
			console.log('onShow')
		},
		methods: {
			// 去认证用户并开始称重
			toWork(){
				let _this = this
				// 连接成功
				if(this.connectStatus){
					uni.navigateTo({
						url: '/pages/userAuth/userAuth'
					})
				}else{
					let hasDev = this.deviceList.length
					uni.showModal({
						title:'提示',
						content:hasDev ? '请先连接设备':'请先绑定设备',
						confirmText: hasDev ? '确定':'去绑定',
						complete(e) {
							console.log(e)
							if(e.confirm){
								if(hasDev == 1){
									_this.connectBlue(_this.deviceList[0])
								}
								if(hasDev == 0){
									_this.toInit()
								}
							}
						}
					})
				}
			},
			// 初始化蓝牙
			toInit(){
				let _this = this
				uni.openBluetoothAdapter({
				  success(res) {
				    console.log(res, 'openBluetoothAdapter success')
					_this.onBluetoothAdapterStateChange()
					setTimeout(()=>{
						_this.toFindDev()
					},1000)
				  },
				  fail(err){
					  console.log(err,'openBluetoothAdapter error')
					  uni.showModal({
					  	title:'提示',
					  	content:'请开启手机蓝牙',
					  	showCancel: false,
					  	complete(e) {
					  		console.log(e)
					  		_this.statusStr = '请开启手机蓝牙'
					  	}
					  })
				  }
				})
			},
			toFindDev(){
				let _this = this
				console.log(this.connectStatus,this.deviceList.length,this.loading)
				if(this.connectStatus || this.deviceList.length > 0 || this.loading){
					return
				}
				_this.statusStr = '开始搜寻附近的电子秤'
				_this.loading = true
				uni.getBluetoothAdapterState({
				  success(res) {
				    console.log(res)
					if(res.available){
						// 开始搜寻附近的蓝牙外围设备
						_this.startBluetoothDevicesDiscovery()
					}else{
						_this.statusStr = '请开启手机蓝牙'
					}
				  },
				  fail(err) {
					  console.log(err)
				  }
				})
			},
			// 监听蓝牙状态
			onBluetoothAdapterStateChange(){
				let _this = this
				// 监听蓝牙适配器状态变化事件
				uni.onBluetoothAdapterStateChange(function (res) {
				  console.log(res,'适配器变化')
				  if(!res.available){
					// 关闭连接
				  	_this.statusStr = '蓝牙已关闭，请开启手机蓝牙'
					_this.connectedDeviceId = null
					_this.closeConnect()
				  }else{
					if(!res.discovering && !_this.loading){
						_this.statusStr = '蓝牙已启用，请绑定设备'
					}
				  }
				})
			},
			startBluetoothDevicesDiscovery(){
				let _this = this
				uni.startBluetoothDevicesDiscovery({
				  services: [],
				  success(res) {
				    console.log(res)
					// 监听寻找到新设备的事件
					uni.onBluetoothDeviceFound(function (res) {
					  let devices = res.devices.filter(item => item.name == 'FAYA')
					  console.log(devices,'devices list')
					  if(devices.length){
						  _this.statusStr = '已发现设备'
						  _this.deviceList = res.devices
						  _this.loading = false
					  }
					})
				  }
				})
			},
			// 连接蓝牙设备
			connectBlue(item){
				this.deviceId = item.deviceId
				this.statusStr = '正在连接设备...'
				this.loading = true
				this.createBLEConnection()
			},
			// 断开蓝牙设备
			closeBlue(){
				this.statusStr = '连接已断开，请重新绑定设备'
				this.closeConnect()
			},
			// 开始连接指定设备
			createBLEConnection(){
				let _this = this
				uni.createBLEConnection({
				  // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
				  deviceId:this.deviceId,
				  success(res) {
				    console.log(res)
					_this.connectedDeviceId = _this.deviceId
					// 获取连接设备的service服务
					setTimeout(()=>{
						_this.getBLEDeviceServices()						  
					},1000)
				  }
				})
			},
			// 获取连接设备的service服务
			getBLEDeviceServices(){
				let _this = this
				uni.getBLEDeviceServices({
				  // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
				  deviceId: _this.deviceId,
				  success(res) {
				    console.log('device services:', res.services)
					// _this.statusStr = '获取连接设备的service服务成功'
					_this.services = res.services
					/* 获取连接设备的所有特征值 */
					setTimeout(()=>{
						_this.getBLEDeviceCharacteristics()
					},500)
					// 停止搜索
					uni.stopBluetoothDevicesDiscovery({
						success: function(res) {
							console.log(res, '停止搜索')
						},
						fail(res) {
						}
					})
				  }
				})
			},
			// 获取连接设备的所有特征值
			getBLEDeviceCharacteristics(){
				let _this = this
				this.notifyServicweId = this.services[1].uuid
				uni.getBLEDeviceCharacteristics({
					deviceId: this.connectedDeviceId,
					serviceId: this.notifyServicweId,
					success: function(res) {
						console.log(res)
						// _this.statusStr = '获取连接设备的所有特征值成功'
						for (let i = 0; i < res.characteristics.length; i++) {
							let properties = res.characteristics[i].properties
							// 读id
							if(properties.notify&&!properties.read&&!properties.write){
								_this.readsId = res.characteristics[i].uuid
							}
							// 写id
							if(!properties.notify&&!properties.read&&properties.write){
								_this.writeId = res.characteristics[i].uuid
							}
							console.log(_this.readsId,_this.writeId, '蓝牙特征值 ==========')
							// 启用低功耗蓝牙设备特征值变化时的 notify 功能
							setTimeout(()=>{
								_this.notifyBLECharacteristicValueChange()
							},500)
						}
					},
					fail: function(res) {
						console.log(res)
					}
				})
			},
			// 启用低功耗蓝牙设备特征值变化时的 notify 功能
			 notifyBLECharacteristicValueChange() { 
				let that = this;
				uni.notifyBLECharacteristicValueChange({
					state: true,
					deviceId: that.connectedDeviceId,
					serviceId: that.notifyServicweId,
					characteristicId: that.readsId,
					success(res) {
						console.log(res,'notifyBLECharacteristicValueChange')
						that.statusStr = '连接成功，请投放称重'
						that.connectStatus = true
						that.loading = false
						/*用来监听手机蓝牙设备的数据变化*/
						uni.onBLECharacteristicValueChange(function(res) {
							console.log(res,'read data')
							that.balanceData = that.buf2string(res.value)
							that.$u.vuex('vuex_balanceData',that.balanceData)
						})
						// that.sendData()
					},
					fail(res) {
						console.log(res, '启用低功耗蓝牙设备监听失败')
						that.statusStr = '设备连接失败，请点击重试'
						that.closeConnect()
					}
				})
			},
			/*转换成需要的格式*/
		    buf2string(buffer) {
				let arr = Array.prototype.map.call(new Uint8Array(buffer), x => x)
				return arr.map((char, i) => {
					return String.fromCharCode(char);
				}).join('');
			},
			receiveData(buf) {
					return this.hexCharCodeToStr(this.ab2hex(buf))
			},
			/*转成二进制*/
			ab2hex (buffer) {
			  let hexArr = Array.prototype.map.call(
				  new Uint8Array(buffer), function (bit) {
					  return ('00' + bit.toString(16)).slice(-2)
				  }
			  )
			  return hexArr.join('')
			},
			/*转成可展会的文字*/
			hexCharCodeToStr(hexCharCodeStr) {
			  let trimedStr = hexCharCodeStr.trim();
			  let rawStr = trimedStr.substr(0, 2).toLowerCase() === '0x' ? trimedStr.substr(2) : trimedStr;
			  let len = rawStr.length;
			  let curCharCode;
			  let resultStr = [];
			  for (let i = 0; i < len; i = i + 2) {
				  curCharCode = parseInt(rawStr.substr(i, 2), 16);
				  resultStr.push(String.fromCharCode(curCharCode));
			  }
			  return resultStr.join('');
			},
			// 发送数据
			sendData(str) {
			    let that = this;
			    let dataBuffer = new ArrayBuffer(3)
			    let dataView = new DataView(dataBuffer)
			     
				dataView.setUint8(0, 0x02)
				dataView.setUint8(1, 0x41)
				dataView.setUint8(2, 0x03)
			    let dataHex = that.ab2hex(dataBuffer);
			    this.writeDatas = that.hexCharCodeToStr(dataHex);
			    uni.writeBLECharacteristicValue({
			        deviceId: that.connectedDeviceId,
			        serviceId: that.notifyServicweId,
			        characteristicId: that.writeId,
			        value: dataBuffer,
			        success: function (res) {
			            console.log('发送数据成功：' + that.writeDatas)
			        },
			        fail: function (res) {
						console.log('发送失败：' + res)
			        },
			        complete: function (res) {
			        }
			    })
			},
			 // 断开设备连接
			closeConnect() {
				let that = this;
			    if (that.connectedDeviceId) {
			        uni.closeBLEConnection({
			            deviceId: that.connectedDeviceId,
			            success: function(res) {
							console.log(res)
							that.closeBluetoothAdapter()
			            },
			            fail(res) {
							console.log(res)
			            }
			        })
			    } else {
			        that.closeBluetoothAdapter()
			    }
			},
			// 关闭蓝牙模块
			closeBluetoothAdapter() {
				let that = this;
			    uni.closeBluetoothAdapter({
			        success: function(res) {
						console.log(res,'closeBluetoothAdapter')
						that.connectStatus = false
						that.loading = false
						that.balanceData = ''
						that.deviceList = []
			        },
			        fail: function(err) {
			        }
			    })
			},
		},
		onUnload() {
			this.closeConnect()
		}
	}
</script>

<style>
	.content{
		display: flex;
		align-items: center;
		justify-content: center;
		flex-direction: column;
		background-image: radial-gradient( #2ab4e5 0%, #0081c1 100%);
		height: 100vh;
		width: 100%;
	}
	.cz-box{
		text-align: center;
		background: #fff;
		border-radius: 300rpx;
		box-shadow: 3rpx 3rpx 10rpx rgba(0,0,0,0.4);
	}
	.cz-box > view{
		width: 250rpx;
		height: 250rpx;
		padding: 50rpx 50rpx 30rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		flex-direction: column;
	}
	.tits{
		padding: 20rpx 0;
		color: #ef9f2e;
	}
	.devList{
		width: 80%;
		padding:10rpx 30rpx;
	}
	.bindDev{
		margin: 20rpx 0;
		padding: 20rpx 40rpx;
		background: rgba(255,255,255,0.8);
		box-shadow: 2rpx 2rpx 8rpx rgba(0,0,0,0.2);
		border-radius: 100rpx;
		color: #666666;
	}
	.devList > view{
		display: flex;
		align-items: center;
		color: #666666;
		border-radius: 20rpx;
		background: rgba(255,255,255,0.8);
		box-shadow: 2rpx 2rpx 5rpx rgba(0,0,0,0.2);
	}
	.devList > view .names{
		flex-grow: 1;
		padding: 15rpx 40rpx;
	}
	.devList > view .texts{
		font-size: 24rpx;
	}
	.devList > view .btns{
		text-align: center;
		padding: 15rpx 40rpx;
		color: #ff5500;
	}
	.turn{
		animation:turn 1s linear infinite;
	}
	@keyframes turn{
	  0%{-webkit-transform:rotate(0deg);}
	  25%{-webkit-transform:rotate(90deg);}
	  50%{-webkit-transform:rotate(180deg);}
	  75%{-webkit-transform:rotate(270deg);}
	  100%{-webkit-transform:rotate(360deg);}
	}
</style>
