Эх сурвалжийг харах

refactor(lss): streamline input components and enhance layout for improved readability

- Consolidated attributes in input components within the search form and various drawers for better clarity and maintainability.
- Reduced unnecessary line breaks to enhance overall readability of the index.vue file.
- Updated the structure of the pagination and parameter configuration sections for a more cohesive user experience.
yb 1 долоо хоног өмнө
parent
commit
2766c2f3fd

+ 1 - 1
src/types/index.ts

@@ -150,7 +150,7 @@ export interface CameraInfoDTO {
   username: string
   brand: string
   capability: 'switch_only' | 'ptz_enabled'
-  status: 'ONLINE' | 'OFFLINE'
+  status: 'active' | 'hold' | 'dead'
   lssId?: string
   model?: string
   rtspUrl?: string

+ 2 - 3
src/views/live-stream/index.vue

@@ -64,9 +64,8 @@
         </el-table-column>
         <el-table-column :label="t('推流控制')" width="120" align="center">
           <template #default="{ row }">
-            <!-- LiveStreamStatus: idle, starting, streaming, stopping, stopped, error, reconnecting 如何实现这里 -->
             <el-button
-              v-if="row.status !== 'idle'"
+              v-if="row.status === 'idle'"
               type="success"
               size="small"
               :loading="row._starting"
@@ -75,7 +74,7 @@
               {{ t('启动') }}
             </el-button>
             <el-button
-              v-else="row.status !== 'streaming'"
+              v-if="row.status === 'streaming'"
               type="danger"
               size="small"
               :loading="row._stopping"

+ 92 - 29
src/views/lss/index.vue

@@ -340,7 +340,7 @@
               <el-table-column prop="name" label="名称" min-width="100" show-overflow-tooltip />
               <el-table-column label="状态(心跳)" min-width="140">
                 <template #default="{ row }">
-                  <span :class="['status-text', row.status === 'ONLINE' ? 'status-active' : 'status-dead']">
+                  <span :class="['status-text', row.status === 'active' ? 'status-active' : 'status-dead']">
                     {{ formatCameraStatus(row) }}
                   </span>
                 </template>
@@ -370,7 +370,13 @@
                 <template #default="{ row }">
                   <el-button type="primary" link :icon="Edit" @click="handleEditCamera(row)" />
                   <el-button type="danger" link :icon="Delete" @click="handleDeleteCamera(row)" />
-                  <el-button type="primary" link :icon="Cross" @click="handleViewCamera(row)" />
+                  <el-button
+                    link
+                    :class="['crosshairs-btn', { active: activeCameraId === row.id }]"
+                    @click="handleViewCamera(row)"
+                  >
+                    <Icon icon="mdi:crosshairs" />
+                  </el-button>
                 </template>
               </el-table-column>
             </el-table>
@@ -442,20 +448,45 @@
         <!-- <el-form-item label="IP 地址" prop="ip">
           <el-input v-model="cameraForm.ip" :disabled="isEditCamera" placeholder="请输入 IP 地址" />
         </el-form-item> -->
-        <el-form-item label="摄像头型号" prop="cameraId">
+        <el-form-item label="设备ID" prop="cameraId">
+          <el-input v-model="cameraForm.cameraId" placeholder="请输入设备ID" />
+        </el-form-item>
+        <el-form-item label="设备名称" prop="cameraName">
+          <el-input v-model="cameraForm.cameraName" placeholder="请输入设备名称" />
+        </el-form-item>
+        <el-form-item label="厂商" prop="vendorName">
           <el-select
-            v-model="cameraForm.selectedVendorId"
+            v-model="cameraForm.vendorName"
             placeholder="请选择摄像头"
             style="width: 100%"
             filterable
             @change="handleVendorSelect"
           >
-            <el-option v-for="vendor in cameraVendorList" :key="vendor.id" :label="vendor.name" :value="vendor.id" />
+            <el-option
+              v-for="vendor in [
+                { id: 'hikvision', name: '海康威视' },
+                { id: 'dahua', name: '大华' },
+                { id: 'uniview', name: '宇视' },
+                { id: 'other', name: '其他' }
+              ]"
+              :key="vendor.id"
+              :label="vendor.name"
+              :value="vendor.id"
+            />
           </el-select>
         </el-form-item>
-        <el-form-item label="名称" prop="name">
-          <el-input v-model="cameraForm.name" placeholder="请输入名称" />
+        <el-form-item label="型号" prop="model">
+          <el-input v-model="cameraForm.model" placeholder="请输入型号" />
         </el-form-item>
+        <!-- <el-form-item label="摄像头型号" prop="cameraId">
+          <el-select v-model="cameraForm.selectedVendorId" placeholder="请选择摄像头" style="width: 100%" filterable
+            @change="handleVendorSelect">
+            <el-option v-for="vendor in cameraVendorList" :key="vendor.id" :label="vendor.name" :value="vendor.id" />
+          </el-select>
+        </el-form-item> -->
+        <!-- <el-form-item label="名称" prop="name">
+          <el-input v-model="cameraForm.name" placeholder="请输入名称" />
+        </el-form-item> -->
         <!-- <el-form-item label="端口" prop="port">
           <el-input-number v-model="cameraForm.port" :min="1" :max="65535" style="width: 100%" />
         </el-form-item> -->
@@ -547,16 +578,14 @@ const { t } = useI18n({ useScope: 'global' })
 // 格式化状态显示
 function formatStatus(status: LssNodeStatus | undefined): string {
   switch (status) {
-    case 'ONLINE':
+    case 'active':
       return '在线'
-    case 'OFFLINE':
+    case 'hold':
+      return '离线'
+    case 'dead':
       return '离线'
-    case 'BUSY':
-      return '繁忙'
-    case 'MAINTENANCE':
-      return '维护中'
     default:
-      return '-'
+      return '离线'
   }
 }
 
@@ -584,15 +613,29 @@ function formatTime(time: string | undefined): string {
 
 // 格式化摄像头状态
 function formatCameraStatus(row: CameraInfoDTO): string {
-  if (row.status === 'ONLINE') {
+  if (row.status === 'active') {
+    // 大约5秒钟
     return `active [${formatTime(row.updatedAt)}]`
+  } else if (row.status === 'hold') {
+    // 大约5分钟没有返回
+    return `hold [${formatTime(row.updatedAt)}]`
   } else {
+    // 大约10分钟没有返回
     return `dead (离线)`
   }
 }
 
+// 当前激活的摄像头 ID
+const activeCameraId = ref<number | null>(null)
+
 function handleViewCamera(row: CameraInfoDTO) {
-  console.log(row)
+  // 切换激活状态
+  if (activeCameraId.value === row.id) {
+    activeCameraId.value = null
+  } else {
+    activeCameraId.value = row.id
+  }
+  console.log('Camera active:', row.id, activeCameraId.value === row.id)
 }
 
 // 格式化品牌
@@ -638,7 +681,7 @@ function handleViewConfig(row: CameraInfoDTO) {
   paramsCamera.value = row
   paramsDialogType.value = 'config'
   paramsDialogTitle.value = `参数配置 - ${row.name}`
-  paramsContent.value = row.configParams || ''
+  paramsContent.value = row.paramConfig || ''
   paramsDialogVisible.value = true
 }
 
@@ -647,7 +690,7 @@ function handleViewRunParams(row: CameraInfoDTO) {
   paramsCamera.value = row
   paramsDialogType.value = 'run'
   paramsDialogTitle.value = `运行参数 - ${row.name}`
-  paramsContent.value = row.runParams || ''
+  paramsContent.value = row.runtimeParams || ''
   paramsDialogVisible.value = true
 }
 
@@ -744,7 +787,9 @@ const paramsCamera = ref<CameraInfoDTO | null>(null)
 const cameraForm = reactive({
   selectedVendorId: null as number | null,
   cameraId: '',
-  name: '',
+  cameraName: '',
+  vendorName: '',
+  model: '',
   ip: '',
   port: 80,
   username: '',
@@ -752,7 +797,6 @@ const cameraForm = reactive({
   brand: '',
   capability: 'switch_only' as 'switch_only' | 'ptz_enabled',
   rtspUrl: '',
-  model: '',
   channelNo: '',
   remark: '',
   enabled: true,
@@ -761,12 +805,7 @@ const cameraForm = reactive({
 })
 
 // 摄像头表单验证规则(动态)
-const cameraRules = computed<FormRules>(() => ({
-  selectedVendorId: isEditCamera.value ? [] : [{ required: true, message: '请选择厂商', trigger: 'change' }],
-  cameraId: isEditCamera.value ? [] : [{ required: true, message: '请输入摄像头 ID', trigger: 'blur' }],
-  ip: isEditCamera.value ? [] : [{ required: true, message: '请输入 IP 地址', trigger: 'blur' }],
-  name: [{ required: true, message: '请输入名称', trigger: 'blur' }]
-}))
+const cameraRules = computed<FormRules>(() => ({}))
 
 // 排序状态
 const sortState = reactive<{
@@ -959,7 +998,9 @@ function handleCameraReset() {
 function resetCameraForm() {
   cameraForm.selectedVendorId = null
   cameraForm.cameraId = ''
-  cameraForm.name = ''
+  cameraForm.cameraName = ''
+  cameraForm.vendorName = ''
+  cameraForm.model = ''
   cameraForm.ip = ''
   cameraForm.port = 80
   cameraForm.username = ''
@@ -1023,7 +1064,9 @@ async function handleEditCamera(row: CameraInfoDTO) {
     currentCamera.value = camera
     cameraForm.selectedVendorId = null
     cameraForm.cameraId = camera.cameraId
-    cameraForm.name = camera.name
+    cameraForm.cameraName = camera.cameraName
+    cameraForm.vendorName = camera.vendorName || ''
+    cameraForm.model = camera.model || ''
     cameraForm.ip = camera.ip
     cameraForm.port = camera.port || 80
     cameraForm.username = camera.username || ''
@@ -1062,7 +1105,9 @@ async function handleSubmitCamera() {
         }
         const data: CameraUpdateRequest = {
           id: currentCamera.value.id,
-          name: cameraForm.name,
+          cameraName: cameraForm.cameraName,
+          vendorName: cameraForm.vendorName,
+          model: cameraForm.model,
           port: cameraForm.port,
           username: cameraForm.username,
           brand: cameraForm.brand,
@@ -1285,6 +1330,24 @@ onMounted(() => {
   font-size: 12px;
 }
 
+// 十字瞄准按钮样式
+.crosshairs-btn {
+  color: #909399;
+  transition: color 0.2s;
+
+  &:hover {
+    color: #606266;
+  }
+
+  &.active {
+    color: #67c23a;
+
+    &:hover {
+      color: #85ce61;
+    }
+  }
+}
+
 .status-active {
   color: #67c23a;
 }