2025-12-24 18:19:05 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="content-container">
|
|
|
|
|
|
<!-- 识别记录数据 -->
|
|
|
|
|
|
<div class="identificate-index">
|
|
|
|
|
|
<FilterCom ref="Filter" :filter-buttons="filterButtons" :filter-items="items" :filter-model="model" @handle="handle"/>
|
|
|
|
|
|
<!-- 多选框筛选 -->
|
|
|
|
|
|
<div class="Form">
|
|
|
|
|
|
<!-- 暂时只支持单个类型的筛选 -->
|
|
|
|
|
|
<!-- <el-checkbox-group v-model="illegalType" :max="1">
|
|
|
|
|
|
<el-checkbox
|
|
|
|
|
|
v-for="item in illegalTypes"
|
|
|
|
|
|
:key="item.value"
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
:value="item.value" />
|
|
|
|
|
|
</el-checkbox-group> -->
|
|
|
|
|
|
<el-radio-group v-model="illegalType" @change="changeRadio">
|
|
|
|
|
|
<el-radio v-for="item in illegalTypes"
|
|
|
|
|
|
:key="item.value"
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
:value="item.value" ></el-radio>
|
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- 表格数据 -->
|
|
|
|
|
|
<TableComponent style="height: 616px;" :loading="loading" :data="tableData" :columns="columns" :config="config" :operate="operate" @handle="handle"/>
|
|
|
|
|
|
<el-pagination
|
|
|
|
|
|
v-model:current-page="pagination.current"
|
|
|
|
|
|
v-model:page-size="pagination.size"
|
|
|
|
|
|
:total="pagination.total"
|
|
|
|
|
|
:page-sizes="[ 10, 15, 20, 50 ]"
|
|
|
|
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
|
|
@size-change="initData"
|
|
|
|
|
|
@current-change="initData"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- 数据详情 -->
|
|
|
|
|
|
<div class="identificate-detail">
|
|
|
|
|
|
<div class="detail-item" v-for="item in detail.data" :key="item.id">
|
|
|
|
|
|
<TitleComponent :title="item.videoName"/>
|
|
|
|
|
|
<div class="detail">
|
|
|
|
|
|
<el-image
|
|
|
|
|
|
v-if="item.trackerPicPath.length>0"
|
|
|
|
|
|
:src="item.trackerPicPath[0]"
|
|
|
|
|
|
:zoom-rate="1.2"
|
|
|
|
|
|
:max-scale="7"
|
|
|
|
|
|
:min-scale="0.2"
|
|
|
|
|
|
:scale="0.8"
|
|
|
|
|
|
:preview-src-list="item.trackerPicPath"
|
|
|
|
|
|
show-progress
|
|
|
|
|
|
/>
|
|
|
|
|
|
<div class="none" v-else>暂无图片</div>
|
|
|
|
|
|
<div class="half">
|
|
|
|
|
|
<div class="boatName">{{detail.boatName}}</div>
|
|
|
|
|
|
<div class="col" v-for="col in detail.columns.slice(0,5)" :key="col.value">
|
|
|
|
|
|
<span class="label">{{ col.label }}:</span>
|
|
|
|
|
|
<span class="value">{{ item[col.prop] }}{{ col.unit }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="row">
|
|
|
|
|
|
<div class="col" v-for="col in detail.columns.slice(5)" :key="col.value">
|
|
|
|
|
|
<span class="label">{{ col.label }}:</span>
|
|
|
|
|
|
<span class="value">{{ item[col.prop] }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="row process-title">
|
|
|
|
|
|
<div class="col">
|
|
|
|
|
|
<span class="label">过程分析:</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="play-back-wrapper"
|
|
|
|
|
|
:class="[`video-window0`]">
|
|
|
|
|
|
<HikPlayerBackCom
|
|
|
|
|
|
ref="appPlayer"
|
|
|
|
|
|
v-if="detail.code"
|
|
|
|
|
|
:cameraIndexCode="detail.code"
|
|
|
|
|
|
videoWindowClassName="play-back-wrapper"
|
|
|
|
|
|
@close="closeVideo"/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<DialogComponent v-if="edit.visible" title="编辑" :modal="true" width="800"
|
|
|
|
|
|
@close="closeDetail">
|
|
|
|
|
|
<DetailComponent :data="edit.data" @close="closeDetail" />
|
|
|
|
|
|
</DialogComponent>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
import FilterCom from '@/components/Filter/index.vue'
|
|
|
|
|
|
import { nextTick, onBeforeUnmount, onMounted, onUnmounted, reactive, ref } from 'vue'
|
|
|
|
|
|
import TableComponent from '@/components/Table/index2.vue'
|
|
|
|
|
|
import TitleComponent from '@/components/Title/index.vue'
|
2025-12-25 18:33:15 +08:00
|
|
|
|
import { videoIdentificationPage, removeVideoIdentification } from '@/api/identification.js'
|
2025-12-24 18:19:05 +08:00
|
|
|
|
import HikPlayerBackCom from '@/components/Player/HikPlayer-back.vue'
|
|
|
|
|
|
import { dayjs, ElMessage, ElMessageBox } from 'element-plus'
|
|
|
|
|
|
import { useRoute } from 'vue-router'
|
|
|
|
|
|
import DialogComponent from '@/components/Dialog/screen.vue'
|
|
|
|
|
|
import DetailComponent from './detail.vue'
|
|
|
|
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
|
const illegalTypes = [
|
|
|
|
|
|
{ value: '未封舱预警', label: '未封舱预警', prop: 'warning' },
|
|
|
|
|
|
{ value: '未穿救生衣预警', label: '未穿救生衣预警', prop: 'warning' },
|
|
|
|
|
|
{ value: '吃水线预警', label: '吃水线预警', prop: 'yellow' },
|
|
|
|
|
|
{ value: '人员落水协助', label: '人员落水协助', prop: 'primary' },
|
|
|
|
|
|
{ value: '未悬挂国旗', label: '未悬挂国旗', prop: 'primary' },
|
|
|
|
|
|
{ value: '异常停靠预警', label: '异常停靠预警', prop: 'yellow' },
|
|
|
|
|
|
{ value: '船只漏油预警', label: '船只漏油预警', prop: 'warning' },
|
|
|
|
|
|
{ value: '船舶火灾预警', label: '船舶火灾预警', prop: 'danger' },
|
|
|
|
|
|
{ value: '超速预警', label: '超速预警', prop: 'primary' },
|
|
|
|
|
|
{ value: '偏航预警', label: '偏航预警', prop: 'yellow' }
|
|
|
|
|
|
]
|
|
|
|
|
|
const Filter = ref(null)
|
|
|
|
|
|
const items = ref([
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '抓拍时间',
|
|
|
|
|
|
prop: 'time',
|
|
|
|
|
|
type: 'datetimerange'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '船型',
|
|
|
|
|
|
prop: 'shipType',
|
|
|
|
|
|
type: 'select',
|
|
|
|
|
|
options: [ {
|
|
|
|
|
|
label: '集装箱船',
|
|
|
|
|
|
value: '集装箱船'
|
|
|
|
|
|
}, {
|
|
|
|
|
|
label: '液货船',
|
|
|
|
|
|
value: '液货船'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '散杂货船',
|
|
|
|
|
|
value: '散杂货船'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '客渡船',
|
|
|
|
|
|
value: '客渡船'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '渔船',
|
|
|
|
|
|
value: '渔船'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '公务船',
|
|
|
|
|
|
value: '公务船'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '引航船',
|
|
|
|
|
|
value: '引航船'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '拖轮',
|
|
|
|
|
|
value: '拖轮'
|
|
|
|
|
|
} ]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '船牌名称',
|
|
|
|
|
|
prop: 'boatName',
|
|
|
|
|
|
type: 'input'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '抓拍类型',
|
|
|
|
|
|
prop: 'takeType',
|
|
|
|
|
|
type: 'select',
|
|
|
|
|
|
options: [
|
|
|
|
|
|
{ value: '', label: '全部' },
|
|
|
|
|
|
{ value: '无人机', label: '无人机' },
|
|
|
|
|
|
{ value: '卡口', label: '卡口' }
|
|
|
|
|
|
],
|
|
|
|
|
|
emptyValues: [ null, undefined ],
|
|
|
|
|
|
valueOnClear: null
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '抓拍设备',
|
|
|
|
|
|
prop: 'videoName',
|
|
|
|
|
|
type: 'input'
|
|
|
|
|
|
}
|
|
|
|
|
|
])
|
|
|
|
|
|
const filterButtons = ref([
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '检索',
|
|
|
|
|
|
prop: 'query',
|
|
|
|
|
|
theme: 'primary',
|
|
|
|
|
|
type: 'button'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '重置',
|
|
|
|
|
|
prop: 'reset',
|
|
|
|
|
|
theme: 'primary',
|
|
|
|
|
|
type: 'button'
|
|
|
|
|
|
}
|
|
|
|
|
|
])
|
|
|
|
|
|
const resetModel = reactive({
|
|
|
|
|
|
time: [ null, null ],
|
|
|
|
|
|
shipType: '',
|
|
|
|
|
|
boatName: '',
|
|
|
|
|
|
takeType: '',
|
|
|
|
|
|
videoName: ''
|
|
|
|
|
|
})
|
|
|
|
|
|
const model = reactive({
|
|
|
|
|
|
time: [ null, null ],
|
|
|
|
|
|
shipType: '',
|
|
|
|
|
|
boatName: '',
|
|
|
|
|
|
takeType: '',
|
|
|
|
|
|
videoName: ''
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const illegalType = ref('')
|
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
|
const tableData = ref([])
|
|
|
|
|
|
const columns = ref([
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '抓拍时间',
|
|
|
|
|
|
prop: 'takeTime',
|
|
|
|
|
|
width: 190
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '船牌名称',
|
|
|
|
|
|
prop: 'boatName',
|
|
|
|
|
|
width: 120
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '船型',
|
|
|
|
|
|
prop: 'shipType',
|
|
|
|
|
|
width: 80
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '是否有AIS信号',
|
|
|
|
|
|
prop: 'isHasAis',
|
|
|
|
|
|
width: 120
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: 'MMSI',
|
|
|
|
|
|
prop: 'mmsi',
|
|
|
|
|
|
width: 100
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '违规类型',
|
|
|
|
|
|
prop: 'illegalType',
|
|
|
|
|
|
width: 310,
|
|
|
|
|
|
sign: true,
|
|
|
|
|
|
tooltip: false
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '抓拍设备',
|
|
|
|
|
|
prop: 'videoName',
|
|
|
|
|
|
width: 160
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '抓拍类型',
|
|
|
|
|
|
prop: 'takeType',
|
|
|
|
|
|
width: 80
|
|
|
|
|
|
}
|
|
|
|
|
|
])
|
|
|
|
|
|
const config = {
|
|
|
|
|
|
label: '操作',
|
|
|
|
|
|
// width: 60
|
|
|
|
|
|
width: 150
|
|
|
|
|
|
}
|
|
|
|
|
|
const operate = [
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '查看',
|
|
|
|
|
|
prop: 'check',
|
|
|
|
|
|
theme: 'text'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '编辑',
|
|
|
|
|
|
prop: 'edit',
|
|
|
|
|
|
theme: 'text'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '删除',
|
|
|
|
|
|
prop: 'delete',
|
|
|
|
|
|
theme: 'danger'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
const pagination = reactive({
|
|
|
|
|
|
current: 1,
|
|
|
|
|
|
size: 15,
|
|
|
|
|
|
total: 0
|
|
|
|
|
|
})
|
|
|
|
|
|
const detail = reactive({
|
|
|
|
|
|
boatName: '',
|
|
|
|
|
|
columns: [
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '船型',
|
|
|
|
|
|
prop: 'shipType'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '名称',
|
|
|
|
|
|
prop: 'boatNameEn'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '船长',
|
|
|
|
|
|
prop: 'length',
|
|
|
|
|
|
unit: 'm'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '航速',
|
|
|
|
|
|
prop: 'speed',
|
|
|
|
|
|
unit: '节'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '船宽',
|
|
|
|
|
|
prop: 'width',
|
|
|
|
|
|
unit: 'm'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: 'MMSI',
|
|
|
|
|
|
prop: 'mmsi'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '方向',
|
|
|
|
|
|
prop: 'entryOut'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '抓拍类型',
|
|
|
|
|
|
prop: 'takeType'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '时间',
|
|
|
|
|
|
prop: 'takeTime'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: 'AIS状态',
|
|
|
|
|
|
prop: 'aisStatus'
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
|
|
|
|
|
data: [],
|
|
|
|
|
|
code: ''
|
|
|
|
|
|
})
|
|
|
|
|
|
const appPlayer = ref(null)
|
|
|
|
|
|
const edit = reactive({
|
|
|
|
|
|
visible: false,
|
|
|
|
|
|
data: {}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const initData = () => {
|
|
|
|
|
|
loading.value = true
|
2025-12-25 18:33:15 +08:00
|
|
|
|
// const params = new FormData()
|
|
|
|
|
|
// const obj = {
|
|
|
|
|
|
// ...model,
|
|
|
|
|
|
// // illegalType: illegalType.value.join(','),
|
|
|
|
|
|
// illegalType: illegalType.value,
|
|
|
|
|
|
// beginTime: model.time && model.time[0] ? model.time[0] : '',
|
|
|
|
|
|
// endTime: model.time && model.time[1] ? model.time[1] : '',
|
|
|
|
|
|
// pageNo: pagination.current,
|
|
|
|
|
|
// pageSize: pagination.size
|
|
|
|
|
|
// }
|
|
|
|
|
|
// delete obj.time
|
|
|
|
|
|
// Object.keys(obj).forEach((key) => {
|
|
|
|
|
|
// params.append(key, obj[key])
|
|
|
|
|
|
// })
|
2025-12-24 18:19:05 +08:00
|
|
|
|
// videoIdentificationPage(params).then(res => {
|
|
|
|
|
|
// if (res.success) {
|
|
|
|
|
|
// tableData.value = res.result.records.map(i => {
|
|
|
|
|
|
// return {
|
|
|
|
|
|
// ...i,
|
|
|
|
|
|
// illegalType: i.illegalType.split(',').map(j => {
|
|
|
|
|
|
// return {
|
|
|
|
|
|
// value: illegalTypes.find(type => type.value === j)?.prop,
|
|
|
|
|
|
// label: j
|
|
|
|
|
|
// }
|
|
|
|
|
|
// })
|
|
|
|
|
|
// }
|
|
|
|
|
|
// })
|
|
|
|
|
|
// pagination.total = res.result.total
|
|
|
|
|
|
// // 有识别记录数据,默认查看第一条详情
|
|
|
|
|
|
// handle('check', res.result.total > 0 ? tableData.value[0] : {})
|
|
|
|
|
|
// } else {
|
2025-12-25 18:33:15 +08:00
|
|
|
|
// ElMessage.error(res.msg || '查询失败!')
|
2025-12-24 18:19:05 +08:00
|
|
|
|
// }
|
|
|
|
|
|
// }).finally(() => {
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
// })
|
|
|
|
|
|
tableData.value = [
|
|
|
|
|
|
{
|
|
|
|
|
|
'aisStatus': '未开启',
|
|
|
|
|
|
'belongPort': '',
|
|
|
|
|
|
'boatCodePath': '',
|
|
|
|
|
|
'boatName': '浙周田货0998',
|
|
|
|
|
|
'boatNameEn': 'WUCHUANHAO',
|
|
|
|
|
|
'cog': '0',
|
|
|
|
|
|
'createAt': '2025-12-01 11:04:44',
|
|
|
|
|
|
'createBy': '',
|
|
|
|
|
|
'crossLineTime': null,
|
|
|
|
|
|
'delFlag': 0,
|
|
|
|
|
|
'distance': null,
|
|
|
|
|
|
'draftMarks': null,
|
|
|
|
|
|
'entryOut': '',
|
|
|
|
|
|
'height': 0.00000000,
|
|
|
|
|
|
'heightRange': '',
|
|
|
|
|
|
'hkResult': '',
|
|
|
|
|
|
'id': 76168,
|
|
|
|
|
|
'identificationType': '',
|
|
|
|
|
|
'illegalType': '未穿救生衣预警,未封舱预警,未悬挂国旗',
|
|
|
|
|
|
'isCloseDoor': '否',
|
|
|
|
|
|
'isHasAis': '否',
|
|
|
|
|
|
'jacketStatus': '',
|
|
|
|
|
|
'latitude': null,
|
|
|
|
|
|
'length': 0.00000000,
|
|
|
|
|
|
'longitude': null,
|
|
|
|
|
|
'mmsi': '413823183',
|
|
|
|
|
|
'shipType': '集装箱船',
|
|
|
|
|
|
'sourcePicPath': 'http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_1_20251201_110559_644.jpg',
|
|
|
|
|
|
'speed': null,
|
|
|
|
|
|
'streetName': '',
|
|
|
|
|
|
'sysShipName': '',
|
|
|
|
|
|
'sysUpdateName': '',
|
|
|
|
|
|
'systemResult': '',
|
|
|
|
|
|
'takeTime': '2025-12-23 11:06:08',
|
|
|
|
|
|
'takeType': '卡口',
|
|
|
|
|
|
'trackerPicPath': 'http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_1_20251201_110559_644.jpg,http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_2_20251201_110603_161.jpg,http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_3_20251201_110605_535.jpg,http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_4_20251201_110608_298.jpg',
|
|
|
|
|
|
'updateAt': '2025-12-01 11:04:44',
|
|
|
|
|
|
'updateBy': '',
|
|
|
|
|
|
'videoCode': 'fd3b45e1429a4e47bba873af602a9bed',
|
|
|
|
|
|
'videoName': '卧旗--雷云一体机',
|
|
|
|
|
|
'videoUrl': '',
|
|
|
|
|
|
'width': 0.00000000
|
|
|
|
|
|
}, {}
|
|
|
|
|
|
].map(i => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
...i,
|
|
|
|
|
|
illegalType: i.illegalType?.split(',').map(j => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
value: illegalTypes.find(type => type.value === j)?.prop,
|
|
|
|
|
|
label: j
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
handle('check', tableData.value.length > 0 ? tableData.value[0] : {})
|
|
|
|
|
|
}
|
|
|
|
|
|
const changeRadio = () => {
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
Object.keys(model).forEach(key => {
|
|
|
|
|
|
model[key] = Filter.value.model[key]
|
|
|
|
|
|
})
|
|
|
|
|
|
pagination.current = 1
|
|
|
|
|
|
initData()
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 按钮操作
|
|
|
|
|
|
* @param type 操作类型
|
|
|
|
|
|
* @param data 数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
const handle = (type, data) => {
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
|
case 'query':
|
|
|
|
|
|
Object.keys(model).forEach(key => {
|
|
|
|
|
|
model[key] = data[key]
|
|
|
|
|
|
})
|
|
|
|
|
|
pagination.current = 1
|
|
|
|
|
|
initData()
|
|
|
|
|
|
break
|
|
|
|
|
|
case 'reset': {
|
|
|
|
|
|
Object.keys(resetModel).forEach(i => {
|
|
|
|
|
|
model[i] = resetModel[i]
|
|
|
|
|
|
})
|
|
|
|
|
|
illegalType.value = ''
|
|
|
|
|
|
Filter.value.reset()
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
case 'check': {
|
|
|
|
|
|
closeVideo()
|
|
|
|
|
|
detail.data = [ { ...data,
|
|
|
|
|
|
videoName: '',
|
|
|
|
|
|
trackerPicPath: data.trackerPicPath.split(',')
|
|
|
|
|
|
} ]
|
|
|
|
|
|
detail.boatName = data.boatName
|
|
|
|
|
|
detail.code = data.videoCode
|
|
|
|
|
|
// 设置播放结束时间
|
|
|
|
|
|
let startTime = new Date(dayjs(data.takeTime).subtract(1.5, 'minute').format('YYYY-MM-DD HH:mm:ss'))
|
|
|
|
|
|
let endTime = new Date(dayjs(data.takeTime).add(1.5, 'minute').format('YYYY-MM-DD HH:mm:ss'))
|
|
|
|
|
|
startTime.setMinutes(startTime.getMinutes())
|
|
|
|
|
|
endTime.setMinutes(endTime.getMinutes())
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
appPlayer.value[0].ready().then(() => {
|
|
|
|
|
|
appPlayer.value[0].playBack(
|
|
|
|
|
|
detail.code,
|
|
|
|
|
|
new Date(startTime),
|
|
|
|
|
|
new Date(endTime)
|
|
|
|
|
|
)
|
|
|
|
|
|
})
|
|
|
|
|
|
}, 500)
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
case 'edit':
|
|
|
|
|
|
edit.data = { ...data }
|
|
|
|
|
|
edit.visible = true
|
|
|
|
|
|
break
|
|
|
|
|
|
case 'delete':
|
|
|
|
|
|
ElMessageBox.confirm('是否删除该条数据?', '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
}).then(() => {
|
2025-12-25 18:33:15 +08:00
|
|
|
|
removeVideoIdentification({ id: data.id }).then(() => {
|
|
|
|
|
|
ElMessage.success('删除成功')
|
|
|
|
|
|
initData()
|
|
|
|
|
|
})
|
2025-12-24 18:19:05 +08:00
|
|
|
|
})
|
|
|
|
|
|
break
|
|
|
|
|
|
default:
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
const closeVideo = () => {
|
|
|
|
|
|
if(appPlayer.value && appPlayer.value.length > 0) {
|
|
|
|
|
|
detail.code = ''
|
|
|
|
|
|
appPlayer.value[0].uninit()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 关闭详情弹窗
|
|
|
|
|
|
* @param refresh 是否刷新数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
const closeDetail = () => {
|
|
|
|
|
|
edit.visible = false
|
|
|
|
|
|
initData()
|
|
|
|
|
|
}
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
if(Object.keys(route.query).length > 0 && route.query.type === 'alarm') {
|
|
|
|
|
|
model.takeType = route.query.takeType
|
|
|
|
|
|
illegalType.value = route.query.illegalType
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
if (Filter.value && Filter.value.model) {
|
|
|
|
|
|
Filter.value.model.takeType = route.query.takeType
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
initData()
|
|
|
|
|
|
})
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
|
|
closeVideo()
|
|
|
|
|
|
|
|
|
|
|
|
})
|
2025-12-25 18:33:15 +08:00
|
|
|
|
defineExpose({
|
|
|
|
|
|
appPlayer
|
|
|
|
|
|
})
|
2025-12-24 18:19:05 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
.content-container{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
height: 812px;
|
|
|
|
|
|
.identificate-index{
|
|
|
|
|
|
width: 1200px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
.line{
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 0px;
|
|
|
|
|
|
border-radius: 0px 0px 0px 0px;
|
|
|
|
|
|
border: 1px solid rgba(0,192,255,0.2);
|
|
|
|
|
|
margin: 8px 0 15px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
:deep .filter{
|
|
|
|
|
|
.el-form-item:last-child{
|
|
|
|
|
|
.el-input{
|
|
|
|
|
|
width: 180px !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 分页器样式
|
|
|
|
|
|
.el-pagination{
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
margin-top: 24px;
|
|
|
|
|
|
font-size: 12px ;
|
|
|
|
|
|
color: #6281A8;
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
// 选项条数
|
|
|
|
|
|
:deep(.el-pagination__sizes){
|
|
|
|
|
|
margin-left: 0;
|
|
|
|
|
|
.el-select{
|
|
|
|
|
|
width: 96px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.el-select__wrapper{
|
|
|
|
|
|
width: 96px;
|
|
|
|
|
|
min-height: 24px;
|
|
|
|
|
|
background: #093369;
|
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
.el-select__placeholder,.el-select__caret{
|
|
|
|
|
|
color: #BAE7FF;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 页数
|
|
|
|
|
|
:deep(.el-pager){
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
// 选中当前页
|
|
|
|
|
|
.is-active{
|
|
|
|
|
|
background: #033E8C;
|
|
|
|
|
|
border: 1px solid #128CE4;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
:deep(.btn-prev),:deep(.el-pager .number),:deep(.btn-next),:deep(.more){
|
|
|
|
|
|
background: #093369;
|
|
|
|
|
|
min-width: 24px;
|
|
|
|
|
|
height: 24px;
|
|
|
|
|
|
color: #BAE7FF;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
margin-left: 0 !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
:deep(.el-pagination__jump){
|
|
|
|
|
|
margin-left: 0;
|
|
|
|
|
|
.el-input{
|
|
|
|
|
|
// width: 32px;
|
|
|
|
|
|
height: 24px;
|
|
|
|
|
|
.el-input__wrapper{
|
|
|
|
|
|
background: #093369;
|
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
|
height: 24px;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
.el-input__inner{
|
|
|
|
|
|
color: #BAE7FF;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
:deep(.el-pagination__goto){
|
|
|
|
|
|
margin-right: 6px;
|
|
|
|
|
|
}
|
|
|
|
|
|
:deep(.el-pagination__classifier){
|
|
|
|
|
|
margin-left: 6px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.identificate-detail{
|
|
|
|
|
|
width: 545px;
|
|
|
|
|
|
height: 802px;
|
|
|
|
|
|
overflow: auto;
|
|
|
|
|
|
// 单个设备抓拍详情
|
|
|
|
|
|
.detail-item{
|
|
|
|
|
|
.detail{
|
|
|
|
|
|
margin: 10px 0 16px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
.el-image,.none{
|
|
|
|
|
|
width: 159px;
|
|
|
|
|
|
height: 105px;
|
|
|
|
|
|
border: 1px solid #2C75A8;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
margin-right: 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.none{
|
|
|
|
|
|
line-height: 105px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.half,.row{
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: 1fr 1fr; // 两列等宽
|
|
|
|
|
|
gap: 10px 0;
|
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
font-family: 'PingFangMedium';
|
|
|
|
|
|
.boatName{
|
|
|
|
|
|
grid-column: 1 / -1;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
color: #FFFFFF;
|
|
|
|
|
|
}
|
|
|
|
|
|
.col{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
.label {
|
|
|
|
|
|
width: 70px;
|
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #00C0FF;
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
.value {
|
|
|
|
|
|
flex: 1; // 自适应剩余空间
|
|
|
|
|
|
white-space: nowrap; // 不换行
|
|
|
|
|
|
overflow: hidden; // 超出隐藏
|
|
|
|
|
|
text-overflow: ellipsis; // 省略号显示
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.row .col{
|
|
|
|
|
|
.label{
|
|
|
|
|
|
width: 100px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.process-title{
|
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
video,.none-video{
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
width: 273px;
|
|
|
|
|
|
height: 150px;
|
|
|
|
|
|
object-fit: cover;
|
|
|
|
|
|
border: 1px solid #2C75A8;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
margin: 10px 0 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.none-video{
|
|
|
|
|
|
line-height: 150px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.play-back-wrapper{
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 300px;
|
|
|
|
|
|
margin: 10px 0 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|