فهرست منبع

简单看板样式

Zimo 4 روز پیش
والد
کامیت
b50562e032
1فایلهای تغییر یافته به همراه243 افزوده شده و 49 حذف شده
  1. 243 49
      src/views/oli-connection/monitoring-board/index.vue

+ 243 - 49
src/views/oli-connection/monitoring-board/index.vue

@@ -1,10 +1,33 @@
 <script setup lang="ts">
-const searchForm = reactive({
-  deviceName: '',
-  status: '',
-  dateRange: []
+import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
+import { rangeShortcuts } from '@/utils/formatTime'
+
+interface DeviceQuery {
+  deptId?: number
+  ifInline?: string
+}
+
+const originalDeviceQuery: DeviceQuery = {
+  deptId: 0,
+  ifInline: '3'
+}
+
+const deviceQuery = ref<DeviceQuery>({
+  ...originalDeviceQuery
 })
 
+interface Query {
+  deviceCodes?: string[]
+  time?: string[]
+}
+
+const originalQuery: Query = {
+  deviceCodes: [],
+  time: []
+}
+
+const query = ref<Query>({ ...originalQuery })
+
 const value = ref([])
 
 const handleChange = (value) => {
@@ -279,6 +302,25 @@ const options = [
     ]
   }
 ]
+
+const deviceOptions = ref([
+  {
+    value: 'guide',
+    label: 'Guide'
+  },
+  {
+    value: 'monitoring',
+    label: 'Monitoring'
+  },
+  {
+    value: 'control',
+    label: 'Control'
+  },
+  {
+    value: 'config',
+    label: 'Config'
+  }
+])
 </script>
 
 <template>
@@ -330,20 +372,67 @@ const options = [
           class="absolute left-0 top-0 w-[2px] h-full bg-gradient-to-b from-transparent via-cyan-500 to-transparent"
         ></div>
         <el-form-item class="col-span-1" label="部门">
-          <el-cascader v-model="value" :options="options" @change="handleChange" />
+          <el-cascader
+            v-model="value"
+            :options="options"
+            @change="handleChange"
+            popper-class="poper"
+            :teleported="false"
+            :show-all-levels="false"
+            :props="{ checkStrictly: true }"
+            class="w-full"
+            placeholder="请选择部门"
+          />
         </el-form-item>
         <el-form-item class="col-span-1" label="在线状态">
-          <el-input />
+          <el-select
+            v-model="deviceQuery.ifInline"
+            placeholder="请选择状态"
+            clearable
+            :teleported="false"
+            popper-class="poper"
+            class="w-full"
+            :class="{ selected: Boolean(deviceQuery.ifInline) }"
+          >
+            <el-option
+              v-for="dict in getStrDictOptions(DICT_TYPE.IOT_DEVICE_STATUS)"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
         </el-form-item>
         <el-form-item class="col-span-3" label="时间范围">
-          <el-input />
+          <el-date-picker
+            v-model="query.time"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            type="datetimerange"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            :shortcuts="rangeShortcuts"
+            :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
+            :teleported="false"
+            popper-class="poper"
+            class="w-full"
+          />
         </el-form-item>
         <el-form-item class="col-span-5 col-start-1" label="设备">
-          <el-input />
+          <el-select
+            v-model="query.deviceCodes"
+            :options="deviceOptions"
+            multiple
+            placeholder="请选择设备"
+            :teleported="false"
+            popper-class="poper"
+            class="w-full"
+            tag-type="primary"
+          />
         </el-form-item>
-        <el-form-item class="col-span-1">
-          <el-button type="primary" class="glow-button">查询</el-button>
-          <el-button type="primary" class="reset-button">重制</el-button>
+        <el-form-item class="col-span-1 flex justify-end">
+          <div class="flex gap-3 w-full justify-end">
+            <el-button class="custom-btn primary-btn">查询数据</el-button>
+            <el-button class="custom-btn reset-btn">重置</el-button>
+          </div>
         </el-form-item>
       </el-form>
     </div>
@@ -371,6 +460,23 @@ const options = [
   }
 }
 
+/* 5. 扫描线动画细节 */
+@keyframes scan-line {
+  0% {
+    left: -40%;
+    opacity: 0;
+  }
+
+  50% {
+    opacity: 1;
+  }
+
+  100% {
+    left: 100%;
+    opacity: 0;
+  }
+}
+
 .animate-scan-line {
   animation: scan-line 3s cubic-bezier(0.4, 0, 0.2, 1) infinite alternate;
 }
@@ -378,60 +484,148 @@ const options = [
 .search-container {
   position: relative;
   padding: 24px;
-  background: rgb(16 24 45 / 80%); /* 稍微调亮的深蓝色 */
-  border: 1px solid rgb(34 211 238 / 15%); /* 明显的青色半透明边框 */
-  border-radius: 8px;
-  box-shadow:
-    0 8px 32px 0 rgb(0 0 0 / 80%),
-    inset 0 0 15px rgb(34 211 238 / 5%); /* 内部微光 */
+  background: linear-gradient(135deg, rgb(11 17 33 / 90%) 0%, rgb(6 9 18 / 95%) 100%);
+  border: 1px solid rgb(34 211 238 / 60%);
+  border-radius: 4px;
+  box-shadow: 0 10px 40px rgb(0 0 0 / 60%);
 }
 
 :deep(.el-form-item) {
+  --background-color: rgb(2 4 8 / 80%) !important;
+  --box-shadow: 0 0 0 1px rgb(34 211 238 / 20%) inset !important;
+  --transition: all 0.3s ease;
+  --active-box-shadow: 0 0 0 1px #22d3ee inset, 0 0 12px rgb(34 211 238 / 30%) !important;
+  --bg-color-overlay: rgb(16 24 45) !important;
+  --border-color: rgb(34 211 238 / 20%) !important;
+  --text-color-regular: rgb(240 249 255 / 90%) !important;
+  --text-color-primary: rgb(92 231 247 / 90%) !important;
+
   margin-bottom: 0;
-}
 
-/* 2. 标签颜色:提高白度 */
-:deep(.el-form-item__label) {
-  font-size: 13px;
-  font-weight: 500;
-  letter-spacing: 0.5px;
-  color: rgb(34 211 238) !important;
-}
+  .el-form-item__label {
+    padding-bottom: 4px;
+    font-size: 14px;
+    font-weight: 500;
+    color: rgb(165 243 252 / 90%) !important;
+  }
+
+  .el-input__wrapper,
+  .el-select__wrapper {
+    background-color: var(--background-color);
+    box-shadow: var(--box-shadow);
+    transition: var(--transition);
+  }
+
+  .el-input__wrapper.is-focus,
+  .is-focused,
+  .is-active {
+    box-shadow: var(--active-box-shadow);
+  }
+
+  .poper {
+    --el-bg-color-overlay: var(--bg-color-overlay);
+    --el-border-color-light: var(--border-color);
+    --el-fill-color-light: var(--border-color);
+    --el-text-color-regular: var(--text-color-regular);
+    --el-text-color-primary: var(--text-color-primary);
+    --el-border-color-extra-light: var(--border-color);
+  }
+
+  .el-cascader-node {
+    &.is-active {
+      box-shadow: none;
+    }
+  }
+
+  .el-time-spinner__item.is-active {
+    box-shadow: none;
+  }
+
+  .cancel {
+    color: var(--el-color-danger);
+  }
 
-/* 3. 输入框:让背景更深以产生“凹陷感”,边框在聚焦时发光 */
-:deep(.el-input__wrapper) {
-  background-color: #05080f !important;
-  box-shadow: 0 0 0 1px rgb(255 255 255 / 10%) inset !important;
+  .el-picker-panel__footer {
+    .is-text {
+      color: var(--el-color-danger);
+    }
+
+    .is-plain {
+      color: var(--text-color-primary);
+      background-color: var(--border-color);
+      border-color: var(--border-color);
+    }
+  }
+
+  .el-picker__popper {
+    border-color: var(--border-color);
+
+    .el-time-panel {
+      border-color: var(--border-color);
+    }
+
+    .el-picker-panel__footer {
+      .is-text {
+        color: var(--el-color-danger);
+      }
+
+      .is-plain {
+        color: var(--text-color-primary);
+        background-color: var(--border-color);
+        border-color: var(--border-color);
+      }
+    }
+  }
+
+  .el-input {
+    --el-input-hover-border-color: var(--border-color);
+  }
+
+  .el-input__inner,
+  .el-date-editor .el-range-input {
+    color: var(--text-color-primary);
+  }
+
+  .selected {
+    .el-select__placeholder {
+      color: var(--text-color-primary);
+    }
+  }
+
+  .el-tag {
+    --el-tag-bg-color: var(--border-color);
+    --el-tag-border-color: var(--border-color);
+    --el-tag-text-color: var(--text-color-primary);
+  }
 }
 
-:deep(.el-input__wrapper.is-focus) {
-  box-shadow:
-    0 0 0 1px #22d3ee inset,
-    0 0 8px rgb(34 211 238 / 40%) !important;
+.custom-btn {
+  border: none;
+  border-radius: 2px;
+  transition: all 0.3s;
 }
 
-/* 4. 按钮样式:保持高对比度 */
-.glow-button {
-  font-weight: bold;
-  color: #020408 !important;
-  background: #22d3ee !important;
-  border: none !important;
-  box-shadow: 0 0 15px rgb(34 211 238 / 40%);
+.primary-btn {
+  color: #020617;
+  background: linear-gradient(90deg, #0891b2 0%, #22d3ee 100%);
+  box-shadow: 0 0 10px rgb(34 211 238 / 30%);
 }
 
-.glow-button:hover {
+.primary-btn:hover {
+  background: linear-gradient(90deg, #22d3ee 0%, #67e8f9 100%);
   transform: translateY(-1px);
-  box-shadow: 0 0 25px rgb(34 211 238 / 60%);
+  box-shadow: 0 0 20px rgb(34 211 238 / 50%);
 }
 
-.reset-button {
-  color: #94a3b8 !important;
-  background: transparent !important;
-  border: 1px solid rgb(255 255 255 / 20%) !important;
+.reset-btn {
+  color: #94a3b8;
+  background: rgb(255 255 255 / 5%);
+  border: 1px solid rgb(148 163 184 / 30%);
 }
 
-.reset-button:hover {
-  color: #22d3ee !important;
-  border-color: #22d3ee !important;
+.reset-btn:hover {
+  color: #fff;
+  background: rgb(255 255 255 / 10%);
+  border-color: rgb(255 255 255 / 50%);
 }
 </style>