You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
331 lines
15 KiB
331 lines
15 KiB
<template>
|
|
<views-shared-layout>
|
|
<div class="row" style="padding-top:1rem;" v-if="store.state.layout&&store.state.layout.organs.length>0&&model.organ">
|
|
<div class="col-sm-2">
|
|
<div class="card">
|
|
<div class="card-header">建筑列表</div>
|
|
<div class="card-body">
|
|
<a-tree ref="tree"
|
|
:tree-data="tree"
|
|
:auto-expand-parent="true"
|
|
:default-expanded-keys="expanded"
|
|
:replace-fields="{title:'name',key:'id'}"
|
|
block-node
|
|
show-line
|
|
@select="onSelect">
|
|
</a-tree>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-10">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
当前:{{model.building?model.building.building.name:model.organ.organ.name}}
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<div class="position-relative p-3 bg-gray">
|
|
<div class="ribbon-wrapper">
|
|
<div class="ribbon bg-primary">
|
|
光照
|
|
</div>
|
|
</div>
|
|
<p>
|
|
最大值:
|
|
<template v-if="model.building">
|
|
{{model.building.maxLight}}
|
|
</template>
|
|
<template v-else>
|
|
{{model.organ.maxLight}}
|
|
</template>
|
|
Lux
|
|
</p>
|
|
<p>
|
|
最小值:
|
|
<template v-if="model.building">
|
|
{{model.building.minLight}}
|
|
</template>
|
|
<template v-else>
|
|
{{model.organ.minLight}}
|
|
</template>
|
|
Lux
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-3">
|
|
<div class="position-relative p-3 bg-gray">
|
|
<div class="ribbon-wrapper">
|
|
<div class="ribbon bg-primary">
|
|
温度
|
|
</div>
|
|
</div>
|
|
<p>
|
|
最大值:
|
|
<template v-if="model.building">
|
|
{{model.building.maxTemperature}}
|
|
</template>
|
|
<template v-else>
|
|
{{model.organ.maxTemperature}}
|
|
</template>
|
|
℃
|
|
</p>
|
|
<p>
|
|
最小值:
|
|
<template v-if="model.building">
|
|
{{model.building.minTemperature}}
|
|
</template>
|
|
<template v-else>
|
|
{{model.organ.minTemperature}}
|
|
</template>
|
|
℃
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-3">
|
|
<div class="position-relative p-3 bg-gray">
|
|
<div class="ribbon-wrapper">
|
|
<div class="ribbon bg-primary">
|
|
湿度
|
|
</div>
|
|
</div>
|
|
<p>
|
|
最大值:
|
|
<template v-if="model.building">
|
|
{{model.building.maxHumidity}}
|
|
</template>
|
|
<template v-else>
|
|
{{model.organ.maxHumidity}}
|
|
</template>
|
|
RH%"
|
|
</p>
|
|
<p>
|
|
最小值:
|
|
<template v-if="model.building">
|
|
{{model.building.minHumidity}}
|
|
</template>
|
|
<template v-else>
|
|
{{model.organ.minHumidity}}
|
|
</template>
|
|
RH%"
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-3">
|
|
<div class="position-relative p-3 bg-gray">
|
|
<div class="ribbon-wrapper">
|
|
<div class="ribbon bg-primary">
|
|
用电
|
|
</div>
|
|
</div>
|
|
<p>
|
|
开:
|
|
<template v-if="model.building">
|
|
{{model.building.deviceOpenCount}}
|
|
</template>
|
|
<template v-else>
|
|
{{model.organ.deviceOpenCount}}
|
|
</template>
|
|
</p>
|
|
<p>
|
|
关:
|
|
<template v-if="model.building">
|
|
{{model.building.deviceCloseCount}}
|
|
</template>
|
|
<template v-else>
|
|
{{model.organ.deviceCloseCount}}
|
|
</template>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card" v-if="scenes.length>0">
|
|
<div class="card-header">场景</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-sm-1" v-for="item in scenes">
|
|
<div class="card bg-light p-2">
|
|
<a class="card-body text-center" href="javascript:;" style="padding:0;" v-on:click="execScene(item.id)">
|
|
<img class="card-img-top" :src="item.image" :alt="item.name" style="width:64px;height:64px;margin:0 auto;">
|
|
<div>{{item.name}}</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card" v-if="devices.length>0">
|
|
<div class="card-header">设备</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div v-for="item in devices" class="col device-container" :title="item.name+item.ioTProduct.template">
|
|
<component :device="item" :is="'devices-'+item.ioTProduct.template"></component>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</views-shared-layout>
|
|
</template>
|
|
<script>
|
|
export default {
|
|
data() {
|
|
return {
|
|
url: config.service('platform/Home/GetOrgan'),
|
|
model: {
|
|
organ: null,
|
|
building: null,
|
|
expanded: [],
|
|
},
|
|
events: [
|
|
'OrganEntityInserted',
|
|
'OrganEntityUpdated',
|
|
'OrganEntityDeleted',
|
|
'BuildingEntityInserted',
|
|
'BuildingEntityUpdated',
|
|
'BuildingEntityDeleted',
|
|
'IoTSceneEntityInserted',
|
|
'IoTSceneEntityUpdated',
|
|
'IoTSceneEntityDeleted',
|
|
'IoTDeviceEntityInserted',
|
|
'IoTDeviceEntityUpdated',
|
|
'IoTDeviceEntityDeleted',
|
|
'IoTDataEntityInserted',
|
|
'IoTDataEntityUpdated',
|
|
'IoTDataEntityDeleted',
|
|
]
|
|
};
|
|
},
|
|
mounted: function () {
|
|
this.subscribe();
|
|
this.load();
|
|
},
|
|
beforeDestroy: function () {
|
|
PubSub.unsubscribes(this.events);
|
|
},
|
|
methods: {
|
|
subscribe: function () {
|
|
var parent = this;
|
|
PubSub.subscribes(this.events, function (method, data) {
|
|
if (method.indexOf('Statistic') !== -1 || method.indexOf('Organ') !== -1 || method.indexOf('Building') !== -1) {
|
|
parent.load();
|
|
}
|
|
else {
|
|
parent.updateItem(method, data);
|
|
}
|
|
});
|
|
},
|
|
load: function () {
|
|
var parent = this;
|
|
axios.post(this.url).then(function (response) {
|
|
parent.model.organ = response.data;
|
|
});
|
|
},
|
|
updateItem: function (method, data) {
|
|
if (this.model.building) {
|
|
var item = JSON.parse(data.message);
|
|
var list;
|
|
if (method.indexOf('Device') !== -1)
|
|
{
|
|
var gateway = Enumerable.from(this.model.building.building.ioTGateways).where(o => o.id == item.ioTGatewayId).firstOrDefault();
|
|
if (gateway) {
|
|
list = gateway.devices;
|
|
}
|
|
}
|
|
else if (method.indexOf('Data') !== -1) {
|
|
var device = Enumerable.from(this.model.building.building.ioTGateways)
|
|
.selectMany(o => o.devices)
|
|
.firstOrDefault(function (o) { return o.id === item.ioTDeviceId; });
|
|
if (device) {
|
|
list = device.data;
|
|
}
|
|
}
|
|
else if (method.indexOf('Scene') !== -1) {
|
|
if (this.model.building && this.model.building.building.id === item.buildingId) {
|
|
list = this.model.building.building.scenes;
|
|
}
|
|
}
|
|
//
|
|
if (list) {
|
|
if (method.indexOf('Deleted') !== -1) {
|
|
removeById(list, item);
|
|
}
|
|
else {
|
|
updateById(list, item);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
onSelect: function (selectedKeys, info) {
|
|
if (selectedKeys.length > 0) {
|
|
this.$refs.tree.selectedKeys = selectedKeys;
|
|
var parent = this;
|
|
var id = selectedKeys[0];
|
|
if (id === this.model.organ.organ.id) {
|
|
this.model.building = null;
|
|
}
|
|
else {
|
|
var url = config.service('platform/Home/GetBuilding/' + id);
|
|
axios.post(url).then(function (response) {
|
|
parent.model.building = response.data;
|
|
});
|
|
}
|
|
}
|
|
},
|
|
findBuildings: function (buildings, id) {
|
|
for (var i in buildings) {
|
|
var item = buildings[i];
|
|
if (item.id == id) {
|
|
return item.children;
|
|
}
|
|
if (item.children.length > 0) {
|
|
return this.findBuildings(item.children, id);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
tree: function () {
|
|
var result = [];
|
|
if (this.model.organ != null) {
|
|
result.push({
|
|
id: this.model.organ.organ.id,
|
|
name: this.model.organ.organ.name,
|
|
children: this.model.organ.organ.buildings
|
|
});
|
|
}
|
|
return result;
|
|
},
|
|
expanded: function () {
|
|
var result = [];
|
|
if (this.model.organ != null) {
|
|
result.push(this.model.organ.organ.id);
|
|
}
|
|
return result;
|
|
},
|
|
scenes: function () {
|
|
var result = [];
|
|
if (this.model.building) {
|
|
result = Enumerable.from(this.model.building.building.scenes).orderBy(o => o.order).toArray();
|
|
}
|
|
return result;
|
|
},
|
|
devices: function () {
|
|
var result = [];
|
|
if (this.model.building) {
|
|
result = Enumerable.from(this.model.building.building.ioTGateways)
|
|
.selectMany(o => o.devices)
|
|
.where(o => !o.disabled)
|
|
.orderBy(o => o.ioTProductId)
|
|
.toArray();
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
};
|
|
</script> |