fix:过车统计、导出该路过车记录

This commit is contained in:
dzc committed 2025-08-06 16:55:52 +08:00
1 parent 6efa90f397
commit b1397a182e
7 files changed
+194 -118

No files matched your search

+1 -1
View File
@@ -5,7 +5,7 @@
children: 'deviceChannelList',
}" node-key="treeValue" v-model="state.selectId" :placeholder="props.placeholder" :clearable="props.clearable"
:loading="state.loading" :data="state.options" :render-after-expand="false" show-checkbox multiple
style="width: 100%" default-expand-all />
style="width: 100%" filterable default-expand-all />
</template>
<script setup lang="ts" name="select-tree-channel">
+2 -2
View File
@@ -58,7 +58,7 @@
<dict-tag :options="dh_enter_Mode" :value="row.enterMode" />
</template>
</el-table-column>
<el-table-column prop="enterTime" min-width="180" label="入场时间" />
<el-table-column prop="enterTime" sortable min-width="180" label="入场时间" />
<el-table-column prop="parseOriginalPicPathEnter" min-width="100" label="抓拍图片">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseOriginalPicPathEnter"
@@ -69,7 +69,7 @@
<el-table-column label="出场">
<el-table-column prop="exitCarNum" min-width="100" label="出场车牌号" />
<el-table-column prop="exitTime" min-width="180" label="出场时间" />
<el-table-column prop="exitTime" sortable min-width="180" label="出场时间" />
<el-table-column prop="parseOriginalPicPathExit" min-width="100" label="抓拍图片">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseOriginalPicPathExit"
+54 -27
View File
@@ -7,12 +7,8 @@
<el-form-item style="width: 250px;" label="车牌号" prop="carNum">
<el-input v-model="state.queryForm.carNum" placeholder="请输入车牌号" />
</el-form-item>
<el-form-item style="width: 350px;" label="入场时间" prop="enterTimeList">
<el-date-picker v-model="state.queryForm.enterTimeList" value-format="YYYY-MM-DD"
type="daterange" />
</el-form-item>
<el-form-item style="width: 350px;" label="出场时间" prop="exitTimeList">
<el-date-picker v-model="state.queryForm.exitTimeList" value-format="YYYY-MM-DD"
<el-form-item style="width: 350px;" label="抓拍时间" prop="capTimeList">
<el-date-picker v-model="state.queryForm.capTimeList" value-format="YYYY-MM-DD"
type="daterange" />
</el-form-item>
<el-form-item>
@@ -47,7 +43,7 @@
{{ getDictByValue(v, "car_alarm_type") }}
<template #content>
<div v-if="v == 3">
在{{ parseTime(row.enterTime, "{y}-{m}-{d}") }}一共出入{{ row.repeatCount }}次
在{{ parseTime(row.capTime, "{y}-{m}-{d}") }}一共出入{{ row.repeatCount }}次
</div>
<div v-else>{{ getDictByValue(v, 'car_alarm_type') }}</div>
</template>
@@ -56,39 +52,68 @@
</div>
</template>
</el-table-column>
<el-table-column label="入场">
<el-table-column prop="carNum" min-width="100" label="入场车牌号" />
<el-table-column prop="enterMode" min-width="100" label="入场方式">
<el-table-column prop="capTime" min-width="180" label="抓拍时间" />
<el-table-column label="车辆信息">
<el-table-column prop="carDirect" width="120" label="行车方向">
<template #default="{ row }">
<dict-tag :options="dh_enter_Mode" :value="row.enterMode" />
<dict-tag :options="dh_car_direct" :value="row.carDirect" />
</template>
</el-table-column>
<el-table-column prop="enterTime" min-width="180" label="入场时间" />
<el-table-column min-width="100" label="抓拍图片">
<el-table-column prop="carColor" width="120" label="车辆颜色">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseOriginalPicPathEnter"
:src="row.parseOriginalPicPathEnter" />
<dict-tag :options="dh_car_color" :value="row.carColor" />
</template>
</el-table-column>
<el-table-column prop="carInnerCategory" width="120" label="车辆进出类型">
<template #default="{ row }">
<dict-tag :options="dh_enter_or_exit" :value="row.carInnerCategory" />
</template>
</el-table-column>
<el-table-column prop="carNum" width="200" label="车牌号码">
<template #default="{ row }">
<div class="flex items-center gap-2">
<dict-tag v-if="row.carNumColor" :options="dh_car_num_color" :value="row.carNumColor" />
<el-tag v-else type="danger">未知</el-tag>
<span>{{ row.carNum }}</span>
</div>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="出场">
<el-table-column prop="exitCarNum" min-width="100" label="出场车牌号" />
<el-table-column prop="exitTime" min-width="180" label="出场时间" />
<el-table-column label="人员信息">
<el-table-column prop="ownerId" width="120" label="人员ID" />
<el-table-column prop="ownerCardId" width="120" label="证件号码" />
</el-table-column>
<el-table-column label="抓拍相机">
<el-table-column prop="devId" min-width="100" label="设备编码" />
<el-table-column prop="devName" min-width="100" label="设备名称" />
<el-table-column prop="devChnName" min-width="100" label="通道名称" />
<el-table-column prop="devChnId" min-width="150" label="通道编码" />
</el-table-column>
<el-table-column label="抓拍图片">
<el-table-column min-width="100" label="抓拍图片">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseOriginalPicPathExit"
:src="row.parseOriginalPicPathExit" />
<preview-image width="50px" height="50px" v-if="row.parseCarImgUrl"
:src="row.parseCarImgUrl" />
</template>
</el-table-column>
<el-table-column min-width="100" label="车牌图片">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseCarNumPic"
:src="row.parseCarNumPic" />
</template>
</el-table-column>
</el-table-column>
<el-table-column v-if="false" label="操作" width="100" fixed="right">
<el-table-column label="操作" width="100" fixed="right">
<template #default="{ row }">
<el-button v-if="row.enterTime && !row.carNum" icon="VideoCamera" text type="primary"
@click="replayVideoDialogRef.openDialog('channel', row.enterItcDevChnId)">
回放
</el-button>
<el-button v-else-if="row.exitTime && !row.exitCarNum" icon="VideoCamera" text type="primary"
@click="replayVideoDialogRef.openDialog('channel', row.exitItcDevChnId)">
<el-button v-if="row.alarmList && row.alarmList.includes('2')" icon="VideoCamera" text
type="primary" @click="replayVideoDialogRef.openDialog('channel', row.devChnId)">
回放
</el-button>
</template>
@@ -112,6 +137,8 @@ import * as CarAccessApi from "/@/api/car/carAccess";
const ReplayVideoDialog = defineAsyncComponent(() => import("../../device/components/replay-video/replay-video-dialog.vue"));
const { dh_car_color, dh_enter_or_exit, dh_car_num_color, dh_car_direct } = useDict("dh_car_color", "dh_enter_or_exit", "dh_car_num_color", "dh_car_direct")
const replayVideoDialogRef = ref()
// 搜索变量
+1
View File
@@ -36,6 +36,7 @@
@sort-change="sortChangeHandle">
<el-table-column type="selection" width="40" align="center" />
<el-table-column type="index" label="#" width="80" />
<el-table-column prop="capTime" min-width="180" label="抓拍时间" />
<el-table-column label="车辆信息">
+54 -27
View File
@@ -3,12 +3,8 @@
<el-dialog title="车辆进去详情" v-model="visible" width="70%" :close-on-click-modal="false" draggable>
<el-row shadow="hover" class="ml10">
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
<el-form-item style="width: 350px;" label="入场时间" prop="enterTimeList">
<el-date-picker v-model="state.queryForm.enterTimeList" value-format="YYYY-MM-DD"
type="daterange" />
</el-form-item>
<el-form-item style="width: 350px;" label="出场时间" prop="exitTimeList">
<el-date-picker v-model="state.queryForm.exitTimeList" value-format="YYYY-MM-DD" type="daterange" />
<el-form-item style="width: 350px;" label="抓拍时间" prop="capTimeList">
<el-date-picker v-model="state.queryForm.capTimeList" value-format="YYYY-MM-DD" type="daterange" />
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="getDataList">
@@ -23,35 +19,62 @@
@sort-change="sortChangeHandle">
<el-table-column type="selection" width="40" align="center" />
<el-table-column type="index" label="#" width="80" />
<el-table-column v-if="false" label="车辆信息">
<el-table-column prop="carOwnerId" min-width="100" label="车主id" />
<el-table-column prop="ownerType" min-width="100" label="车辆类型" />
</el-table-column>
<el-table-column label="入场">
<el-table-column prop="carNum" min-width="100" label="入场车牌号" />
<el-table-column prop="enterMode" min-width="100" label="入场方式">
<el-table-column prop="capTime" min-width="180" label="抓拍时间" />
<el-table-column label="车辆信息">
<el-table-column prop="carDirect" width="120" label="行车方向">
<template #default="{ row }">
<dict-tag :options="dh_enter_Mode" :value="row.enterMode" />
<dict-tag :options="dh_car_direct" :value="row.carDirect" />
</template>
</el-table-column>
<el-table-column prop="enterTime" min-width="180" label="入场时间" />
<el-table-column prop="parseOriginalPicPathEnter" min-width="100" label="抓拍图片">
<el-table-column prop="carColor" width="120" label="车辆颜色">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseOriginalPicPathEnter"
:src="row.parseOriginalPicPathEnter" />
<dict-tag :options="dh_car_color" :value="row.carColor" />
</template>
</el-table-column>
<el-table-column prop="carInnerCategory" width="120" label="车辆进出类型">
<template #default="{ row }">
<dict-tag :options="dh_enter_or_exit" :value="row.carInnerCategory" />
</template>
</el-table-column>
<el-table-column prop="carNum" width="200" label="车牌号码">
<template #default="{ row }">
<div class="flex items-center gap-2">
<dict-tag v-if="row.carNumColor" :options="dh_car_num_color" :value="row.carNumColor" />
<el-tag v-else type="danger">未知</el-tag>
<span>{{ row.carNum }}</span>
</div>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="出场">
<el-table-column prop="exitCarNum" min-width="100" label="出场车牌号" />
<el-table-column prop="exitTime" min-width="180" label="出场时间" />
<el-table-column prop="parseOriginalPicPathExit" min-width="100" label="抓拍图片">
<el-table-column label="人员信息">
<el-table-column prop="ownerId" width="120" label="人员ID" />
<el-table-column prop="ownerCardId" width="120" label="证件号码" />
</el-table-column>
<el-table-column label="抓拍相机">
<el-table-column prop="devId" min-width="100" label="设备编码" />
<el-table-column prop="devName" min-width="100" label="设备名称" />
<el-table-column prop="devChnName" min-width="100" label="通道名称" />
<el-table-column prop="devChnId" min-width="150" label="通道编码" />
</el-table-column>
<el-table-column label="抓拍图片">
<el-table-column min-width="100" label="抓拍图片">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseOriginalPicPathExit"
:src="row.parseOriginalPicPathExit" />
<preview-image width="50px" height="50px" v-if="row.parseCarImgUrl" :src="row.parseCarImgUrl" />
</template>
</el-table-column>
<el-table-column min-width="100" label="车牌图片">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseCarNumPic" :src="row.parseCarNumPic" />
</template>
</el-table-column>
</el-table-column>
</el-table>
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
</el-dialog>
@@ -61,9 +84,11 @@
import { BasicTableProps, useTable } from "/@/hooks/table";
import { useDict } from '/@/hooks/dict';
import * as CarAccessApi from "/@/api/car/carAccess";
// import * as CarAccessApi from "/@/api/car/carAccess";
import * as CarRecordApi from "/@/api/car/carRecord";
const { dh_enter_Mode } = useDict("dh_enter_Mode")
// 定义查询字典
const { dh_car_color, dh_enter_or_exit, dh_car_num_color, dh_car_direct } = useDict("dh_car_color", "dh_enter_or_exit", "dh_car_num_color", "dh_car_direct")
defineExpose({
openDialog
@@ -82,7 +107,7 @@ const state: BasicTableProps = reactive<BasicTableProps>({
},
queryForm: {
},
pageList: CarAccessApi.fetchList
pageList: CarRecordApi.fetchList
})
// table hook
@@ -108,6 +133,8 @@ function openDialog(row: any) {
if (state.queryForm.carNum == "未知") {
state.queryForm.carNum = null
state.queryForm.carNumIsNull = true
} else {
state.queryForm.carNumIsNull = false
}
visible.value = true
getDataList();
@@ -15,10 +15,10 @@
</div>
<div class="flex-1 flex flex-col overflow-hidden video-container">
<el-form :model="queryForm" ref="queryRef" :inline="true" @keyup.enter="initVideo">
<el-form-item style="width: 350px;" label="录像时间段" prop="videoDateList">
<el-date-picker v-model="queryForm.videoDateList" value-format="YYYY-MM-DD" type="daterange"
:disabled-date="disabledDate" placeholder="请选择日期范围" start-placeholder="开始日期"
end-placeholder="结束日期" @change="handleDateChange" />
<el-form-item style="width: 450px;" label="录像时间" prop="videoDateList">
<el-date-picker v-model="queryForm.videoDateList" value-format="YYYY-MM-DD HH:mm:ss"
type="datetimerange" :disabled-date="disabledDate" placeholder="请选择日期范围"
start-placeholder="开始日期" end-placeholder="结束日期" @change="handleDateChange" />
</el-form-item>
<el-form-item style="width: 250px;" label="码流" prop="streamType">
<dict-select v-model="queryForm.streamType" :options="dh_video_stream_type"
@@ -309,8 +309,15 @@ function getDefaultDateRange() {
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
const seconds = String(date.getSeconds()).padStart(2, '0')
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}
// 设置开始时间为三天前的 00:00:00
threeDaysAgo.setHours(0, 0, 0, 0)
// 设置结束时间为今天的 23:59:59
today.setHours(23, 59, 59, 999)
return [formatDate(threeDaysAgo), formatDate(today)]
}
@@ -320,7 +327,7 @@ const handleDateChange = (dates: string[]) => {
const startDate = new Date(dates[0])
const endDate = new Date(dates[1])
const diffTime = Math.abs(endDate.getTime() - startDate.getTime())
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1 // 包含起始日期
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
if (diffDays > 3) {
useMessage().warning('最多只能选择3天的时间范围')
+69 -55
View File
@@ -7,12 +7,8 @@
<el-form-item style="width: 250px;" label="车牌号" prop="carNum">
<el-input v-model="state.queryForm.carNum" placeholder="请输入车牌号" />
</el-form-item>
<el-form-item style="width: 350px;" label="入场时间" prop="enterTimeList">
<el-date-picker v-model="state.queryForm.enterTimeList" value-format="YYYY-MM-DD"
type="daterange" />
</el-form-item>
<el-form-item style="width: 350px;" label="出场时间" prop="exitTimeList">
<el-date-picker v-model="state.queryForm.exitTimeList" value-format="YYYY-MM-DD"
<el-form-item style="width: 350px;" label="抓拍时间" prop="capTimeList">
<el-date-picker v-model="state.queryForm.capTimeList" value-format="YYYY-MM-DD"
type="daterange" />
</el-form-item>
<el-form-item>
@@ -38,46 +34,56 @@
<el-table-column type="index" label="#" width="80" />
<el-table-column v-if="columnSetting['carNum'].visible" prop="carNum" min-width="100"
<el-table-column v-if="columnSetting['carDirect'].visible" prop="carNum" min-width="100"
:label="columnSetting['carDirect'].label">
<template #default="{ row }">
<dict-tag :options="dh_car_direct" :value="row.carDirect" />
</template>
</el-table-column>
<el-table-column v-if="columnSetting['carColor'].visible" prop="enterMode" min-width="100"
:label="columnSetting['carColor'].label">
<template #default="{ row }">
<dict-tag :options="dh_car_color" :value="row.carColor" />
</template>
</el-table-column>
<el-table-column v-if="columnSetting['carInnerCategory'].visible" prop="enterTime" min-width="180"
:label="columnSetting['carInnerCategory'].label">
<template #default="{ row }">
<dict-tag :options="dh_enter_or_exit" :value="row.carInnerCategory" />
</template>
</el-table-column>
<el-table-column v-if="columnSetting['carNum'].visible" prop="parseOriginalPicPathEnter" min-width="200"
:label="columnSetting['carNum'].label">
<template #default="{ row }">
<span v-if="row.carNum && row.enterTime">{{ row.carNum }}</span>
<span v-else class="color-danger">未识别</span>
</template>
</el-table-column>
<el-table-column v-if="columnSetting['enterMode'].visible" prop="enterMode" min-width="100"
:label="columnSetting['enterMode'].label">
<template #default="{ row }">
<dict-tag :options="dh_enter_Mode" :value="row.enterMode" />
</template>
</el-table-column>
<el-table-column v-if="columnSetting['enterTime'].visible" prop="enterTime" min-width="180"
:label="columnSetting['enterTime'].label">
</el-table-column>
<el-table-column v-if="columnSetting['parseOriginalPicPathEnter'].visible"
prop="parseOriginalPicPathEnter" min-width="100"
:label="columnSetting['parseOriginalPicPathEnter'].label">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseOriginalPicPathEnter"
:src="row.parseOriginalPicPathEnter">
</preview-image>
<div class="flex items-center gap-2">
<dict-tag v-if="row.carNumColor" :options="dh_car_num_color" :value="row.carNumColor" />
<el-tag v-else type="danger">未知</el-tag>
<span>{{ row.carNum }}</span>
</div>
</template>
</el-table-column>
<el-table-column v-if="columnSetting['exitCarNum'].visible" prop="exitCarNum" min-width="100"
:label="columnSetting['exitCarNum'].label">
<el-table-column v-if="columnSetting['devName'].visible" prop="exitCarNum" min-width="100"
:label="columnSetting['devName'].label">
</el-table-column>
<el-table-column v-if="columnSetting['exitTime'].visible" prop="exitTime" min-width="180"
:label="columnSetting['exitTime'].label">
<el-table-column v-if="columnSetting['devChnName'].visible" prop="exitTime" min-width="180"
:label="columnSetting['devChnName'].label">
</el-table-column>
<el-table-column v-if="columnSetting['parseOriginalPicPathExit'].visible"
prop="parseOriginalPicPathExit" min-width="100"
:label="columnSetting['parseOriginalPicPathExit'].label">
<el-table-column v-if="columnSetting['parseCarImgUrl'].visible" prop="parseOriginalPicPathExit"
min-width="100" :label="columnSetting['parseCarImgUrl'].label">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseOriginalPicPathExit"
:src="row.parseOriginalPicPathExit" />
<preview-image width="50px" height="50px" v-if="row.parseCarImgUrl" :src="row.parseCarImgUrl" />
</template>
</el-table-column>
<el-table-column v-if="columnSetting['parseCarNumPic'].visible" prop="parseOriginalPicPathExit"
min-width="100" :label="columnSetting['parseCarNumPic'].label">
<template #default="{ row }">
<preview-image width="50px" height="50px" v-if="row.parseCarNumPic" :src="row.parseCarNumPic" />
</template>
</el-table-column>
<el-table-column v-if="columnSetting['capTime'].visible" prop="capTime" min-width="180"
:label="columnSetting['capTime'].label" />
</el-table>
@@ -93,7 +99,7 @@ import { fetchList, delObjs } from "/@/api/door/doorRecord";
import { useMessage, useMessageBox } from "/@/hooks/message";
import { useDict } from '/@/hooks/dict';
import * as CarAccessApi from "/@/api/car/carAccess";
import * as CarRecordApi from "/@/api/car/carRecord";
// 搜索变量
const queryRef = ref()
@@ -104,35 +110,43 @@ const selectObjs = ref([]) as any
const multiple = ref(true)
// 定义查询字典
const { dh_enter_Mode } = useDict('dh_enter_Mode');
const { dh_car_color, dh_enter_or_exit, dh_car_num_color, dh_car_direct } = useDict("dh_car_color", "dh_enter_or_exit", "dh_car_num_color", "dh_car_direct")
const columnSetting = ref({
carDirect: {
label: "行车方向",
visible: true
},
carColor: {
label: "车辆颜色",
visible: true
},
carInnerCategory: {
label: "车辆进出类型",
visible: true
},
carNum: {
label: "入场车牌号",
label: "车牌号码",
visible: true
},
enterMode: {
label: "入场方式",
devName: {
label: "设备-名称",
visible: true
},
enterTime: {
label: "入场时间",
devChnName: {
label: "设备-通道名称",
visible: true
},
parseOriginalPicPathEnter: {
label: "入场抓拍图片",
parseCarImgUrl: {
label: "抓拍图片",
visible: true
},
exitCarNum: {
label: "出场车牌号",
parseCarNumPic: {
label: "车牌图片",
visible: true
},
exitTime: {
label: "出场时间",
visible: true
},
parseOriginalPicPathExit: {
label: "出场抓拍图片",
capTime: {
label: "抓拍时间",
visible: true
}
})
@@ -143,7 +157,7 @@ const state: BasicTableProps = reactive<BasicTableProps>({
size: 20,
pageSizes: [20, 50, 100, 500, 1000, 2000]
},
pageList: CarAccessApi.fetchList
pageList: CarRecordApi.fetchList
})
// table hook
@@ -182,7 +196,7 @@ const selectionChangHandle = (objs: { id: string }[]) => {
const exportExcel = () => {
// @ts-ignore
const keys = Object.keys(columnSetting.value).filter(key => columnSetting.value[key].visible)
downBlobFile('/admin/car/carAccess/export', {
downBlobFile('/admin/car/carRecord/export', {
...state.queryForm,
current: state.pagination?.current,
size: state.pagination?.size,