|
|
|
@ -1,23 +1,24 @@
|
|
|
|
|
<!-- src/components/PollingComponent.vue -->
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { config } from '@/config';
|
|
|
|
|
import { config } from "@/config";
|
|
|
|
|
import Type1ObjectDetect from "./components/Type1ObjectDetect.vue";
|
|
|
|
|
import Type2LicensePlateRecog from "./components/Type2LicensePlateRecog.vue";
|
|
|
|
|
import Type3TargetRecog from "./components/Type3TargetRecog.vue";
|
|
|
|
|
import Type4AudioDetection from "./components/Type4AudioDetection.vue";
|
|
|
|
|
import { useAllData } from './hooks/useAllData';
|
|
|
|
|
import { useAllData } from "./hooks/useAllData";
|
|
|
|
|
//定义接口返回的单个对象类型
|
|
|
|
|
interface ListItem {
|
|
|
|
|
titles: string[];
|
|
|
|
|
video_url: string;
|
|
|
|
|
}
|
|
|
|
|
const { filterMenuByData, filterDetailsByData, fetchTypeByTitle } = useAllData()
|
|
|
|
|
const { filterMenuByData, filterDetailsByData, fetchTypeByTitle } =
|
|
|
|
|
useAllData();
|
|
|
|
|
// 存储列表数据和状态
|
|
|
|
|
const dataList = ref<ListItem[]>([]);
|
|
|
|
|
const menuList = ref<string[]>([])
|
|
|
|
|
const menuList = ref<string[]>([]);
|
|
|
|
|
const detailInfo = ref<ListItem | null>(); // 详情信息
|
|
|
|
|
const isLoading = ref<boolean>(false);
|
|
|
|
|
const isHomePage = ref<boolean>(true)
|
|
|
|
|
const isHomePage = ref<boolean>(true);
|
|
|
|
|
const currentTilte = ref<string>("");
|
|
|
|
|
const currentType = ref<string>("1");
|
|
|
|
|
let pollingTimer: number | null = null;
|
|
|
|
@ -30,11 +31,11 @@ const fetchList = async (): Promise<ListItem[]> => {
|
|
|
|
|
isLoading.value = true;
|
|
|
|
|
// 模拟 API 请求(替换为实际接口)
|
|
|
|
|
const response = await fetch(config.apiHost);
|
|
|
|
|
if (!response.ok) throw new Error('请求失败');
|
|
|
|
|
if (!response.ok) throw new Error("请求失败");
|
|
|
|
|
const result = await response.json();
|
|
|
|
|
// 确保返回的是数组(TypeScript 类型守卫)
|
|
|
|
|
if (!Array.isArray(result)) {
|
|
|
|
|
throw new Error('返回数据格式错误');
|
|
|
|
|
throw new Error("返回数据格式错误");
|
|
|
|
|
}
|
|
|
|
|
return result as ListItem[];
|
|
|
|
|
} catch (err) {
|
|
|
|
@ -44,11 +45,31 @@ const fetchList = async (): Promise<ListItem[]> => {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 获取菜单列表
|
|
|
|
|
const fetchMenuByData = async () => {
|
|
|
|
|
try {
|
|
|
|
|
isLoading.value = true;
|
|
|
|
|
// 模拟 API 请求(替换为实际接口)
|
|
|
|
|
const response = await fetch(config.apiHost + "/titles");
|
|
|
|
|
if (!response.ok) throw new Error("请求失败");
|
|
|
|
|
const result = await response.json();
|
|
|
|
|
// 确保返回的是数组(TypeScript 类型守卫)
|
|
|
|
|
if (!Array.isArray(result)) {
|
|
|
|
|
throw new Error("返回数据格式错误");
|
|
|
|
|
}
|
|
|
|
|
menuList.value = result;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
// return []; // 失败时返回空数组
|
|
|
|
|
} finally {
|
|
|
|
|
isLoading.value = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 获取详情信息
|
|
|
|
|
const fetchInfoList = (result: ListItem[]) => {
|
|
|
|
|
dataList.value = result;
|
|
|
|
|
menuList.value = filterMenuByData(result);
|
|
|
|
|
}
|
|
|
|
|
// menuList.value = filterMenuByData(result);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//启动轮询
|
|
|
|
|
const startPolling = () => {
|
|
|
|
@ -69,7 +90,6 @@ const stopPolling = () => {
|
|
|
|
|
abortController?.abort();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**跳转页面 */
|
|
|
|
|
const tabDetails = (title: string) => {
|
|
|
|
|
currentTilte.value = title;
|
|
|
|
@ -77,17 +97,18 @@ const tabDetails = (title: string) => {
|
|
|
|
|
detailInfo.value = filterDetailsByData(toRaw(dataList.value), title);
|
|
|
|
|
currentType.value = fetchTypeByTitle(title);
|
|
|
|
|
isHomePage.value = false;
|
|
|
|
|
console.log(currentType.value, detailInfo.value, 'tabDetails');
|
|
|
|
|
}
|
|
|
|
|
console.log(currentType.value, detailInfo.value, "tabDetails");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 组件挂载时启动轮询
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
startPolling()
|
|
|
|
|
fetchMenuByData();
|
|
|
|
|
startPolling();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 组件卸载时清理资源
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
stopPolling()
|
|
|
|
|
stopPolling();
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
@ -95,28 +116,55 @@ onUnmounted(() => {
|
|
|
|
|
<div class="flex items-center justify-center data-overview-wrap">
|
|
|
|
|
<div class="menu-wrap" v-if="isHomePage">
|
|
|
|
|
<!-- 递钱 递烟 。。。 -->
|
|
|
|
|
<div class="flex items-center justify-center menu-item" v-for="title in menuList" :key="title"
|
|
|
|
|
@click="tabDetails(title)">
|
|
|
|
|
<div
|
|
|
|
|
class="flex items-center justify-center menu-item"
|
|
|
|
|
v-for="title in menuList"
|
|
|
|
|
:key="title"
|
|
|
|
|
@click="tabDetails(title)"
|
|
|
|
|
>
|
|
|
|
|
<span>{{ title }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="w-full content-box" v-else>
|
|
|
|
|
<!-- 标题栏 -->
|
|
|
|
|
<div class="tilte-bar type-first-top" @click="() => isHomePage = true">
|
|
|
|
|
<div class="tilte-bar type-first-top" @click="() => (isHomePage = true)">
|
|
|
|
|
<span>←</span> <span>{{ currentTilte }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<ul class="content-list-box">
|
|
|
|
|
<ul class="content-list-box" v-if="detailInfo?.length">
|
|
|
|
|
<li class="content-detail-box">
|
|
|
|
|
<Type2LicensePlateRecog typeKey="2" :info="detailInfo" :title="currentTilte" v-if="currentType === '2'" />
|
|
|
|
|
<Type3TargetRecog typeKey="3" :info="detailInfo" :title="currentTilte" v-else-if="currentType === '3'" />
|
|
|
|
|
<Type4AudioDetection typeKey="4" :info="detailInfo" :title="currentTilte" v-else-if="currentType === '4'" />
|
|
|
|
|
<Type1ObjectDetect typeKey="1" :info="detailInfo" :title="currentTilte" v-else />
|
|
|
|
|
<Type2LicensePlateRecog
|
|
|
|
|
typeKey="2"
|
|
|
|
|
:info="detailInfo"
|
|
|
|
|
:title="currentTilte"
|
|
|
|
|
v-if="currentType === '2'"
|
|
|
|
|
/>
|
|
|
|
|
<Type3TargetRecog
|
|
|
|
|
typeKey="3"
|
|
|
|
|
:info="detailInfo"
|
|
|
|
|
:title="currentTilte"
|
|
|
|
|
v-else-if="currentType === '3'"
|
|
|
|
|
/>
|
|
|
|
|
<Type4AudioDetection
|
|
|
|
|
typeKey="4"
|
|
|
|
|
:info="detailInfo"
|
|
|
|
|
:title="currentTilte"
|
|
|
|
|
v-else-if="currentType === '4'"
|
|
|
|
|
/>
|
|
|
|
|
<Type1ObjectDetect
|
|
|
|
|
typeKey="1"
|
|
|
|
|
:info="detailInfo"
|
|
|
|
|
:title="currentTilte"
|
|
|
|
|
v-else
|
|
|
|
|
/>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<el-empty v-else>
|
|
|
|
|
<el-button type="primary" @click="() => (isHomePage = true)">返回</el-button>
|
|
|
|
|
</el-empty>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
|
|
|
@import url('./DataOverview.scss');
|
|
|
|
|
@import url("./DataOverview.scss");
|
|
|
|
|
</style>
|