first commit
This commit is contained in:
256
src/views/business/identification/alarm/detail.vue
Normal file
256
src/views/business/identification/alarm/detail.vue
Normal file
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<el-form class="Form detail-form" ref="form" :model="model" label-width="auto" :rules="rules" label-suffix=":">
|
||||
<el-form-item v-for="(item,index) in items" :key="index" :label="item.label" :prop="item.prop" :style="`grid-column-start: span ${item.width || '1'};`">
|
||||
<el-input v-if="item.type === 'input'" v-model="model[item.prop]" />
|
||||
<el-input v-if="item.type === 'textarea'" autosize v-model="model[item.prop]" :rows="item.rows || 2" type="textarea" />
|
||||
<el-input-number v-if="item.type === 'number'" v-model="model[item.prop]" :min="0" style="width: 100%;"/>
|
||||
|
||||
<el-select
|
||||
v-if="item.type === 'select'"
|
||||
v-model="model[item.prop]"
|
||||
:clearable="item.clearable"
|
||||
:multiple="item.multiple"
|
||||
>
|
||||
<el-option
|
||||
v-for="(opt, index) in item.options"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
|
||||
<el-date-picker v-if="item.type === 'datetime'" v-model="model[item.prop]" type="datetime"
|
||||
:placeholder="item.placeholder ? item.placeholder : '请选择时间'" value-format="YYYY-MM-DD HH:mm:ss"
|
||||
:clearable="item.clearable" style="width:100%">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="button-wrapper">
|
||||
<el-button type="primary" @click="validate">提交</el-button>
|
||||
<el-button @click="$emit('close')">取消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
// import { updateVideoIdentification } from '@/api/identification.js'
|
||||
|
||||
const emit = defineEmits([ 'close' ])
|
||||
const props = defineProps({
|
||||
data: {
|
||||
default() {
|
||||
return {}
|
||||
},
|
||||
required: false,
|
||||
type: Object
|
||||
}
|
||||
})
|
||||
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 form = ref(null)
|
||||
|
||||
const model = reactive({
|
||||
boatName: '',
|
||||
shipType: '',
|
||||
boatNameEn: '',
|
||||
length: 0,
|
||||
speed: 0,
|
||||
width: 0,
|
||||
mmsi: '',
|
||||
entryOut: '',
|
||||
takeType: '',
|
||||
takeTime: '',
|
||||
aisStatus: '',
|
||||
videoName: '',
|
||||
illegalType: [],
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const items = ref([
|
||||
{
|
||||
label: '船牌名称',
|
||||
prop: 'boatName',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '名称',
|
||||
prop: 'boatNameEn',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '抓拍类型',
|
||||
prop: 'takeType',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: '无人机', label: '无人机' },
|
||||
{ value: '卡口', label: '卡口' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '抓拍设备',
|
||||
prop: 'videoName',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '船型',
|
||||
prop: 'shipType',
|
||||
type: 'select',
|
||||
options: [ {
|
||||
label: '集装箱船',
|
||||
value: '集装箱船'
|
||||
}, {
|
||||
label: '液货船',
|
||||
value: '液货船'
|
||||
},
|
||||
{
|
||||
label: '散杂货船',
|
||||
value: '散杂货船'
|
||||
},
|
||||
{
|
||||
label: '客渡船',
|
||||
value: '客渡船'
|
||||
},
|
||||
{
|
||||
label: '渔船',
|
||||
value: '渔船'
|
||||
},
|
||||
{
|
||||
label: '公务船',
|
||||
value: '公务船'
|
||||
},
|
||||
{
|
||||
label: '引航船',
|
||||
value: '引航船'
|
||||
},
|
||||
{
|
||||
label: '拖轮',
|
||||
value: '拖轮'
|
||||
} ]
|
||||
},
|
||||
{
|
||||
label: '船长(m)',
|
||||
prop: 'length',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
label: '航速(节)',
|
||||
prop: 'speed',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
label: '船宽(m)',
|
||||
prop: 'width',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
label: 'MMSI',
|
||||
prop: 'mmsi',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '方向',
|
||||
prop: 'entryOut',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '时间',
|
||||
prop: 'takeTime',
|
||||
type: 'datetime'
|
||||
},
|
||||
{
|
||||
label: '是否有AIS信号',
|
||||
prop: 'isHasAis',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: 'AIS状态',
|
||||
prop: 'aisStatus',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '违规类型',
|
||||
prop: 'illegalType',
|
||||
type: 'select',
|
||||
multiple: true,
|
||||
options: illegalTypes
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
prop: 'remark',
|
||||
type: 'textarea',
|
||||
width: 2
|
||||
}
|
||||
])
|
||||
|
||||
const rules = {
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化赋值
|
||||
*/
|
||||
const initData = () => {
|
||||
Object.keys(props.data).forEach((key) => {
|
||||
model[key] = props.data[key]
|
||||
if(key === 'illegalType') {
|
||||
model[key] = props.data[key].map(i => i.label)
|
||||
console.log(model[key])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单校验
|
||||
*/
|
||||
const validate = () => {
|
||||
form.value.validate().then((valid) => {
|
||||
if (valid) {
|
||||
submit()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单校验
|
||||
*/
|
||||
const submit = () => {
|
||||
const params = {
|
||||
...model,
|
||||
illegalType: model.illegalType.join(',')
|
||||
}
|
||||
// updateVideoIdentification(params).then(res => {
|
||||
// ElMessage.success(res.msg)
|
||||
// emit('close', true)
|
||||
// })
|
||||
|
||||
}
|
||||
|
||||
initData()
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.detail-form{
|
||||
display: grid;
|
||||
box-sizing: border-box;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
column-gap: 20px;
|
||||
}
|
||||
|
||||
.button-wrapper{
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
}
|
||||
</style>
|
||||
713
src/views/business/identification/alarm/index.vue
Normal file
713
src/views/business/identification/alarm/index.vue
Normal file
@@ -0,0 +1,713 @@
|
||||
<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'
|
||||
// import { videoIdentificationPage, removeVideoIdentification } from '@/api/identification.js'
|
||||
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
|
||||
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])
|
||||
})
|
||||
// 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 {
|
||||
// Message.error(res.msg || '查询失败!')
|
||||
// }
|
||||
// }).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()
|
||||
console.log(data, 'datatata')
|
||||
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(() => {
|
||||
// removeVideoIdentification({ id: data.id }).then(() => {
|
||||
// ElMessage.success('删除成功')
|
||||
// initData()
|
||||
// })
|
||||
})
|
||||
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()
|
||||
|
||||
})
|
||||
</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>
|
||||
477
src/views/business/identification/config.js
Normal file
477
src/views/business/identification/config.js
Normal file
@@ -0,0 +1,477 @@
|
||||
// 船牌号识别
|
||||
const shipPlate = {
|
||||
items: [
|
||||
{
|
||||
label: '抓拍时间',
|
||||
prop: 'time',
|
||||
type: 'datetimerange'
|
||||
},
|
||||
{
|
||||
label: '识别类型',
|
||||
prop: 'identifyType',
|
||||
type: 'select',
|
||||
options: [ {
|
||||
label: '全部',
|
||||
value: ''
|
||||
}, {
|
||||
label: '船牌识别',
|
||||
value: '船牌识别'
|
||||
},
|
||||
{
|
||||
label: '船型识别',
|
||||
value: '船型识别'
|
||||
} ],
|
||||
event: 'select'
|
||||
},
|
||||
{
|
||||
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'
|
||||
}
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
label: '抓拍时间',
|
||||
prop: 'takeTime',
|
||||
width: 170
|
||||
},
|
||||
{
|
||||
label: '船牌名称',
|
||||
prop: 'boatName',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
label: '船型',
|
||||
prop: 'shipType',
|
||||
width: 70
|
||||
},
|
||||
{
|
||||
label: '抓拍类型',
|
||||
prop: 'takeType',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
label: '抓拍设备',
|
||||
prop: 'videoName',
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
label: '是否有AIS信号',
|
||||
prop: 'isHasAis',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
label: 'MMSI',
|
||||
prop: 'mmsi',
|
||||
width: 120
|
||||
}
|
||||
],
|
||||
detailColumns: [
|
||||
{
|
||||
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'
|
||||
}
|
||||
],
|
||||
edit: [
|
||||
{
|
||||
label: '船牌名称',
|
||||
prop: 'boatName',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '名称',
|
||||
prop: 'boatNameEn',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '抓拍类型',
|
||||
prop: 'takeType',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: '无人机', label: '无人机' },
|
||||
{ value: '卡口', label: '卡口' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '抓拍设备',
|
||||
prop: 'videoName',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '船型',
|
||||
prop: 'shipType',
|
||||
type: 'select',
|
||||
options: [ {
|
||||
label: '集装箱船',
|
||||
value: '集装箱船'
|
||||
}, {
|
||||
label: '液货船',
|
||||
value: '液货船'
|
||||
},
|
||||
{
|
||||
label: '散杂货船',
|
||||
value: '散杂货船'
|
||||
},
|
||||
{
|
||||
label: '客渡船',
|
||||
value: '客渡船'
|
||||
},
|
||||
{
|
||||
label: '渔船',
|
||||
value: '渔船'
|
||||
},
|
||||
{
|
||||
label: '公务船',
|
||||
value: '公务船'
|
||||
},
|
||||
{
|
||||
label: '引航船',
|
||||
value: '引航船'
|
||||
},
|
||||
{
|
||||
label: '拖轮',
|
||||
value: '拖轮'
|
||||
} ]
|
||||
},
|
||||
{
|
||||
label: '船长(m)',
|
||||
prop: 'length',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
label: '航速(节)',
|
||||
prop: 'speed',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
label: '船宽(m)',
|
||||
prop: 'width',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
label: 'MMSI',
|
||||
prop: 'mmsi',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '方向',
|
||||
prop: 'entryOut',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '时间',
|
||||
prop: 'takeTime',
|
||||
type: 'datetime'
|
||||
},
|
||||
{
|
||||
label: '是否有AIS信号',
|
||||
prop: 'isHasAis',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: 'AIS状态',
|
||||
prop: 'aisStatus',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
prop: 'remark',
|
||||
type: 'textarea',
|
||||
width: 2
|
||||
}
|
||||
]
|
||||
}
|
||||
// 船型识别
|
||||
const shipType = {
|
||||
items: [
|
||||
{
|
||||
label: '抓拍时间',
|
||||
prop: 'time',
|
||||
type: 'datetimerange'
|
||||
},
|
||||
{
|
||||
label: '识别类型',
|
||||
prop: 'identifyType',
|
||||
type: 'select',
|
||||
options: [ {
|
||||
label: '全部',
|
||||
value: ''
|
||||
}, {
|
||||
label: '船牌识别',
|
||||
value: '船牌识别'
|
||||
},
|
||||
{
|
||||
label: '船型识别',
|
||||
value: '船型识别'
|
||||
} ],
|
||||
event: 'select'
|
||||
},
|
||||
{
|
||||
label: '船型',
|
||||
prop: 'shipType',
|
||||
type: 'select',
|
||||
options: [ {
|
||||
label: '集装箱船',
|
||||
value: '集装箱船'
|
||||
}, {
|
||||
label: '液货船',
|
||||
value: '液货船'
|
||||
},
|
||||
{
|
||||
label: '散杂货船',
|
||||
value: '散杂货船'
|
||||
},
|
||||
{
|
||||
label: '客渡船',
|
||||
value: '客渡船'
|
||||
},
|
||||
{
|
||||
label: '渔船',
|
||||
value: '渔船'
|
||||
},
|
||||
{
|
||||
label: '公务船',
|
||||
value: '公务船'
|
||||
},
|
||||
{
|
||||
label: '引航船',
|
||||
value: '引航船'
|
||||
},
|
||||
{
|
||||
label: '拖轮',
|
||||
value: '拖轮'
|
||||
} ]
|
||||
},
|
||||
{
|
||||
label: '抓拍类型',
|
||||
prop: 'takeType',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: '', label: '全部' },
|
||||
{ value: '无人机', label: '无人机' },
|
||||
{ value: '卡口', label: '卡口' }
|
||||
],
|
||||
emptyValues: [ null, undefined ],
|
||||
valueOnClear: null
|
||||
},
|
||||
{
|
||||
label: '抓拍设备',
|
||||
prop: 'videoName',
|
||||
type: 'input'
|
||||
}
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
label: '抓拍时间',
|
||||
prop: 'takeTime',
|
||||
width: 170
|
||||
},
|
||||
{
|
||||
label: '船型',
|
||||
prop: 'shipType',
|
||||
width: 70
|
||||
},
|
||||
{
|
||||
label: '抓拍类型',
|
||||
prop: 'takeType',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
label: '抓拍设备',
|
||||
prop: 'videoName',
|
||||
width: 140
|
||||
}
|
||||
],
|
||||
detailColumns: [
|
||||
{
|
||||
label: '船型',
|
||||
prop: 'shipType'
|
||||
},
|
||||
// {
|
||||
// label: '船长',
|
||||
// prop: 'length',
|
||||
// unit: 'm'
|
||||
// },
|
||||
// {
|
||||
// label: '航速',
|
||||
// prop: 'speed',
|
||||
// unit: '节'
|
||||
// },
|
||||
// {
|
||||
// label: '船宽',
|
||||
// prop: 'width',
|
||||
// unit: 'm'
|
||||
// },
|
||||
{
|
||||
label: '方向',
|
||||
prop: 'entryOut'
|
||||
},
|
||||
{
|
||||
label: '识别类型',
|
||||
prop: 'takeType'
|
||||
},
|
||||
{
|
||||
label: '时间',
|
||||
prop: 'takeTime'
|
||||
}
|
||||
],
|
||||
edit: [
|
||||
{
|
||||
label: '抓拍类型',
|
||||
prop: 'takeType',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: '无人机', label: '无人机' },
|
||||
{ value: '卡口', label: '卡口' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '抓拍设备',
|
||||
prop: 'videoName',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '船型',
|
||||
prop: 'shipType',
|
||||
type: 'select',
|
||||
options: [ {
|
||||
label: '集装箱船',
|
||||
value: '集装箱船'
|
||||
}, {
|
||||
label: '液货船',
|
||||
value: '液货船'
|
||||
},
|
||||
{
|
||||
label: '散杂货船',
|
||||
value: '散杂货船'
|
||||
},
|
||||
{
|
||||
label: '客渡船',
|
||||
value: '客渡船'
|
||||
},
|
||||
{
|
||||
label: '渔船',
|
||||
value: '渔船'
|
||||
},
|
||||
{
|
||||
label: '公务船',
|
||||
value: '公务船'
|
||||
},
|
||||
{
|
||||
label: '引航船',
|
||||
value: '引航船'
|
||||
},
|
||||
{
|
||||
label: '拖轮',
|
||||
value: '拖轮'
|
||||
} ]
|
||||
},
|
||||
{
|
||||
label: '时间',
|
||||
prop: 'takeTime',
|
||||
type: 'datetime'
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
prop: 'remark',
|
||||
type: 'textarea',
|
||||
width: 2
|
||||
}
|
||||
]
|
||||
}
|
||||
export{
|
||||
shipPlate,
|
||||
shipType
|
||||
}
|
||||
45
src/views/business/identification/index.vue
Normal file
45
src/views/business/identification/index.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<!-- 识别记录页面 -->
|
||||
<DialogComponent :style="{ resize: 'both', overflow: 'auto' }" v-if="type === 'alarm'" title="识别记录" width="1800" :draggable="true" :modal="false" @close="close">
|
||||
<AlarmCom/>
|
||||
</DialogComponent>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import DialogComponent from '@/components/Dialog/screen.vue'
|
||||
import AlarmCom from './alarm/index.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import useMapStore from '@/store/modules/map'
|
||||
|
||||
const mapStore = useMapStore()
|
||||
const router = useRouter()
|
||||
const type = computed(() => mapStore.dialogVisible.type)
|
||||
|
||||
const close = () => {
|
||||
mapStore.updateDialog('')
|
||||
router.back()
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.el-tabs {
|
||||
box-sizing: border-box;
|
||||
:deep(.el-tabs__header){
|
||||
.el-tabs__nav-wrap::after {
|
||||
background-color: rgba(0, 192, 255, 0.2) !important;
|
||||
}
|
||||
.el-tabs__item {
|
||||
color: rgba(68, 165, 255, 1);
|
||||
&.is-active{
|
||||
color: #00C0FF;
|
||||
}
|
||||
}
|
||||
.el-tabs__item.is-disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.el-tabs__active-bar {
|
||||
background-color: #00C0FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user