congming_huose-apk/pages/luru/index.vue

613 lines
15 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">
<app-top-push-notice />
<view class="title">
<view class="title_li" style="display: flex;align-items: center;">
<view class="text">{{$i18n.t('deviceList')}}</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="cen">
<view class="name">
{{$i18n.t('macLabel')}}{{item.localName.substring(5)}}
<span
:style="{ fontSize: '24rpx', marginLeft: '30rpx', color: item.isBand ? '#808080' : '#4297F3' }">
<!-- 根据接口 userId 是否有值:已绑定 / 未绑定 -->
{{ item.isBand ? $i18n.t('deviceAlreadyBound') : $i18n.t('deviceUnbound') }}
</span>
</view>
<view class="mac">
{{$i18n.t('bluetoothSignal')}}{{item.RSSI}} <span style="margin-left: 20rpx;" v-if="item.sn"> SN:{{item.sn}}</span>
</view>
</view>
<view class="rt" style="margin-right: 10rpx;">
<text :id="item.deviceId" :style="item.isBand ? 'opacity:0.5' : ''">{{$i18n.t('select')}}</text>
</view>
<view class="" v-if="devicesList.length == 0 || devicesList == [] || devicesList == null || devicesList == undefined">
<image src="https://api.ccttiot.com/smartmeter/img/static/VhMNQ3Nf43oSKKbsPPPk" style="margin-top: 50rpx;width: 400rpx;height: 400rpx;" mode="aspectFill"></image>
</view>
</view>
<view class="anniu">
<view style="width: 200rpx;" @click="backPage">{{$i18n.t('back')}}</view>
<view style="width: 450rpx;" @click="Search">{{$i18n.t('rescan')}}</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("@/common/blufi/xBlufi.js")
let _this = null;
export default {
data() {
return {
titleflag: false, //提示隐藏
bgc: {
backgroundColor: "#F7FAFE",
},
devicesList: [],
devicesLists: [],
searching: false,
texts: this.$i18n.t('scanningBluetooth'),
btnflag: true,
tishiflag: false,
option: '',
bluthlist: [], //蓝牙数组
status: 'loading',
statusflag: false,
Bluetoothmac: '',
gps: {},
mac: '',
status: false,
deviceinfo: null,
sn: ''
}
},
onLoad(e) {
if (e.sn) {
this.sn = e.sn
}
xBlufi.initXBlufi(1)
},
onShow: function() {
this.bluthlist = []
this.devicesList = []
this.devicesLists = []
// 强制视图更新
this.$forceUpdate()
// 后续的蓝牙初始化和扫描逻辑
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent)
xBlufi.notifyStartDiscoverBle({ 'isStart': true })
setTimeout(() => {
xBlufi.notifyStartDiscoverBle({ 'isStart': false })
if (this.devicesList.length == 0) {
this.tishiflag = true
this.texts = this.$i18n.t('scanCompleteNoDevice')
} else {
this.texts = this.$i18n.t('devicesFound')
}
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() {
},
methods: {
/** 接口 userId 有有效值视为已绑定(不可再绑) */
hasBoundUserId(userId) {
if (userId === null || userId === undefined) return false
if (typeof userId === 'number') return !isNaN(userId) && userId !== 0
const s = String(userId).trim()
return s !== '' && s !== 'null' && s !== 'undefined'
},
replay(){
uni.reLaunch({
url:'/pages/luru/index'
})
},
backPage(){
uni.reLaunch({
url:'/pages/index/index'
})
},
toControl(){
uni.redirectTo({
url:'/pages/luru/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
// 向批量接口请求录入状态
let data = macs
this.$u.post(`/bst/device/listSnByMac`,data).then((res) => {
const resultList = res.data // 获取接口返回的数据数组
console.log(res,'请求')
// 遍历 devicesList 并对比 mac 地址
this.devicesList.forEach(device => {
const mac = device.localName.substring(5)
const matchingResult = resultList.find(result => result.mac === mac)
device.isBand = false
if (matchingResult) {
device.sn = matchingResult.sn
const uid = matchingResult.userId !== undefined && matchingResult.userId !== null
? matchingResult.userId
: matchingResult.user_id
device.isBand = this.hasBoundUserId(uid)
}
})
// 对 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)
if (e.isBand) {
uni.showToast({
title: this.$i18n.t('deviceAlreadyBound'),
icon: 'none'
})
return
}
let Bluetoothmac = e.name.substring(5)
uni.navigateTo({
url: '/pages/luru/bind_mac?mac=' + Bluetoothmac
})
},
funListenDeviceMsgEvent: function(options) {
switch (options.type) {
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS:
if (options.result) {
this.devicesLists = options.data
}
break
case xBlufi.XBLUFI_TYPE.TYPE_CONNECTED:
console.log("连接回调:" + JSON.stringify(options))
if (options.result) {
uni.hideLoading()
uni.showToast({
title: this.$i18n.t('connectionSuccess'),
icon: 'none'
}); {
console.log("连接回调options.data.deviceId" + options.data.deviceId,
"连接回调options.data.name" + options.data.name);
xBlufi.notifyInitBleEsp32({
deviceId: options.data.deviceId
})
}
}
break;
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START:
if (!options.result) {
console.log("蓝牙未开启", options);
uni.showToast({
title: this.$i18n.t('bluetoothNotEnabled'),
icon: 'none',
duration: 3000
});
if (this.devicesList.length == 0) {
this.tishiflag = true
this.texts = this.$i18n.t('scanComplete')
} else {
this.texts = this.$i18n.t('devicesFound')
}
} else {
this.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)
});
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
break;
}
},
// 点击重新搜索
Search() {
if (this.status) {
xBlufi.notifyStartDiscoverBle({
'isStart': true
});
// 重新搜索清空蓝牙数组
this.bluthlist = []
this.devicesList = []
this.devicesLists = []
// 重新搜索
// this.startBluetoothDevicesDiscovery()
this.statusflag = true
this.texts = this.$i18n.t('scanningBluetooth')
setTimeout(() => {
this.statusflag = false
if (this.searching) {
// 判断是否存在浇花器设备
if (this.devicesList.length == 0) {
this.tishiflag = true
this.texts = this.$i18n.t('scanCompleteNoDevice')
} else {
this.texts = this.$i18n.t('devicesFound')
}
xBlufi.notifyStartDiscoverBle({
'isStart': false
})
} else {
xBlufi.notifyStartDiscoverBle({
'isStart': true
});
}
}, 2000)
}
},
}
}
</script>
<style lang="scss">
page {
background-color: #F7FAFE !important;
}
.tabback{
width: 750rpx;
height: 130rpx;
background: #FCFCFC;
border-radius: 0rpx 0rpx 0rpx 0rpx;
position: fixed;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 28rpx;
box-sizing: border-box;
border-bottom: 1px solid #D8D8D8;
padding-top: 52rpx;
z-index: 999;
.name{
font-size: 36rpx;
color: #3D3D3D;
}
.rtjt {
font-size: 36rpx;
}
}
.containers {
width: 100%;
height: 100vh;
position: fixed;
top: 0;
padding-top: 130rpx;
box-sizing: border-box;
left: 0;
z-index: 999 !important;
z-index: 99;
}
.pages {
padding-top: 136rpx !important;
padding: 0 66rpx;
box-sizing: border-box;
padding-bottom: 200rpx;
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 40rpx;
width: 100%;
box-sizing: border-box;
position: fixed;
left: 0;
bottom: 60rpx;
display: flex;
align-items: center;
justify-content: space-between;
view {
background: #000;
border-radius: 52rpx 52rpx 52rpx 52rpx;
color: #fff;
height: 80rpx;
line-height: 80rpx;
text-align: center;
}
}
.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>