From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/views/iot/device/device/detail/DeviceDetailsThingModelPropertyHistory.vue |  216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 216 insertions(+), 0 deletions(-)

diff --git a/src/views/iot/device/device/detail/DeviceDetailsThingModelPropertyHistory.vue b/src/views/iot/device/device/detail/DeviceDetailsThingModelPropertyHistory.vue
new file mode 100644
index 0000000..c913f1d
--- /dev/null
+++ b/src/views/iot/device/device/detail/DeviceDetailsThingModelPropertyHistory.vue
@@ -0,0 +1,216 @@
+<!-- 璁惧鐗╂ā鍨� -> 杩愯鐘舵�� -> 鏌ョ湅鏁版嵁锛堣澶囩殑灞炴�у�煎巻鍙诧級-->
+<template>
+  <Dialog title="鏌ョ湅鏁版嵁" v-model="dialogVisible" width="1024px" :appendToBody="true">
+    <ContentWrap>
+      <!-- 鎼滅储宸ヤ綔鏍� -->
+      <el-form
+        class="-mb-15px"
+        :model="queryParams"
+        ref="queryFormRef"
+        :inline="true"
+        label-width="68px"
+      >
+        <el-form-item label="" prop="createTime">
+          <el-date-picker
+            v-model="queryParams.times"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            type="datetimerange"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            class="!w-360px"
+            @change="handleTimeChange"
+            :shortcuts="defaultShortcuts"
+          />
+        </el-form-item>
+        <el-form-item class="float-right !mr-0 !mb-0">
+          <el-button-group>
+            <el-button
+              :type="viewMode === 'chart' ? 'primary' : 'default'"
+              @click="viewMode = 'chart'"
+              :disabled="isComplexDataType"
+            >
+              <Icon icon="ep:histogram" />
+            </el-button>
+            <el-button
+              :type="viewMode === 'list' ? 'primary' : 'default'"
+              @click="viewMode = 'list'"
+            >
+              <Icon icon="ep:list" />
+            </el-button>
+          </el-button-group>
+        </el-form-item>
+      </el-form>
+    </ContentWrap>
+
+    <!-- 鏁版嵁灞曠ず鍖哄煙 -->
+    <ContentWrap>
+      <!-- 鍥捐〃妯″紡 -->
+      <div v-if="viewMode === 'chart'" class="chart-container">
+        <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="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)) }}
+            </template>
+          </el-table-column>
+          <el-table-column label="灞炴�у��" align="center" prop="value">
+            <template #default="scope">
+              {{ scope.row.value }}
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </ContentWrap>
+  </Dialog>
+</template>
+<script setup lang="ts">
+import { DeviceApi, IotDevicePropertyRespVO } from '@/api/iot/device/device'
+import { beginOfDay, defaultShortcuts, endOfDay, formatDate } from '@/utils/formatTime'
+import { Echart } from '@/components/Echart'
+import { IoTDataSpecsDataTypeEnum } from '@/views/iot/utils/constants'
+
+defineProps<{ deviceId: number }>()
+
+/** IoT 璁惧灞炴�у巻鍙叉暟鎹鎯� */
+defineOptions({ name: 'DeviceDetailsThingModelPropertyHistory' })
+
+const dialogVisible = ref(false) // 寮圭獥鐨勬槸鍚﹀睍绀�
+const loading = ref(false)
+const viewMode = ref<'chart' | 'list'>('chart') // 瑙嗗浘妯″紡鐘舵��
+const list = ref<IotDevicePropertyRespVO[]>([]) // 鍒楄〃鐨勬暟鎹�
+const chartKey = ref(0) // 鍥捐〃閲嶆柊娓叉煋鐨刱ey
+const thingModelDataType = ref<string>('') // 鐗╂ā鍨嬫暟鎹被鍨�
+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() // 鎼滅储鐨勮〃鍗�
+
+// 鍒ゆ柇鏄惁涓哄鏉傛暟鎹被鍨嬶紙struct 鎴� array锛�
+const isComplexDataType = computed(() => {
+  if (!thingModelDataType.value) return false
+  return [IoTDataSpecsDataTypeEnum.STRUCT, IoTDataSpecsDataTypeEnum.ARRAY].includes(
+    thingModelDataType.value as any
+  )
+})
+
+// Echarts 鏁版嵁
+const echartsData = computed(() => {
+  if (!list.value || list.value.length === 0) return []
+  return list.value.map((item) => [item.updateTime, item.value])
+})
+// Echarts 閰嶇疆
+const echartsOption = reactive<any>({
+  title: {
+    text: '璁惧灞炴�у��',
+    left: 'center'
+  },
+  grid: {
+    left: 60,
+    right: 40,
+    bottom: 80,
+    top: 80,
+    containLabel: true
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'cross'
+    }
+  },
+  xAxis: {
+    type: 'time',
+    name: '鏃堕棿',
+    axisLabel: {
+      formatter: (value: number) => formatDate(new Date(value), 'MM-DD HH:mm')
+    }
+  },
+  yAxis: {
+    type: 'value',
+    name: '灞炴�у��'
+  },
+  series: [
+    {
+      name: '灞炴�у��',
+      type: 'line',
+      smooth: true,
+      symbol: 'circle',
+      symbolSize: 6,
+      lineStyle: {
+        width: 2,
+        color: '#1890FF'
+      },
+      itemStyle: {
+        color: '#1890FF'
+      },
+      data: []
+    }
+  ],
+  dataZoom: [
+    {
+      type: 'inside'
+    },
+    {
+      type: 'slider',
+      height: 30
+    }
+  ]
+})
+
+/** 鑾峰緱璁惧鍘嗗彶鏁版嵁 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await DeviceApi.getHistoryDevicePropertyList(queryParams)
+    list.value = data || []
+    updateChartData()
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 鎵撳紑寮圭獥 */
+const open = async (deviceId: number, identifier: string, dataType: string) => {
+  dialogVisible.value = true
+  queryParams.deviceId = deviceId
+  queryParams.identifier = identifier
+  thingModelDataType.value = dataType
+
+  // 濡傛灉鐗╂ā鍨嬫槸 struct銆乤rray锛岄渶瑕侀粯璁や娇鐢� list 妯″紡
+  if (isComplexDataType.value) {
+    viewMode.value = 'list'
+  } else {
+    viewMode.value = 'chart'
+  }
+  // 閲嶇疆鍥捐〃 key锛岀‘淇濇瘡娆℃墦寮�閮借兘姝e父娓叉煋
+  chartKey.value = 0
+
+  // 绛夊緟寮圭獥瀹屽叏娓叉煋鍚庡啀鑾峰彇鏁版嵁
+  await nextTick()
+  await getList()
+}
+
+/** 鏃堕棿鍙樺寲澶勭悊 */
+const handleTimeChange = () => {
+  getList()
+}
+
+/** 鏇存柊鍥捐〃鏁版嵁 */
+const updateChartData = () => {
+  if (echartsOption.series && echartsOption.series[0]) {
+    echartsOption.series[0].data = echartsData.value
+  }
+}
+
+defineExpose({ open }) // 鎻愪緵 open 鏂规硶锛岀敤浜庢墦寮�寮圭獥
+</script>

--
Gitblit v1.8.0