视频巡检详情页面

This commit is contained in:
砂糖
2025-10-07 10:02:26 +08:00
parent f4418b8860
commit 0e4f543434
4 changed files with 141 additions and 123 deletions

View File

@@ -1,139 +1,140 @@
<template>
<div class="app-container home">
<el-row :gutter="20">
<el-col :sm="24" :lg="12" style="padding-left: 20px">
<h2>RTSP视频分析平台</h2>
<p>
RTSP视频分析平台项目集成了虹软SDK实现了人脸识别活体检测3D角度分析年龄及性别识别等功能同时利用JavaCV进行高效的视频处理后端采用SpringBoot框架前端则运用了Vue3框架确保系统的稳定与用户体验的流畅<br>
</p>
</el-col>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="设备类型" prop="type">
<el-radio-group type="button" v-model="queryParams.type" @change="handleQuery">
<el-radio-button :label="undefined">全部</el-radio-button>
<el-radio-button v-for="dict in device_type" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio-button>
</el-radio-group>
</el-form-item>
</el-form>
<el-col :sm="24" :lg="12" style="padding-left: 50px">
<el-row>
<el-col :span="12">
<h2>技术选型</h2>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<h4>后端技术</h4>
<ul>
<li>SpringBoot</li>
<li>Spring Security</li>
<li>JWT</li>
<li>MyBatis</li>
<li>Druid</li>
<li>JavaCv</li>
<li>...</li>
</ul>
</el-col>
<el-col :span="6">
<h4>前端技术</h4>
<ul>
<li>Vue</li>
<li>Vite</li>
<li>Element-Plus</li>
<li>Axios</li>
<li>Sass</li>
<li>Xgplayer</li>
<li>...</li>
</ul>
</el-col>
</el-row>
</el-col>
</el-row>
<el-divider />
<el-row :gutter="20">
<el-col :xs="24" :sm="24" :md="12" :lg="8">
<el-card class="update-log">
<template v-slot:header>
<div class="clearfix">
<span>更新日志</span>
</div>
</template>
<el-collapse accordion>
<el-collapse-item title="v1.0.0 - 2025-01-16">
<ol>
<li>RTSP视频分析平台正式发布</li>
<li>rtsp转http-flv和ws-flv</li>
<li>javaCV抽帧转换</li>
</ol>
</el-collapse-item>
</el-collapse>
</el-card>
</el-col>
</el-row>
<div style="display: flex;">
<div class="card" @click="handleVideoCameraFilled(item)" v-for="item in deviceList" :key="item.deviceId">
<div class="card-image"></div>
<div class="category"><dict-tag :options="device_type" :value="item.type"/></div>
<div class="heading">
{{ item.ip }}
<!-- <div class="author"> By <span class="name">Abi</span> 4 days ago</div> -->
</div>
</div>
</div>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="getList" />
</div>
</template>
<script setup name="Index">
const version = ref('3.8.9')
function goTarget(url) {
window.open(url, '__blank')
<script setup name="Device">
import router from '@/router'
import { listDevice } from "@/api/video/device";
const { proxy } = getCurrentInstance();
const { device_on_status, device_type } = proxy.useDict('device_on_status', 'device_type');
const deviceList = ref([]);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 20,
type: undefined,
},
});
const { queryParams } = toRefs(data);
const handleVideoCameraFilled = (row) => {
router.push({ path: "/video/flv", query: { deviceId: row.deviceId } });
}
/** 查询设备列表 */
function getList() {
loading.value = true;
listDevice(queryParams.value).then(response => {
deviceList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
// 多选框选中数据
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.deviceId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
getList();
</script>
<style scoped lang="scss">
.home {
blockquote {
padding: 10px 20px;
margin: 0 0 20px;
font-size: 17.5px;
border-left: 5px solid #eee;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eee;
}
.col-item {
margin-bottom: 20px;
}
<style scoped>
/* From Uiverse.io by alexmaracinaru */
.card {
width: 190px;
background: white;
padding: .4em;
border-radius: 6px;
}
ul {
padding: 0;
margin: 0;
}
.card-image {
background-color: rgb(236, 236, 236);
width: 100%;
height: 130px;
border-radius: 6px 6px 0 0;
}
font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 13px;
color: #676a6c;
overflow-x: hidden;
.card-image:hover {
transform: scale(0.98);
}
ul {
list-style-type: none;
}
.category {
text-transform: uppercase;
font-size: 0.7em;
font-weight: 600;
color: rgb(63, 121, 230);
padding: 10px 7px 0;
}
h4 {
margin-top: 0px;
}
.category:hover {
cursor: pointer;
}
h2 {
margin-top: 10px;
font-size: 26px;
font-weight: 100;
}
.heading {
font-weight: 600;
color: rgb(88, 87, 87);
padding: 7px;
}
p {
margin-top: 10px;
.heading:hover {
cursor: pointer;
}
b {
font-weight: 700;
}
}
.author {
color: gray;
font-weight: 400;
font-size: 11px;
padding-top: 20px;
}
.update-log {
ol {
display: block;
list-style-type: decimal;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0;
margin-inline-end: 0;
padding-inline-start: 40px;
}
}
.name {
font-weight: 600;
}
.name:hover {
cursor: pointer;
}
</style>

View File

@@ -103,6 +103,7 @@
<el-button link type="warning" icon="VideoPause" @click="handleStop(scope.row)" v-hasPermi="['video:inspection:stop']" v-if="scope.row.status === '0'">停止</el-button>
<el-button link type="success" icon="CaretRight" @click="handleExecute(scope.row)" v-hasPermi="['video:inspection:execute']">执行</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['video:inspection:remove']">删除</el-button>
<el-button link type="primary" icon="Document" @click="handleDetail(scope.row)" v-hasPermi="['video:inspection:video']">详情</el-button>
</template>
</el-table-column>
</el-table>
@@ -171,6 +172,8 @@
import { listInspection, getInspection, delInspection, addInspection, updateInspection, startTask, stopTask, executeTask } from "@/api/video/inspection";
import { listDevice } from "@/api/video/device";
import router from '@/router'
const { proxy } = getCurrentInstance();
const { sys_normal_disable } = proxy.useDict('sys_normal_disable');
@@ -290,6 +293,10 @@ function handleUpdate(row) {
});
}
function handleDetail(row) {
router.push({ path: "/insrecord", query: { taskId: row.taskId } });
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["inspectionRef"].validate(valid => {

View File

@@ -161,6 +161,9 @@ import { listInspection } from "@/api/video/inspection";
const { proxy } = getCurrentInstance();
const { ins_record_status } = proxy.useDict('ins_record_status');
const route = useRoute();
const taskId = route.query.taskId;
const inspectionList = ref([]);
const inspectionRecordList = ref([]);
const open = ref(false);
@@ -177,7 +180,7 @@ const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 20,
taskId: null,
taskId: taskId ? parseInt(taskId) : null,
executeTime: null,
duration: null,
accessory: null,
@@ -188,6 +191,13 @@ const data = reactive({
}
});
watch(() => taskId, (newVal) => {
if (newVal) {
queryParams.value.taskId = parseInt(newVal);
getList();
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询巡检任务记录列表 */

View File

@@ -31,7 +31,7 @@ export default defineConfig(({ mode, command }) => {
proxy: {
// https://cn.vitejs.dev/config/#server-proxy
'/dev-api': {
target: 'http://localhost:10081',
target: 'http://49.232.154.205:10082',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, '')
},