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/DeviceDetailsMessage.vue |  201 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 201 insertions(+), 0 deletions(-)

diff --git a/src/views/iot/device/device/detail/DeviceDetailsMessage.vue b/src/views/iot/device/device/detail/DeviceDetailsMessage.vue
new file mode 100644
index 0000000..aebb03b
--- /dev/null
+++ b/src/views/iot/device/device/detail/DeviceDetailsMessage.vue
@@ -0,0 +1,201 @@
+<!-- 璁惧娑堟伅鍒楄〃 -->
+<template>
+  <ContentWrap>
+    <!-- 鎼滅储鍖哄煙 -->
+    <el-form :model="queryParams" inline>
+      <el-form-item>
+        <el-select v-model="queryParams.method" placeholder="鎵�鏈夋柟娉�" class="!w-160px" clearable>
+          <el-option
+            v-for="item in methodOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-select
+          v-model="queryParams.upstream"
+          placeholder="涓婅/涓嬭"
+          class="!w-160px"
+          clearable
+        >
+          <el-option label="涓婅" value="true" />
+          <el-option label="涓嬭" value="false" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="handleQuery">
+          <Icon icon="ep:search" class="mr-5px" /> 鎼滅储
+        </el-button>
+        <el-switch
+          size="large"
+          width="80"
+          v-model="autoRefresh"
+          class="ml-20px"
+          inline-prompt
+          active-text="瀹氭椂鍒锋柊"
+          inactive-text="瀹氭椂鍒锋柊"
+          style="--el-switch-on-color: #13ce66"
+        />
+      </el-form-item>
+    </el-form>
+
+    <!-- 娑堟伅鍒楄〃 -->
+    <el-table v-loading="loading" :data="list" :stripe="true" class="whitespace-nowrap">
+      <el-table-column label="鏃堕棿" align="center" prop="ts" width="180">
+        <template #default="scope">
+          {{ formatDate(scope.row.ts) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="涓婅/涓嬭" align="center" prop="upstream" width="140">
+        <template #default="scope">
+          <el-tag :type="scope.row.upstream ? 'primary' : 'success'">
+            {{ scope.row.upstream ? '涓婅' : '涓嬭' }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="鏄惁鍥炲" align="center" prop="reply" width="140">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.reply" />
+        </template>
+      </el-table-column>
+      <el-table-column label="璇锋眰缂栧彿" align="center" prop="requestId" width="300" />
+      <el-table-column label="璇锋眰鏂规硶" align="center" prop="method" width="140">
+        <template #default="scope">
+          {{ methodOptions.find((item) => item.value === scope.row.method)?.label }}
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="璇锋眰/鍝嶅簲鏁版嵁"
+        align="center"
+        prop="params"
+        :show-overflow-tooltip="true"
+      >
+        <template #default="scope">
+          <span v-if="scope.row.reply">
+            {{ `{"code":${scope.row.code},"msg":"${scope.row.msg}","data":${scope.row.data}\}` }}
+          </span>
+          <span v-else>{{ scope.row.params }}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 鍒嗛〉 -->
+    <div class="mt-10px flex justify-end">
+      <Pagination
+        :total="total"
+        v-model:page="queryParams.pageNo"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getMessageList"
+      />
+    </div>
+  </ContentWrap>
+</template>
+
+<script setup lang="ts">
+import { DICT_TYPE } from '@/utils/dict'
+import { DeviceApi } from '@/api/iot/device/device'
+import { formatDate } from '@/utils/formatTime'
+import { IotDeviceMessageMethodEnum } from '@/views/iot/utils/constants'
+
+const props = defineProps<{
+  deviceId: number
+}>()
+
+// 鏌ヨ鍙傛暟
+const queryParams = reactive({
+  deviceId: props.deviceId,
+  method: undefined,
+  upstream: undefined,
+  pageNo: 1,
+  pageSize: 10
+})
+
+// 鍒楄〃鏁版嵁
+const loading = ref(false)
+const total = ref(0)
+const list = ref([])
+const autoRefresh = ref(false) // 鑷姩鍒锋柊寮�鍏�
+let autoRefreshTimer: any = null // 鑷姩鍒锋柊瀹氭椂鍣�
+
+// 娑堟伅鏂规硶閫夐」
+const methodOptions = computed(() => {
+  return Object.values(IotDeviceMessageMethodEnum).map((item) => ({
+    label: item.name,
+    value: item.method
+  }))
+})
+
+/** 鏌ヨ娑堟伅鍒楄〃 */
+const getMessageList = async () => {
+  if (!props.deviceId) return
+  loading.value = true
+  try {
+    const data = await DeviceApi.getDeviceMessagePage(queryParams)
+    total.value = data.total
+    list.value = data.list
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 鎼滅储鎿嶄綔 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getMessageList()
+}
+
+/** 鐩戝惉鑷姩鍒锋柊 */
+watch(autoRefresh, (newValue) => {
+  if (newValue) {
+    autoRefreshTimer = setInterval(() => {
+      getMessageList()
+    }, 5000)
+  } else {
+    clearInterval(autoRefreshTimer)
+    autoRefreshTimer = null
+  }
+})
+
+/** 鐩戝惉璁惧鏍囪瘑鍙樺寲 */
+watch(
+  () => props.deviceId,
+  (newValue) => {
+    if (newValue) {
+      handleQuery()
+    }
+  }
+)
+
+/** 缁勪欢鍗歌浇鏃舵竻闄ゅ畾鏃跺櫒 */
+onBeforeUnmount(() => {
+  if (autoRefreshTimer) {
+    clearInterval(autoRefreshTimer)
+    autoRefreshTimer = null
+  }
+})
+
+/** 鍒濆鍖� */
+onMounted(() => {
+  if (props.deviceId) {
+    getMessageList()
+  }
+})
+
+/** 鍒锋柊娑堟伅鍒楄〃 */
+const refresh = (delay = 0) => {
+  if (delay > 0) {
+    setTimeout(() => {
+      handleQuery()
+    }, delay)
+  } else {
+    handleQuery()
+  }
+}
+
+/** 鏆撮湶鏂规硶缁欑埗缁勪欢 */
+defineExpose({
+  refresh
+})
+</script>

--
Gitblit v1.8.0