Former-commit-id: 9ecfef1e8848b0b3527362e533f19a306472e40a
Former-commit-id: a0f6ff186f90c1121818a50f874d16c33ad8d031
TSXN
wanggang 5 years ago
parent 3aeffe596d
commit 674dc1ae5f

@ -89,7 +89,13 @@
"files": [ "css/all.min.css", "webfonts/**" ]
},
{
"library": "ionicons@2.0.1",
"provider": "unpkg",
"library": "sweetalert2@9.15.2",
"destination": "wwwroot/lib/sweetalert2",
"files": [ "dist/sweetalert2.all.min.js", "dist/sweetalert2.min.css" ]
},
{
"library": "ionicons@4.6.3",
"destination": "wwwroot/lib/ionicons",
"files": [ "css/ionicons.min.css", "fonts/**" ]
},

@ -1,29 +1,28 @@
<template>
<div>
<div class="card" style="box-sizing:border-box;min-height:490px;margin:10px;">
<div class="card-header">
{{device.displayName}}
<span class="float-right text-success" v-if="device.isOnline"><i class="ion ion-ios-wifi"></i></span>
<span class="float-right text-danger" v-else><i class="ion ion-ios-wifi"></i></span>
<div class="card" :id="device.number" style="box-sizing:border-box;min-height:490px;margin:10px;">
<div class="card-header d-flex" style="height:50px;">
<div class="card-title">{{device.displayName}}</div>
<ul class="nav nav-pills ml-auto">
<li class="nav-item">
<a id="tv-tab" :href="'#tv-'+device.number" class="nav-link active" data-toggle="tab" aria-controls="tv" aria-selected="true" style="padding:2px 8px">电视</a>
</li>
<li class="nav-item">
<a id="air-tab" :href="'#air'+device.number" class="nav-link" data-toggle="tab" aria-controls="air" aria-selected="false" style="padding:2px 8px">空调</a>
</li>
<li class="nav-item">
<a id="box-tab" :href="'#box'+device.number" class="nav-link" data-toggle="tab" aria-controls="box" aria-selected="false" style="padding:2px 8px">机顶盒</a>
</li>
<li class="nav-item">
<a id="diy-tab" :href="'#diy'+device.number" class="nav-link" data-toggle="tab" aria-controls="diy" aria-selected="false" style="padding:2px 8px">自定义</a>
</li>
</ul>
</div>
<div class="card-body" style="padding:10px;">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs" role="tablist" id="myTab" style="font-size: 14px;">
<li class="nav-item">
<a id="tv-tab" href="#tv" class="nav-link active" role="tab" aria-controls="tv" aria-selected="true" style="padding:8px">电视</a>
</li>
<li class="nav-item">
<a id="air-tab" href="#air" class="nav-link" role="tab" aria-controls="air" aria-selected="false" style="padding:8px">空调</a>
</li>
<li class="nav-item">
<a id="box-tab" href="#box" class="nav-link" role="tab" aria-controls="box" aria-selected="false" style="padding:8px">机顶盒</a>
</li>
<li class="nav-item">
<a id="diy-tab" href="#diy" class="nav-link" role="tab" aria-controls="diy" aria-selected="false" style="padding:8px">自定义</a>
</li>
</ul>
<div class="tab-content" style="padding:20px;">
<div id="tv" class="tab-pane fade show active" role="tabpanel" aria-labelledby="tv-tab">
<div :id="'tv'+device.number" class="tab-pane fade show active" role="tabpanel" aria-labelledby="tv-tab">
<table style="margin: 20px auto;">
<tr>
<td>
@ -154,7 +153,7 @@
</tr>
</table>
</div>
<div id="air" class="tab-pane fade" role="tabpanel" aria-labelledby="air-tab">
<div :id="'air'+device.number" class="tab-pane fade" role="tabpanel" aria-labelledby="air-tab">
<table style="margin: 50px auto;">
<tr>
<td>
@ -197,7 +196,7 @@
</tr>
</table>
</div>
<div id="box" class="tab-pane fade" role="tabpanel" aria-labelledby="box-tab">
<div :id="'box'+device.number" class="tab-pane fade" role="tabpanel" aria-labelledby="box-tab">
<table style="margin: 20px auto;">
<tr>
<td>
@ -326,7 +325,7 @@
</tr>
</table>
</div>
<div id="diy" class="tab-pane fade" role="tabpanel" aria-labelledby="diy-tab">
<div :id="'diy'+device.number" class="tab-pane fade" role="tabpanel" aria-labelledby="diy-tab">
<div class="button-sp-area cell" style="width:100%;height:100%;overflow:auto;">
<button v-for="button in getCustomButtons()" type="button" class="btn btn-default px-2 m-2 btn-sm" :value="button.value" v-on:click="send($event.target.value,5)">{{button.name}}</button>
</div>
@ -385,10 +384,15 @@
export default {
props: ['device', 'edit'],
mounted: function () {
//weui.tab('.weui-tab');
$('#myTab a').on('click', function (e) {
e.preventDefault()
$(this).tab('show')
var number = this.device.number;
this.$nextTick(function () {
$(document).on('click', '#' + number + ' .nav-link:not(.active)', function () {
$('#' + number + ' .nav-link.active').removeClass('active');
$(this).addClass('active');
$('#' + number + ' .tab-pane.active').removeClass('active');
$($(this).attr('href')).addClass('active').addClass('show');
return false;
});
});
},
methods: {

@ -20,7 +20,7 @@
<span v-else class="text-danger mx-2" style="font-size:28px;">
{{getDeviceDataDescription(device,'光照度')}}
</span>
{{getDeviceData(device,'光照度')}}
{{getDeviceData(device,'温度')}} {{getDeviceData(device,'湿度')}}
</span>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

@ -11,6 +11,7 @@
<!--<link rel="stylesheet" href="lib/ant-design-vue/antd.min.css" />-->
<!--<link rel="stylesheet" href="lib/element-ui/theme-chalk/index.css" />-->
<link rel="stylesheet" href="lib/weui/style/weui.min.css" />
<link rel="stylesheet" href="lib/sweetalert2/dist/sweetalert2.min.css" />
<link rel="stylesheet" href="css/site.css" />
<title></title>
</head>
@ -38,6 +39,7 @@
<script src="lib/signalr/signalr.min.js"></script>
<script src="lib/chart.js/Chart.bundle.min.js"></script>
<script src="lib/flv.js/flv.min.js"></script>
<script src="lib/sweetalert2/dist/sweetalert2.all.min.js"></script>
<!--<script src="lib/toastr.js/toastr.min.js"></script>-->
<!--<script src="lib/bootstrap/js/bootstrap.min.js"></script>-->
<!--<script src="lib/bootstrap-vue/bootstrap-vue.min.js"></script>-->

@ -106,7 +106,7 @@ function execScene(id) {
console.log(error);
})
.finally(function () {
loading.show();
loading.hide();
});
}
@ -120,7 +120,7 @@ function nodePower(number, command) {
console.log(error);
})
.finally(function () {
loading.show();
loading.hide();
});
}
@ -134,11 +134,11 @@ function nodeMethod(number, method) {
console.log(error);
})
.finally(function () {
loading.show();
loading.hide();
});
}
//
function Select(e) {
function selectNode(e) {
var checkbox = $(e.target);
if (checkbox.hasClass('checkall')) {
if (e.target.checked) {

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 326 KiB

After

Width:  |  Height:  |  Size: 305 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,6 +1,6 @@
<template>
<layout v-bind:title="title">
<div class="row overlay-wrapper">
<div class="row">
<div class="col-md-2 col-sm-4 col-xs-6" v-for="item in products">
<div class="card">
<div class="card-header">
@ -13,6 +13,22 @@
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">平台场景</h3>
<div class="card-tools"><span data-toggle="tooltip" class="badge bg-green">{{scenes.count}}</span></div>
</div>
<div class="card-body">
<a class="btn btn-app" href="javascript:;" v-for="scene in scenes" v-on:click="execScene(scene.id)">
<img :src="config.baseUrl+scene.image" style="height:20px;max-width:68px;" />
<div>{{scene.name}}</div>
</a>
</div>
</div>
</div>
</div>
</layout>
</template>
<script>
@ -20,10 +36,14 @@
data: function () {
return {
title: '产品列表',
getProductsApi: '/IoTCenter/api/v1/product/getProducts',
getScenesApi: '/IoTCenter/api/v1/scene/getScenes',
url: '/IoTCenter/api/v1/product/getProducts',
products: [],
scenes: [],
events: ['ProductEntityInserted', 'ProductEntityUpdated', 'ProductEntityDeleted',
'DeviceEntityInserted', 'DeviceEntityUpdated', 'DeviceEntityDeleted']
'DeviceEntityInserted', 'DeviceEntityUpdated', 'DeviceEntityDeleted',
'SceneEntityInserted', 'SceneEntityUpdated', 'SceneEntityDeleted']
}
},
mounted: function () {
@ -32,11 +52,13 @@
},
methods: {
load() {
var url = config.baseUrl + this.url;
var vm = this;
axios.post(url).then(function (response) {
axios.post(config.baseUrl + this.getProductsApi).then(function (response) {
vm.products = response.data;
});
axios.post(config.baseUrl + this.getScenesApi).then(function (response) {
vm.scenes = response.data;
});
},
subscribe() {
var vm = this;

@ -6,7 +6,10 @@
<div class="card" style="margin:10px;">
<div class="card-header">{{node.name}}的场景</div>
<div class="card-body">
<button class="btn btn-success" v-for="scene in node.scenes" v-on:click="execScene(scene.id)">{{scene.name}}</button>
<a class="btn btn-app" href="javascript:;" v-for="scene in node.scenes" v-on:click="execScene(scene.id)">
<img :src="config.baseUrl+scene.image" style="height:20px;max-width:68px;" />
<div>{{scene.name}}</div>
</a>
</div>
</div>
</div>

@ -1,10 +1,26 @@
<template>
<layout v-bind:title="title">
<div class="row overlay-wrapper">
<div class="col-md-12" v-if="nodes.length">
<div class="card">
<div class="card-header">
<div class="card-title">
<input type="checkbox" id="All" class="checkall" v-on:change="SelectNode($event)" />
<label for="All" class="btn btn-sm btn-info" style="height:31px;margin-bottom:0;">全选</label>
<button class="btn btn-sm btn-info uncheck" v-on:click="SelectNode($event)">反选</button>
</div>
<div class="card-tools">
<button class="btn btn-success" v-on:click="Power('On')"></button>
<button class="btn btn-success" v-on:click="Power('Off')"></button>
</div>
</div>
</div>
</div>
<div class="col-md-2 col-sm-4 col-xs-6" v-for="item in nodes">
<div class="card">
<div class="card-header">
<h3 class="card-title">
<input type="checkbox" name="numbers[]" class="item" :value="item.number" v-on:change="SelectNode($event)">
<span v-if="item.isOnline" style="color:green;">{{item.name}}</span>
<span v-else style="color:red;">{{item.name}}</span>
</h3>
@ -13,6 +29,10 @@
<router-link :to="{path:'/pages/node.html',query:{number:item.number}}" class="card-body" style="display: block; text-align: center;">
<img :src="config.baseUrl+item.image" style="margin: 0px auto; width: 64px;">
</router-link>
<div class="card-footer text-center">
<button class="btn btn-success" v-on:click="nodePower(item.number,'On')"></button>
<button class="btn btn-success" v-on:click="nodePower(item.number,'Off')"></button>
</div>
</div>
</div>
</div>
@ -40,6 +60,21 @@
vm.nodes = response.data;
});
},
SelectNode: selectNode,
Power(method) {
var numbers = [];
$('.item:checked').each(function () {
numbers.push($(this).val());
});
if (numbers.length) {
for (var i = 0; i < numbers.length; i++) {
nodePower(numbers[i], method);
}
}
else {
Swal.fire('没有选中任何项');
}
},
subscribe() {
var vm = this;
subscribe(this.events, function (method, data) {

@ -1,15 +1,59 @@
<template>
<layout v-bind:title="title">
<div class="row mb-2">
<div class="col-sm-6">
<h1>{{product.name}}</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><router-link to="/">产品列表</router-link></li>
<li class="breadcrumb-item active">{{product.name}}</li>
</ol>
</div>
</div>
<div class="row overlay-wrapper">
<div class="col-md-12" v-if="HasBatchCommand()">
<div class="card">
<div class="card-header">
<div class="card-title">
<input type="checkbox" id="All" class="checkall" v-on:change="SelectDevice($event)" />
<label for="All" class="btn btn-sm btn-info" style="height:31px;margin-bottom:0;">全选</label>
<button class="btn btn-sm btn-info uncheck" v-on:click="SelectDevice($event)">反选</button>
</div>
<div class="card-tools">
<button class="btn btn-success" v-on:click="CallApiAll('On')"></button>
<button class="btn btn-success" v-on:click="CallApiAll('Stop')" v-if="product.name.indexOf('窗帘电机')>=0"></button>
<button class="btn btn-success" v-on:click="CallApiAll('Off')"></button>
</div>
</div>
</div>
</div>
<div class="col-md-2 col-sm-4 col-xs-6" v-for="item in product.devices">
<div class="card">
<div class="card-header">
<h3 class="card-title">{{item.displayName||item.name}}</h3>
<div class="card-tools"><span data-toggle="tooltip" class="badge bg-green">{{item.count}}</span></div>
<h3 class="card-title">
<label style="font-weight:normal;"><input type="checkbox" name="numbers[]" class="item" :value="item.number" v-if="HasBatchCommand()" v-on:change="SelectDevice($event)">{{item.name}}</label>
</h3>
<div class="card-tools">
<template v-if="HasBatchCommand()">
{{GetDataValue(item.number,'状态')}}
</template>
</div>
</div>
<router-link :to="{path:'/pages/device.html',query:{number:item.number}}" class="card-body" style="display: block; text-align: center;">
<img :src="config.baseUrl+product.image" style="margin: 0px auto; width: 64px;">
<div>
<template v-if="item.name==='光强检测器'">
{{GetDataValue(item.number,'光照度')}}
</template>
<template v-else-if="item.name==='温湿度传感器'">
{{GetDataValue(item.number,'温度')}}℃ {{GetDataValue(item.number,'湿度')}}RH%
</template>
</div>
</router-link>
<div class="card-footer">
{{item.node.name}}
</div>
</div>
</div>
</div>
@ -22,6 +66,7 @@
title: '产品',
url: '/IoTCenter/api/v1/product/getProduct?number=' + this.$route.query.number,
product: {
name: "",
devices: []
},
events: ['ProductEntityInserted', 'ProductEntityUpdated', 'ProductEntityDeleted',
@ -41,10 +86,55 @@
vm.product = response.data;
});
},
HasBatchCommand() {
return this.product.name === '调色灯'
|| this.product.name.indexOf('窗帘电机') >= 0
|| this.product.name.indexOf('开关') >= 0
|| this.product.name.indexOf('插座') >= 0;
},
GetDevices() {
return Enumerable.from(this.product.devices).orderBy(function (o) { return o.displayOrder; }).orderBy(function (o) { return o.name; }).toArray();
},
GetDataValue(number, name) {
var device = Enumerable.from(this.product.devices)
.where(function (o) { return o.number === number; })
.firstOrDefault();
if (device !== null) {
var data = Enumerable.from(device.data)
.where(function (o) { return o.name === name; })
.firstOrDefault();
if (data) {
return data.value;
}
}
return null;
},
GetDeviceDataAttr(number, name, attr) {
var device = Enumerable.from(this.product.devices).where(function (o) { return o.number === number; }).firstOrDefault();
var data = Enumerable.from(device.data).where(o => o.name === name).firstOrDefault();
if (data !== null) {
return data[attr];
}
return null;
},
SelectDevice: selectNode,
CallApiAll(method) {
var numbers = [];
$('.item:checked').each(function () {
numbers.push($(this).val());
});
if (numbers.length) {
for (var i = 0; i < numbers.length; i++) {
execApi(numbers[i], this.product.path + method);
}
} else {
Swal.fire('没有选中任何项');
}
},
subscribe() {
var vm = this;
subscribe(this.events, function (method, data) {
var item = JSON.product(data.message);
var item = JSON.parse(data.message);
if (method.indexOf('Product') == 0) {
vm.load();
}

Loading…
Cancel
Save