2025-07-07 09:21:15 +08:00

364 lines
8.6 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>