Преглед изворни кода

feat:【IoT 物联网】物模型数据-设备属性,优化列表界面,增加定时刷新

YunaiV пре 11 месеци
родитељ
комит
c44d177b1d

+ 0 - 134
src/views/iot/device/device/detail/DeviceDetailsModel.vue

@@ -1,134 +0,0 @@
-<!-- 设备物模型:运行状态(属性)、事件管理、服务调用 -->
-<template>
-  <ContentWrap>
-    <el-tabs v-model="activeTab">
-      <el-tab-pane label="运行状态" name="status">
-        <ContentWrap>
-          <!-- 搜索工作栏 -->
-          <el-form
-            class="-mb-15px"
-            :model="queryParams"
-            ref="queryFormRef"
-            :inline="true"
-            label-width="68px"
-          >
-            <el-form-item label="标识符" prop="identifier">
-              <el-input
-                v-model="queryParams.identifier"
-                placeholder="请输入标识符"
-                clearable
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item label="属性名称" prop="name">
-              <el-input
-                v-model="queryParams.name"
-                placeholder="请输入属性名称"
-                clearable
-                class="!w-240px"
-              />
-            </el-form-item>
-            <el-form-item>
-              <el-button @click="handleQuery"
-                ><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
-              >
-              <el-button @click="resetQuery"
-                ><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button
-              >
-            </el-form-item>
-          </el-form>
-        </ContentWrap>
-        <ContentWrap>
-          <el-tabs>
-            <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
-              <el-table-column label="属性标识符" align="center" prop="property.identifier" />
-              <el-table-column label="属性名称" align="center" prop="property.name" />
-              <el-table-column label="数据类型" align="center" prop="property.dataType" />
-              <el-table-column label="属性值" align="center" prop="value" />
-              <el-table-column
-                label="更新时间"
-                align="center"
-                prop="updateTime"
-                :formatter="dateFormatter"
-                width="180px"
-              />
-              <el-table-column label="操作" align="center">
-                <template #default="scope">
-                  <el-button
-                    link
-                    type="primary"
-                    @click="openDetail(props.device.id, scope.row.property.identifier)"
-                  >
-                    查看数据
-                  </el-button>
-                </template>
-              </el-table-column>
-            </el-table>
-          </el-tabs>
-          <!-- 表单弹窗:添加/修改 -->
-          <DeviceDataDetail ref="detailRef" :device="device" :product="product" />
-        </ContentWrap>
-      </el-tab-pane>
-      <el-tab-pane label="事件管理" name="event">
-        <p>事件管理</p>
-      </el-tab-pane>
-      <el-tab-pane label="服务调用" name="service">
-        <p>服务调用</p>
-      </el-tab-pane>
-    </el-tabs>
-  </ContentWrap>
-</template>
-<script setup lang="ts">
-import { ProductVO } from '@/api/iot/product/product'
-import { DeviceApi, DeviceDataVO, DeviceVO } from '@/api/iot/device/device'
-import { dateFormatter } from '@/utils/formatTime'
-import DeviceDataDetail from './DeviceDataDetail.vue'
-
-const props = defineProps<{ product: ProductVO; device: DeviceVO }>()
-
-const loading = ref(true) // 列表的加载中
-const list = ref<DeviceDataVO[]>([]) // 列表的数据
-const queryParams = reactive({
-  deviceId: -1,
-  identifier: undefined as string | undefined,
-  name: undefined as string | undefined
-})
-
-const queryFormRef = ref() // 搜索的表单
-const activeTab = ref('status') // 默认选中的标签
-
-/** 查询列表 */
-const getList = async () => {
-  loading.value = true
-  try {
-    queryParams.deviceId = props.device.id
-    list.value = await DeviceApi.getLatestDeviceProperties(queryParams)
-  } finally {
-    loading.value = false
-  }
-}
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  getList()
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value.resetFields()
-  queryParams.identifier = undefined
-  queryParams.name = undefined
-  handleQuery()
-}
-
-/** 添加/修改操作 */
-const detailRef = ref()
-const openDetail = (deviceId: number, identifier: string) => {
-  detailRef.value.open(deviceId, identifier)
-}
-
-/** 初始化 **/
-onMounted(() => {
-  getList()
-})
-</script>

+ 27 - 0
src/views/iot/device/device/detail/DeviceDetailsThingModel.vue

@@ -0,0 +1,27 @@
+<!-- 设备物模型:设备属性、事件管理、服务调用 -->
+<template>
+  <ContentWrap>
+    <el-tabs v-model="activeTab">
+      <el-tab-pane label="设备属性(运行状态)" name="property">
+        <DeviceDetailsThingModelProperty :product="product" :device="device" />
+      </el-tab-pane>
+      <el-tab-pane label="设备事件" name="event">
+        <DeviceDetailsThingModelEvent :product="product" :device="device" />
+      </el-tab-pane>
+      <el-tab-pane label="服务调用" name="service">
+        <DeviceDetailsThingModelService :product="product" :device="device" />
+      </el-tab-pane>
+    </el-tabs>
+  </ContentWrap>
+</template>
+<script setup lang="ts">
+import { ProductVO } from '@/api/iot/product/product'
+import { DeviceVO } from '@/api/iot/device/device'
+import DeviceDetailsThingModelProperty from './DeviceDetailsThingModelProperty.vue'
+import DeviceDetailsThingModelEvent from './DeviceDetailsThingModelEvent.vue'
+import DeviceDetailsThingModelService from './DeviceDetailsThingModelService.vue'
+
+const props = defineProps<{ product: ProductVO; device: DeviceVO }>()
+
+const activeTab = ref('property') // 默认选中设备属性
+</script>

+ 16 - 0
src/views/iot/device/device/detail/DeviceDetailsThingModelEvent.vue

@@ -0,0 +1,16 @@
+<!-- 设备事件管理 -->
+<template>
+  <ContentWrap>
+    <div class="text-center p-4">
+      <el-empty description="设备事件管理功能开发中..." />
+    </div>
+  </ContentWrap>
+</template>
+<script setup lang="ts">
+import { ProductVO } from '@/api/iot/product/product'
+import { DeviceVO } from '@/api/iot/device/device'
+
+const props = defineProps<{ product: ProductVO; device: DeviceVO }>()
+
+// TODO: 实现设备事件管理功能
+</script>

+ 150 - 0
src/views/iot/device/device/detail/DeviceDetailsThingModelProperty.vue

@@ -0,0 +1,150 @@
+<!-- 设备属性管理 -->
+<template>
+  <ContentWrap>
+    <!-- 搜索工作栏 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="68px"
+      @submit.prevent
+    >
+      <el-form-item label="" prop="keyword">
+        <el-input
+          v-model="queryParams.keyword"
+          placeholder="请输入属性名称、标志符"
+          clearable
+          class="!w-240px"
+          @keyup.enter="handleQuery"
+          @clear="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-switch
+          size="large"
+          width="80"
+          v-model="autoRefresh"
+          class="-ml-15px"
+          inline-prompt
+          active-text="定时刷新"
+          inactive-text="定时刷新"
+          style="--el-switch-on-color: #13ce66"
+        />
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+  <ContentWrap>
+    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
+      <el-table-column label="属性标识符" align="center" prop="property.identifier" />
+      <el-table-column label="属性名称" align="center" prop="property.name" />
+      <el-table-column label="数据类型" align="center" prop="property.dataType" />
+      <el-table-column label="属性值" align="center" prop="value" />
+      <el-table-column
+        label="更新时间"
+        align="center"
+        prop="updateTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+      <el-table-column label="操作" align="center">
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openDetail(props.device.id, scope.row.property.identifier)"
+          >
+            查看数据
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 表单弹窗:添加/修改 -->
+    <DeviceDataDetail ref="detailRef" :device="device" :product="product" />
+  </ContentWrap>
+</template>
+<script setup lang="ts">
+import { ProductVO } from '@/api/iot/product/product'
+import { DeviceApi, DeviceDataVO, DeviceVO } from '@/api/iot/device/device'
+import { dateFormatter } from '@/utils/formatTime'
+import DeviceDataDetail from './DeviceDataDetail.vue'
+
+const props = defineProps<{ product: ProductVO; device: DeviceVO }>()
+
+const loading = ref(true) // 列表的加载中
+const list = ref<DeviceDataVO[]>([]) // 显示的列表数据
+const allList = ref<DeviceDataVO[]>([]) // 完整的数据列表
+const queryParams = reactive({
+  keyword: '' as string
+})
+const autoRefresh = ref(false) // 自动刷新开关
+let autoRefreshTimer: any = null // 定时器
+
+const queryFormRef = ref() // 搜索的表单
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const params = {
+      deviceId: props.device.id,
+      identifier: undefined as string | undefined,
+      name: undefined as string | undefined
+    }
+    allList.value = await DeviceApi.getLatestDeviceProperties(params)
+    filterData()
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 前端筛选数据 */
+const filterData = () => {
+  if (!queryParams.keyword.trim()) {
+    list.value = allList.value
+  } else {
+    const keyword = queryParams.keyword.toLowerCase()
+    list.value = allList.value.filter(
+      (item) =>
+        item.property?.identifier?.toLowerCase().includes(keyword) ||
+        item.property?.name?.toLowerCase().includes(keyword)
+    )
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  filterData()
+}
+
+/** 添加/修改操作 */
+const detailRef = ref()
+const openDetail = (deviceId: number, identifier: string) => {
+  detailRef.value.open(deviceId, identifier)
+}
+
+/** 监听自动刷新 */
+watch(autoRefresh, (newValue) => {
+  if (newValue) {
+    autoRefreshTimer = setInterval(() => {
+      getList()
+    }, 5000) // 每5秒刷新一次
+  } else {
+    clearInterval(autoRefreshTimer)
+    autoRefreshTimer = null
+  }
+})
+
+/** 组件卸载时清除定时器 */
+onBeforeUnmount(() => {
+  if (autoRefreshTimer) {
+    clearInterval(autoRefreshTimer)
+  }
+})
+
+/** 初始化 **/
+onMounted(() => {
+  getList()
+})
+</script>

+ 16 - 0
src/views/iot/device/device/detail/DeviceDetailsThingModelService.vue

@@ -0,0 +1,16 @@
+<!-- 设备服务调用 -->
+<template>
+  <ContentWrap>
+    <div class="text-center p-4">
+      <el-empty description="设备服务调用功能开发中..." />
+    </div>
+  </ContentWrap>
+</template>
+<script setup lang="ts">
+import { ProductVO } from '@/api/iot/product/product'
+import { DeviceVO } from '@/api/iot/device/device'
+
+const props = defineProps<{ product: ProductVO; device: DeviceVO }>()
+
+// TODO: 实现设备服务调用功能
+</script>

+ 2 - 2
src/views/iot/device/device/detail/index.vue

@@ -11,7 +11,7 @@
         <DeviceDetailsInfo v-if="activeTab === 'info'" :product="product" :device="device" />
       </el-tab-pane>
       <el-tab-pane label="物模型数据" name="model">
-        <DeviceDetailsModel v-if="activeTab === 'model'" :product="product" :device="device" />
+        <DeviceDetailsThingModel v-if="activeTab === 'model'" :product="product" :device="device" />
       </el-tab-pane>
       <el-tab-pane label="子设备管理" v-if="product.deviceType === DeviceTypeEnum.GATEWAY" />
       <el-tab-pane label="设备消息" name="log">
@@ -40,7 +40,7 @@ import { DeviceApi, DeviceVO } from '@/api/iot/device/device'
 import { DeviceTypeEnum, ProductApi, ProductVO } from '@/api/iot/product/product'
 import DeviceDetailsHeader from './DeviceDetailsHeader.vue'
 import DeviceDetailsInfo from './DeviceDetailsInfo.vue'
-import DeviceDetailsModel from './DeviceDetailsModel.vue'
+import DeviceDetailsThingModel from './DeviceDetailsThingModel.vue'
 import DeviceDetailsMessage from './DeviceDetailsMessage.vue'
 import DeviceDetailsSimulator from './DeviceDetailsSimulator.vue'
 import DeviceDetailConfig from './DeviceDetailConfig.vue'