bike-ali/pages_admin/worke/bind_sn.vue

741 lines
16 KiB
Vue
Raw Normal View History

2024-06-20 18:08:54 +08:00
<template>
<view class="pages">
<u-navbar title="添加设备" :border-bottom="false" :background="bgc" title-color='#262B37' title-size='38'
2024-09-30 18:02:20 +08:00
height='50' :custom-back='backPage'></u-navbar>
2024-06-20 18:08:54 +08:00
<view class="title">
2024-09-30 18:02:20 +08:00
<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>
2024-06-20 18:08:54 +08:00
<image src="https://api.ccttiot.com/smartmeter/img/static/uCfe9273aC89tGOT7n1G" mode="widthFix"></image>
<text class="sm">{{texts}}</text>
</view>
2024-09-30 18:02:20 +08:00
2024-09-27 18:03:55 +08:00
<view class="dblist" v-for="(item, index) in devicesList" :key="index" @tap="choose(item)">
2024-06-20 18:08:54 +08:00
<!-- <view class="lt">
2024-12-12 18:02:37 +08:00
<image src="https://api.ccttiot.com/smartmeter/img/static/uoQO0pUZ1UHcW5uVKkuR" mode="aspectFit"></image>
2024-06-20 18:08:54 +08:00
</view> -->
<view class="cen">
<view class="name">
2024-09-27 18:03:55 +08:00
MAC{{item.localName.substring(5)}}
<span
:style="{ fontSize: '24rpx', marginLeft: '30rpx', color: item.isBand ? '#808080' : '#4297F3' }">
<!-- 根据 isBound 显示录入或未录入 -->
{{ item.isBand ? '已录入' : '未录入' }}
</span>
2024-06-20 18:08:54 +08:00
</view>
<view class="mac">
2024-09-27 18:03:55 +08:00
蓝牙信号{{item.RSSI}} <span style="margin-left: 20rpx;" v-if="item.isBand "> SN:{{item.sn}}</span>
2024-06-20 18:08:54 +08:00
</view>
</view>
2024-09-27 18:03:55 +08:00
<!-- <view class="rt">
2024-06-20 18:08:54 +08:00
<text :id="item.deviceId" @tap="openConfirmModal(item)">绑定</text>
2024-06-22 18:06:23 +08:00
</view> -->
2024-09-27 18:03:55 +08:00
<view class="rt" style="margin-right: 10rpx;">
<text :id="item.deviceId">选择</text>
2024-06-20 18:08:54 +08:00
</view>
</view>
<view class="anniu" @click="Search">
<button>重新扫描</button>
2024-09-27 18:03:55 +08:00
2024-06-20 18:08:54 +08:00
</view>
2024-06-22 18:06:23 +08:00
<!-- <view class="anniu2 " @click="send">
2024-06-20 18:08:54 +08:00
响铃
2024-06-22 18:06:23 +08:00
</view> -->
2024-06-20 18:08:54 +08:00
<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>
2024-12-17 14:17:42 +08:00
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'
}
},
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
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'
})
2024-06-20 18:08:54 +08:00
},
2024-09-27 18:03:55 +08:00
2024-12-17 14:17:42 +08:00
backPage() {
uni.redirectTo({
url: '/pages_admin/admin_worke'
})
2024-06-20 18:08:54 +08:00
},
2024-12-17 14:17:42 +08:00
toControl() {
uni.redirectTo({
url: '/pages_admin/controlDevice'
})
2024-06-20 18:08:54 +08:00
},
2024-09-27 18:03:55 +08:00
2024-12-17 14:17:42 +08:00
// 蓝牙初始化
initBluetooth() {
// 重置设备列表
this.bluthlist = [];
this.devicesList = [];
this.devicesLists = [];
// 初始化蓝牙
xBlufi.initXBlufi(xBlufi.XMQTT_SYSTEM.Alis);
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent);
// 开始搜索设备
this.startSearch();
2024-06-20 18:08:54 +08:00
},
2024-12-17 14:17:42 +08:00
// 清理蓝牙连接
cleanupBluetooth() {
2024-06-20 18:08:54 +08:00
xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent);
2024-12-17 14:17:42 +08:00
xBlufi.notifyStartDiscoverBle({ 'isStart': false });
2024-06-20 18:08:54 +08:00
},
2024-12-17 14:17:42 +08:00
// 开始搜索设备
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);
2024-06-20 18:08:54 +08:00
},
2024-09-27 18:03:55 +08:00
2024-12-17 14:17:42 +08:00
// 选择设备
choose(device) {
console.log('选择设备:', device);
let Bluetoothmac = device.name.substring(5);
uni.redirectTo({
url: '/pages_admin/worke/bind_mac?mac=' + Bluetoothmac
});
},
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
// 设备消息监听处理
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) {
2024-06-20 18:08:54 +08:00
this.devicesLists.push(device);
2024-12-17 14:17:42 +08:00
// 更新最终显示的设备列表
this.devicesList = [...this.devicesLists];
// 获取设备绑定状态
this.fetchDevicesBoundStatus();
2024-06-20 18:08:54 +08:00
}
}
2024-12-17 14:17:42 +08:00
});
}
break;
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
case xBlufi.XBLUFI_TYPE.TYPE_STATUS_CONNECTED:
this.handleConnectionStatus(options);
break;
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
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;
2024-06-20 18:08:54 +08:00
}
break;
2024-12-17 14:17:42 +08:00
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP:
this.searching = false;
break;
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
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;
}
},
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
// 处理连接状态
handleConnectionStatus(res) {
if (res.result) {
uni.showToast({
title: '连接成功',
icon: 'success'
});
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
// 初始化设备
xBlufi.notifyInitBleEsp32({
deviceId: res.data.deviceId
});
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
// 更新设备连接状态
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];
2024-06-20 18:08:54 +08:00
}
2024-12-17 14:17:42 +08:00
} else {
uni.showToast({
title: '连接断开',
icon: 'none'
});
this.hasConnectedDevice = false;
this.selectedDevice = null;
}
},
2024-09-27 18:03:55 +08:00
2024-12-17 14:17:42 +08:00
// 响铃功能
rings() {
if (!this.hasConnectedDevice || !this.selectedDevice) {
uni.showToast({
title: '请先连接设备',
icon: 'none'
});
return;
}
2024-09-27 18:03:55 +08:00
2024-12-17 14:17:42 +08:00
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'
});
}
});
},
2024-09-27 18:03:55 +08:00
2024-12-17 14:17:42 +08:00
// 重新搜索
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);
}
},
2024-09-27 18:03:55 +08:00
2024-12-17 14:17:42 +08:00
// 获取设备绑定状态
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);
});
},
2024-09-27 18:03:55 +08:00
2024-12-17 14:17:42 +08:00
// 打开确认弹窗
openConfirmModal(device) {
this.deviceinfo = device;
this.showConfirmModal = true;
},
2024-09-27 18:03:55 +08:00
2024-12-17 14:17:42 +08:00
// 关闭确认弹窗
closeConfirmModal() {
this.showConfirmModal = false;
},
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
// 确认绑定
confirmBind() {
this.closeConfirmModal();
this.createBLEConnection(this.deviceinfo);
},
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
// 建立蓝牙连接
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
});
2024-06-20 18:08:54 +08:00
xBlufi.notifyStartDiscoverBle({
2024-12-17 14:17:42 +08:00
'isStart': false
2024-06-20 18:08:54 +08:00
});
2024-09-27 18:03:55 +08:00
2024-12-17 14:17:42 +08:00
xBlufi.notifyConnectBle({
isStart: true,
deviceId: device.deviceId,
name: device.name
});
2024-06-20 18:08:54 +08:00
2024-12-17 14:17:42 +08:00
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
setTimeout(() => {
uni.navigateBack({
delta: 1
});
}, 2000);
2024-06-20 18:08:54 +08:00
}
2024-12-17 14:17:42 +08:00
});
2024-06-20 18:08:54 +08:00
}
}
2024-12-17 14:17:42 +08:00
}
2024-06-20 18:08:54 +08:00
</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;
}
2024-09-27 18:03:55 +08:00
.anniu2 {
2024-06-20 18:08:54 +08:00
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;
2024-09-27 18:03:55 +08:00
2024-06-20 18:08:54 +08:00
}
2024-09-27 18:03:55 +08:00
2024-06-20 18:08:54 +08:00
.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;
2024-09-30 18:02:20 +08:00
2024-06-20 18:08:54 +08:00
image {
display: inline-block;
width: 48rpx;
height: 48rpx;
vertical-align: bottom;
margin-right: 10rpx;
}
2024-09-30 18:02:20 +08:00
}
.title_li{
display: flex;
flex-wrap: nowrap;
align-items: center;
.text{
2024-06-20 18:08:54 +08:00
font-weight: 400;
2024-09-30 18:02:20 +08:00
font-size: 70rpx;
2024-06-20 18:08:54 +08:00
color: #262B37;
2024-09-30 18:02:20 +08:00
2024-06-20 18:08:54 +08:00
text-align: left;
font-style: normal;
text-transform: none;
display: block;
2024-09-30 18:02:20 +08:00
}
.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;
2024-06-20 18:08:54 +08:00
}
}
2024-09-30 18:02:20 +08:00
2024-06-20 18:08:54 +08:00
.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 {
2024-09-27 18:03:55 +08:00
white-space: nowrap;
2024-06-20 18:08:54 +08:00
font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;
font-weight: 400;
2024-09-27 18:03:55 +08:00
font-size: 28rpx;
2024-06-20 18:08:54 +08:00
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 {
2024-06-22 18:06:23 +08:00
margin-left: auto;
2024-06-20 18:08:54 +08:00
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>