|
|
@@ -1,6 +1,6 @@
|
|
|
<!-- 设备物模型 -> 运行状态 -> 查看数据(设备的属性值历史)-->
|
|
|
<template>
|
|
|
- <Dialog title="查看数据" v-model="dialogVisible" width="1024px">
|
|
|
+ <Dialog title="查看数据" v-model="dialogVisible" width="1024px" :appendToBody="true">
|
|
|
<ContentWrap>
|
|
|
<!-- 搜索工作栏 -->
|
|
|
<el-form
|
|
|
@@ -19,6 +19,7 @@
|
|
|
end-placeholder="结束日期"
|
|
|
class="!w-360px"
|
|
|
@change="handleTimeChange"
|
|
|
+ :shortcuts="defaultShortcuts"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
<el-form-item class="float-right !mr-0 !mb-0">
|
|
|
@@ -44,18 +45,13 @@
|
|
|
<ContentWrap>
|
|
|
<!-- 图表模式 -->
|
|
|
<div v-if="viewMode === 'chart'" class="chart-container">
|
|
|
- <div v-if="sortedList.length === 0" class="text-center text-gray-500 py-20"> 暂无数据 </div>
|
|
|
- <Echart v-else :options="echartsOption" height="400px" />
|
|
|
+ <div v-if="list.length === 0" class="text-center text-gray-500 py-20"> 暂无数据 </div>
|
|
|
+ <Echart v-else :key="'erchart' + Date.now()" :options="echartsOption" height="400px" />
|
|
|
</div>
|
|
|
|
|
|
<!-- 表格模式 -->
|
|
|
<div v-else>
|
|
|
- <el-table
|
|
|
- v-loading="detailLoading"
|
|
|
- :data="sortedList"
|
|
|
- :stripe="true"
|
|
|
- :show-overflow-tooltip="true"
|
|
|
- >
|
|
|
+ <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
|
|
<el-table-column label="时间" align="center" prop="time" width="180px">
|
|
|
<template #default="scope">
|
|
|
{{ formatDate(new Date(scope.row.updateTime)) }}
|
|
|
@@ -68,41 +64,41 @@
|
|
|
</Dialog>
|
|
|
</template>
|
|
|
<script setup lang="ts">
|
|
|
-import { DeviceApi, DeviceHistoryDataVO, DeviceVO } from '@/api/iot/device/device'
|
|
|
+import { DeviceApi, IotDevicePropertyRespVO, DeviceVO } from '@/api/iot/device/device'
|
|
|
import { ProductVO } from '@/api/iot/product/product'
|
|
|
-import { beginOfDay, endOfDay, formatDate } from '@/utils/formatTime'
|
|
|
+import { beginOfDay, defaultShortcuts, endOfDay, formatDate } from '@/utils/formatTime'
|
|
|
import { Echart } from '@/components/Echart'
|
|
|
|
|
|
defineProps<{ product: ProductVO; device: DeviceVO }>()
|
|
|
|
|
|
-/** IoT 设备数据详情 */
|
|
|
-defineOptions({ name: 'IoTDeviceDataDetail' })
|
|
|
+/** IoT 设备属性历史数据详情 */
|
|
|
+defineOptions({ name: 'DeviceDetailsThingModelPropertyHistory' })
|
|
|
|
|
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
|
|
-const detailLoading = ref(false)
|
|
|
+const loading = ref(false)
|
|
|
const viewMode = ref<'chart' | 'list'>('chart') // 视图模式状态
|
|
|
+const list = ref<IotDevicePropertyRespVO[]>([]) // 列表的数据
|
|
|
+const chartKey = ref(0) // 图表重新渲染的key
|
|
|
+const queryParams = reactive({
|
|
|
+ deviceId: -1,
|
|
|
+ identifier: '',
|
|
|
+ times: [
|
|
|
+ // 默认显示最近一周的数据
|
|
|
+ formatDate(beginOfDay(new Date(new Date().getTime() - 3600 * 1000 * 24 * 7))),
|
|
|
+ formatDate(endOfDay(new Date()))
|
|
|
+ ]
|
|
|
+})
|
|
|
+const queryFormRef = ref() // 搜索的表单
|
|
|
|
|
|
-const list = ref<DeviceHistoryDataVO[]>([]) // 列表的数据
|
|
|
-
|
|
|
-// 根据视图模式排序的数据
|
|
|
-const sortedList = computed(() => {
|
|
|
+// Echarts 数据
|
|
|
+const echartsData = computed(() => {
|
|
|
if (!list.value || list.value.length === 0) return []
|
|
|
-
|
|
|
- const sortedData = [...list.value]
|
|
|
-
|
|
|
- if (viewMode.value === 'list') {
|
|
|
- // 列表模式:按时间倒序(最新的在前)
|
|
|
- return sortedData.sort((a, b) => b.time - a.time)
|
|
|
- } else {
|
|
|
- // 图表模式:按时间升序(最早的在前)
|
|
|
- return sortedData.sort((a, b) => a.time - b.time)
|
|
|
- }
|
|
|
+ return list.value.map((item) => [item.updateTime, item.value])
|
|
|
})
|
|
|
-
|
|
|
// Echarts 配置
|
|
|
const echartsOption = reactive<any>({
|
|
|
title: {
|
|
|
- text: '设备数据趋势',
|
|
|
+ text: '设备属性值',
|
|
|
left: 'center'
|
|
|
},
|
|
|
grid: {
|
|
|
@@ -157,47 +153,27 @@ const echartsOption = reactive<any>({
|
|
|
]
|
|
|
})
|
|
|
|
|
|
-// 更新图表数据
|
|
|
-const updateChartData = () => {
|
|
|
- if (echartsOption.series && echartsOption.series[0]) {
|
|
|
- echartsOption.series[0].data = sortedList.value.map((item) => [
|
|
|
- item.updateTime,
|
|
|
- parseFloat(item.value) || 0
|
|
|
- ])
|
|
|
- debugger
|
|
|
- }
|
|
|
-}
|
|
|
-const queryParams = reactive({
|
|
|
- deviceId: -1,
|
|
|
- identifier: '',
|
|
|
- times: [
|
|
|
- // 默认显示最近一周的数据
|
|
|
- formatDate(beginOfDay(new Date(new Date().getTime() - 3600 * 1000 * 24 * 7))),
|
|
|
- formatDate(endOfDay(new Date()))
|
|
|
- ]
|
|
|
-})
|
|
|
-const queryFormRef = ref() // 搜索的表单
|
|
|
-
|
|
|
/** 获得设备历史数据 */
|
|
|
const getList = async () => {
|
|
|
- detailLoading.value = true
|
|
|
+ loading.value = true
|
|
|
try {
|
|
|
const data = await DeviceApi.getHistoryDevicePropertyList(queryParams)
|
|
|
list.value = data || []
|
|
|
- // 数据获取后更新图表
|
|
|
- nextTick(() => {
|
|
|
- updateChartData()
|
|
|
- })
|
|
|
+ updateChartData()
|
|
|
} finally {
|
|
|
- detailLoading.value = false
|
|
|
+ loading.value = false
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/** 打开弹窗 */
|
|
|
-const open = (deviceId: number, identifier: string) => {
|
|
|
+const open = async (deviceId: number, identifier: string) => {
|
|
|
dialogVisible.value = true
|
|
|
queryParams.deviceId = deviceId
|
|
|
queryParams.identifier = identifier
|
|
|
+ // 重置图表key,确保每次打开都能正常渲染
|
|
|
+ chartKey.value = 0
|
|
|
+ // 等待弹窗完全渲染后再获取数据
|
|
|
+ await nextTick()
|
|
|
getList()
|
|
|
}
|
|
|
|
|
|
@@ -206,16 +182,12 @@ const handleTimeChange = () => {
|
|
|
getList()
|
|
|
}
|
|
|
|
|
|
-// 监听数据变化,更新图表
|
|
|
-watch(
|
|
|
- () => sortedList.value,
|
|
|
- () => {
|
|
|
- if (viewMode.value === 'chart') {
|
|
|
- updateChartData()
|
|
|
- }
|
|
|
- },
|
|
|
- { deep: true }
|
|
|
-)
|
|
|
+/** 更新图表数据 */
|
|
|
+const updateChartData = () => {
|
|
|
+ if (echartsOption.series && echartsOption.series[0]) {
|
|
|
+ echartsOption.series[0].data = echartsData.value
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
|
|
</script>
|