Zimo 3 days ago
parent
commit
27cb18905d
2 changed files with 105 additions and 140 deletions
  1. 1 1
      .env.local
  2. 104 139
      src/views/oli-connection/monitoring-query/index.vue

+ 1 - 1
.env.local

@@ -4,7 +4,7 @@ NODE_ENV=development
 VITE_DEV=true
 VITE_DEV=true
 
 
 # 请求路径  http://192.168.188.149:48080  https://iot.deepoil.cc
 # 请求路径  http://192.168.188.149:48080  https://iot.deepoil.cc
-VITE_BASE_URL='https://iot.deepoil.cc'
+VITE_BASE_URL='http://192.168.188.79:48080'
 
 
 # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
 # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
 VITE_UPLOAD_TYPE=server
 VITE_UPLOAD_TYPE=server

+ 104 - 139
src/views/oli-connection/monitoring-query/index.vue

@@ -1,6 +1,5 @@
 <script lang="ts" setup>
 <script lang="ts" setup>
 import { IotDeviceApi } from '@/api/pms/device'
 import { IotDeviceApi } from '@/api/pms/device'
-import { useTableComponents } from '@/components/ZmTable/useTableComponents'
 import { useUserStore } from '@/store/modules/user'
 import { useUserStore } from '@/store/modules/user'
 import { rangeShortcuts } from '@/utils/formatTime'
 import { rangeShortcuts } from '@/utils/formatTime'
 import { useDebounceFn } from '@vueuse/core'
 import { useDebounceFn } from '@vueuse/core'
@@ -9,11 +8,9 @@ import { computed, ref } from 'vue'
 
 
 const { t } = useI18n()
 const { t } = useI18n()
 
 
-// --- 状态定义 ---
 const id = useUserStore().getUser.deptId ?? 157
 const id = useUserStore().getUser.deptId ?? 157
 const deptId = id
 const deptId = id
 
 
-// 查询参数
 interface Query {
 interface Query {
   deptId?: number
   deptId?: number
   deviceName?: string
   deviceName?: string
@@ -24,15 +21,13 @@ interface Query {
 const query = ref<Query>({
 const query = ref<Query>({
   deviceCode: 'YF6660355',
   deviceCode: 'YF6660355',
   time: [
   time: [
-    dayjs().subtract(5, 'minute').format('YYYY-MM-DD HH:mm:ss'),
+    dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'),
     dayjs().format('YYYY-MM-DD HH:mm:ss')
     dayjs().format('YYYY-MM-DD HH:mm:ss')
   ]
   ]
 })
 })
 
 
-// 分页相关参数
-const pageSize = ref(20) // 每页数量
-const lastTs = ref<string | null>(null) // 当前查询的游标 (上一页最后一条的时间)
-const historyStack = ref<(string | null)[]>([]) // 历史游标栈,用于实现“上一页”
+const pageSize = ref(100)
+const historyStack = ref<string[]>([]) // 存储历史开始时间
 
 
 // 数据列表类型
 // 数据列表类型
 interface ListItem {
 interface ListItem {
@@ -46,23 +41,14 @@ interface ListItem {
 const list = ref<ListItem[]>([])
 const list = ref<ListItem[]>([])
 const loading = ref(false)
 const loading = ref(false)
 
 
-// --- 计算属性 ---
+const isDeviceSelected = computed(() => !!query.value.deviceCode)
 
 
-// 判断是否选择了设备 (根据你的需求,这里主要判断 deviceCode)
-const isDeviceSelected = computed(() => {
-  return !!query.value.deviceCode
-})
-
-// 判断是否可以点击上一页
 const canGoBack = computed(() => historyStack.value.length > 0)
 const canGoBack = computed(() => historyStack.value.length > 0)
-// 判断是否可以点击下一页 (简单逻辑:当前列表数量等于每页数量,说明可能还有下一页)
-const canGoNext = computed(() => list.value.length === pageSize.value)
 
 
-// --- 核心逻辑 ---
+const canGoNext = computed(() => list.value.length >= pageSize.value)
 
 
 const loadList = useDebounceFn(async function () {
 const loadList = useDebounceFn(async function () {
-  // 如果没有选择设备,不请求,直接清空列表
-  if (!isDeviceSelected.value) {
+  if (!isDeviceSelected.value || !query.value.time?.length) {
     list.value = []
     list.value = []
     return
     return
   }
   }
@@ -71,15 +57,12 @@ const loadList = useDebounceFn(async function () {
   try {
   try {
     const { time, ...other } = query.value
     const { time, ...other } = query.value
 
 
-    // 构造请求参数,加入分页参数
-    // 注意:这里假设后端接口支持 pageSize 和 lastTs 参数
-    // 如果后端字段名不同(例如 limit, offset 等),请在此处修改
     const params = {
     const params = {
       ...other,
       ...other,
+      // 直接使用 query 中的时间
       beginTime: time?.[0],
       beginTime: time?.[0],
       endTime: time?.[1],
       endTime: time?.[1],
-      pageSize: pageSize.value, // 每页条数
-      lastTs: lastTs.value // 游标
+      pageSize: pageSize.value
     }
     }
 
 
     const data = await IotDeviceApi.getMonitoringQuery(params)
     const data = await IotDeviceApi.getMonitoringQuery(params)
@@ -92,69 +75,76 @@ const loadList = useDebounceFn(async function () {
   }
   }
 })
 })
 
 
-// 搜索按钮逻辑
 function handleQuery() {
 function handleQuery() {
   if (!query.value.deviceCode) {
   if (!query.value.deviceCode) {
     ElMessage.warning('请先输入设备编码')
     ElMessage.warning('请先输入设备编码')
     return
     return
   }
   }
-  // 重置分页状态
-  lastTs.value = null
+  if (!query.value.time || query.value.time.length !== 2) {
+    ElMessage.warning('请选择时间范围')
+    return
+  }
+
+  // 重置历史栈
   historyStack.value = []
   historyStack.value = []
+
   loadList()
   loadList()
 }
 }
 
 
-// 下一页
 function handleNext() {
 function handleNext() {
   if (list.value.length === 0) return
   if (list.value.length === 0) return
+  if (!query.value.time || query.value.time.length < 2) return
 
 
-  // 1. 将当前游标推入栈中 (保存当前页的状态以便返回)
-  historyStack.value.push(lastTs.value)
-
-  // 2. 获取列表最后一条数据的时间戳作为新的游标
-  // 假设 list 中包含 ts 字段,且数据是按时间排序的
+  // 1. 获取当前页最后一条数据的时间
   const lastItem = list.value[list.value.length - 1]
   const lastItem = list.value[list.value.length - 1]
+
   if (lastItem && lastItem.ts) {
   if (lastItem && lastItem.ts) {
-    lastTs.value = lastItem.ts
+    // 2. 将当前的【开始时间】存入栈中,以便返回
+    historyStack.value.push(query.value.time[1])
+
+    // 3. 直接修改 query.time 的开始时间,保持结束时间不变
+    // 注意:重新赋值数组以触发响应式更新
+    query.value.time = [query.value.time[0], dayjs(lastItem.ts).format('YYYY-MM-DD HH:mm:ss')]
+
     loadList()
     loadList()
   } else {
   } else {
-    ElMessage.warning('无法获取下一页游标')
+    ElMessage.warning('无法获取最后一条数据的时间,无法跳转')
   }
   }
 }
 }
 
 
-// 上一页
 function handlePrev() {
 function handlePrev() {
   if (historyStack.value.length === 0) return
   if (historyStack.value.length === 0) return
+  if (!query.value.time || query.value.time.length < 2) return
 
 
-  // 1. 弹出栈顶元素作为游标
-  const prevTs = historyStack.value.pop()
+  // 1. 弹出上一次的开始时间
+  const prevEndTime = historyStack.value.pop()
 
 
-  // 2. 设置并加载
-  lastTs.value = prevTs ?? null
-  loadList()
+  if (prevEndTime) {
+    // 2. 恢复 query.time 的开始时间
+    query.value.time = [query.value.time[0], dayjs(prevEndTime).format('YYYY-MM-DD HH:mm:ss')]
+
+    loadList()
+  }
 }
 }
 
 
-// 每页数量变化
 function handleSizeChange() {
 function handleSizeChange() {
-  // 切换大小时重置回第一页,避免游标错乱
-  lastTs.value = null
-  historyStack.value = []
-  loadList()
+  // 切换分页大小时,为了逻辑简单,直接重新查询第一页
+  if (isDeviceSelected.value && query.value.time) {
+    // 清空栈,因为分页切片改变了,之前的历史游标可能不再准确
+    historyStack.value = []
+    loadList()
+  }
 }
 }
-
-const { ZmTable, ZmTableColumn } = useTableComponents<ListItem>()
 </script>
 </script>
 
 
 <template>
 <template>
   <div
   <div
     class="grid grid-cols-[15%_1fr] grid-rows-[62px_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
     class="grid grid-cols-[15%_1fr] grid-rows-[62px_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
   >
   >
-    <!-- 左侧部门树 -->
     <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg row-span-2">
     <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg row-span-2">
       <DeptTreeSelect :top-id="156" :deptId="deptId" :init-select="false" :show-title="false" />
       <DeptTreeSelect :top-id="156" :deptId="deptId" :init-select="false" :show-title="false" />
     </div>
     </div>
 
 
-    <!-- 顶部搜索栏 -->
     <el-form
     <el-form
       size="default"
       size="default"
       class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
       class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
@@ -198,98 +188,73 @@ const { ZmTable, ZmTableColumn } = useTableComponents<ListItem>()
       </div>
       </div>
     </el-form>
     </el-form>
 
 
-    <!-- 表格区域 -->
-    <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg flex flex-col p-4 relative">
-      <!-- 场景1:未选择设备 -->
-      <div
-        v-if="!isDeviceSelected"
-        class="flex-1 flex flex-col items-center justify-center text-gray-400"
-      >
-        <Icon icon="ep:warning" class="text-6xl mb-4" />
-        <span class="text-lg">请先输入设备编码进行搜索</span>
+    <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg flex flex-col p-4">
+      <div class="flex-1 relative">
+        <el-auto-resizer class="absolute">
+          <template #default="{ width, height }">
+            <zm-table
+              :data="list"
+              :loading="loading"
+              :width="width"
+              :height="height"
+              :max-height="height"
+            >
+              <zm-table-column type="index" label="序号" :width="60" align="center" />
+              <zm-table-column
+                prop="deviceName"
+                title="设备名称"
+                label="设备名称"
+                align="center"
+                min-width="120"
+              />
+              <zm-table-column
+                prop="serialNumber"
+                title="设备编码"
+                label="设备编码"
+                align="center"
+                min-width="120"
+              />
+              <zm-table-column
+                prop="identity"
+                title="属性"
+                label="属性"
+                align="center"
+                min-width="100"
+              />
+              <zm-table-column prop="value" title="值" label="值" align="center" min-width="100" />
+              <zm-table-column
+                prop="ts"
+                title="时间"
+                :formatter="(row: ListItem) => dayjs(row.ts).format('YYYY-MM-DD HH:mm:ss')"
+                label="时间"
+                align="center"
+                min-width="160"
+              />
+            </zm-table>
+          </template>
+        </el-auto-resizer>
       </div>
       </div>
 
 
-      <!-- 场景2:已选择设备 (显示表格) -->
-      <div v-else class="flex-1 flex flex-col h-full overflow-hidden">
-        <div class="flex-1 min-h-0">
-          <!-- 注意:这里使用了 el-auto-resizer 包裹 zm-table 以获得自适应高度 -->
-          <el-auto-resizer>
-            <template #default="{ width, height }">
-              <zm-table
-                :data="list"
-                :loading="loading"
-                :width="width"
-                :height="height"
-                :max-height="height"
-              >
-                <zm-table-column type="index" label="序号" :width="60" align="center" />
-                <zm-table-column
-                  prop="deviceName"
-                  title="设备名称"
-                  label="设备名称"
-                  align="center"
-                  min-width="120"
-                />
-                <zm-table-column
-                  prop="serialNumber"
-                  title="设备编码"
-                  label="设备编码"
-                  align="center"
-                  min-width="120"
-                />
-                <zm-table-column
-                  prop="identity"
-                  title="属性"
-                  label="属性"
-                  align="center"
-                  min-width="100"
-                />
-                <zm-table-column
-                  prop="value"
-                  title="值"
-                  label="值"
-                  align="center"
-                  min-width="100"
-                />
-                <zm-table-column
-                  prop="ts"
-                  title="时间"
-                  label="时间"
-                  align="center"
-                  min-width="160"
-                />
-              </zm-table>
-            </template>
-          </el-auto-resizer>
+      <div
+        class="h-[50px] flex items-center justify-end border-t border-gray-100 dark:border-gray-700 mt-2 gap-4"
+      >
+        <div class="text-sm text-gray-500">
+          每页显示:
+          <el-select v-model="pageSize" class="!w-[80px]" size="default" @change="handleSizeChange">
+            <el-option :value="10" label="10" />
+            <el-option :value="20" label="20" />
+            <el-option :value="50" label="50" />
+            <el-option :value="100" label="100" />
+          </el-select>
         </div>
         </div>
 
 
-        <!-- 自定义分页工具栏 -->
-        <div
-          class="h-[50px] flex items-center justify-end border-t border-gray-100 dark:border-gray-700 mt-2 gap-4"
-        >
-          <div class="text-sm text-gray-500">
-            每页显示:
-            <el-select
-              v-model="pageSize"
-              class="!w-[80px]"
-              size="default"
-              @change="handleSizeChange"
-            >
-              <el-option :value="10" label="10" />
-              <el-option :value="20" label="20" />
-              <el-option :value="50" label="50" />
-              <el-option :value="100" label="100" />
-            </el-select>
-          </div>
-
-          <div class="flex gap-2">
-            <el-button size="default" :disabled="!canGoBack || loading" @click="handlePrev">
-              <Icon icon="ep:arrow-left" /> 上一页
-            </el-button>
-            <el-button size="default" :disabled="!canGoNext || loading" @click="handleNext">
-              下一页 <Icon icon="ep:arrow-right" />
-            </el-button>
-          </div>
+        <div class="flex gap-2">
+          <el-button size="default" :disabled="!canGoBack || loading" @click="handlePrev">
+            <Icon icon="ep:arrow-left" /> 上一页
+          </el-button>
+          <el-button size="default" :disabled="!canGoNext || loading" @click="handleNext">
+            下一页 <Icon icon="ep:arrow-right" />
+          </el-button>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>