[1078] 增加立即拍摄

This commit is contained in:
lin
2025-07-25 15:37:03 +08:00
parent ee52b43c99
commit 43ef080f55
12 changed files with 506 additions and 134 deletions

View File

@@ -91,5 +91,5 @@ export default {
margin-top: 6px;
font-size: 12px;
width: 2rem !important;
}
}
</style>

View File

@@ -22,10 +22,10 @@
<el-option label="QCIF( 164×144 )" :value="0" />
<el-option label="CIF( 360×288 )" :value="1" />
<el-option label="WCIF( 480×288 )" :value="2" />
<el-option label="D1( 720x576 )" :value="2" />
<el-option label="WD1( 960×576 )" :value="2" />
<el-option label="720P( 1280×720 )" :value="2" />
<el-option label="1080P( 1920×1080 )" :value="2" />
<el-option label="D1( 720x576 )" :value="3" />
<el-option label="WD1( 960×576 )" :value="4" />
<el-option label="720P( 1280×720 )" :value="5" />
<el-option label="1080P( 1920×1080 )" :value="6" />
</el-select>
</el-form-item>
<el-form-item label="实时流关键帧间隔" prop="chroma">

View File

@@ -10,7 +10,7 @@
:destroy-on-close="true"
@close="close()"
>
<div id="shared">
<div id="shared" style="height: 45rem; overflow: auto">
<el-descriptions title="基本信息" :column="3" v-if="positionData" style="margin-bottom: 1rem;">
<el-descriptions-item label="经度">{{ positionData.longitude }}</el-descriptions-item>
<el-descriptions-item label="纬度">{{ positionData.latitude }}</el-descriptions-item>

View File

@@ -1,121 +1,113 @@
<template>
<div id="configInfo">
<el-dialog
v-el-drag-dialog
title="存储多媒体数据检索"
width="60%"
top="2rem"
:close-on-click-modal="false"
:visible.sync="showDialog"
:destroy-on-close="true"
@close="close()"
>
<el-form :inline="true" size="mini" @submit.native.prevent>
<el-form-item>
<el-select
v-model="type"
style="width: 8rem; margin-right: 1rem;"
placeholder="请选择类型"
default-first-option
>
<el-option label="图像" :value="0" />
<el-option label="音频" :value="1" />
<el-option label="视频" :value="2" />
</el-select>
<el-select
v-model="chanelId"
style="width: 8rem; margin-right: 1rem;"
placeholder="请选择通道"
default-first-option
>
<el-option label="平台下发指令" :value="0" />
<el-option label="定时动作" :value="1" />
<el-option label="抢劫报警触发" :value="2" />
<el-option label="碰撞侧翻报警触发" :value="3" />
</el-select>
<el-select
v-model="event"
style="width: 8rem; margin-right: 1rem;"
placeholder="请选择事件"
default-first-option
>
<el-option label="所有通道" :value="0" />
<el-option v-for="item in channelList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-date-picker
v-model="timeRange"
type="datetimerange"
:picker-options="pickerOptions"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
align="right">
</el-date-picker>
<el-form :inline="true" size="mini" @submit.native.prevent>
<el-form-item>
<el-select
v-model="type"
style="width: 8rem; margin-right: 1rem;"
placeholder="请选择类型"
default-first-option
>
<el-option label="图像" :value="0" />
<el-option label="音频" :value="1" />
<el-option label="视频" :value="2" />
</el-select>
<el-select
v-model="event"
style="width: 8rem; margin-right: 1rem;"
placeholder="请选择事件"
default-first-option
>
<el-option label="平台下发指令" :value="0" />
<el-option label="定时动作" :value="1" />
<el-option label="抢劫报警触发" :value="2" />
<el-option label="碰撞侧翻报警触发" :value="3" />
</el-select>
<el-select
v-model="chanelId"
style="width: 8rem; margin-right: 1rem;"
placeholder="请选择通道"
default-first-option
>
<el-option label="所有通道" :value="0" />
<el-option v-for="item in channelList" :key="item.channelId" :label="item.name" :value="item.channelId" />
</el-select>
<el-date-picker
v-model="timeRange"
type="datetimerange"
format="yyyy-MM-dd HH-mm-ss"
value-format="yyyy-MM-dd HH:mm:ss"
:picker-options="pickerOptions"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
align="right">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="removeRow(scope.$index)" >
检索
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="queryLoading" icon="el-icon-search" @click="search()" >
检索
</el-button>
</el-form-item>
</el-form>
<el-table :data="mediaDataInfoList" :height="500" stripe style="width: 100%" empty-text="暂无数据">
<el-table-column prop="id" label="ID" />
<el-table-column prop="type" label="类型" >
<template v-slot:default="scope">
{{typeLabel(scope.row.type)}}
</template>
</el-table-column>
<el-table-column label="事件" >
<template v-slot:default="scope">
{{eventCodeLabel(scope.row.eventCode)}}
</template>
</el-table-column>
<el-table-column prop="channelId" label="通道ID" />
<el-table-column label="操作" fixed="right">
<template v-slot:default="scope">
<el-button
size="medium"
type="text"
icon="el-icon-location-information"
:loading="scope.row.addRegionLoading"
@click="showPositionInfo(scope.row)"
>
位置汇报
</el-button>
</el-form-item>
</el-form>
<el-table :data="mediaDataInfoList" :height="500" stripe style="width: 100%" empty-text="暂无数据">
<el-table-column prop="ID" label="ID" />
<el-table-column prop="type" label="类型" />
<el-table-column label="事件" >
<template v-slot:default="scope">
{{eventCodeLabel(scope.row.eventCode)}}
</template>
</el-table-column>
<el-table-column prop="channelId" label="通道ID" />
<el-table-column label="操作" fixed="right">
<template v-slot:default="scope">
<el-button
size="medium"
type="text"
style="color: #f56c6c"
icon="el-icon-delete"
:loading="scope.row.addRegionLoading"
@click="removeRow(scope.$index)"
>
位置汇报
</el-button>
<el-button
size="medium"
type="text"
style="color: #f56c6c"
icon="el-icon-delete"
:loading="scope.row.addRegionLoading"
@click="removeRow(scope.$index)"
>
下载
</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
<el-button
size="medium"
type="text"
icon="el-icon-download"
:loading="scope.row.addRegionLoading"
@click="download(scope.row)"
>
下载
</el-button>
</template>
</el-table-column>
</el-table>
<position ref="position"></position>
</div>
</template>
<script>
import * as XLSX from 'xlsx'
import elDragDialog from '@/directive/el-drag-dialog'
import position from './position.vue'
import dayjs from 'dayjs'
export default {
name: 'ConfigInfo',
directives: { elDragDialog },
props: {},
components: { position },
props: ['phoneNumber', 'deviceId', 'channelList'],
data() {
return {
deviceId: null,
phoneNumber: null,
showDialog: false,
queryLoading: false,
type: 0,
chanelId: 0,
event: 0,
channelList: [],
mediaDataInfoList: [],
timeRange: '',
pickerOptions: {
@@ -160,30 +152,29 @@ export default {
}
},
computed: {},
created() {},
created() {
},
methods: {
openDialog: function(phoneNumber, deviceId) {
this.showDialog = true
this.phoneNumber = phoneNumber
this.deviceId = deviceId
this.mediaDataInfoList = []
this.$store.dispatch('jtDevice/queryChannels', {
page: 1,
count: 1000,
deviceId: this.deviceId
})
.then(data => {
this.channelList = data.list
})
},
close: function() {
this.showDialog = false
this.mediaDataInfoList = []
this.channelList = []
this.type = 0
this.chanelId = 0
this.event = 0
},
typeLabel: function(type) {
switch (type){
case 0:
return '图像'
case 1:
return '音频'
case 2:
return '视频'
default:
return type
}
},
eventCodeLabel: function(eventCode) {
switch (eventCode){
case 0:
@@ -205,6 +196,70 @@ export default {
default:
return eventCode
}
},
search: function() {
this.mediaDataInfoList = []
this.queryLoading = true
console.log(this.timeRange)
this.$store.dispatch('jtDevice/queryMediaData', {
phoneNumber: this.phoneNumber,
queryMediaDataCommand: {
type: this.type,
channelId: this.chanelId,
event: this.event,
startTime: this.timeRange === '' ? null : this.timeRange[0],
endTime: this.timeRange === '' ? null : this.timeRange[1]
}
})
.then(data => {
console.log(data)
if (data.length === 0) {
this.$message.info('未查询到相关记录')
}
this.mediaDataInfoList = data
})
.finally(() => {
this.queryLoading = false
})
},
showPositionInfo: function(row) {
this.$refs.position.openDialog(row.positionBaseInfo)
},
download: function(row) {
this.$message.success('已申请截图,完成后自动下载', { closed: true })
// 文件下载地址
const baseUrl = window.baseUrl ? window.baseUrl : ''
const fileUrl = ((process.env.NODE_ENV === 'development') ? process.env.VUE_APP_BASE_API : baseUrl) + `/api/jt1078/media/upload/one?phoneNumber=${this.phoneNumber}&mediaId=${row.id}`
let controller = new AbortController()
let signal = controller.signal
// 设置请求头
const headers = new Headers()
headers.append('access-token', this.$store.getters.token) // 设置授权头替换YourAccessToken为实际的访问令牌
// 发起 请求
fetch(fileUrl, {
method: 'GET',
headers: headers,
signal: signal
})
.then(response => response.blob())
.then(blob => {
console.log(blob)
// 创建一个虚拟的链接元素,模拟点击下载
const link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = `${this.device.phoneNumber}-${row.channelId}-${dayjs().format('YYYYMMDDHHmmss')}.jpg` // 设置下载文件名替换filename.ext为实际的文件名和扩展名
document.body.appendChild(link)
// 模拟点击
link.click()
// 移除虚拟链接元素
document.body.removeChild(link)
})
.catch(error => console.error('下载失败:', error))
setTimeout(() => {
this.$message.error('下载超时', { closed: true })
controller.abort('timeout')
}, 15000)
}
}
}
@@ -214,4 +269,9 @@ export default {
>>> .el-upload {
width: 100% !important;
}
.el-slider__marks-text {
margin-top: -36px;
font-size: 12px;
width: 2rem !important;
}
</style>

View File

@@ -0,0 +1,57 @@
<template>
<div id="configInfo">
<el-dialog
v-el-drag-dialog
title="存储多媒体数据检索"
width="60%"
top="2rem"
:close-on-click-modal="false"
:visible.sync="showDialog"
:destroy-on-close="true"
@close="close()"
>
<queryMediaList :phoneNumber="phoneNumber" :deviceId="deviceId" :channelList="channelList"/>
</el-dialog>
</div>
</template>
<script>
import elDragDialog from '@/directive/el-drag-dialog'
import queryMediaList from './queryMediaList.vue'
export default {
name: 'ConfigInfo',
directives: { elDragDialog },
components: { queryMediaList },
props: {},
data() {
return {
showDialog: false,
phoneNumber: null,
deviceId: null,
channelList: null
}
},
computed: {},
created() {},
methods: {
openDialog: function(phoneNumber, deviceId) {
this.showDialog = true
this.phoneNumber = phoneNumber
this.deviceId = deviceId
this.$store.dispatch('jtDevice/queryChannels', {
page: 1,
count: 1000,
deviceId: this.deviceId
})
.then(data => {
this.channelList = data.list
})
},
close: function() {
this.showDialog = false
}
}
}
</script>

View File

@@ -0,0 +1,203 @@
<template>
<div id="configInfo">
<el-dialog
v-el-drag-dialog
title="立即拍摄"
width="60%"
top="2rem"
:close-on-click-modal="false"
:visible.sync="showDialog"
:destroy-on-close="true"
@close="close()"
>
<el-form size="small" @submit.native.prevent>
<el-form-item>
<el-form inline @submit.native.prevent>
<el-form-item style="margin-right: 14.5rem">
<el-radio-group v-model="commandType">
<el-radio :label="true" border>拍摄</el-radio>
<el-radio :label="false" border>录像</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</el-form-item>
<el-form-item>
<el-form inline size="small" @submit.native.prevent>
<el-form-item label="录像时长" v-if="!commandType">
<el-input type="number" v-model="time" placeholder="一直录像" style="width: 8rem"></el-input>
</el-form-item>
<el-form-item label="连拍" v-if="commandType">
<el-input type="number" v-model="commandNumber" placeholder="连拍张数" style="width: 4rem"></el-input>
</el-form-item>
<el-form-item label="拍照间隔" v-if="commandType">
<el-input type="number" v-model="time" placeholder="最小间隔拍照" style="width: 8rem"></el-input>
</el-form-item>
<el-form-item label="存储方式">
<el-select
v-model="save"
style="width: 8rem"
placeholder="请选择存储方式"
>
<el-option label="实时上传" :value="0" />
<el-option label="保存" :value="1" />
</el-select>
</el-form-item>
<el-form-item label="通道">
<el-select
v-model="chanelId"
style="width: 8rem"
placeholder="请选择通道"
>
<el-option v-for="item in channelList" :key="item.id" :label="item.name" :value="item.channelId" />
</el-select>
</el-form-item>
<el-form-item label="分辨率">
<el-select
v-model="resolvingPower"
style="width: 8rem"
placeholder="请选择分辨率"
>
<el-option label="最低分辨率" :value="0x00" />
<el-option label="320×240" :value="0x01" />
<el-option label="640×480" :value="0x02" />
<el-option label="800×600" :value="0x03" />
<el-option label="1024×768" :value="0x04" />
<el-option label="176×144" :value="0x05" />
<el-option label="352×288" :value="0x06" />
<el-option label="704×288" :value="0x07" />
<el-option label="704×576" :value="0x08" />
<el-option label="最高分辨率" :value="0xff" />
</el-select>
</el-form-item>
<el-form-item>
<el-checkbox v-model="showImageConfig">高级配置</el-checkbox>
</el-form-item>
<el-form-item style="margin-left: 2rem; text-align: right" >
<el-button type="primary" :loading="queryLoading" icon="el-icon-search" @click="shooting()" >
执行
</el-button>
</el-form-item>
</el-form>
</el-form-item>
<el-form-item v-if="showImageConfig">
<el-form size="small" label-width="80px" style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 0.5rem">
<el-form-item label="质量" prop="topSpeed" >
<el-slider v-model="quality" show-input :height="1" :marks="qualityMarks" :min="1" :max="10" :step="1"/>
</el-form-item>
<el-form-item label="亮度" prop="brightness">
<el-slider v-model="brightness" show-input :height="1" :min="0" :max="255" :step="1" />
</el-form-item>
<el-form-item label="对比度" prop="contrastRatio">
<el-slider v-model="contrastRatio" show-input :height="1" :min="0" :max="127" :step="1"/>
</el-form-item>
<el-form-item label="饱和度" prop="saturation">
<el-slider v-model="saturation" show-input :height="1" :min="0" :max="127" :step="1"/>
</el-form-item>
<el-form-item label="色度" prop="chroma">
<el-slider v-model="chroma" show-input :height="1" :min="0" :max="255" :step="1"/>
</el-form-item>
</el-form>
</el-form-item>
</el-form>
<queryMediaList :phoneNumber="phoneNumber" :deviceId="deviceId" :channelList="channelList"></queryMediaList>
</el-dialog>
</div>
</template>
<script>
import elDragDialog from '@/directive/el-drag-dialog'
import queryMediaList from './queryMediaList.vue'
export default {
name: 'ConfigInfo',
directives: { elDragDialog },
components: { queryMediaList },
props: {},
data() {
return {
deviceId: null,
phoneNumber: null,
showDialog: false,
queryLoading: false,
showImageConfig: false,
commandType: true,
commandNumber: 1,
time: null,
save: 1,
chanelId: null,
resolvingPower: 0xff,
qualityMarks: {
1: '最优',
10: '最差'
},
quality: 1,
brightness: 125,
contrastRatio: 63,
saturation: 63,
chroma: 125,
channelList: [],
}
},
computed: {},
created() {},
methods: {
openDialog: function(phoneNumber, deviceId) {
console.log(phoneNumber)
this.showDialog = true
this.phoneNumber = phoneNumber
this.deviceId = deviceId
this.$store.dispatch('jtDevice/queryChannels', {
page: 1,
count: 1000,
deviceId: this.deviceId
})
.then(data => {
this.channelList = data.list
this.chanelId = data.list[0].channelId
})
},
close: function() {
this.showDialog = false
this.channelList = []
this.type = 0
this.chanelId = null
},
shooting: function() {
this.$store.dispatch('jtDevice/shooting', {
phoneNumber: this.phoneNumber,
shootingCommand: {
chanelId: this.chanelId,
command: !this.commandType? 0xFFFF : this.commandNumber,
time: this.time,
save: this.save,
resolvingPower: this.resolvingPower,
quality: this.quality,
brightness: this.brightness,
contrastRatio: this.contrastRatio,
saturation: this.saturation,
chroma: this.chroma
}
})
.then( data => {
this.$message.success({
showClose: true,
message: '消息已经下发'
})
})
}
}
}
</script>
<style scoped>
>>> .el-upload {
width: 100% !important;
}
>>> .el-slider__marks-text {
margin-top: -36px;
font-size: 12px;
width: 2rem !important;
}
</style>

View File

@@ -46,8 +46,16 @@
>
<el-table-column prop="phoneNumber" label="终端手机号" min-width="120" />
<el-table-column prop="terminalId" label="终端ID" min-width="120" />
<el-table-column prop="provinceText" label="省域" min-width="120" />
<el-table-column prop="cityText" label="市县域" min-width="120" />
<el-table-column label="省域" min-width="120" >
<template slot-scope="scope">
{{scope.row.provinceText || scope.row.provinceId}}
</template>
</el-table-column>
<el-table-column label="市县域" min-width="120" >
<template slot-scope="scope">
{{scope.row.cityText || scope.row.cityId}}
</template>
</el-table-column>
<el-table-column prop="makerId" label="制造商" min-width="120" />
<el-table-column prop="model" label="型号" min-width="120" />
<el-table-column label="车牌颜色" min-width="120">
@@ -129,6 +137,8 @@
连接指定服务器</el-dropdown-item>
<el-dropdown-item command="door" v-bind:disabled="!scope.row.status" >
车门控制</el-dropdown-item>
<el-dropdown-item command="shooting" v-bind:disabled="!scope.row.status" >
立即拍摄</el-dropdown-item>
<el-dropdown-item command="queryMediaList" v-bind:disabled="!scope.row.status" >
多媒体检索</el-dropdown-item>
</el-dropdown-menu>
@@ -158,6 +168,7 @@
<mediaAttribute ref="mediaAttribute" />
<phoneBook ref="phoneBook" />
<queryMediaList ref="queryMediaList" />
<shootingNow ref="shootingNow" />
</div>
</template>
@@ -173,13 +184,14 @@ import connectionServer from './dialog/connectionServer.vue'
import controlDoor from './dialog/controlDoor.vue'
import mediaAttribute from './dialog/mediaAttribute.vue'
import phoneBook from './dialog/phoneBook.vue'
import queryMediaList from './dialog/queryMediaList.vue'
import queryMediaList from './dialog/queryMediaListDialog.vue'
import shootingNow from './dialog/shootingNow.vue'
export default {
name: 'App',
components: {
deviceEdit, configInfo, attribute, position, textMsg, telephoneCallback, driverInfo, connectionServer, controlDoor
, mediaAttribute, phoneBook, queryMediaList
, mediaAttribute, phoneBook, queryMediaList, shootingNow
},
data() {
return {
@@ -304,6 +316,8 @@ export default {
this.setPhoneBook(itemData)
} else if (command === 'queryMediaList') {
this.queryMediaList(itemData)
} else if (command === 'shooting') {
this.shootingNow(itemData)
} else {
this.$message.info('尚不支持')
}
@@ -393,6 +407,9 @@ export default {
controlDoor: function(itemData) {
this.$refs.controlDoor.openDialog(itemData.phoneNumber)
},
shootingNow: function(itemData) {
this.$refs.shootingNow.openDialog(itemData.phoneNumber, itemData.id)
},
linkDetection: function(itemData) {
this.$store.dispatch('jtDevice/linkDetection', itemData.phoneNumber)
.then((data) => {