563 lines
14 KiB
Vue
563 lines
14 KiB
Vue
<template>
|
||
<view class="device-management">
|
||
<!-- 顶部导航栏 -->
|
||
<u-navbar title="设备管理" :border-bottom="false" :background="{ background: '#1a1a1a' }" back-icon-color="#fff"
|
||
title-color='#fff' title-size='36' height='36' id="navbar">
|
||
</u-navbar>
|
||
|
||
<!-- 搜索和筛选区域 -->
|
||
<view class="search-filter">
|
||
<view class="search-box">
|
||
<u-icon name="search" color="#666" size="32"></u-icon>
|
||
<input type="text" placeholder="搜索设备编号" placeholder-style="color: #666;" v-model="searchText"
|
||
@input="handleSearch" />
|
||
<u-icon name="scan" color="#666" @click="saoma" size="32"></u-icon>
|
||
</view>
|
||
|
||
<view class="filters">
|
||
<view class="filter-item" @tap="showStorePopup">
|
||
<text>门店:{{storesname}}</text>
|
||
<u-icon name="arrow-down" color="#666" size="28"></u-icon>
|
||
</view>
|
||
<view class="filter-item" @tap="showStatusPopup">
|
||
<text>状态:{{statusname}}</text>
|
||
<u-icon name="arrow-down" color="#666" size="28"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 设备列表 -->
|
||
<scroll-view scroll-y class="device-list" @scrolltolower="handqixing" refresher-enabled @refresherrefresh="onRefresh" :refresher-triggered="isRefreshing" refresher-default-style="white">
|
||
<view v-for="(device,index) in deviceList" :key="index" class="device-item">
|
||
<view class="device-header" @click="btnxq(device.deviceId)">
|
||
<text class="sn">{{device.deviceName == null ? '--' : device.deviceName}}</text>
|
||
<text :class="['status', device.onlineStatus == 1 ? 'online' : 'offline']">
|
||
<view class="status-dot"></view>
|
||
{{device.onlineStatus == 1 ? '在线' : '离线'}}
|
||
</text>
|
||
</view>
|
||
|
||
<view class="device-content" @click="btnxq(device.deviceId)">
|
||
<image src="https://api.ccttiot.com/smartmeter/img/static/uyKu3YhTED9tkOUSs919" mode="aspectFit"
|
||
class="device-image" />
|
||
<view class="device-info">
|
||
<view class="info-row">
|
||
<text class="label">SN:</text>
|
||
<text class="value">{{device.deviceNo == null ? '--' : device.deviceNo}}</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="label">门店名称:</text>
|
||
<text class="value">{{device.storeName == null ? '--' : device.storeName}}</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="label">设备状态:</text>
|
||
<text class="value" v-if="device.status == 1">正常</text>
|
||
<text class="value" v-if="device.status == 2">使用中</text>
|
||
<text class="value" v-if="device.status == 3">维修中</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="label">亮灯时长:</text>
|
||
<text class="value">{{device.duration == null ? 0 : device.duration}}s</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="device-footer">
|
||
<view class=""></view>
|
||
<view class="" style="display: flex;align-items: center;">
|
||
<u-switch v-model="device.powerStatus == 1"
|
||
@change="(e) => handleSwitch(e, device.deviceId,index)" style="transform:scale(0.8);"
|
||
active-color="#FF4D7D"></u-switch>
|
||
<button class="code-btn" @tap="showDeviceCode(device.deviceNo)">设备码</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="" style="font-size: 28rpx;color: #808080;margin-top: 30rpx;text-align: center;width: 100%;">
|
||
没有更多设备了...</view>
|
||
</scroll-view>
|
||
<!-- 弹出层 -->
|
||
<u-popup v-model="showStorePicker" mode="bottom">
|
||
<view class="popup-content">
|
||
<view class="popup-header">
|
||
<text>选择门店</text>
|
||
<u-icon name="close" @tap="showStorePicker = false"></u-icon>
|
||
</view>
|
||
<view class="popup-list">
|
||
<view v-for="(store, index) in stores" :key="index" class="popup-item"
|
||
:class="{ active: selectedStore === index }" @tap="selectStore(index)">
|
||
{{store.name}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
|
||
<u-popup v-model="showStatusPicker" mode="bottom">
|
||
<view class="popup-content">
|
||
<view class="popup-header">
|
||
<text>选择状态</text>
|
||
<u-icon name="close" @tap="showStatusPicker = false"></u-icon>
|
||
</view>
|
||
<view class="popup-list">
|
||
<view v-for="(status, index) in statusOptions" :key="index" class="popup-item"
|
||
:class="{ active: selectedStatus === index }" @tap="selectStatus(index)">
|
||
{{status}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
var xBlufi = require("@/components/blufi/xBlufi.js")
|
||
export default {
|
||
data() {
|
||
return {
|
||
searchText: '',
|
||
stores: [{
|
||
name: '全部',
|
||
id: ''
|
||
}],
|
||
storesname: '全部',
|
||
statusname: '全部',
|
||
statusOptions: ['全部', '在线', '离线'],
|
||
selectedStore: 0,
|
||
selectedStatus: 0,
|
||
deviceList: [],
|
||
showStorePicker: false,
|
||
showStatusPicker: false,
|
||
bgc: {
|
||
background: '#1a1a1a'
|
||
},
|
||
storeId: '',
|
||
devicestatus: '',
|
||
bdsn: '',
|
||
user: {},
|
||
pagesum:'',
|
||
total:'',
|
||
isRefreshing:false
|
||
}
|
||
},
|
||
onLoad(option) {
|
||
// xBlufi.initXBlufi(1)
|
||
if(option.storeId){
|
||
this.storeId = option.storeId
|
||
this.storesname = option.tit
|
||
}
|
||
},
|
||
onShow() {
|
||
this.pagesum = 1
|
||
this.getinfo()
|
||
this.getlist()
|
||
this.getshop()
|
||
this.
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': true
|
||
})
|
||
},
|
||
methods: {
|
||
// 下拉刷新
|
||
onRefresh() {
|
||
this.isRefreshing = true
|
||
this.pageNum = 1
|
||
this.getlist()
|
||
setTimeout(() => {
|
||
this.isRefreshing = false
|
||
}, 1000)
|
||
},
|
||
// 点击扫码绑定设备
|
||
saoma() {
|
||
uni.scanCode({
|
||
onlyFromCamera: true,
|
||
scanType: ['qrCode'],
|
||
success: res => {
|
||
console.log(res);
|
||
function getQueryParam(url, paramName) {
|
||
let regex = new RegExp(`[?&]${paramName}=([^&]*)`)
|
||
let results = regex.exec(url)
|
||
return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null
|
||
}
|
||
let sceneValue = res.result
|
||
let decodedValue = decodeURIComponent(sceneValue)
|
||
this.bdsn = getQueryParam(decodedValue, 's')
|
||
console.log(this.bdsn, 'snsnsnsnsn');
|
||
let data = {
|
||
deviceNo: this.bdsn
|
||
}
|
||
this.$u.put(`/bst/device/bindMch?mchId=${this.user.userId}`, data).then(res => {
|
||
if (res.code == 200) {
|
||
uni.showToast({
|
||
title: '操作成功',
|
||
icon: 'success',
|
||
duration: 2000
|
||
})
|
||
this.pagesum = 1
|
||
this.getlist()
|
||
} else if (res.msg == null) {
|
||
uni.showToast({
|
||
title: '未知错误',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
} else {
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
})
|
||
},
|
||
fail: err => {
|
||
console.error('扫描失败:', err)
|
||
uni.showToast({
|
||
title: '扫描失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 获取用户信息
|
||
getinfo() {
|
||
this.$u.get(`/getInfo`).then(res => {
|
||
if (res.code == 200) {
|
||
this.user = res.user
|
||
}
|
||
})
|
||
},
|
||
// 查询设备列表
|
||
getlist() {
|
||
this.$u.get(`/bst/device/list?pageNum=${this.pagesum}&pageSize=20&storeId=${this.storeId}&onlineStatus=${this.devicestatus}&deviceNo=${this.searchText}`).then(res => {
|
||
if (res.code == 200) {
|
||
this.total = res.total
|
||
if(this.pagesum == 1){
|
||
this.deviceList = res.rows
|
||
this.pagesum++
|
||
}else{
|
||
this.deviceList = this.deviceList.concat(res.rows)
|
||
this.pagesum++
|
||
}
|
||
} else if (res.msg == null) {
|
||
uni.showToast({
|
||
title: '未知错误',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
} else {
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 获取所有店铺
|
||
getshop() {
|
||
this.$u.get(`/bst/store/list?pageNum=1&pageSize=999`).then(res => {
|
||
if (res.code == 200) {
|
||
res.rows.forEach((item) => {
|
||
this.stores.push({
|
||
name: item.storeName,
|
||
id: item.storeId
|
||
})
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 点击跳转到详情
|
||
btnxq(deviceId) {
|
||
// uni.navigateTo({
|
||
// url: '/page_shanghu/device/devicexq?deviceId=' + deviceId
|
||
// })
|
||
uni.navigateTo({
|
||
url: '/page_user/devicekzxq?deviceId=' + deviceId
|
||
})
|
||
// console.log('跳转到详情');
|
||
},
|
||
// 滚动骑行订单到底部分页请求
|
||
handqixing() {
|
||
if(this.total > this.deviceList.length){
|
||
this.getlist()
|
||
}else{
|
||
console.log(11);
|
||
}
|
||
},
|
||
// 进行搜索
|
||
handleSearch(e) {
|
||
this.pagesum = 1
|
||
this.searchText = e.detail.value
|
||
this.getlist()
|
||
},
|
||
// 选择店铺
|
||
showStorePopup() {
|
||
this.showStorePicker = true
|
||
},
|
||
//选择状态
|
||
showStatusPopup() {
|
||
this.showStatusPicker = true
|
||
},
|
||
//筛选门店条件
|
||
selectStore(index) {
|
||
this.storesname = this.stores[index].name
|
||
this.storeId = this.stores[index].id
|
||
console.log(this.storesname, this.storeId, '0000')
|
||
this.selectedStore = index
|
||
this.showStorePicker = false
|
||
this.pagesum = 1
|
||
this.getlist()
|
||
},
|
||
// 筛选在线离线条件
|
||
selectStatus(index) {
|
||
this.statusname = this.statusOptions[index]
|
||
this.selectedStatus = index
|
||
if (index == 0) {
|
||
this.devicestatus = ''
|
||
} else if (index == 1) {
|
||
this.devicestatus = 1
|
||
} else if (index == 2) {
|
||
this.devicestatus = 0
|
||
}
|
||
this.showStatusPicker = false
|
||
this.pagesum = 1
|
||
this.getlist()
|
||
},
|
||
// 点击开关
|
||
handleSwitch(e, deviceId, index) {
|
||
console.log(e, deviceId, index)
|
||
if (this.deviceList[index].powerStatus == 0) {
|
||
this.$u.put(`/bst/device/iot/${deviceId}/switch?open=true`).then(res => {
|
||
if (res.code == 200) {
|
||
this.deviceList[index].powerStatus = 1
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'success',
|
||
duration: 2000
|
||
})
|
||
} else {
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
})
|
||
} else {
|
||
this.$u.put(`/bst/device/iot/${deviceId}/switch?open=false`).then(res => {
|
||
if (res.code == 200) {
|
||
this.deviceList[index].powerStatus = 0
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'success',
|
||
duration: 2000
|
||
})
|
||
} else {
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
})
|
||
}
|
||
},
|
||
// 点击设备码
|
||
showDeviceCode(sn) {
|
||
uni.navigateTo({
|
||
url: '/page_shanghu/ewm?sn=' + sn
|
||
})
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/deep/ .u-iconfont {
|
||
color: #fff !important;
|
||
}
|
||
|
||
.device-management {
|
||
min-height: 100vh;
|
||
background-color: #1a1a1a;
|
||
|
||
.search-filter {
|
||
padding: 20rpx;
|
||
background-color: #1a1a1a;
|
||
|
||
.search-box {
|
||
display: flex;
|
||
align-items: center;
|
||
background-color: #2c2c2c;
|
||
padding: 15rpx 30rpx;
|
||
border-radius: 40rpx;
|
||
margin-bottom: 30rpx;
|
||
|
||
input {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
color: #fff;
|
||
margin: 0 20rpx;
|
||
}
|
||
}
|
||
|
||
.filters {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
|
||
.filter-item {
|
||
flex: 1;
|
||
margin: 0 10rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
background-color: #2c2c2c;
|
||
padding: 15rpx 30rpx;
|
||
border-radius: 40rpx;
|
||
|
||
text {
|
||
font-size: 28rpx;
|
||
color: #fff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.device-list {
|
||
width: 680rpx;
|
||
margin: auto;
|
||
height: 76vh;
|
||
overflow: scroll;
|
||
|
||
.device-item {
|
||
background-color: #2c2c2c;
|
||
margin-bottom: 20rpx;
|
||
padding: 30rpx;
|
||
border-radius: 20rpx;
|
||
|
||
.device-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 20rpx;
|
||
|
||
.sn {
|
||
font-size: 32rpx;
|
||
color: #fff;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.status {
|
||
font-size: 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.status-dot {
|
||
width: 12rpx;
|
||
height: 12rpx;
|
||
border-radius: 50%;
|
||
margin-right: 10rpx;
|
||
}
|
||
|
||
&.online {
|
||
color: #67C23A;
|
||
|
||
.status-dot {
|
||
background-color: #67C23A;
|
||
}
|
||
}
|
||
|
||
&.offline {
|
||
color: #909399;
|
||
|
||
.status-dot {
|
||
background-color: #909399;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.device-content {
|
||
display: flex;
|
||
margin-bottom: 20rpx;
|
||
|
||
.device-image {
|
||
width: 170rpx;
|
||
height: 170rpx;
|
||
margin-right: 30rpx;
|
||
background-color: #1a1a1a;
|
||
border-radius: 10rpx;
|
||
}
|
||
|
||
.device-info {
|
||
flex: 1;
|
||
|
||
.info-row {
|
||
margin-bottom: 15rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.label {
|
||
color: #909399;
|
||
font-size: 26rpx;
|
||
width: 140rpx;
|
||
}
|
||
|
||
.value {
|
||
color: #fff;
|
||
font-size: 26rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.device-footer {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
.code-btn {
|
||
width: 152rpx;
|
||
// height: 64rpx;
|
||
background-color: #2c2c2c;
|
||
border-radius: 14rpx 14rpx 14rpx 14rpx;
|
||
border: 2rpx solid #FF8998;
|
||
font-size: 32rpx;
|
||
color: #FF8998;
|
||
text-align: center;
|
||
margin-left: 30rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.popup-content {
|
||
background-color: #2c2c2c;
|
||
border-radius: 20rpx 20rpx 0 0;
|
||
|
||
.popup-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 30rpx;
|
||
border-bottom: 2rpx solid #3a3a3a;
|
||
|
||
text {
|
||
color: #fff;
|
||
font-size: 32rpx;
|
||
}
|
||
}
|
||
|
||
.popup-list {
|
||
padding: 20rpx 0;
|
||
|
||
.popup-item {
|
||
padding: 30rpx;
|
||
color: #fff;
|
||
font-size: 28rpx;
|
||
|
||
&.active {
|
||
color: #FF4D7D;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |