bike-ali/pages_admin/worke/bind_sn.vue
2024-12-17 14:17:42 +08:00

741 lines
16 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="pages">
<u-navbar title="添加设备" :border-bottom="false" :background="bgc" title-color='#262B37' title-size='38'
height='50' :custom-back='backPage'></u-navbar>
<view class="title">
<view class="title_li" style="display: flex;align-items: center;">
<view class="text">设备列表</view>
<view class="btns" @click="toControl()">
控制台
</view>
<view class="btns" @click="replay()">
重置页面
</view>
</view>
<image src="https://api.ccttiot.com/smartmeter/img/static/uCfe9273aC89tGOT7n1G" mode="widthFix"></image>
<text class="sm">{{texts}}</text>
</view>
<view class="dblist" v-for="(item, index) in devicesList" :key="index" @tap="choose(item)">
<!-- <view class="lt">
<image src="https://api.ccttiot.com/smartmeter/img/static/uoQO0pUZ1UHcW5uVKkuR" mode="aspectFit"></image>
</view> -->
<view class="cen">
<view class="name">
MAC{{item.localName.substring(5)}}
<span
:style="{ fontSize: '24rpx', marginLeft: '30rpx', color: item.isBand ? '#808080' : '#4297F3' }">
<!-- 根据 isBound 显示录入或未录入 -->
{{ item.isBand ? '已录入' : '未录入' }}
</span>
</view>
<view class="mac">
蓝牙信号:{{item.RSSI}} <span style="margin-left: 20rpx;" v-if="item.isBand "> SN:{{item.sn}}</span>
</view>
</view>
<!-- <view class="rt">
<text :id="item.deviceId" @tap="openConfirmModal(item)">绑定</text>
</view> -->
<view class="rt" style="margin-right: 10rpx;">
<text :id="item.deviceId">选择</text>
</view>
</view>
<view class="anniu" @click="Search">
<button>重新扫描</button>
</view>
<!-- <view class="anniu2 " @click="send">
响铃
</view> -->
<view v-if="showConfirmModal" class="modal-overlay">
<view class="modal">
<view class="modal-content">
<view class="modal-title">确认绑定</view>
<view class="modal-body">是否确认绑定设备?</view>
<view class="modal-footer">
<view class="btn" @click="closeConfirmModal" style="background: #ccc;">取消</view>
<view class="btn" @click="confirmBind">确定</view>
</view>
</view>
</view>
</view>
<!-- 加载状态 -->
<view class="containers" v-show="statusflag">
<uni-section>
<uni-load-more :status="status" />
</uni-section>
</view>
</view>
</template>
<script>
const app = getApp();
var xBlufi = require("@/utils/blufi/xBlufi.js");
export default {
data() {
return {
titleflag: false,
bgc: {
backgroundColor: "#F7FAFE",
},
devicesList: [], // 最终显示的设备列表
devicesLists: [], // 临时存储扫描到的设备
searching: false,
texts: '正在扫描蓝牙设备...',
btnflag: true,
tishiflag: false,
option: '',
bluthlist: [],
statusflag: false,
Bluetoothmac: '',
gps: {},
mac: '',
status: false,
showConfirmModal: false,
deviceinfo: null,
sn: '',
hasConnectedDevice: false,
selectedDevice: null,
serviceId: '000000FF-0000-1000-8000-00805F9B34FB',
characteristicId: '0000FF01-0000-1000-8000-00805F9B34FB'
}
},
onLoad(e) {
if (e.sn) {
this.sn = e.sn;
}
},
onShow() {
this.initBluetooth();
},
onUnload() {
this.cleanupBluetooth();
},
onHide() {
this.cleanupBluetooth();
},
methods: {
// 页面跳转相关方法
replay() {
uni.reLaunch({
url: '/pages_admin/worke/bind_sn'
})
},
backPage() {
uni.redirectTo({
url: '/pages_admin/admin_worke'
})
},
toControl() {
uni.redirectTo({
url: '/pages_admin/controlDevice'
})
},
// 蓝牙初始化
initBluetooth() {
// 重置设备列表
this.bluthlist = [];
this.devicesList = [];
this.devicesLists = [];
// 初始化蓝牙
xBlufi.initXBlufi(xBlufi.XMQTT_SYSTEM.Alis);
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent);
// 开始搜索设备
this.startSearch();
},
// 清理蓝牙连接
cleanupBluetooth() {
xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent);
xBlufi.notifyStartDiscoverBle({ 'isStart': false });
},
// 开始搜索设备
startSearch() {
this.searching = true;
this.texts = '正在扫描蓝牙设备...';
xBlufi.notifyStartDiscoverBle({ 'isStart': true });
setTimeout(() => {
xBlufi.notifyStartDiscoverBle({ 'isStart': false });
if (this.devicesList.length == 0) {
this.tishiflag = true;
this.texts = '扫描完毕,暂无发现电动车设备';
} else {
this.texts = '扫描到以下设备,请点击连接!';
}
this.searching = false;
}, 5000);
},
// 选择设备
choose(device) {
console.log('选择设备:', device);
let Bluetoothmac = device.name.substring(5);
uni.redirectTo({
url: '/pages_admin/worke/bind_mac?mac=' + Bluetoothmac
});
},
// 设备消息监听处理
funListenDeviceMsgEvent(options) {
switch (options.type) {
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS:
if (options.result && options.data) {
let devicesarr = options.data;
devicesarr.forEach(device => {
// 只处理BBLE开头的设备
if (device.name && device.name.startsWith('BBLE')) {
// 检查是否已存在相同设备
const existingDevice = this.devicesLists.find(d =>
d.deviceId === device.deviceId
);
if (!existingDevice) {
this.devicesLists.push(device);
// 更新最终显示的设备列表
this.devicesList = [...this.devicesLists];
// 获取设备绑定状态
this.fetchDevicesBoundStatus();
}
}
});
}
break;
case xBlufi.XBLUFI_TYPE.TYPE_STATUS_CONNECTED:
this.handleConnectionStatus(options);
break;
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START:
if (!options.result) {
console.log("蓝牙未开启", options);
uni.showToast({
title: '蓝牙未开启,如有疑问请查看常见问题',
icon: 'none',
duration: 3000
});
} else {
this.searching = true;
}
break;
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP:
this.searching = false;
break;
case xBlufi.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT:
if (options.result) {
console.log('设备初始化成功');
this.hasConnectedDevice = true;
} else {
console.error('设备初始化失败');
uni.showModal({
title: '温馨提示',
content: '设备初始化失败',
showCancel: false
});
}
break;
}
},
// 处理连接状态
handleConnectionStatus(res) {
if (res.result) {
uni.showToast({
title: '连接成功',
icon: 'success'
});
// 初始化设备
xBlufi.notifyInitBleEsp32({
deviceId: res.data.deviceId
});
// 更新设备连接状态
const index = this.devicesList.findIndex(d => d.deviceId === res.data.deviceId);
if (index !== -1) {
this.$set(this.devicesList[index], 'connected', true);
this.hasConnectedDevice = true;
this.selectedDevice = this.devicesList[index];
}
} else {
uni.showToast({
title: '连接断开',
icon: 'none'
});
this.hasConnectedDevice = false;
this.selectedDevice = null;
}
},
// 响铃功能
rings() {
if (!this.hasConnectedDevice || !this.selectedDevice) {
uni.showToast({
title: '请先连接设备',
icon: 'none'
});
return;
}
console.log('准备发送响铃命令');
my.getBLEDeviceServices({
deviceId: this.selectedDevice.deviceId,
success: (res) => {
console.log('设备的所有服务:', res.services);
xBlufi.notifySendCustomData({
customData: "11play1@"
});
},
fail: (error) => {
console.error('获取服务列表失败:', error);
uni.showToast({
title: '获取服务失败',
icon: 'none'
});
}
});
},
// 重新搜索
Search() {
if (this.status) {
// 重置设备列表
this.bluthlist = [];
this.devicesList = [];
this.devicesLists = [];
this.statusflag = true;
this.texts = '正在扫描蓝牙设备...';
// 开始新的搜索
xBlufi.notifyStartDiscoverBle({ 'isStart': true });
setTimeout(() => {
this.statusflag = false;
if (this.searching) {
if (this.devicesList.length == 0) {
this.tishiflag = true;
this.texts = '扫描完毕,暂无发现电动车设备';
} else {
this.texts = '扫描到以下设备,请点击连接!';
}
xBlufi.notifyStartDiscoverBle({ 'isStart': false });
}
}, 2000);
}
},
// 获取设备绑定状态
fetchDevicesBoundStatus() {
// 提取所有设备的 MAC 地址并去重
let uniqueDevices = Array.from(new Set(this.devicesList.map(item => item.name.substring(5))));
// 重新构建去重后的 devicesList
this.devicesList = uniqueDevices.map(mac => {
return this.devicesList.find(item => item.name.substring(5) === mac);
});
// 拼接MAC地址字符串
const macs = uniqueDevices.join(',');
// 批量查询设备绑定状态
this.$u.get(`app/getDeviceInfoByMacList?macList=${macs}`).then((res) => {
const resultList = res.data;
// 更新设备列表的绑定状态
this.devicesList.forEach(device => {
const mac = device.name.substring(5);
const matchingResult = resultList.find(result => result.mac === mac);
if (matchingResult) {
device.sn = matchingResult.sn;
device.isBand = matchingResult.isBand;
}
});
// 未绑定的设备排在前面
this.devicesList.sort((a, b) => {
return (a.isBand === false ? -1 : 1) - (b.isBand === false ? -1 : 1);
});
this.$forceUpdate();
}).catch((error) => {
console.error('获取设备绑定状态失败', error);
});
},
// 打开确认弹窗
openConfirmModal(device) {
this.deviceinfo = device;
this.showConfirmModal = true;
},
// 关闭确认弹窗
closeConfirmModal() {
this.showConfirmModal = false;
},
// 确认绑定
confirmBind() {
this.closeConfirmModal();
this.createBLEConnection(this.deviceinfo);
},
// 建立蓝牙连接
createBLEConnection(device) {
this.mac = device.name.substring(5);
let that = this;
that.$u.post(`/appVerify/band?sn=${that.sn}&mac=${that.mac}`).then((res) => {
uni.showLoading({
title: '绑定中'
});
if (res.code == 200) {
uni.showToast({
title: '绑定成功',
icon: 'none',
duration: 2000
});
xBlufi.notifyStartDiscoverBle({
'isStart': false
});
xBlufi.notifyConnectBle({
isStart: true,
deviceId: device.deviceId,
name: device.name
});
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
setTimeout(() => {
uni.navigateBack({
delta: 1
});
}, 2000);
}
});
}
}
}
</script>
<style lang="scss">
page {
background-color: #F7FAFE !important;
}
.containers {
width: 100%;
height: 100vh;
position: fixed;
top: 0;
padding-top: 130rpx;
box-sizing: border-box;
left: 0;
z-index: 999 !important;
/* background-color: #fff; */
z-index: 99;
}
.anniu2 {
display: flex;
align-items: center;
justify-content: center;
width: 586rpx;
height: 90rpx;
border-radius: 54rpx 54rpx 54rpx 54rpx;
border: 4rpx solid #4C97E7;
box-sizing: border-box;
position: fixed;
left: 90rpx;
bottom: 222rpx;
font-weight: 500;
font-size: 40rpx;
color: #4C97E7;
}
.pages {
// padding-top: 136rpx !important;
padding: 0 66rpx;
box-sizing: border-box;
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal {
width: 300px;
background: #fff;
border-radius: 8px;
overflow: hidden;
}
.modal-content {
padding: 20px;
}
.modal-title {
font-size: 18px;
margin-bottom: 10px;
text-align: center;
}
.modal-body {
font-size: 16px;
margin-bottom: 20px;
text-align: center;
}
.modal-footer {
display: flex;
justify-content: space-around;
}
.modal-footer button {
width: 80px;
height: 60rpx;
padding: 10px;
background: #8883F0;
color: #fff;
border: none;
border-radius: 4px;
}
.btn {
display: flex;
align-items: center;
justify-content: center;
background: #8883F0;
width: 80px;
height: 60rpx;
color: #fff;
border-radius: 4px;
}
.modal-footer button:first-of-type {
background: #ccc;
}
// text{
// display: block;
// }
.sm {
color: #77808D;
border-radius: 0rpx 0rpx 0rpx 0rpx;
// margin-top: 48rpx;
display: inline-block;
}
.title {
margin-bottom: 84rpx;
image {
display: inline-block;
width: 48rpx;
height: 48rpx;
vertical-align: bottom;
margin-right: 10rpx;
}
}
.title_li{
display: flex;
flex-wrap: nowrap;
align-items: center;
.text{
font-weight: 400;
font-size: 70rpx;
color: #262B37;
text-align: left;
font-style: normal;
text-transform: none;
display: block;
}
.btns{
margin-left: 30rpx;
display: flex;
align-items: center;
justify-content: center;
width: 138rpx;
height: 50rpx;
background: #F14C4C;
border-radius: 31rpx 31rpx 31rpx 31rpx;
font-weight: 500;
font-size: 24rpx;
color: #FFFFFF;
}
}
.dblist {
display: flex;
width: 100%;
margin-top: 34rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
padding: 20rpx 0 24rpx 18rpx;
box-sizing: border-box;
text-align: center;
border-radius: 10rpx;
.lt {
padding-left: 10rpx;
box-sizing: border-box;
margin-right: 38rpx;
image {
width: 42rpx;
// height: 112rpx;
}
}
.cen {
width: 370rpx;
padding-left: 10rpx;
box-sizing: border-box;
.name {
white-space: nowrap;
font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;
font-weight: 400;
font-size: 28rpx;
color: #262B37;
line-height: 40rpx;
text-align: left;
font-style: normal;
text-transform: none;
margin-top: 10rpx;
}
.mac {
font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;
font-weight: 400;
font-size: 24rpx;
color: #262B37;
line-height: 32rpx;
text-align: left;
font-style: normal;
text-transform: none;
margin-top: 16rpx;
}
}
.rt {
margin-left: auto;
margin-top: 22rpx;
text {
display: inline-block;
width: 108rpx;
height: 60rpx;
background: rgba(255, 255, 255, 0);
border: 2rpx solid #8883F0;
filter: blur(0px);
border-radius: 20rpx;
text-align: center;
line-height: 60rpx;
color: #8883F0;
}
}
}
.anniu {
padding: 0 90rpx;
width: 100%;
box-sizing: border-box;
position: fixed;
left: 0;
bottom: 112rpx;
button {
background: #8883F0;
border-radius: 52rpx 52rpx 52rpx 52rpx;
color: #fff;
}
}
.mask {
width: 622rpx;
height: 710rpx;
background: #FFFFFF;
filter: blur(0px);
border-radius: 20rpx;
position: fixed;
top: 475rpx;
left: 50%;
transform: translateX(-50%);
padding-top: 38rpx;
padding-left: 60rpx;
padding-right: 60rpx;
box-sizing: border-box;
.titles {
font-size: 48rpx;
color: #262B37;
line-height: 70rpx;
text-align: center;
margin-bottom: 24rpx;
}
text {
display: block;
font-size: 32rpx;
color: #262B37;
line-height: 56rpx;
text-align: left;
}
button {
margin-top: 46rpx;
width: 266rpx;
height: 96rpx;
background: #8883F0;
border-radius: 52rpx 52rpx 52rpx 52rpx;
color: #fff;
text-align: center;
line-height: 96rpx;
}
}
</style>