|
|
@@ -10,7 +10,7 @@
|
|
|
:active-tab-key="activeTabKey"
|
|
|
@tabChange="key => onTabChange(key)"
|
|
|
>
|
|
|
- <a-row :gutter="[8, 8]" style="margin-top: 20px;" >
|
|
|
+ <a-row :gutter="[8, 8]" style="margin: 0 20px;" >
|
|
|
|
|
|
<a-col :span="24" >
|
|
|
<a-space>
|
|
|
@@ -35,12 +35,26 @@
|
|
|
</template>
|
|
|
</a-select>
|
|
|
</a-spin>
|
|
|
- <a-range-picker v-model:value="times" @change="changeRangePicker" />
|
|
|
+ <a-select
|
|
|
+ v-if="activeTabKey === 'attr'"
|
|
|
+ v-model:value="state.attributeKey"
|
|
|
+ placeholder="请选择属性"
|
|
|
+ style="width: 170px"
|
|
|
+ :show-arrow="false"
|
|
|
+ @change="selectAttr"
|
|
|
+ >
|
|
|
+ <a-select-option
|
|
|
+ v-for="item in deviceState.attrList"
|
|
|
+ :key="item.key"
|
|
|
+ :value="item.key"
|
|
|
+ >{{item.keyLabel}}</a-select-option>
|
|
|
+ </a-select>
|
|
|
+ <a-range-picker :show-time="{ format: 'HH:mm' }" v-model:value="times" @change="changeRangePicker" />
|
|
|
</a-space>
|
|
|
</a-col>
|
|
|
<a-col :span="24">
|
|
|
<a-spin :spinning="state.loading" >
|
|
|
- <a-empty style="margin: 0 auto;" v-if="!state.deviceId" description="请选择设备" ></a-empty>
|
|
|
+ <a-empty style="margin: 0 auto;" v-if="emptyCondition" :description="emptyDesc" ></a-empty>
|
|
|
<span v-else>
|
|
|
<a-col :span="24" v-if="activeTabKey === 'session'">
|
|
|
<a-row>
|
|
|
@@ -54,10 +68,8 @@
|
|
|
</a-col>
|
|
|
<a-col :span="24" v-else>
|
|
|
<div
|
|
|
- :id="`device-attr-` + key"
|
|
|
+ id="device-attr"
|
|
|
style="width: 1000px; height: 400px;"
|
|
|
- v-for="key in attrKeys"
|
|
|
- :key="key"
|
|
|
>
|
|
|
</div>
|
|
|
</a-col>
|
|
|
@@ -90,12 +102,16 @@ const route = useRoute()
|
|
|
|
|
|
const activeTabKey = ref<'session' | 'attr'>('session')
|
|
|
|
|
|
-const attrKeys = computed(() => Object.keys(state.attrSource))
|
|
|
+const emptyCondition = computed(() => activeTabKey.value === 'session' ? state.dataSource.length === 0 : state.attrSource.length === 0)
|
|
|
+
|
|
|
+const emptyDesc = computed(() => !state.deviceId ? '请选择设备' : '该设备下暂无数据')
|
|
|
|
|
|
const deviceState = reactive<{
|
|
|
dataSource: IOT.API.DEVICE.Device[]
|
|
|
+ attrList: IOT.API.DEVICE.Attr[]
|
|
|
}>({
|
|
|
- dataSource: []
|
|
|
+ dataSource: [],
|
|
|
+ attrList: []
|
|
|
})
|
|
|
|
|
|
const state = reactive<{
|
|
|
@@ -112,18 +128,24 @@ const state = reactive<{
|
|
|
analysisType: '',
|
|
|
spinning: false,
|
|
|
onlineNum: 0,
|
|
|
- offlineNum: 0
|
|
|
+ offlineNum: 0,
|
|
|
+ attributeKey: null
|
|
|
})
|
|
|
|
|
|
-const times = ref([dayjs(), dayjs()])
|
|
|
+const times = ref([dayjs().subtract(30, 'minute'), dayjs()])
|
|
|
|
|
|
state.deviceId = route.query.id as string
|
|
|
|
|
|
const onTabChange = (key: 'session' | 'attr') => activeTabKey.value = key
|
|
|
|
|
|
+// 切换上下线分析
|
|
|
watch(
|
|
|
() => activeTabKey.value,
|
|
|
- () => activeTabKey.value === 'session' ? getDeviceSession() : getDeviceAttr()
|
|
|
+ () => {
|
|
|
+ state.deviceId = null
|
|
|
+ state.searchDeviceLabel = null
|
|
|
+ state.attributeKey = null
|
|
|
+ }
|
|
|
)
|
|
|
|
|
|
// 获取设备属性分析数据
|
|
|
@@ -131,20 +153,22 @@ watch(
|
|
|
() => state.attrSource,
|
|
|
() => {
|
|
|
nextTick(() => {
|
|
|
- Object.keys(state.attrSource).forEach(key => {
|
|
|
- const chartDom = document.getElementById('device-attr-' + key)
|
|
|
+ if (state.attrSource.length === 0) {
|
|
|
+ state.loading = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const chartDom = document.getElementById('device-attr')
|
|
|
|
|
|
- const myChart = echarts.init(chartDom!)
|
|
|
- const attrItem = state.attrSource[key]
|
|
|
+ const myChart = echarts.init(chartDom!)
|
|
|
+
|
|
|
+ attrEchartsJson.xAxis.data = (state.attrSource.map(item => dayjs(item.ts).format('HH:MM:ss')) || []) as never[]
|
|
|
|
|
|
- attrEchartsJson.xAxis.data = (attrItem.map(item => dayjs(item.ts).format('HH:MM:ss')) || []) as never[]
|
|
|
+ attrEchartsJson.series[0].data = state.attrSource.map(item => item.value)
|
|
|
|
|
|
- attrEchartsJson.series[0].data = attrItem.map(item => item.longValue)
|
|
|
+ attrEchartsJson.title.text = state.attrSource[0].keyLabel
|
|
|
|
|
|
- attrEchartsJson.title.text = key
|
|
|
+ myChart.setOption(attrEchartsJson)
|
|
|
|
|
|
- myChart.setOption(attrEchartsJson)
|
|
|
- })
|
|
|
state.loading = false
|
|
|
})
|
|
|
}
|
|
|
@@ -153,9 +177,13 @@ watch(
|
|
|
// 获取上下线分析图表数据
|
|
|
// state.dataSource
|
|
|
watch(
|
|
|
- () => state.deviceId,
|
|
|
+ () => state.dataSource,
|
|
|
() => {
|
|
|
setTimeout(() => {
|
|
|
+ if (state.dataSource.length === 0) {
|
|
|
+ state.loading = false
|
|
|
+ return
|
|
|
+ }
|
|
|
if (activeTabKey.value === 'session') {
|
|
|
const chartDom = document.getElementById('device-session')
|
|
|
const chartDomScatter = document.getElementById('device-session-scatter')
|
|
|
@@ -165,6 +193,7 @@ watch(
|
|
|
const chartDomScatterChart = echarts.init(chartDomScatter!)
|
|
|
sessionEchartsJson.xAxis.data = state.dataSource.map(item => item.createAt) as never[]
|
|
|
sessionEchartsJson.series[0].data = state.dataSource.map(item => item.sessionType === 'CONNECT' ? '上线' : '下线')
|
|
|
+ sessionEchartsJson.series[1].data = state.dataSource.map(item => item.sessionType !== 'CONNECT' ? '上线' : '下线')
|
|
|
|
|
|
const connectCount = state.dataSource.filter(item => item.sessionType === 'CONNECT').length
|
|
|
const disconnectCount = state.dataSource.length - connectCount
|
|
|
@@ -180,20 +209,10 @@ watch(
|
|
|
}
|
|
|
]
|
|
|
|
|
|
- sessionEchartsJson.legend.data = [`上线数量 ${state.onlineNum}`, `下线数量 ${state.offlineNum}`]
|
|
|
-
|
|
|
- scatterOption.series[0].data = state.dataSource.filter(item => item.sessionType === 'CONNECT').map(item => [0, connectCount])
|
|
|
-
|
|
|
- scatterOption.series[1].data = state.dataSource.filter(item => item.sessionType !== 'CONNECT').map(item => [1, disconnectCount])
|
|
|
-
|
|
|
- let currentOption = scatterOption
|
|
|
+ sessionEchartsJson.series[0].name = `上线数量 ${state.onlineNum}`
|
|
|
+ sessionEchartsJson.series[1].name = `下线数量 ${state.offlineNum}`
|
|
|
|
|
|
- setInterval(function () {
|
|
|
- currentOption = currentOption === scatterOption ? barOption : scatterOption
|
|
|
- chartDomScatterChart.setOption(currentOption, true)
|
|
|
- }, 2000)
|
|
|
-
|
|
|
- chartDomScatterChart.setOption(currentOption)
|
|
|
+ chartDomScatterChart.setOption(barOption)
|
|
|
myChart.setOption(sessionEchartsJson)
|
|
|
|
|
|
state.loading = false
|
|
|
@@ -202,19 +221,24 @@ watch(
|
|
|
}
|
|
|
)
|
|
|
|
|
|
-watch(
|
|
|
- () => state.deviceId,
|
|
|
- () => activeTabKey.value === 'session' ? getDeviceSession() : getDeviceAttr()
|
|
|
-)
|
|
|
+const selectAttr = (value: string) => {
|
|
|
+ state.attributeKey = value
|
|
|
+ getDeviceAttr()
|
|
|
+}
|
|
|
|
|
|
const changeRangePicker = (time) => {
|
|
|
activeTabKey.value === 'session' ? getDeviceSession() : getDeviceAttr()
|
|
|
}
|
|
|
|
|
|
-const selectDevice = async (value: records) => {
|
|
|
+const selectDevice = async (value: string) => {
|
|
|
const device = await DeviceContriller.byId(value)
|
|
|
state.deviceId = device.id
|
|
|
console.log('device:', state.deviceId)
|
|
|
+ if (activeTabKey.value === 'attr') {
|
|
|
+ getDeviceAttribute()
|
|
|
+ } else {
|
|
|
+ getDeviceSession()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
const getDeviceLabel = async (val: string) => {
|
|
|
@@ -229,7 +253,7 @@ const getDeviceLabel = async (val: string) => {
|
|
|
const getDeviceSession = async () => {
|
|
|
if (!state.deviceId) return
|
|
|
state.loading = true
|
|
|
- const { data } = await DeviceContriller.getSession({ deviceId: state.deviceId, start: state.start, end: state.end })
|
|
|
+ const { data } = await DeviceContriller.getSession({ deviceId: state.deviceId, start: dayjs(times.value[0]).unix() * 1000, end: dayjs(times.value[1]).unix() * 1000 })
|
|
|
state.dataSource = data.sessionEntities
|
|
|
state.offlineNum = data.offlineNum
|
|
|
state.onlineNum = data.onlineNum
|
|
|
@@ -238,20 +262,22 @@ const getDeviceSession = async () => {
|
|
|
const getDeviceAttr = async () => {
|
|
|
if (!state.deviceId) return
|
|
|
state.loading = true
|
|
|
-
|
|
|
- const { data } = await DeviceContriller.getAttr({ deviceId: state.deviceId, start: 1, end: state.end })
|
|
|
+ // .format('YYYY/MM/DD HH:mm:ss')
|
|
|
+ const { data } = await DeviceContriller.getAttr({
|
|
|
+ deviceId: state.deviceId,
|
|
|
+ start: 1,
|
|
|
+ end: new Date().getTime(),
|
|
|
+ attributeKey: state.attributeKey
|
|
|
+ })
|
|
|
state.attrSource = data
|
|
|
}
|
|
|
|
|
|
-const getDeviceList = async () => {
|
|
|
- state.spinning = true
|
|
|
- const { data } = await DeviceContriller.list()
|
|
|
- state.spinning = false
|
|
|
- deviceState.dataSource = data
|
|
|
+const getDeviceAttribute = async () => {
|
|
|
+ const { data } = await DeviceContriller.getDeviceAttribute(state.deviceId)
|
|
|
+ deviceState.attrList = data
|
|
|
}
|
|
|
|
|
|
onMounted(() => {
|
|
|
- // getDeviceList()
|
|
|
if (state.deviceId) {
|
|
|
getDeviceSession()
|
|
|
}
|