|
@@ -1,10 +1,33 @@
|
|
|
<script setup lang="ts">
|
|
<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 value = ref([])
|
|
|
|
|
|
|
|
const handleChange = (value) => {
|
|
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>
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
<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"
|
|
class="absolute left-0 top-0 w-[2px] h-full bg-gradient-to-b from-transparent via-cyan-500 to-transparent"
|
|
|
></div>
|
|
></div>
|
|
|
<el-form-item class="col-span-1" label="部门">
|
|
<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>
|
|
|
<el-form-item class="col-span-1" label="在线状态">
|
|
<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>
|
|
|
<el-form-item class="col-span-3" label="时间范围">
|
|
<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>
|
|
|
<el-form-item class="col-span-5 col-start-1" label="设备">
|
|
<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>
|
|
|
- <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-item>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
</div>
|
|
</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 {
|
|
.animate-scan-line {
|
|
|
animation: scan-line 3s cubic-bezier(0.4, 0, 0.2, 1) infinite alternate;
|
|
animation: scan-line 3s cubic-bezier(0.4, 0, 0.2, 1) infinite alternate;
|
|
|
}
|
|
}
|
|
@@ -378,60 +484,148 @@ const options = [
|
|
|
.search-container {
|
|
.search-container {
|
|
|
position: relative;
|
|
position: relative;
|
|
|
padding: 24px;
|
|
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) {
|
|
: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;
|
|
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);
|
|
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>
|
|
</style>
|