364 lines
8.6 KiB
Vue
364 lines
8.6 KiB
Vue
<template>
|
||
<view class="ble-connect">
|
||
<u-navbar :title="$tt('navBar.bleAddDevice')" bgColor="#F1F3F9"
|
||
:titleStyle="{fontWeight: 700, fontSize: '16px'}" @leftClick="handleGoback">
|
||
</u-navbar>
|
||
<view class="device-search">
|
||
<view class="img-wrap">
|
||
<image class="img" :class="{'rotating': isSearch }" src="/static/common/searching.png" />
|
||
</view>
|
||
<view class="title" v-if="isSearch">{{$tt('bleConnect.scanning')}}</view>
|
||
<view class="title" v-else>{{$tt('bleConnect.ifNoDev')}}</view>
|
||
<view class="describe" v-if="!isSearch">{{errmgs}}</view>
|
||
<view class="describe" v-if="isSearch">{{$tt('bleConnect.scanningDev')}}</view>
|
||
<view class="again" v-else @click="handleAgainSearch">{{$tt('bleConnect.rescan')}}</view>
|
||
</view>
|
||
<view class="device-title">{{$tt('bleConnect.usableDev')}}</view>
|
||
<view class="device-list" v-if="deviceList.length !== 0">
|
||
<view class="item-wrap" v-for="item in deviceList" :key="item.deviceId">
|
||
<view class="icon">
|
||
<u--image src="/static/common/device.png" width="28px" height="28px"></u--image>
|
||
</view>
|
||
<view class="name">{{item.name}}</view>
|
||
<view class="btn" @click="handleConnect(item.deviceId)">{{$tt('bleConnect.connect')}}</view>
|
||
</view>
|
||
</view>
|
||
<u-empty v-else mode="data" :iconSize="80" :text="$tt('bleConnect.connect')" marginTop="65px">
|
||
</u-empty>
|
||
<view class="tools-wrap">
|
||
<view class="btn" @click="handleManualAdd">{{$tt('bleConnect.manuallyAdd')}}</view>
|
||
<view class="btn" @click="handleScan">{{$tt('bleConnect.scan')}}</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
data() {
|
||
return {
|
||
nDelayTimer: -1, // 定时器
|
||
isFind: false, // 是否发现设备
|
||
deviceList: [], // 设备列表
|
||
isSearch: false,
|
||
errmgs: ''
|
||
};
|
||
},
|
||
mounted() {
|
||
this.searchBlueToothDevice();
|
||
},
|
||
methods: {
|
||
searchBlueToothDevice() {
|
||
this.initBlueTooth();
|
||
},
|
||
stopBlueToothDevice() {
|
||
clearInterval(this.nDelayTimer);
|
||
this.isSearch = false;
|
||
this.isFind = false;
|
||
this.deviceList = [];
|
||
this.errmgs = '';
|
||
this.nDelayTimer = -1;
|
||
},
|
||
// 重新扫描
|
||
handleAgainSearch() {
|
||
this.stopBlueToothDevice();
|
||
this.searchBlueToothDevice();
|
||
},
|
||
// 连接
|
||
handleConnect(deviceId) {
|
||
uni.navigateTo({
|
||
url: `/pagesB/home/device/add/bleConnect/setWifi?deviceId=${deviceId}`
|
||
});
|
||
},
|
||
// 初始化蓝牙适配器
|
||
initBlueTooth() {
|
||
let _this = this;
|
||
uni.closeBluetoothAdapter({
|
||
success: (res) => {
|
||
uni.openBluetoothAdapter({
|
||
success: (res) => {
|
||
this.findBlueTooth();
|
||
},
|
||
fail: (err) => {
|
||
console.log('openBluetoothAdapter', err.errMsg);
|
||
uni.showModal({
|
||
content: this.$tt('bleConnect.turnOnBle'),
|
||
showCancel: false,
|
||
});
|
||
}
|
||
})
|
||
},
|
||
})
|
||
},
|
||
// 搜索蓝牙设备
|
||
findBlueTooth() {
|
||
let _this = this;
|
||
uni.startBluetoothDevicesDiscovery({
|
||
allowDuplicatesKey: false,
|
||
interval: 0,
|
||
success: (res) => {
|
||
_this.isSearch = true;
|
||
_this.nDelayTimer = setInterval(() => _this.discoveryBlueTooth(), 1000);
|
||
setTimeout(() => {
|
||
_this.isSearch = false;
|
||
if (_this.isFind) {
|
||
uni.stopBluetoothDevicesDiscovery({
|
||
success: (result) => {
|
||
console.log(result);
|
||
},
|
||
});
|
||
clearInterval(_this.nDelayTimer);
|
||
_this.nDelayTimer = -1;
|
||
return;
|
||
} else {
|
||
uni.stopBluetoothDevicesDiscovery({
|
||
success: (result) => {
|
||
console.log(result);
|
||
},
|
||
});
|
||
clearInterval(_this.nDelayTimer);
|
||
_this.nDelayTimer = -1;
|
||
_this.errmgs = this.$tt('bleConnect.checkBleAndTurnOnGPSForAndroid');
|
||
}
|
||
}, 15000);
|
||
},
|
||
fail: (res) => {
|
||
_this.errmgs = this.$tt('bleConnect.bleDiscoverydev') + `${res.errMsg}`;
|
||
}
|
||
})
|
||
},
|
||
// 搜索设备回调
|
||
discoveryBlueTooth() {
|
||
const _this = this;
|
||
uni.getBluetoothDevices({
|
||
success: (res) => {
|
||
if (res?.devices && res?.devices?.length != 0) {
|
||
const list = res.devices;
|
||
const devices = [];
|
||
list.forEach((item) => {
|
||
let bname = '';
|
||
if (item.name && item.name.length > 0) {
|
||
bname = item.name;
|
||
}
|
||
if (item.localName && item.localName.length > 0) {
|
||
bname = item.localName;
|
||
}
|
||
if (bname !== "" && bname !== "未知设备") {
|
||
devices.push(item);
|
||
}
|
||
});
|
||
_this.deviceList = devices;
|
||
_this.isFind = true;
|
||
clearInterval(_this.nDelayTimer);
|
||
_this.nDelayTimer = -1;
|
||
}
|
||
},
|
||
fail: (res) => {
|
||
console.log('getBluetoothDevices', res);
|
||
_this.errmgs = this.$tt('bleConnect.failedToSearchBle');
|
||
},
|
||
});
|
||
},
|
||
// 返回
|
||
handleGoback() {
|
||
uni.switchTab({
|
||
url: '/pages/tabBar/home/index'
|
||
});
|
||
},
|
||
// 扫码添加
|
||
async handleScan() {
|
||
// #ifndef MP-WEIXIN || APP-PLUS
|
||
uni.showToast({
|
||
icon: 'none',
|
||
title: this.$tt('user.scanning')
|
||
});
|
||
return;
|
||
// #endif
|
||
|
||
// 权限问题,app 需要做权限说明
|
||
let onlyFromCamera = false;
|
||
// #ifdef APP-PLUS
|
||
onlyFromCamera = true;
|
||
let result = await this.$store.dispatch("permission/requestPermissions", 'CAMERA');
|
||
if (result !== 1) return;
|
||
// #endif
|
||
this.startScanCode(onlyFromCamera);
|
||
},
|
||
// 开始扫码
|
||
startScanCode(onlyFromCamera) {
|
||
uni.scanCode({
|
||
onlyFromCamera, // 是否允许从相册扫码
|
||
success: res => {
|
||
// 解析JSON
|
||
try {
|
||
const scanJson = JSON.parse(res.result);
|
||
// type=1 代表扫码关联设备
|
||
if (scanJson.deviceId) {
|
||
uni.showModal({
|
||
content: '【' + this.$tt('bleConnect.deviceName') +
|
||
':' + scanJson.name + ',' + this.$tt('bleConnect.deviceNum') +
|
||
':' + scanJson.deviceId + '】' + this.$tt(
|
||
'bleConnect.isConfirmed'),
|
||
cancelText: this.$tt('common.cancel'),
|
||
confirmText: this.$tt('common.confirm'),
|
||
confirmColor: '#486ff2',
|
||
cancelColor: '#606266',
|
||
success: result => {
|
||
if (result.confirm) {
|
||
this.handleConnect(scanJson.deviceId);
|
||
}
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
uni.showToast({
|
||
icon: 'none',
|
||
title: $tt('bleConnect.qsNosupport')
|
||
});
|
||
} catch (error) {
|
||
uni.showToast({
|
||
icon: 'none',
|
||
title: this.$tt('user.errorParseQRcode')
|
||
});
|
||
}
|
||
}
|
||
});
|
||
},
|
||
// 手动添加
|
||
handleManualAdd() {
|
||
uni.navigateTo({
|
||
url: `/pagesB/home/device/add/bleConnect/manualAdd`
|
||
});
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
page {
|
||
height: 100%;
|
||
background: $uni-bg-color-grey;
|
||
}
|
||
</style>
|
||
<style lang="scss" scoped>
|
||
.ble-connect {
|
||
height: 100vh;
|
||
overflow-y: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
.device-search {
|
||
margin-top: calc(44px + var(--status-bar-height));
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
height: 700rpx;
|
||
|
||
.img-wrap {
|
||
padding: 20rpx 0;
|
||
margin-top: 20rpx;
|
||
|
||
.img {
|
||
width: 500rpx;
|
||
height: 500rpx;
|
||
}
|
||
|
||
.rotating {
|
||
animation: rotation 4s infinite linear;
|
||
}
|
||
|
||
@keyframes rotation {
|
||
from {
|
||
transform: rotate(0deg);
|
||
}
|
||
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
}
|
||
|
||
.title {
|
||
font-size: 32rpx;
|
||
font-weight: 500;
|
||
line-height: 64rpx;
|
||
}
|
||
|
||
.describe {
|
||
font-size: 24rpx;
|
||
line-height: 48rpx;
|
||
color: #7e7e7e;
|
||
}
|
||
|
||
.again {
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
line-height: 64rpx;
|
||
color: #486ff2;
|
||
}
|
||
}
|
||
|
||
.device-title {
|
||
font-size: 32rpx;
|
||
font-weight: 500;
|
||
line-height: 64rpx;
|
||
padding: 40rpx 40rpx 10rpx 40rpx;
|
||
}
|
||
|
||
.device-list {
|
||
padding: 20rpx 40rpx;
|
||
flex-direction: column;
|
||
overflow-y: auto;
|
||
margin-bottom: 160rpx;
|
||
|
||
.item-wrap {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
margin-bottom: 26rpx;
|
||
|
||
.name {
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
line-height: 64rpx;
|
||
margin-left: 12px;
|
||
flex: 1
|
||
}
|
||
|
||
.btn {
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
line-height: 50rpx;
|
||
background: #7e7e7e21;
|
||
width: 120rpx;
|
||
text-align: center;
|
||
color: #486ff2;
|
||
border-radius: 40rpx;
|
||
padding: 0 10rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.tools-wrap {
|
||
position: fixed;
|
||
bottom: 60rpx;
|
||
left: 0;
|
||
right: 0;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
gap: 40rpx;
|
||
|
||
.btn {
|
||
font-size: 32rpx;
|
||
font-weight: 500;
|
||
line-height: 62rpx;
|
||
background: #7e7e7e21;
|
||
width: 260rpx;
|
||
text-align: center;
|
||
color: #486ff2;
|
||
border-radius: 40rpx;
|
||
padding: 5rpx 10rpx;
|
||
}
|
||
}
|
||
}
|
||
</style> |