gy-app-shop/pages/project/equipmentStatus/status.vue

695 lines
19 KiB
Vue

<template>
<view class="equipmentStatus">
<view class="equipmentStatus-header" :style="{height:isShowDropdown?'100%':''}">
<u-dropdown @open="isShowDropdown = true" @close="isShowDropdown = false">
<!-- <u-dropdown-item v-model="value1" title="设备" :options="options1" @change="modelOnchageFn"></u-dropdown-item> -->
<u-dropdown-item v-model="selectValue" title="设备状态" :options="selectList"
@change="modelOnchageFn"></u-dropdown-item>
<u-dropdown-item v-model="deviceGroupValue" title="设备组" :options="deviceGroupOptions" @change="modelOnchageFn"></u-dropdown-item>
<!-- <u-dropdown-item v-model="value2" title="楼栋" :options="buildingOptions" @change="buildingOnchageFn"></u-dropdown-item> -->
<!-- <u-dropdown-item v-model="value3" title="单元" :options="unitOptions" @change="unitOnchageFn"></u-dropdown-item> -->
</u-dropdown>
<view class="equipmentStatus-search-ctn">
<u-search @search="onSearchFn" class="equipmentStatus-search" placeholder="输入设备号和设备名" v-model="searchValue"
:show-action="false"></u-search>
<view class="equipmentStatus-search-picker" @click="openSpace">
<text>{{activeSpaceName}}</text>
<u-icon class="pl20" name="arrow-down"></u-icon>
</view>
</view>
</view>
<view class="equipmentStatus-facility-list">
<mescroll-body ref="mescrollRef" top="166" @init="mescrollInit" @down="downCallback" @up="upCallback">
<view class="equipmentStatus-facility-box-main">
<view class="equipmentStatus-facility-box" v-for="(item,index) in facilityList" :key="index"
@click="goDeviceDetailFn(item)">
<view class="equipmentStatus-facility-box-title">
<view style="font-weight: 550;">线路数:{{item.childrenNumber}}</view>
<view class="" style="display: flex; align-items: center;">
<view class="">
<tuiIcon :name="item.deviceState | statusIco" :color="item.deviceState | statusColor" size="28">
</tuiIcon>
<text class="pl10"
:style="{color: statusStyle(item.deviceState)}">{{item.deviceState | statusName}}</text>
</view>
<view v-if="item.deviceType == 'GATEWAY_CONTROLLER'"
style="margin-left: 10rpx;display: flex;align-items: center;">
<tuiIcon name="baojingjilu" :color="item.tenantAlarmVo?'red':'#999'" size="36"></tuiIcon>
<text class="pl10"
:style="{color:item.tenantAlarmVo?'red':'#999'}">{{item.tenantAlarmVo ? '报警' : '正常'}}</text>
</view>
<view v-else class="" style="margin-left: 10rpx;display: flex;align-items: center;">
<tuiIcon name="baojingjilu" size="36"></tuiIcon>
<text class="pl10">{{item.deviceAlarmStatus ? '正常' : '报警'}}</text>
</view>
</view>
</view>
<view class="equipmentStatus-facility-box-content">
<view class="tag-list">
<u-tag v-for="(val,i) in item.deviceLabel" size="mini" :key="i" :text="val" type="primary"
style="margin-right: 10rpx;" />
</view>
<view class="equipmentStatus-facility-box-content-box">
<template v-if="item.deviceImage">
<u-image class="equipmentStatus-facility-box-img" width="160" height="160"
:src="fullURL(item.deviceImage)"></u-image>
</template>
<template v-else>
<u-image class="equipmentStatus-facility-box-img" width="160" height="160"
src="http://static.drgyen.com/app/hc-app-power/images/switch.png"></u-image>
</template>
<view class="equipmentStatus-facility-box-info">
<view class="row">
<view class="row-label">设备号:</view>
<view class="row-value ellipsis">{{item.deviceKey || "-"}}</view>
</view>
<view class="row">
<view class="row-label">设备:</view>
<view class="row-value">{{item.deviceName || "-"}}</view>
</view>
<view class="row">
<view class="row-label">设备组:</view>
<view class="row-value ellipsis">{{item.groupName || "-"}}</view>
</view>
<view class="row">
<view class="row-label">地址:</view>
<view class="row-value ellipsis">{{item.deviceAddress || "-"}}</view>
</view>
<!-- <view class="status">
<view class="pl10">{{item.deviceAlarmStatus ? '正常' : '报警'}}</view>
<tuiIcon name="baojingjilu"></tuiIcon>
</view> -->
<view class="btn-box" v-if="adminFlag == 'true' || projectRole == 'operator'">
<u-button type="primary" size="mini" @click="unBind(item)">解绑设备</u-button>
</view>
</view>
</view>
</view>
</view>
</view>
</mescroll-body>
</view>
<tki-tree ref="tkiTree" :selectParent="true" :range="spaceTreeList" idKey="labelCode" rangeKey="labelKey"
@confirm="treeConfirm" @cancel="treeCancel"></tki-tree>
<u-select v-model="stateShowFlag" :list="selectList" @confirm="selectConfirmFn"></u-select>
<u-toast ref="uToast" />
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import tkiTree from '@/components/tki-tree/tki-tree.vue';
export default {
components: {
tkiTree
},
data() {
return {
value1: "GATEWAY_CONTROLLER",
value2: "",
deviceGroupValue: "",
selectLabel: "全部",
selectValue: "",
isShowDropdown: false,
selectList: [{
value: '',
label: '全部'
},
{
value: 'ONLINE',
label: '在线'
},
{
value: 'OFFLINE',
label: '离线'
},
{
value: 'UNACTIVE',
label: '未激活'
},
],
options1: [{
label: '全部',
value: ""
},
{
label: '网关控制器',
value: "GATEWAY_CONTROLLER"
},
{
label: '烟雾传感器',
value: "SMOKE_SENSOR"
}
],
deviceGroupOptions: [{
label: '全部',
value: ""
}
],
spaceShowFlag: false,
spaceTreeList: [],
activeSpaceValue: '',
activeSpaceName: '全部空间',
projectId: "",
buildingOptions: [],
unitOptions: [],
searchValue: '',
spaceActionId: "",
facilityList: [], // 设备列表
adminFlag: true, // 管理员权限
projectRole: ''
}
},
mixins: [MescrollMixin],
onLoad(e) {
this.projectId = e.projectId;
this.getTagTypeList();
// this.getbuildingOptListFn();
// this.getDeviceTypeList()
this.getDeviceGroupList()
if (e.adminFlag != undefined) {
this.adminFlag = e.adminFlag;
}
if (e.projectRole != undefined) {
this.projectRole = e.projectRole;
}
if(e.deviceState){
this.selectValue = e.deviceState;
this.onSearchFn()
}
if(e.queryType == 'device' && e.deviceKey){
this.searchValue = e.deviceKey;
this.onSearchFn()
}else if(e.queryType == 'group' && e.groupCode){
this.deviceGroupValue = e.groupCode;
this.onSearchFn()
}else if(e.queryType == '空间' && e.code){
this.value2 = e.code;
this.onSearchFn()
}
},
onShow() {
// 刷新状态
// if (this.facilityList.length > 0) {
// this.resetDevice(this.facilityList.length)
// }
this.mescroll.resetUpScroll()
},
methods: {
openSpace() {
this.$refs.tkiTree._show();
},
getTagTypeList() {
let obj = {
projectId: this.projectId,
}
this.$get("iot/labelType/list", obj).then((res) => {
if (res.rows && res.rows.length > 0) {
let tagType = '';
res.rows.forEach(item => {
if (item.labelName == '空间') {
tagType = item.labelType;
}
})
if (tagType) {
this.getTagList(tagType)
}
} else {}
}).catch(() => {})
},
getTagList(tagType) {
let obj = {
labelType: tagType,
projectId: this.projectId,
}
this.$get("iot/labelData/list", obj).then((res) => {
if (res.rows && res.rows.length > 0) {
// 接口返回的当前页数据列表 (数组)
let curPageData = res.rows;
this.spaceTreeList = handleTree(curPageData, "labelCode", "parentId");
} else {
this.spaceTreeList = [];
}
}).catch(() => {
//联网失败, 结束加载
})
},
treeConfirm(e) {
console.log(e)
if (e != []) {
this.activeSpaceName = e[0].labelKey;
this.activeSpaceValue = e[0].labelCode;
this.mescroll.resetUpScroll();
}
},
// 取消回调事件
treeCancel(e) {
console.log(e)
},
unBind(device) {
console.log("当前设备", device)
uni.showModal({
title: '提示',
content: '确认要解绑设备(' + device.deviceName + ')吗?',
confirmText: '确认',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
this.$DELETE("/app/device/unbind/" + device.deviceKey, {}).then((res) => {
console.log("res", res)
if (res.code == 200) {
this.$refs.uToast.show({
title: '解绑成功',
type: 'success',
})
this.mescroll.resetUpScroll();
} else {
this.$refs.uToast.show({
title: res.msg,
type: 'error',
})
}
}).catch((err) => {
this.$refs.uToast.show({
title: err.msg,
type: 'error',
})
})
} else if (res.cancel) {
}
}
});
},
goDeviceDetailFn(item) {
uni.navigateTo({
url: `../../home/wisdomElectricity/electricityDetail?deviceId=${item.deviceId}`
})
},
/*上拉加载的回调*/
upCallback(page) {
console.log(page, "page");
let pageNum = page.num; // 页码, 默认从1开始
let pageSize = page.size; // 页长, 默认每页10条
const {
projectId,
value1,
value2,
value3,
searchValue,
selectValue,
activeSpaceValue,
deviceGroupValue
} = this;
let obj = {
pageSize: pageSize,
pageNum: pageNum,
projectId: projectId,
deviceTypes: value1,
// spaceId: value3? value3 : value2,
// deviceSpace: searchValue, // 设备号或者架构名称
deviceInfo: searchValue, // 设备号或者架构名称
deviceState: selectValue, // 设备状态(1:'未激活', 2:'在线', 3:'离线'),可用值:UNACTIVE,ONLINE,OFFLINE
labelCode: activeSpaceValue,
groupCode: deviceGroupValue
// projectName:this.searchValue
// projectId:this.projectIdVal,
// deviceState:this.screeningValue,
}
this.$get("/app/device/table", obj).then((res) => {
// console.log(res,"ressssssssssss");
if (res.rows && res.rows.length > 0) {
// 接口返回的当前页数据列表 (数组)
let curPageData = res.rows;
curPageData = res.rows.map(item => {
if (item.deviceLabel && item.deviceLabel[0] == '空间') {
item.deviceLabel.shift();
return item;
}
return item;
})
// 接口返回的当前页数据长度 (如列表有26个数据,当前页返回8个,则curPageLen=8)
let curPageLen = curPageData.length;
//设置列表数据
if (pageNum == 1) this.facilityList = []; //如果是第一页需手动置空列表
this.facilityList = this.facilityList.concat(curPageData); //追加新数据
this.mescroll.endBySize(curPageLen, res.total); // 推荐
// this.mescroll.endByPage(curPageLen, res.data.total)
// this.mescroll.endSuccess(curPageData.length);
} else {
this.facilityList = [];
this.mescroll.endErr();
this.mescroll.showEmpty();
// this.mescroll.endUpScroll(true);
}
}).catch(() => {
//联网失败, 结束加载
this.mescroll.endErr();
}).finally(() => {
// this.dropdownIsOpen = false;
})
},
/*上拉加载的回调*/
resetDevice(size) {
const {
projectId,
value1,
value2,
value3,
searchValue,
selectValue,
deviceGroupValue
} = this;
let obj = {
pageSize: size,
pageNum: 1,
projectId: projectId,
deviceTypes: value1,
deviceGroupValue: deviceGroupValue,
spaceId: value3 ? value3 : value2,
deviceSpace: searchValue, // 设备号或者架构名称
deviceState: selectValue // 设备状态(1:'未激活', 2:'在线', 3:'离线'),可用值:UNACTIVE,ONLINE,OFFLINE
}
this.$get("/app/device/table", obj).then((res) => {
if (res.rows && res.rows.length > 0) {
// 接口返回的当前页数据列表 (数组)
let curPageData = res.rows;
// 接口返回的当前页数据长度 (如列表有26个数据,当前页返回8个,则curPageLen=8)
let curPageLen = curPageData.length;
//设置列表数据
this.facilityList = curPageData;
this.mescroll.endBySize(curPageLen, res.total); // 推荐
} else {
this.facilityList = [];
this.mescroll.endErr();
this.mescroll.showEmpty();
// this.mescroll.endUpScroll(true);
}
}).catch(() => {
//联网失败, 结束加载
this.mescroll.endErr();
}).finally(() => {
// this.dropdownIsOpen = false;
})
},
onSearchFn() {
this.mescroll.resetUpScroll();
},
selectConfirmFn(e) {
console.log(e, "e");
this.selectLabel = e[0].label;
this.selectValue = e[0].value;
this.mescroll.resetUpScroll();
},
modelOnchageFn() {
this.mescroll.resetUpScroll();
},
unitOnchageFn(e) {
this.spaceActionId = e;
this.mescroll.resetUpScroll();
},
buildingOnchageFn(e) {
console.log(e, "e------");
this.spaceActionId = e;
if (!!e) {
this.$get("/app/project/space", {
projectId: this.projectId,
spaceId: e
}).then((res) => {
this.unitOptions = res.data.map((item) => {
return {
label: item.spaceName,
value: item.spaceId
}
});
this.unitOptions.unshift({
label: "全部",
value: ""
})
})
} else {
this.unitOptions = [];
}
this.mescroll.resetUpScroll();
},
getbuildingOptListFn() {
this.$get("/app/project/space", {
projectId: this.projectId,
spaceId: 0
}).then((res) => {
this.buildingOptions = res.data.map((item) => {
return {
label: item.spaceName,
value: item.spaceId
}
});
this.buildingOptions.unshift({
label: "全部",
value: ""
})
})
},
statusStyle(val) {
if (val == 'UNACTIVE') {
return '#999';
} else if (val == 'ONLINE') {
return '#289A00';
} else if (val == 'OFFLINE') {
return '#FF3838';
} else if (val == 'OUTLINE') {
return '#F6970A';
} else {
return '#FF3838';
}
},
fullURL(url) {
return this.$config.baseUrl + url;
},
// 获取设备类型
getDeviceTypeList() {
this.$get("/iot/device/type-list").then((res) => {
if (res.code === 200) {
this.options1 = [{
label: '全部',
value: ""
}];
let data = res.data
for (let item in data) {
let obj = {
label: data[item],
value: item
}
this.options1.push(obj)
}
}
}).catch((err) => {
console.log(err)
})
},
// 获取设备分组
getDeviceGroupList() {
this.$get("/iot/group/list",{projectId: this.projectId}).then((res) => {
console.log("获取设备分组",res)
let deviceGroupList = [{
label: '全部',
value: ""
}];
if (res.code === 200) {
let data = res.rows || [];
data.forEach(item=>{
deviceGroupList.push({
label: item.groupName,
value: item.groupCode
})
})
}
this.deviceGroupOptions = deviceGroupList;
}).catch((err) => {
console.log(err)
})
}
},
filters: {
statusIco(val) {
if (val == 'UNACTIVE') {
return 'weijihuo';
} else if (val == 'ONLINE') {
return 'zaixian';
} else if (val == 'OFFLINE') {
return 'lixian2';
} else if (val == 'OUTLINE') {
return 'lixian3';
} else {
return 'xhyichang';
}
},
statusColor(val) {
if (val == 'UNACTIVE') {
return '#999';
} else if (val == 'ONLINE') {
return '#289A00';
} else if (val == 'OFFLINE') {
return '#FF3838';
} else if (val == 'OUTLINE') {
return '#F6970A';
} else {
return '#FF3838';
}
},
statusName(val) {
if (val == 'UNACTIVE') {
return '未激活';
} else if (val == 'ONLINE') {
return '在线';
} else if (val == 'OFFLINE') {
return '离线';
} else if (val == 'OUTLINE') {
return '脱线';
} else {
return '异常';
}
}
}
}
function handleTree(data, id, parentId, children, rootId) {
id = id || 'id';
parentId = parentId || 'parentId';
children = children || 'children';
rootId = rootId || Math.min.apply(Math, data.map(item => {
return item[parentId];
})) || 0;
// 对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data));
// 循环所有项
const treeData = cloneData.filter(father => {
let branchArr = cloneData.filter(child => {
// 返回每一项的子级数组
return father[id] === child[parentId];
});
// 按 orderNum 排序子节点
branchArr.sort((a, b) => a.orderNum - b.orderNum);
// 如果子节点数组不为空,将其赋值给父节点的 children 属性
if (branchArr.length > 0) {
father[children] = branchArr;
}
// 返回第一层
return father[parentId] === rootId;
});
return treeData.length > 0 ? treeData : data;
}
</script>
<style lang='scss' scoped>
.equipmentStatus {
width: 100%;
background-color: #F9F9F9;
:not(not) {
box-sizing: border-box;
}
&-header {
position: fixed;
left: 0;
top: 0;
width: 100%;
z-index: 999;
background-color: #fff;
height: 166rpx;
}
&-search-ctn {
padding: 10rpx $paddingLR;
display: flex;
}
&-search {
width: calc(100% - 180rpx);
}
&-search-picker {
width: 180rpx;
padding-left: 20rpx;
display: flex;
align-items: center;
justify-content: center;
}
.equipmentStatus-facility-box-main {
/* margin-top: 184rpx; */
padding: 20rpx;
box-sizing: border-box;
/* background-color: #F9F9F9; */
}
&-facility-box {
padding: 20rpx;
background-color: #fff;
border-radius: 20rpx;
margin-bottom: 30rpx;
&-title {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
border-bottom: 1px solid #eee;
}
.tag-list {
padding-top: 10rpx;
}
&-content-box {
display: flex;
width: 100%;
}
&-img {
padding: 20rpx;
}
}
&-facility-box-info {
width: calc(100% - 200rpx);
padding-top: 20rpx;
font-size: 26rpx;
.row {
padding-bottom: 10rpx;
display: flex;
/* justify-content: space-between; */
align-items: center;
&-label {
color: $uni-text-color-grey;
width: 110rpx;
}
&-value {
width: calc(100% - 130rpx);
font-weight: 550;
}
}
.status {
display: flex;
align-items: center;
flex-direction: row-reverse;
color: #666;
}
.btn-box {
text-align: right;
}
}
}
</style>