更新隐患列表、隐患检查页、隐患结果页

隐患列表
- 移除物体标签
- 重大隐患时编号标签为危险色
- 一般隐患时编号标签为主题色
隐患检查页
- 接入视频文件列表刷新api
- 更新表单提交逻辑
隐患结果页
- 完善视频路径获取接口(临时版,自动拼接为本机地址)
This commit is contained in:
yueliuli 2026-04-22 17:56:30 +08:00
parent b3af3f8aa9
commit e4b3a91dd2
4 changed files with 75 additions and 26 deletions

View File

@ -36,7 +36,24 @@ function handleItemClick(item: string, index: number) {
<el-row style="flex: 1; overflow-y: auto;"> <el-row style="flex: 1; overflow-y: auto;">
<el-col> <el-col>
<el-row v-for="(item, index) in props.data" :key="index"> <el-row v-for="(item, index) in props.data" :key="index">
<!-- 无物体类型标签 隐患等级体颜色显示在编号标签上 -->
<!-- 0为隐患等级 1为隐患描述 -->
<el-button class="item-btn" text @click="handleItemClick(item as string, index)"> <el-button class="item-btn" text @click="handleItemClick(item as string, index)">
<el-tag v-if="(item as number[])[0] === 0" type="primary" size="small">
{{ index + 1 }}
</el-tag>
<el-tag v-else-if="(item as number[])[0] === 1" type="danger" size="small">
{{ index + 1 }}
</el-tag>
<div class="w-2" />
<el-text class="item-text">
{{ (item as number[])[1] }}
</el-text>
</el-button>
<!-- 有物体类型标签 隐患等级体颜色显示在物体类型标签上 -->
<!-- 0为隐患等级 1为物体类型 2为隐患描述 -->
<!-- <el-button class="item-btn" text @click="handleItemClick(item as string, index)">
<el-text type="info" size="small"> <el-text type="info" size="small">
{{ index + 1 }} {{ index + 1 }}
</el-text> </el-text>
@ -51,7 +68,7 @@ function handleItemClick(item: string, index: number) {
<el-text class="item-text"> <el-text class="item-text">
{{ (item as number[])[2] }} {{ (item as number[])[2] }}
</el-text> </el-text>
</el-button> </el-button> -->
</el-row> </el-row>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -17,6 +17,6 @@ export async function runApi(funcName: string, params: Record<string, any>) {
catch (error) { catch (error) {
// 捕获异常,打印错误信息 // 捕获异常,打印错误信息
console.error('接口调用失败:', error) console.error('接口调用失败:', error)
throw error return 'error'
} }
} }

View File

@ -2,7 +2,7 @@
import { computed, onMounted, ref } from 'vue' import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
// import { runApi } from '~/composables/api' import { runApi } from '~/composables/api'
interface HazardItem { interface HazardItem {
隐患编号: string 隐患编号: string
@ -19,7 +19,8 @@ interface HazardItem {
} }
interface DataFormat { interface DataFormat {
隐患列表: [number, string, string][] 隐患列表: [number, string][]
// : [number, string, string][]
隐患范围字典: Record<string, { ranges: number[], level: number, tip: string }> 隐患范围字典: Record<string, { ranges: number[], level: number, tip: string }>
隐患数据: HazardItem[] 隐患数据: HazardItem[]
} }
@ -134,7 +135,7 @@ function getData() {
data.value.隐患列表 = (objects || []).map((obj: any) => { data.value.隐患列表 = (objects || []).map((obj: any) => {
return [ return [
obj.level, obj.level,
resultData.value?.class_list?.[obj.class_id] || '', // resultData.value?.class_list?.[obj.class_id] || '',
tag?.[obj.tag_id] || '', tag?.[obj.tag_id] || '',
] ]
}) })
@ -241,17 +242,21 @@ onMounted(() => {
// //
const vidFile = router.currentRoute.value.query.vid_file as string const vidFile = router.currentRoute.value.query.vid_file as string
if (vidFile) { if (vidFile) {
// runApi('/get_vidUrl', { runApi('/get_full_vid_path', {
// vid_file: vidFile, vid_file: vidFile,
// }).then((res) => { }).then((res) => {
// // console.log('', res) // console.log('', res)
// // vidUrl.value = res[0] vidUrl.value = (res as string[])[0]
// vidUrl.value = 'http://localhost:8086/santai5_h264.mp4'
// console.log(':', vidUrl.value) //
// }) const fileName = vidUrl.value.split('\\').pop() || ''
// //
vidUrl.value = 'http://localhost:8086/santai5_h264.mp4' const fileNameNoExt = fileName.split('.')[0]
// console.log(':', vidUrl.value) //
const fileExt = fileName.split('.')[1]
//
vidUrl.value = `http://localhost:8086/${fileNameNoExt}_h264.${fileExt}`
})
// runApi('/run', { // runApi('/run', {
// vid_file: vidFile, // vid_file: vidFile,

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import { reactive, ref } from 'vue' import { onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { runApi } from '~/composables/api' import { runApi } from '~/composables/api'
@ -9,6 +9,7 @@ const router = useRouter()
const runCheckBtnRef = ref() const runCheckBtnRef = ref()
const isRunningCheck = ref(false) const isRunningCheck = ref(false)
const vidPaths = ref<string[]>([])
interface RuleForm { interface RuleForm {
vidPath: string vidPath: string
@ -18,8 +19,8 @@ const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive<RuleForm>({ const ruleForm = reactive<RuleForm>({
vidPath: '', vidPath: '',
function: [ function: [
'runSam3', // 'runSam3',
'runHazardCheck', // 'runHazardCheck',
// 'runGenerateReport', // 'runGenerateReport',
// 'runAudioRecognition', // 'runAudioRecognition',
], ],
@ -50,15 +51,31 @@ async function runCheck(formEl: FormInstance | undefined) {
if (valid) { if (valid) {
isRunningCheck.value = true isRunningCheck.value = true
await runApi('/run', { await runApi('/run', {
vid_file: 'Miehhuoxqih.AVI', vid_file: vidPaths.value[vidPaths.value.indexOf(ruleForm.vidPath)],
run_sam3: ruleForm.function.includes('runSam3'), run_sam3: ruleForm.function.includes('runSam3'),
run_inspection: false, run_inspection: ruleForm.function.includes('runHazardCheck'),
gen_report: false, gen_report: ruleForm.function.includes('runGenerateReport'),
}).then((res) => {
isRunningCheck.value = false
//
if (res !== 'error') {
router.push({
path: '/nav/hazardCheck/hazardCheckResult',
query: { vid_file: vidPaths.value[vidPaths.value.indexOf(ruleForm.vidPath)] },
})
}
}) })
isRunningCheck.value = false
} }
} }
async function reloadFiles() {
await runApi('/reload_files', {}).then((res) => {
for (const item of (res as any)[0].choices) {
vidPaths.value.push(item[0])
}
})
}
function resetForm(formEl: FormInstance | undefined) { function resetForm(formEl: FormInstance | undefined) {
if (!formEl) if (!formEl)
return return
@ -86,6 +103,10 @@ async function goToResult(formEl: FormInstance | undefined) {
// isRunningCheck.value = false // isRunningCheck.value = false
} }
} }
onMounted(() => {
reloadFiles()
})
</script> </script>
<template> <template>
@ -111,12 +132,11 @@ async function goToResult(formEl: FormInstance | undefined) {
> >
<el-form-item label="视频" prop="vidPath"> <el-form-item label="视频" prop="vidPath">
<el-select v-model="ruleForm.vidPath" placeholder="视频"> <el-select v-model="ruleForm.vidPath" placeholder="视频">
<el-option label="视频1" value="1" /> <el-option v-for="item in vidPaths" :key="item" :label="item" :value="item" />
<el-option label="视频2" value="2" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="功能选择" prop="function"> <el-form-item label="功能选择" prop="function">
<el-checkbox-group v-model="ruleForm.function"> <el-checkbox-group v-model="ruleForm.function" class="checkbox-group">
<el-checkbox value="runSam3" name="function"> <el-checkbox value="runSam3" name="function">
物体识别 物体识别
</el-checkbox> </el-checkbox>
@ -158,4 +178,11 @@ async function goToResult(formEl: FormInstance | undefined) {
justify-content: center; justify-content: center;
align-items: start; align-items: start;
} }
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 16px;
justify-content: flex-start;
}
</style> </style>