<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=""></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"); let _this = null; export default { data() { return { titleflag: false, //提示隐藏 bgc: { backgroundColor: "#F7FAFE", }, devicesList: [ // {name:'110000', // mac:'11111'} ], devicesLists: [], searching: false, texts: '正在扫描蓝牙设备...', btnflag: true, tishiflag: false, option: '', bluthlist: [], //蓝牙数组 status: 'loading', statusflag: false, Bluetoothmac: '', gps: {}, mac: '', status: false, showConfirmModal: false, // 控制弹窗显示的标志 deviceinfo: null, sn: '' } }, onLoad(e) { if (e.sn) { this.sn = e.sn } }, onShow: function() { this.bluthlist = []; this.devicesList = []; this.devicesLists = []; // 强制视图更新 this.$forceUpdate(); // 后续的蓝牙初始化和扫描逻辑 xBlufi.initXBlufi(1); xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent); xBlufi.notifyStartDiscoverBle({ 'isStart': true }); setTimeout(() => { xBlufi.notifyStartDiscoverBle({ 'isStart': false }); if (this.devicesList.length == 0) { this.tishiflag = true; this.texts = '扫描完毕,暂无发现电动车设备'; } else { this.texts = '扫描到以下设备,请点击连接!'; } this.status = true; // 再次强制更新 this.$forceUpdate(); }, 2000); }, onUnload: function() { xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent); xBlufi.notifyStartDiscoverBle({ 'isStart': false }); }, onHide() { xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent); xBlufi.notifyStartDiscoverBle({ 'isStart': false }); }, onBeforeUnmount() { xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent); xBlufi.notifyStartDiscoverBle({ 'isStart': false }); }, mounted() { // this.videoContext = uni.createVideoContext('myVideo', this) }, methods: { replay(){ uni.reLaunch({ url:'/pages_admin/worke/bind_sn' }) }, backPage(){ uni.redirectTo({ url:'/page_user/my' }) }, toControl(){ uni.redirectTo({ url:'/pages_admin/controlDevice' }) }, fetchDevicesBoundStatus() { // 提取所有设备的 MAC 地址,并通过 Set 去重 let uniqueDevices = Array.from(new Set(this.devicesList.map(item => item.localName.substring(5)))); // 重新构建去重后的 devicesList this.devicesList = uniqueDevices.map(mac => { return this.devicesList.find(item => item.localName.substring(5) === mac); }); // 拼接成字符串 const macs = uniqueDevices.join(','); // 向批量接口请求录入状态 this.$u.get(`app/getDeviceInfoByMacList?macList=${macs}`).then((res) => { const resultList = res.data; // 获取接口返回的数据数组 // 遍历 devicesList 并对比 mac 地址 this.devicesList.forEach(device => { const mac = device.localName.substring(5); // 查找返回结果中是否有与该设备 MAC 地址相同的项 const matchingResult = resultList.find(result => result.mac === mac); // 如果找到了匹配的 MAC 地址项,则更新设备的 sn 和 isBand if (matchingResult) { device.sn = matchingResult.sn; device.isBand = matchingResult.isBand; } }); // 对 devicesList 进行排序,将 isBand 为 false 的设备排在前面 this.devicesList.sort((a, b) => { return (a.isBand === false ? -1 : 1) - (b.isBand === false ? -1 : 1); }); this.$forceUpdate(); // 强制更新视图 console.log(this.devicesList, 'Updated devicesList'); }).catch((error) => { console.error('批量获取设备录入状态失败', error); }); }, choose(e) { console.log(e); let Bluetoothmac = e.name.substring(5) uni.redirectTo({ url: '/pages_admin/worke/bind_mac?mac=' + Bluetoothmac }) }, send() { this.$u.post('/app/device/ring?sn=' + this.sn).then((res) => { if (res.code === 200) { } else { uni.showToast({ title: res.msg, icon: 'none', duration: 2000 }); } }) }, openConfirmModal(e) { this.deviceinfo = e this.showConfirmModal = true; }, closeConfirmModal() { this.showConfirmModal = false; }, confirmBind() { this.closeConfirmModal(); this.createBLEConnection(this.deviceinfo) }, btnyc() { this.titleflag = false }, sing() { let vm = this; // 将外部的 this 绑定到 vm 上 uni.getNetworkType({ success(res) { if (res.networkType !== 'none') { uni.getConnectedBluetoothDevices({ success(res) { console.log('已连接的蓝牙设备信息:', res); // vm.dl = (vm.orderinfo.deviceAmount / vm.orderinfo.unitPrice).toFixed(2); // 使用 vm 访问 Vue 实例的属性 xBlufi.notifySendCustomData({ customData: "11play1@" }); uni.hideLoading() vm.remakr() }, fail(err) { uni.hideLoading() console.error('获取已连接蓝牙设备信息失败:', err); } }); } else { console.log('手机未连接网络'); } } }); }, remakr() { let vm = this; // 将外部的 this 绑定到 vm 上 uni.getNetworkType({ success(res) { if (res.networkType !== 'none') { uni.getConnectedBluetoothDevices({ success(res) { console.log('已连接的蓝牙设备信息:', res); // vm.dl = (vm.orderinfo.deviceAmount / vm.orderinfo.unitPrice).toFixed(2); // 使用 vm 访问 Vue 实例的属性 xBlufi.notifySendCustomData({ customData: "11reboot" }); uni.navigateBack({ delta: 1 // delta值为1时表示返回的页面层数 }); }, fail(err) { console.error('获取已连接蓝牙设备信息失败:', err); } }); } else { console.log('手机未连接网络'); } } }); }, funListenDeviceMsgEvent: function(options) { switch (options.type) { case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS: if (options.result) { let devicesarr = options.data // this.devicesList = options.data // console.log(devicesarr, 'devicesarrdevicesarr'); devicesarr.forEach(device => { const mac = device.name.substring(6); if (device.name.indexOf("BBLE") != -1) { // this.$u.get(`/app/device/${mac}/isBind`).then((res) => { // if (res.data == false) { this.devicesLists.push(device); let uniqueDevicesList = Array.from(new Set(this.devicesLists)); // 将去重后的数组重新赋值给 this.devicesList this.devicesLists = uniqueDevicesList; // } // }) } // getisband(mac).then(res => { // console.log(res); // if (res.data == true) { // console.log(`MAC 地址 ${mac} 已经绑定`); // } else { // this.devicesList.push(device) // } // }).catch(error => { // console.error(`检查 MAC 地址 ${mac} 是否绑定的过程中出错:`, error); // }); }); } break; case xBlufi.XBLUFI_TYPE.TYPE_CONNECTED: console.log("连接回调:" + JSON.stringify(options)); if (options.result) { uni.hideLoading(); uni.showToast({ title: '连接成功', icon: 'none' }); { console.log("连接回调options.data.deviceId:" + options.data.deviceId, "连接回调options.data.name:" + options.data.name); // 连接成功绑定设备 // let params = { // mac: this.Bluetoothmac, // userId: this.$store.state.user.userId // } xBlufi.notifyInitBleEsp32({ deviceId: options.data.deviceId }); // xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvents); // setTimeout(() => { // this.sing() // }, 3000) let systemInfo = uni.getSystemInfoSync(); if (systemInfo.platform === 'android') { // 当前设备是 Android // uni.navigateTo({ // url: '/pages/wifilist/index?deviceId=' + options // .data.deviceId + '&name=' + options.data.name // }) } else if (systemInfo.platform === 'ios') { // 当前设备是 iOS // uni.navigateTo({ // url: '/pages/wifilist/index?deviceId=' + options // .data.deviceId + '&name=' + options.data.name // }) } } } break; case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START: if (!options.result) { console.log("蓝牙未开启", options); uni.showToast({ title: '蓝牙未开启,如有疑问请查看查看常见问题', icon: 'none', duration: 3000 }); if (this.devicesList.length == 0) { this.tishiflag = true this.texts = '扫描完毕,暂无发现电动车设备' } else { this.texts = '扫描到以下设备,请点击连接!' } } else { this.searching = true //蓝牙搜索开始 // _this.setData({ // searching: true // }); } break; case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP: if (options.result) { let uniqueDevicesList = Array.from(new Set(this.devicesLists)); // 将去重后的数组重新赋值给 this.devicesList this.devicesLists = uniqueDevicesList; let list = [] uniqueDevicesList.forEach(device => { // 从设备名称中提取 MAC 地址(假设 MAC 地址是设备名称的后6个字符) let macFromName = device.name.substring(device.name.length - 12); // console.log(macFromName); // 与 this.mac 进行比较 list.push(device) // this.$u.get(`/app/device/${macFromName}/isBind`).then((res) => { // if (res.data == false) { // list.push(device) // } else { // } // }) }); setTimeout(() => { this.devicesList = list let uniqueDevicesList = Array.from(new Set(this.devicesList)); // 将去重后的数组重新赋值给 this.devicesList this.devicesList = uniqueDevicesList; this.fetchDevicesBoundStatus(); }, 200) console.log('蓝牙停止搜索ok'); } else { //蓝牙停止搜索失败 console.log('蓝牙停止搜索失败'); } this.searching = false // _this.setData({ // searching: false // }); break; } }, funListenDeviceMsgEvents: function(options) { let that = this; switch (options.type) { case xBlufi.XBLUFI_TYPE.TYPE_STATUS_CONNECTED: { // console.log('状态', options.result) if (options.result == false) { // uni.showModal({ // title: '很抱歉提醒你!', // content: '小程序与设备异常断开', // showCancel: false, // success: function(res) { // // uni.navigateBack({ // // url: '../search/search' // // }); // } // }); this.statusflag = false uni.hideLoading(); } } break; case xBlufi.XBLUFI_TYPE.TYPE_RECIEVE_CUSTON_DATA: console.log("1收到设备发来的自定义数据结果:", options.data); break; case xBlufi.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT: uni.hideLoading(); if (options.result) { console.log('初始化成功'); } else { console.log('初始化失败'); uni.showModal({ title: '温馨提示', content: `设备初始化失败`, showCancel: false, //是否显示取消按钮 success: function(res) { // uni.redirectTo({ // url: '../search/search' // }); } }); } break; } }, //4、建立连接 createBLEConnection(e) { this.mac = e.localName.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 }); const deviceId = that.deviceinfo.deviceId that.Bluetoothmac = that.deviceinfo.localName.substring(5) //从第七位开始截取 只取后面的mac号 let name = that.deviceinfo.name; console.log(that.deviceinfo.deviceId, 'that.deviceinfo.deviceId'); xBlufi.notifyConnectBle({ isStart: true, deviceId: that.deviceinfo.deviceId, name }); } else { uni.showToast({ title: res.msg, icon: 'none', duration: 2000 }); setTimeout(() => { uni.navigateBack({ delta: 1 // delta值为1时表示返回的页面层数 }); }, 2000) } }) // uni.getLocation({ // type: 'wgs84', // success: function(lb) { // console.log('位置信息', lb); // console.log('当前位置的经度:' + lb.longitude); // console.log('当前位置的纬度:' + lb.latitude); // that.gps.lat = lb.latitude; // that.gps.lon = lb.longitude; // that.$u.put(`/app/device/bind/${that.mac}`, that.gps).then((res) => { // if (res.code == 200) { // uni.showToast({ // title: '绑定成功', // icon: 'none', // duration: 2000 // }); // uni.removeStorageSync('mac'); // // setTimeout(()=>{ // // uni.switchTab({ // // url:'/pages/index/index' // // }) // // },) // } else { // uni.showToast({ // title:res.msg, // icon: 'none', // duration: 2000 // }); // // setTimeout(()=>{ // // uni.switchTab({ // // url:'/pages/index/index' // // }) // // },) // } // }) // }, // fail: function(error) { // console.error('获取位置信息失败:', error); // that.gps.lat = 0; // that.gps.lon = 0; // that.$u.put(`/app/device/bind/${that.mac}`, that.gps).then((res) => { // if (res.code == 200) { // uni.showToast({ // title: '绑定成功', // icon: 'none', // duration: 2000 // }); // uni.removeStorageSync('mac'); // xBlufi.notifyStartDiscoverBle({ // 'isStart': false // }); // const deviceId = that.deviceinfo.deviceId // that.Bluetoothmac = that.deviceinfo.localName.substring(6) //从第七位开始截取 只取后面的mac号 // let name = that.deviceinfo.name; // xBlufi.notifyConnectBle({ // isStart: true, // deviceId: that.deviceinfo.deviceId, // name // }); // // setTimeout(()=>{ // // uni.switchTab({ // // url:'/pages/index/index' // // }) // // },) // } else { // uni.showToast({ // title:res.msg, // icon: 'none', // duration: 2000 // }); // // setTimeout(()=>{ // // uni.switchTab({ // // url:'/pages/index/index' // // }) // // },) // } // }) // // 在这里处理获取位置信息失败的情况 // } // }) }, // 点击重新搜索 Search() { if (this.status) { xBlufi.notifyStartDiscoverBle({ 'isStart': true }); // 重新搜索清空蓝牙数组 this.bluthlist = [] this.devicesList = [] this.devicesLists = [] // 重新搜索 // this.startBluetoothDevicesDiscovery() this.statusflag = true this.texts = '正在扫描蓝牙设备...' setTimeout(() => { this.statusflag = false if (this.searching) { // 判断是否存在浇花器设备 if (this.devicesList.length == 0) { this.tishiflag = true this.texts = '扫描完毕,暂无发现电动车设备' } else { this.texts = '扫描到以下设备,请点击连接!' } xBlufi.notifyStartDiscoverBle({ 'isStart': false }); } else { xBlufi.notifyStartDiscoverBle({ 'isStart': true }); } }, 2000) } }, // 点击隐藏没有设备提示 btnhd() { this.tishiflag = false } } } </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>