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.
352 lines
8.1 KiB
352 lines
8.1 KiB
<template> |
|
<div> |
|
<div class='infos'> |
|
<el-card> |
|
<div class='title'> |
|
<span class='icon el-icon-tickets'></span> |
|
租户基本信息 |
|
</div> |
|
<div class='content'> |
|
<div> |
|
租户ID <span>{{tenantDetail.tenantId}}</span> |
|
</div> |
|
<div> |
|
租户名称 <span>{{tenantDetail.tenantName}}</span> |
|
</div> |
|
<div> |
|
开通时间 <span>{{tenantDetail.tenantCreateTime}}</span> |
|
</div> |
|
</div> |
|
</el-card> |
|
<el-card> |
|
<div class='title'> |
|
<span class='icon el-icon-cpu'></span> |
|
设备数 |
|
</div> |
|
<div class='content'> |
|
<Bar |
|
:current-value='tenantDetail.countStatistics.productCount || 0' |
|
:total-value='tenantDetail.countStatistics.productLimitNumber || 1' |
|
> |
|
<template #title> |
|
<div class='bar-title'> |
|
<div class='label'> |
|
产品 |
|
</div> |
|
</div> |
|
</template> |
|
<template #currentValue>已添加</template> |
|
</Bar> |
|
<Bar |
|
:current-value='tenantDetail.countStatistics.deviceCount || 0' |
|
:total-value='(tenantDetail.countStatistics.deviceLimitNumberPerProduct || 1) * (tenantDetail.countStatistics.productLimitNumber || 1)' |
|
> |
|
<template #title> |
|
<div class='bar-title'> |
|
<div class='label'> |
|
设备 |
|
</div> |
|
</div> |
|
</template> |
|
<template #currentValue>已添加</template> |
|
</Bar> |
|
</div> |
|
</el-card> |
|
<el-card> |
|
<div class='title'> |
|
<span class='icon el-icon-coin'></span> |
|
Open API |
|
</div> |
|
<div class='content'> |
|
<div> |
|
AppID <span>{{tenantDetail.openApi.appId || '-'}}</span> |
|
</div> |
|
<div class='secret'> |
|
AppSecret |
|
<span> |
|
{{tenantDetail.openApi.appSecret || '-'}} |
|
</span> |
|
<a class='reset' @click='handleReset'>重置</a> |
|
</div> |
|
<div> |
|
生成时间 <span>{{tenantDetail.openApi.createTime || '-'}}</span> |
|
</div> |
|
</div> |
|
</el-card> |
|
</div> |
|
<div class='device'> |
|
<el-card> |
|
<div class='title'> |
|
<span class='icon el-icon-cpu'></span> |
|
实时在线设备数 |
|
<el-tooltip effect='dark' content='于物联网平台建立长连接的设备数量,数据采集有一定延迟。' placement='top'> |
|
<span class='tips el-icon-question'></span> |
|
</el-tooltip> |
|
</div> |
|
<div class='content'> |
|
<Bar |
|
:current-value='tenantDetail.onlineStatistics.onlineCount || 0' |
|
:total-value='tenantDetail.onlineStatistics.totalCount || 1' |
|
> |
|
<template #title> |
|
<div class='bar-title'> |
|
<div class='label'> |
|
当前在线设备 |
|
</div> |
|
</div> |
|
</template> |
|
</Bar> |
|
<div class='not-active'> |
|
<div> |
|
占比: {{ |
|
((tenantDetail.onlineStatistics.onlineCount || 0) / (tenantDetail.onlineStatistics.totalCount || 1) * 100).toFixed(2) |
|
}}% |
|
</div> |
|
</div> |
|
</div> |
|
</el-card> |
|
<el-card> |
|
<div class='title'> |
|
<span class='icon el-icon-cpu'></span> |
|
在线设备数量 |
|
<DatePicker |
|
v-model='onLineDeviceQueryDate' |
|
@change='getOnLineDevice' |
|
/> |
|
</div> |
|
<BasicLine class='line-chart' :data='onLineDeviceList' /> |
|
</el-card> |
|
</div> |
|
<div class='message'> |
|
<el-card> |
|
<div class='title'> |
|
<span class='icon el-icon-chat-dot-square'></span> |
|
发送到平台的消息量 |
|
<el-tooltip effect='dark' content='从物联网发送到服务端和设备的消息,数据采集有一定延迟。' placement='top'> |
|
<span class='tips el-icon-question'></span> |
|
</el-tooltip> |
|
</div> |
|
<BasicLine :height='210'/> |
|
<div class='month'>本月消息量: 3000</div> |
|
</el-card> |
|
<el-card> |
|
<div class='title'> |
|
<span class='icon el-icon-chat-dot-square'></span> |
|
平台发出的消息量 |
|
<el-tooltip effect='dark' content='从物联网发送到服务端和设备的消息,数据采集有一定延迟。' placement='top'> |
|
<span class='tips el-icon-question'></span> |
|
</el-tooltip> |
|
</div> |
|
<BasicLine :height='210' /> |
|
<div class='month'>本月消息量: 3000</div> |
|
</el-card> |
|
</div> |
|
</div> |
|
</template> |
|
|
|
<script> |
|
import {mapGetters} from 'vuex'; |
|
import dayjs from 'dayjs'; |
|
import Bar from '@/components/Bar/index.vue'; |
|
import BasicLine from '@/components/Charts/BasicLine'; |
|
import {getOnlineDeviceData, getTenantDetail} from '@/api/sys'; |
|
import DatePicker from '@/components/DatePicker/index.vue'; |
|
|
|
export default { |
|
name: 'Sys', |
|
components: { |
|
Bar, |
|
BasicLine, |
|
DatePicker, |
|
}, |
|
data() { |
|
return { |
|
tenantDetail: { |
|
countStatistics: {}, |
|
onlineStatistics: {}, |
|
openApi: {}, |
|
}, |
|
onLineDeviceQueryDate: [dayjs().subtract(24, 'hour'), dayjs()], |
|
onLineDeviceList: [], |
|
}; |
|
}, |
|
computed: { |
|
...mapGetters(['userInfo']), |
|
}, |
|
methods: { |
|
// 重置 |
|
handleReset() { |
|
this.$confirm('重置后将导致原有AppSecret失效, 是否确定重置?', { type: 'warning' }).then(() => { |
|
// todo reset |
|
}).catch(() => {}); |
|
}, |
|
|
|
// 获取在线设备数量 |
|
getOnLineDevice() { |
|
let [start, end] = this.onLineDeviceQueryDate; |
|
const format = 'YYYY-MM-DD HH:mm:ss'; |
|
start = dayjs(start).format(format); |
|
end = dayjs(end).format(format); |
|
getOnlineDeviceData(start, end).then((res) => { |
|
this.onLineDeviceList = res.data.data.map((item) => ({ |
|
label: dayjs(item.timeString).format('MM/DD HH:mm'), |
|
value: item.onlineNum, |
|
})); |
|
}); |
|
}, |
|
|
|
initData() { |
|
getTenantDetail(this.userInfo['tenant_id']).then((res) => { |
|
this.tenantDetail = res.data.data; |
|
}); |
|
this.getOnLineDevice(); |
|
}, |
|
}, |
|
mounted() { |
|
this.initData(); |
|
}, |
|
}; |
|
</script> |
|
|
|
<style scoped lang='scss'> |
|
.infos { |
|
display: flex; |
|
|
|
.el-card { |
|
flex: 1; |
|
margin-right: 20px; |
|
|
|
&:last-child { |
|
margin-right: 0; |
|
} |
|
|
|
.content { |
|
color: #555555; |
|
font-size: 14px; |
|
line-height: 3; |
|
|
|
span { |
|
margin-left: 10px; |
|
} |
|
|
|
.reset { |
|
color: red; |
|
cursor: pointer; |
|
margin: 0 20px; |
|
|
|
&:hover { |
|
text-decoration: underline; |
|
} |
|
} |
|
|
|
.ki-bar:first-child { |
|
margin-top: 20px; |
|
} |
|
|
|
.ki-bar { |
|
margin-top: 30px; |
|
} |
|
|
|
.secret { |
|
display: flex; |
|
|
|
span { |
|
width: 0; |
|
flex: 1; |
|
overflow: hidden; |
|
white-space: nowrap; |
|
text-overflow: ellipsis; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
.title { |
|
color: #000c17; |
|
font-weight: bold; |
|
display: flex; |
|
align-items: center; |
|
|
|
.icon { |
|
margin-right: 10px; |
|
} |
|
} |
|
|
|
.bar-title { |
|
color: #555555; |
|
font-size: 14px; |
|
display: flex; |
|
align-items: baseline; |
|
|
|
.label { |
|
font-size: 16px; |
|
font-weight: bold; |
|
margin-right: 20px; |
|
} |
|
|
|
span { |
|
font-size: 14px; |
|
font-weight: normal; |
|
} |
|
} |
|
|
|
.tips { |
|
color: #cccccc; |
|
margin-left: 10px; |
|
} |
|
|
|
.el-date-editor { |
|
margin-left: auto; |
|
} |
|
|
|
.device { |
|
margin-top: 20px; |
|
display: flex; |
|
|
|
.el-card:first-child { |
|
flex: 1; |
|
margin-right: 20px; |
|
} |
|
|
|
.el-card:last-child { |
|
flex: 2; |
|
padding-right: 20px |
|
} |
|
|
|
.ki-bar, .line-chart { |
|
margin-top: 25px; |
|
} |
|
|
|
.not-active { |
|
margin-top: 30px; |
|
|
|
span { |
|
font-size: 14px; |
|
margin-left: 10px; |
|
} |
|
} |
|
} |
|
|
|
.message { |
|
margin-top: 20px; |
|
display: flex; |
|
|
|
.title { |
|
margin-bottom: 30px; |
|
} |
|
|
|
.el-card { |
|
flex: 1; |
|
} |
|
|
|
.el-card:first-child { |
|
margin-right: 20px; |
|
} |
|
|
|
.month { |
|
font-size: 14px; |
|
margin-top: 15px; |
|
} |
|
} |
|
</style>
|
|
|