Former-commit-id: 503dcbc6e3eae3aa5fb761be5f657a14e3be8e06
Former-commit-id: 777958ab2d922aeebf80b56676ca792308480027
TSXN
wanggang 5 years ago
parent aea591d978
commit d770402680

@ -6,15 +6,15 @@ namespace Infrastructure.Application
{ {
public class PagedList<T> : IPagedList, IValidatableObject public class PagedList<T> : IPagedList, IValidatableObject
{ {
[ScaffoldColumn(false)]
public int DefaultPageSize { get; set; } = 20;
public PagedList() public PagedList()
{ {
PageIndex = 1; PageIndex = 1;
PageSize = this.DefaultPageSize; PageSize = this.DefaultPageSize;
} }
[ScaffoldColumn(false)]
public int DefaultPageSize { get; set; } = 20;
[ScaffoldColumn(false)] [ScaffoldColumn(false)]
public int PageIndex { get; set; } public int PageIndex { get; set; }

@ -1,6 +1,18 @@
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System;
namespace Infrastructure.Application namespace Infrastructure.Application
{ {
public class PagedListModel<T> : PagedList<T> public class PagedListModel<T> : PagedList<T>
{ {
public PagedListModel()
{
this.Query = (T)Activator.CreateInstance(typeof(T));
}
public T Query { get; set; }
public object Schema { get; set; }
public ViewDataDictionary ViewData { get; set; }
} }
} }

@ -56,7 +56,13 @@ namespace Infrastructure.Web.Mvc
.ToList()); .ToList());
ViewData["EntityTypeExt"] = typeof(TEntity); ViewData["EntityTypeExt"] = typeof(TEntity);
ViewData["ModelTypeExt"] = typeof(TDisplayModel); ViewData["ModelTypeExt"] = typeof(TDisplayModel);
return this.Result(model); if (this.Request.Headers["accept"].ToString().Contains("json", StringComparison.OrdinalIgnoreCase))
{
model.ViewData = ViewData;
model.Schema = this.GetSchema();
return Json(model, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
}
return View(model);
} }
[HttpGet] [HttpGet]
@ -287,17 +293,16 @@ namespace Infrastructure.Web.Mvc
[ApiExplorerSettings(IgnoreApi = true)] [ApiExplorerSettings(IgnoreApi = true)]
private IActionResult Result(object model) private IActionResult Result(object model)
{ {
return this.Request.Headers["accept"].ToString().Contains("json", StringComparison.OrdinalIgnoreCase) ? Json(model) as IActionResult : View(model); if (this.Request.Headers["accept"].ToString().Contains("json", StringComparison.OrdinalIgnoreCase))
} {
return Json(model);
public IActionResult GetSearchSchema() }
{ return View(model);
return Json(this.GetJsonSchema<TSearchModel>());
} }
public IActionResult GetEditSchema() public object GetSchema()
{ {
return Json(this.GetJsonSchema<TEditModel>(), new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); return this.GetJsonSchema<TEditModel>();
} }
} }
} }

@ -6,7 +6,7 @@
<span class="float-right text-danger" v-else><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> </div>
<div class="card-body"> <div class="card-body">
<div class="row" style="height:100%;width:300px;margin: 0 auto;"> <div class="row" style="height:100%;width:auto;margin: 0 auto;">
<div class="col-2 align-self-center"> <div class="col-2 align-self-center">
<div class="mh-100" :style="'width:48px;height:48px;border-radius: 10px;background:'+hsl"></div> <div class="mh-100" :style="'width:48px;height:48px;border-radius: 10px;background:'+hsl"></div>
</div> </div>

@ -7,10 +7,10 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="row" style="height:100%;width:300px;margin: 0 auto;"> <div class="row" style="height:100%;width:300px;margin: 0 auto;">
<div class="col-4 align-self-center"> <div class="col-3 align-self-center">
<img class="mh-100" :src="device.product.image" style="width:48px;" /> <img class="mh-100" :src="device.product.image" style="width:48px;" />
</div> </div>
<div class="col-8 align-self-center"> <div class="col-9 align-self-center">
<div class="row" style="height:25px;line-height:25px;"> <div class="row" style="height:25px;line-height:25px;">
<span> <span>
温度: 温度:

@ -1,17 +1,7 @@
.loader { .display-string {
position: relative; width:8em;
height: 80px; white-space: nowrap;
width: 80px; text-overflow: ellipsis;
top: 28%; overflow: hidden;
top: -webkit-calc(50% - 43px); word-break: break-all;
top: calc(50% - 43px);
left: 35%;
left: -webkit-calc(50% - 43px);
left: calc(50% - 43px);
border: 3px solid #fff;
border-radius: 80px;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-animation: hourglass 2s ease-in-out infinite;
animation: hourglass 2s ease-in-out infinite;
} }

@ -54,6 +54,7 @@
<script src="js/components.js"></script> <script src="js/components.js"></script>
<script src="js/state.js"></script> <script src="js/state.js"></script>
<script src="js/signalr.js"></script> <script src="js/signalr.js"></script>
<script src="js/form.js"></script>
<script src="js/iot.js"></script> <script src="js/iot.js"></script>
<script src="js/main.js"></script> <script src="js/main.js"></script>
</body> </body>

@ -35,7 +35,7 @@ axios.interceptors.response.use(function (response) {
.catch(function (error) { .catch(function (error) {
if (error.response.status === 401) { if (error.response.status === 401) {
console.log('refreshToken 已过期'); console.log('refreshToken 已过期');
router.push('/pages/login'); router.push('/router/login');
} }
}); });
} }

@ -1,4 +1,11 @@
function parseModel(response) { function vueComponent(name,url) {
Vue.component(name, function (resolve, reject) {
axios.get(url).then(function (response) {
resolve(parseModel(response));
});
});
}
function parseModel(response) {
var html = new DOMParser().parseFromString(response.data, 'text/html'); var html = new DOMParser().parseFromString(response.data, 'text/html');
var template = html.getElementsByTagName('template')[0].innerHTML; var template = html.getElementsByTagName('template')[0].innerHTML;
var script = html.getElementsByTagName('script')[0].innerHTML; var script = html.getElementsByTagName('script')[0].innerHTML;

@ -1,10 +1,10 @@
Vue.component('pagination', function (resolve, reject) { Vue.component('pagination', function (resolve, reject) {
axios.get("/pages/shared/pagination.html").then(function (response) { axios.get("/router/shared/pagination.html").then(function (response) {
resolve(parseModel(response)); resolve(parseModel(response));
}); });
}); });
Vue.component('layout', function (resolve, reject) { Vue.component('layout', function (resolve, reject) {
axios.get("/pages/shared/layout.html").then(function (response) { axios.get("/router/shared/layout.html").then(function (response) {
resolve(parseModel(response)); resolve(parseModel(response));
}); });
}); });

@ -0,0 +1,16 @@
var formComponents = [
'display-string',
'display-boolean',
'display-imageurl',
'display-integer',
'display-selectlist',
'display-multiselectlist',
'edit-string',
'edit-boolean',
'edit-integer',
];
for (var i = 0; i < formComponents.length; i++) {
var name = formComponents[i];
var url = "/router/shared/" + name.replace('-', '/') + ".html";
vueComponent(name, url);
}

@ -1,11 +1,4 @@
var time = '1d'; function getDeviceDataValue(device, name) {
if (window.WXInlinePlayer && WXInlinePlayer.isSupport()) {
WXInlinePlayer.init({
asmUrl: '/lib/WXInlinePlayer/prod.all.asm.combine.js',
wasmUrl: '/lib/WXInlinePlayer/prod.all.wasm.combine.js'
});
}
function getDeviceDataValue(device, name) {
var data = Enumerable.from(device.data).where(o => o.name === name).firstOrDefault(); var data = Enumerable.from(device.data).where(o => o.name === name).firstOrDefault();
if (data) { if (data) {
return data['value']; return data['value'];
@ -37,73 +30,41 @@ function getData(device, name) {
return Enumerable.from(device.data).where(o => o.name === name).firstOrDefault(); return Enumerable.from(device.data).where(o => o.name === name).firstOrDefault();
} }
//devices //devices
Vue.component('iot-gateway', function (resolve, reject) { var iotComponents = [
axios.get("/components/device/gateway.html").then(function (response) { 'gateway',
resolve(parseModel(response)); 'light',
}); 'humiture',
}); 'smoke',
Vue.component('iot-light', function (resolve, reject) { 'person',
axios.get("/components/device/light.html").then(function (response) { 'curtain',
resolve(parseModel(response)); 'switch',
}); 'switch3',
}); 'socket',
Vue.component('iot-humiture', function (resolve, reject) { 'ir',
axios.get("/components/device/humiture.html").then(function (response) { 'color-light',
resolve(parseModel(response)); 'door',
}); 'camera',
}); 'serial-port',
Vue.component('iot-smoke', function (resolve, reject) { ];
axios.get("/components/device/smoke.html").then(function (response) { for (var i = 0; i < iotComponents.length; i++) {
resolve(parseModel(response)); var name = 'iot-'+iotComponents[i];
}); var url = "/components/iot/" + iotComponents[i] + ".html";
}); vueComponent(name, url);
Vue.component('iot-person', function (resolve, reject) { }
axios.get("/components/device/person.html").then(function (response) { var deviceInfo = [];
resolve(parseModel(response)); deviceInfo['网关'] = 'iot-gateway';
}); deviceInfo['光强检测器'] = 'iot-light';
}); deviceInfo['温湿度传感器'] = 'iot-humiture';
Vue.component('iot-curtain', function (resolve, reject) { deviceInfo['烟雾报警器'] = 'iot-smoke';
axios.get("/components/device/curtain.html").then(function (response) { deviceInfo['人体感应器'] = 'iot-person';
resolve(parseModel(response)); deviceInfo['窗帘电机'] = 'iot-curtain';
}); deviceInfo['一路开关'] = 'iot-switch';
}); deviceInfo['三路开关'] = 'iot-switch3';
Vue.component('iot-switch', function (resolve, reject) { deviceInfo['插座'] = 'iot-socket';
axios.get("/components/device/switch.html").then(function (response) { deviceInfo['智能插座'] = 'iot-socket';
resolve(parseModel(response)); deviceInfo['红外转发器'] = 'iot-ir';
}); deviceInfo['调色灯'] = 'iot-color-light';
}); deviceInfo['门锁'] = 'iot-door';
Vue.component('iot-switch3', function (resolve, reject) { deviceInfo['摄像头'] = 'iot-camera';
axios.get("/components/device/switch3.html").then(function (response) { deviceInfo['摄像头'] = 'gateway';
resolve(parseModel(response)); deviceInfo['串口控制器'] = 'iot-serial-port';
});
});
Vue.component('iot-socket', function (resolve, reject) {
axios.get("/components/device/socket.html").then(function (response) {
resolve(parseModel(response));
});
});
Vue.component('iot-ir', function (resolve, reject) {
axios.get("/components/device/ir.html").then(function (response) {
resolve(parseModel(response));
});
});
Vue.component('iot-color-light', function (resolve, reject) {
axios.get("/components/device/color-light.html").then(function (response) {
resolve(parseModel(response));
});
});
Vue.component('iot-door', function (resolve, reject) {
axios.get("/components/device/door.html").then(function (response) {
resolve(parseModel(response));
});
});
Vue.component('iot-camera', function (resolve, reject) {
axios.get("/components/device/camera.html").then(function (response) {
resolve(parseModel(response));
});
});
Vue.component('iot-serial-port', function (resolve, reject) {
axios.get("/components/device/serial-port.html").then(function (response) {
resolve(parseModel(response));
});
});

@ -1,18 +1,18 @@
var routes = []; var routes = [];
const router = new VueRouter(); const router = new VueRouter();
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
if (to.path !== '/pages/login.html') { if (to.path !== '/router/login.html') {
var isAuthenticated = false; var isAuthenticated = false;
if (store.state.token.accessToken) { if (store.state.token.accessToken) {
var jwt = jwt_decode(store.state.token.accessToken); var jwt = jwt_decode(store.state.token.accessToken);
isAuthenticated = jwt.exp * 1000 >= new Date().getTime(); isAuthenticated = jwt.exp * 1000 >= new Date().getTime();
} }
if (!isAuthenticated) { if (!isAuthenticated) {
router.push('/pages/login.html'); router.push('/router/login.html');
return; return;
} }
} }
var url = to.path === '/' ? '/pages/home.html' : to.path; var url = to.path === '/' ? '/router/home.html' : to.path;
var name = url.replace(/\//g, "-").replace(/\./g, "-").substring(1); var name = url.replace(/\//g, "-").replace(/\./g, "-").substring(1);
var route = routes[name]; var route = routes[name];
if (!route) { if (!route) {

@ -1,97 +0,0 @@
<template>
<layout v-bind:title="title">
<h1>{{schema.title}}</h1>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
</div>
<div class="card-body">
<div class="dataTables_wrapper dt-bootstrap4">
<div class="row" style="padding-bottom:10px;" v-if="hasPermissions()">
<div class="col-sm-12 col-md-6">
<button class="btn btn-default" v-if="hasPermission('Add')">新建</button>
<button class="btn btn-danger" v-if="hasPermission('Delete')">删除</button>
</div>
<div class="col-sm-12 col-md-6">
<div style="text-align:right;">
<a href="javascript:;" class="btn btn-primary" v-if="hasPermission('Read')">查询</a>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<table class="table table-bordered">
<thead>
<tr>
<th>
<input type="checkbox" class="select_all" />
</th>
<th v-for="(value,key,index) in schema.properties" v-if="key!=='id'">{{value.title}}</th>
<th v-if="hasPermission('Edit')">编辑</th>
<th v-if="hasPermission('Delete')">删除</th>
</tr>
</thead>
<tbody>
<tr v-for="item in data.list">
<td>
<input type="checkbox" name="list[]" :value="item.Id" />
</td>
<td v-for="(value,key,index) in schema.properties" v-if="key!=='id'">{{item[key]}}</td>
<td v-if="hasPermission('Edit')">
<a href="javascript:;" class="btn btn-sm btn-info">编辑</a>
</td>
<td v-if="hasPermission('Delete')">
<a href="javascript:;" class="btn btn-sm btn-danger">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<pagination :nav="load" :index="data.pageIndex" :size="data.pageSize" :total="data.totalCount" />
</div>
</div>
</div>
</div>
</div>
</layout>
</template>
<script>
export default {
data: function () {
return {
title: '列表页',
url: '/IoTCenter/Admin/' + this.$route.query.entity + '/GetEditSchema',
entity: this.$route.query.entity,
schema: {},
data: {
list: []
}
}
},
mounted: function () {
this.load(1, 20);
},
methods: {
load: function (index, size) {
var url = config.baseUrl + this.url;
var vm = this;
axios.post(url).then(function (response) {
vm.schema = response.data;
var url = config.baseUrl + '/IoTCenter/Admin/' + vm.$route.query.entity + '/Index?pageIndex=' + index + '&pageSize=' + size;
axios.get(url).then(function (response) {
vm.data = response.data;
});
});
},
hasPermission: function (cmd) {
var permission = cmd + '-' + this.entity;
return Enumerable.from(store.state.permissions).any(o => o === permission);
},
hasPermissions: function () {
return this.hasPermission('Read') || this.hasPermission('Add') || this.hasPermission('Edit') || this.hasPermission('Delete');
}
}
}
</script>

@ -0,0 +1,134 @@
<template>
<layout v-bind:title="title">
<h1>{{data.schema.title}}</h1>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<!--query from-->
<form class="form-horizontal query" v-if="hasPermission('Read')" :action="url" @submit.prevent="onSubmit">
<div class="row">
<div class="col-12 col-sm-6 col-md-4 col-lg-3" v-for="(value,key,index) in data.schema.properties" v-if="showForQuery(key,value)">
<div class="form-group row">
<label class="col-sm-3 col-form-label" :for="key" :title="value.type+value.format">{{value.title}}:</label>
<div class="col-sm-9">
<component :is="getQueryComponent(value)" :title="value.title" :name="'query.'+key" :value="data.query[key]" v-if="data.query" />
</div>
</div>
</div>
</div>
<div class="row" style="padding-bottom:10px;" v-if="hasPermissions()">
<div class="col-12">
<a href="javascript:;" class="btn btn-primary" v-if="hasPermission('Read')" v-on:click="onSubmit()">查询</a>
<a href="javascript:;" class="btn btn-success" v-if="hasPermission('Add')">新建</a>
<a href="javascript:;" class="btn btn-danger" v-if="hasPermission('Delete')">删除</a>
</div>
</div>
</form>
</div>
<div class="card-body">
<div class="dataTables_wrapper dt-bootstrap4">
<!--list table-->
<div class="row">
<div class="col-12">
<table class="table table-bordered table-striped dataTable dtr-inline">
<thead>
<tr>
<th>
<input type="checkbox" class="select_all" />
</th>
<th v-for="(value,key,index) in data.schema.properties" v-if="key!=='id'">
{{value.title}}
</th>
<th v-if="hasPermission('Edit')">编辑</th>
</tr>
</thead>
<tbody>
<tr v-for="item in data.list">
<td>
<input type="checkbox" name="list[]" :value="item.Id" />
</td>
<td v-for="(value,key,index) in data.schema.properties" v-if="key!=='id'">
<component :is="getDisplayComponent(key)" v-bind:key="key" v-bind:value="item[key]" v-bind:data="data.viewData" />
</td>
<td v-if="hasPermission('Edit')">
<a href="javascript:;" class="btn btn-sm btn-info">编辑</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!--page list-->
<pagination :nav="load" :index="data.pageIndex" :size="data.pageSize" :total="data.totalCount" />
</div>
</div>
</div>
</div>
</div>
</layout>
</template>
<script>
export default {
data: function () {
return {
title: '列表页',
url: '/IoTCenter/Admin/' + this.$route.query.entity + '/Index',
entity: this.$route.query.entity,
data: {
pageIndex: 1,
pageSize: 20,
list: [],
schema: {}
}
}
},
mounted: function () {
this.load(this.data.pageIndex, this.data.pageSize);
},
methods: {
load: function (index, size) {
if (index) {
this.data.pageIndex = index;
}
if (size) {
this.data.pageSize = size;
}
var vm = this;
var url = config.baseUrl + this.url;
var query = $("form.query").serialize();
var page = 'pageIndex=' + this.data.pageIndex + '&pageSize=' + this.data.pageSize;
if (query) {
url += '?' + query + '&' + page;
}
axios.get(url).then(function (response) {
vm.data = response.data;
});
},
hasPermission: function (cmd) {
var permission = cmd + '-' + this.entity;
return Enumerable.from(store.state.permissions).any(o => o === permission);
},
hasPermissions: function () {
return this.hasPermission('Read') || this.hasPermission('Add') || this.hasPermission('Edit') || this.hasPermission('Delete');
},
getDisplayComponent: function (key) {
var property = this.data.schema.properties[key];
var template = 'display-' + (property.format || property.type);
console.log(template);
return template;
},
getQueryComponent: function (value) {
var template = 'edit-' + (value.format || value.type);
console.log(template);
return template;
},
showForQuery: function (key, value) {
return value.type !== 'array' && value.type !== 'object' && value.format !== 'imageurl' && key !== 'displayOrder';
},
onSubmit: function () {
this.load();
}
}
}
</script>

@ -3,21 +3,7 @@
<div v-if="device"> <div v-if="device">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<iot-gateway v-if="device.name==='网关'" v-bind:device="device"></iot-gateway> <component :is="getComponent()" :device="device" :edit="showEdit()" />
<iot-light v-else-if="device.name==='光强检测器'" v-bind:device="device"></iot-light>
<iot-humiture v-else-if="device.name==='温湿度传感器'" v-bind:device="device"></iot-humiture>
<iot-smoke v-else-if="device.name==='烟雾报警器'" v-bind:device="device"></iot-smoke>
<iot-person v-else-if="device.name==='人体感应器'" v-bind:device="device"></iot-person>
<iot-curtain v-else-if="device.name==='窗帘电机'" v-bind:device="device"></iot-curtain>
<iot-switch v-else-if="device.name==='一路开关'" v-bind:device="device"></iot-switch>
<iot-switch3 v-else-if="device.name==='三路开关'" v-bind:device="device"></iot-switch3>
<iot-socket v-else-if="device.name==='插座'" v-bind:device="device"></iot-socket>
<iot-socket v-else-if="device.name==='智能插座'" v-bind:device="device"></iot-socket>
<iot-ir v-else-if="device.name==='红外转发器'" v-bind:device="device" v-bind:edit="true"></iot-ir>
<iot-color-light v-else-if="device.name==='调色灯'" v-bind:device="device"></iot-color-light>
<iot-door v-else-if="device.name==='门锁'" v-bind:device="device"></iot-door>
<iot-camera v-else-if="device.name==='摄像头'" v-bind:device="device"></iot-camera>
<iot-serial-port v-else-if="device.name==='串口控制器'" v-bind:device="device" v-bind:edit="true"></iot-serial-port>
</div> </div>
</div> </div>
<!--折线图--> <!--折线图-->
@ -70,6 +56,12 @@
}); });
}); });
}, },
getComponent: function () {
return deviceInfo[this.device.name];
},
showEdit: function () {
return this.device.name === '红外转发器' || this.device.name === '串口控制器';
},
updateChart: function () { updateChart: function () {
var dataList = Enumerable.from(this.device.data).where(function (o) { var dataList = Enumerable.from(this.device.data).where(function (o) {
return o.type === 10 || o.type === 20; return o.type === 10 || o.type === 20;

@ -7,7 +7,7 @@
<h3 class="card-title">{{item.name}}</h3> <h3 class="card-title">{{item.name}}</h3>
<div class="card-tools"><span data-toggle="tooltip" class="badge bg-green">{{item.count}}</span></div> <div class="card-tools"><span data-toggle="tooltip" class="badge bg-green">{{item.count}}</span></div>
</div> </div>
<router-link :to="{path:'/pages/product.html',query:{number:item.number}}" class="card-body" style="display: block; text-align: center;"> <router-link :to="{path:'/router/product.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;"> <img :src="config.baseUrl+item.image" style="margin: 0px auto; width: 64px;">
</router-link> </router-link>
</div> </div>

@ -158,7 +158,7 @@
if (vm.node.id === item.id) { if (vm.node.id === item.id) {
if (method.indexOf('Deleted') >= 0) { if (method.indexOf('Deleted') >= 0) {
console.log('node has deleted'); console.log('node has deleted');
router.push('/pages/nodes.html'); router.push('/router/nodes.html');
} }
else { else {
vm.load(); vm.load();

@ -26,7 +26,7 @@
</h3> </h3>
<div class="card-tools"><span data-toggle="tooltip" class="badge bg-green">{{item.count}}</span></div> <div class="card-tools"><span data-toggle="tooltip" class="badge bg-green">{{item.count}}</span></div>
</div> </div>
<router-link :to="{path:'/pages/node.html',query:{number:item.number}}" class="card-body" style="display: block; text-align: center;"> <router-link :to="{path:'/router/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;"> <img :src="config.baseUrl+item.image" style="margin: 0px auto; width: 64px;">
</router-link> </router-link>
<div class="card-footer text-center"> <div class="card-footer text-center">

@ -6,7 +6,7 @@
<div class="card-header"> <div class="card-header">
<h3 class="card-title">{{item.name}}</h3> <h3 class="card-title">{{item.name}}</h3>
</div> </div>
<router-link :to="{path:'/pages/organ.html',query:{number:item.number}}" class="card-body" style="display: block; text-align: center;"> <router-link :to="{path:'/router/organ.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;"> <img :src="config.baseUrl+item.image" style="margin: 0px auto; width: 64px;">
</router-link> </router-link>
</div> </div>

@ -40,7 +40,7 @@
</template> </template>
</div> </div>
</div> </div>
<router-link :to="{path:'/pages/device.html',query:{number:item.number}}" class="card-body" style="display: block; text-align: center;"> <router-link :to="{path:'/router/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;"> <img :src="config.baseUrl+product.image" style="margin: 0px auto; width: 64px;">
<div> <div>
<template v-if="item.name==='光强检测器'"> <template v-if="item.name==='光强检测器'">

@ -0,0 +1,8 @@
<template>
<input type="checkbox" disabled v-model="value" />
</template>
<script>
export default {
props: ['value']
};
</script>

@ -0,0 +1,8 @@
<template>
<img style="height:32px;" :src="value||'/images/empty.png'" />
</template>
<script>
export default {
props: ['value']
};
</script>

@ -0,0 +1,8 @@
<template>
<div>{{value}}</div>
</template>
<script>
export default {
props: ['value']
};
</script>

@ -0,0 +1,8 @@
<template>
<div><span class="badge badge-light" v-for="item in value">{{data[item]}} </span></div>
</template>
<script>
export default {
props: ['key', 'value', 'data']
};
</script>

@ -0,0 +1,8 @@
<template>
<span>{{data[value]}}</span>
</template>
<script>
export default {
props: ['key', 'value', 'data']
};
</script>

@ -0,0 +1,8 @@
<template>
<div style="overflow:hidden;white-space: nowrap;text-overflow:ellipsis;max-width:20em;" :title="value">{{value}}</div>
</template>
<script>
export default {
props: ['value']
};
</script>

@ -0,0 +1,8 @@
<template>
<div class="form-check col-form-label"><input type="checkbox" class="form-check-input" :name="name" :value="value" /></div>
</template>
<script>
export default {
props: ['title', 'name', 'value', 'data']
};
</script>

@ -0,0 +1,8 @@
<template>
<input type="number" class="form-control" :name="name" v-model="value" />
</template>
<script>
export default {
props: ['title', 'name', 'value', 'data']
};
</script>

@ -0,0 +1,8 @@
<template>
<input type="text" :name="name" class="form-control" v-model="value" />
</template>
<script>
export default {
props: ['name', 'value']
};
</script>

@ -11,7 +11,7 @@
</ul> </ul>
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
<li class="nav-item"> <li class="nav-item">
<router-link class="nav-link" to="/pages/user.html">{{model.username}}</router-link> <router-link class="nav-link" to="/router/user.html">{{model.username}}</router-link>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="javascript:;" v-on:click="logout">退出</a> <a class="nav-link" href="javascript:;" v-on:click="logout">退出</a>
@ -19,10 +19,10 @@
</ul> </ul>
<ul class="navbar-nav ml-auto" v-else> <ul class="navbar-nav ml-auto" v-else>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/pages/register.html">注册</a> <a class="nav-link" href="/router/register.html">注册</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/pages/login.html">登录</a> <a class="nav-link" href="/router/login.html">登录</a>
</li> </li>
</ul> </ul>
</nav> </nav>
@ -35,32 +35,32 @@
<nav class="mt-2"> <nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false"> <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
<li class="nav-item"> <li class="nav-item">
<router-link :to="{path:'/'}" :class="isPageActive('/','/pages/product.html','/pages/device.html')"> <router-link :to="{path:'/'}" :class="isPageActive('/','/router/product.html','/router/device.html')">
<i class="nav-icon far fa-image"></i> <i class="fa fa-folder"></i>
<p> <p>
产品 产品
</p> </p>
</router-link> </router-link>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<router-link :to="{path:'/pages/nodes.html'}" :class="isPageActive('/pages/nodes.html','/pages/node.html')"> <router-link :to="{path:'/router/nodes.html'}" :class="isPageActive('/router/nodes.html','/router/node.html')">
<i class="nav-icon far fa-image"></i> <i class="fa fa-cube"></i>
<p> <p>
节点 节点
</p> </p>
</router-link> </router-link>
</li> </li>
<li class="nav-item" v-if="hasPermission('Read-Setting')"> <li class="nav-item" v-if="hasPermission('Read-Setting')">
<router-link :to="{path:'/pages/admin/home.html'}" :class="isPageActive('/pages/admin/home.html')"> <router-link :to="{path:'/router/admin/home.html'}" :class="isPageActive('/router/admin/home.html')">
<i class="nav-icon far fa-image"></i> <i class="fa fa-folder"></i>
<p> <p>
控制台 控制台
</p> </p>
</router-link> </router-link>
</li> </li>
<li class="nav-item" v-if="hasPermission('Read-Node')"> <li class="nav-item" v-if="hasPermission('Read-Node')">
<router-link :to="{path:'/pages/admin/list.html',query:{entity:'Node'}}" :class="isEntityActive('Node')"> <router-link :to="{path:'/router/admin/list.html',query:{entity:'Node'}}" :class="isEntityActive('Node')">
<i class="nav-icon far fa-image"></i> <i class="fa fa-folder"></i>
<p> <p>
节点 节点
</p> </p>
@ -138,7 +138,7 @@
methods: { methods: {
logout() { logout() {
store.commit('logout'); store.commit('logout');
router.push('/pages/login.html'); router.push('/router/login.html');
}, },
hasPermission(permission) { hasPermission(permission) {
return Enumerable.from(this.model.permissions).any(o => o == permission); return Enumerable.from(this.model.permissions).any(o => o == permission);

@ -59,7 +59,7 @@
return this.index > 1; return this.index > 1;
}, },
hasNext: function () { hasNext: function () {
return this.index + 1 < this.getPageCount(); return this.index < this.getPageCount();
}, },
getPageList: function () { getPageList: function () {
var pageCount = this.getPageCount(); var pageCount = this.getPageCount();

@ -0,0 +1,8 @@
<template>
<input type="checkbox" disabled v-model="value" />
</template>
<script>
export default {
props: ['value']
};
</script>
Loading…
Cancel
Save