97 lines
2.3 KiB
Vue
97 lines
2.3 KiB
Vue
<script setup lang="ts">
|
|
import { onMounted, ref, watch } from "vue";
|
|
import { RunningTaskList, GetOnlineDevices } from "@/api/videoTask";
|
|
import videoTask from "./index.vue";
|
|
import { SearchConditions, TableConfig } from "@/components/hTable/hTable";
|
|
|
|
defineOptions({
|
|
name: `monitor`,
|
|
});
|
|
|
|
const devices = ref<string[]>([]);
|
|
const selectedDevice = ref<string>("all");
|
|
const videoTaskKey = ref(0);
|
|
|
|
const fetchDevices = async () => {
|
|
const res = await GetOnlineDevices();
|
|
devices.value = res;
|
|
};
|
|
|
|
async function searchCallback(s: SearchConditions, tv: TableConfig): Promise<boolean> {
|
|
// Pass deviceId to API
|
|
const params = { ...s, DeviceId: selectedDevice.value };
|
|
let res = await RunningTaskList(params);
|
|
tv.data = res.data.map((s: any, i: number) => {
|
|
return { ...s, customId: i };
|
|
});
|
|
tv.pageData = res;
|
|
return true;
|
|
}
|
|
|
|
const handleDeviceClick = (device: string) => {
|
|
if (selectedDevice.value === device) return;
|
|
selectedDevice.value = device;
|
|
videoTaskKey.value++; // Force re-render to trigger initial search with new device
|
|
};
|
|
|
|
onMounted(async () => {
|
|
await fetchDevices();
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<el-card class="mb-4">
|
|
<template #header>
|
|
<div class="card-header flex justify-between items-center">
|
|
<span>在线设备 ({{ devices.length }})</span>
|
|
<el-button text @click="fetchDevices">刷新设备</el-button>
|
|
</div>
|
|
</template>
|
|
<div class="device-list">
|
|
<el-tag
|
|
class="mx-1 cursor-pointer"
|
|
:effect="selectedDevice === 'all' ? 'dark' : 'plain'"
|
|
@click="handleDeviceClick('all')"
|
|
>
|
|
全部
|
|
</el-tag>
|
|
<el-tag
|
|
v-for="device in devices"
|
|
:key="device"
|
|
class="mx-1 cursor-pointer"
|
|
:effect="selectedDevice === device ? 'dark' : 'plain'"
|
|
@click="handleDeviceClick(device)"
|
|
>
|
|
{{ device }}
|
|
</el-tag>
|
|
</div>
|
|
</el-card>
|
|
|
|
<videoTask :key="videoTaskKey" :searchCallback="searchCallback"></videoTask>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.device-list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
}
|
|
.cursor-pointer {
|
|
cursor: pointer;
|
|
}
|
|
.mb-4 {
|
|
margin-bottom: 1rem;
|
|
}
|
|
.flex {
|
|
display: flex;
|
|
}
|
|
.justify-between {
|
|
justify-content: space-between;
|
|
}
|
|
.items-center {
|
|
align-items: center;
|
|
}
|
|
</style>
|