main
徐景良 1 week ago
commit f5a16baab2

@ -137,6 +137,7 @@
"resize-observer-polyfill": "^1.5.1",
"showdown": "^2.1.0",
"shpjs": "^6.1.0",
"socket.io-client": "^4.8.1",
"sortablejs": "^1.15.1",
"tcplayer.js": "^5.3.4",
"terraformer-wkt-parser": "^1.2.1",

@ -5,6 +5,9 @@ enum Api {
GetDroneDockflightInfos = '/api/DroneDock/GetDroneDockflightInfos',
GetTaskPicList = '/api/Manage/GetTaskPicList',
GetTaskVideoList = '/api/Manage/GetTaskVideoList',
SaveHandFlyTask = '/api/Manage/SaveHandFlyTask',
CallAiModel = '/api/Manage/CallAiModel',
EndHandFlyTask = '/api/Manage/EndHandFlyTask',
}
export function getVerifyToken(token) {
@ -26,3 +29,24 @@ export function getTaskVideoList(params) {
url: Api.GetTaskVideoList + '?flightId=' + params.flightId + '&timestamp=' + params.timestamp,
});
}
export function saveHandFlyTask(params) {
return defHttp.post({
url: Api.SaveHandFlyTask,
params,
});
}
export function callAiModel(params) {
return defHttp.post({
url: Api.CallAiModel,
params,
});
}
export function endHandFlyTask(params) {
return defHttp.post({
url: Api.EndHandFlyTask + '?taskid = ' + params.taskid,
params,
});
}

@ -22,6 +22,8 @@ export const airPortStore = defineStore({
url: 'http://box.wisestcity.com:8081/live/',
},
gateway: null,
project: null,
taskId: null,
}),
getters: {
getAirport(state) {
@ -36,6 +38,12 @@ export const airPortStore = defineStore({
getGateway(state) {
return state.gateway;
},
getProject(state) {
return state.project;
},
getTaskId(state) {
return state.taskId;
},
},
actions: {
setAirPort(item: any, value: any) {
@ -47,5 +55,11 @@ export const airPortStore = defineStore({
setGateway(value: any) {
this.gateway = value;
},
setProject(value: any) {
this.project = value;
},
setTaskId(value: any) {
this.taskId = value;
},
},
});

@ -13,7 +13,7 @@
<div class="show-list-div">
<div :class="`list-item-outer ${selectItemId == item.id?'list-item-outer-select' : ''}`" v-for="(item,index) in dataList" >
<div class="list-item-inner">
<img class="item-image" :src="`${VITE_GLOB_API_URL}/${item.cover}`" >
<img class="item-image" :src="`${item.cover}`" >
<div class="item-info-div">
<div class="item-confidence">
<div class="confidence-icon"></div>

@ -231,8 +231,8 @@ onMounted(() => {
spaceConstraint.value = props.showInfoData.spaceConstraint
expansionDistance.value = props.showInfoData.expansionDistance
temporalConstraints.value = props.showInfoData.temporalConstraints
tcStartTime.value = dayjs(props.showInfoData.tcStartTime)
tcEndTime.value = dayjs(props.showInfoData.tcEndTime)
tcStartTime.value = props.showInfoData.tcStartTime? dayjs(props.showInfoData.tcStartTime): ''
tcEndTime.value = props.showInfoData.tcEndTime? dayjs(props.showInfoData.tcEndTime): ''
flySpeedFirst.value = props.showInfoData.flySpeed?.split('~')[0] || ''
flySpeedLast.value = props.showInfoData.flySpeed.split('~')[1] || ''
gimbalPitchDegreeFirst.value = props.showInfoData.gimbalPitchDegree?.split('~')[0] || ''

@ -154,6 +154,7 @@ const changeAddModal = (type: boolean, isInsert:boolean = true) => {
modalType.value = 'insert'
}else{
modalType.value = 'update'
changeDrawerModal(false)
}
}
addInstanceModal.value = type

@ -72,7 +72,7 @@
@loadLiveStreaming="livePreviewVisible = false"
@changeCameraType="changeCameraType"
/>
<div class="intelligent-patrol">
<div class="intelligent-patrol" v-if="taskId">
<div @click="patrolVisible = true">
<span> <RadarChartOutlined /> </span>
<span>智能巡检</span>
@ -82,7 +82,7 @@
<span>上报事件</span>
</div>
</div>
<Patrol v-if="patrolVisible" @changePatrol="patrolVisible = false" />
<Patrol :taskId="taskId" v-if="patrolVisible" @changePatrol="patrolVisible = false" />
<Report @changeReport="reportVisible = false" v-if="reportVisible" />
</div>
</template>
@ -225,8 +225,12 @@
flyToFormVisible.value = true;
zIndex.value++;
};
const taskId = ref('');
const changeTakeOffForm = (val) => {
takeOffFormVisible.value = false;
if (val) {
taskId.value = val;
}
// if (!val) {
// setTimeout(() => {
// uavLive.value = true;

@ -190,7 +190,10 @@
import VueDragResize from 'vue-drag-resize/src';
import { airPortStore } from '@/store/modules/airport';
import { EventBus } from '@/utils/eventBus';
import { endHandFlyTask } from '@/api/workmanagement/droneDock';
import io from 'socket.io-client';
let socket;
const props = defineProps({
zIndex: Number,
});
@ -343,6 +346,18 @@
timestamp: new Date().getTime(),
data: {},
});
if (airPortStoreVal.getTaskId) {
endHandFlyTask({
taskid: airPortStoreVal.getTaskId,
}).then((res) => {
if (res) {
if (socket) {
socket.disconnect();
}
airPortStoreVal.setTaskId(null);
}
});
}
};
const seq = ref(1);
const longPressTimer = ref();
@ -543,6 +558,7 @@
}
};
onMounted(() => {
socket = io('http://192.168.10.131:9025');
//
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);

@ -47,11 +47,14 @@
</a-radio-group>
</div>
<div class="content-title">
<span>警告提示</span>
<span>警告提示标题</span>
</div>
<div class="content-edit">
<a-input v-model:value="data.code" placeholder="异常提示" />
</div>
<div class="content-title">
<span>警告提示内容</span>
</div>
<div class="content-edit">
<a-textarea v-model:value="data.desc" placeholder="识别到异常目标" />
</div>
@ -59,10 +62,7 @@
<a-button type="primary" style="background: #3a57e8" @click="emits('changePatrol')"
>取消</a-button
>
<a-button
type="primary"
style="background: #0a99eb; margin-left: 20px"
@click="emits('changeLoadControl')"
<a-button type="primary" style="background: #0a99eb; margin-left: 20px" @click="submit"
>确定</a-button
>
</div>
@ -100,10 +100,18 @@
} from '@ant-design/icons-vue';
import { Map } from '../index';
import { GetAlgoInstanceList } from '@/api/demo/aiinstance';
import { airPortStore } from '@/store/modules/airport';
import { callAiModel } from '@/api/workmanagement/droneDock';
import { EventBus } from '@/utils/eventBus';
const airPortStoreVal = airPortStore();
const { createMessage } = useMessage();
const emits = defineEmits(['changePatrol']);
const props = defineProps({});
const props = defineProps({
taskId: String,
type: String,
});
const data = reactive({
instantiate: null,
code: '',
@ -160,6 +168,47 @@
instantiateOptions.value = res.items;
});
};
const liveCode = ref('7');
const live_info = airPortStoreVal.getLiveInfo;
const submit = () => {
console.log(props.type);
if (!instantiateItem.value) {
createMessage.warning('请选择AI算法实例');
return;
}
if (!data.code) {
createMessage.warning('警告提示标题不能为空');
return;
}
if (!data.desc) {
createMessage.warning('警告提示内容不能为空');
return;
}
if (props.type == 'plan') {
const querys = {
algoInstanceId: instantiateItem.value.id,
warningTitle: data.code,
warningContent: data.desc,
};
EventBus.emit('palnPatrol', querys);
emits('changePatrol');
return;
}
const querys = {
taskId: props.taskId,
algoInstanceId: instantiateItem.value.id,
rtmpUrl: live_info.rtmp + liveCode.value,
warningTitle: data.code,
warningContent: data.desc,
};
callAiModel(querys).then((res) => {
console.log(res);
createMessage.success('操作成功');
airPortStoreVal.setTaskId(props.taskId);
emits('changePatrol');
});
};
onMounted(() => {
getList();
});

@ -57,6 +57,7 @@
airPortStoreVal.setAirPort('sn', selectVal.airport);
airPortStoreVal.setUAV('sn', selectVal.equipment);
airPortStoreVal.setGateway(selectVal.gateway);
airPortStoreVal.setProject(selectVal.project);
emits('selectChange', selectVal);
};
//

@ -118,6 +118,7 @@
import { airPortStore } from '@/store/modules/airport';
import VueDragResize from 'vue-drag-resize/src';
import { useMessage } from '@/hooks/web/useMessage';
import { saveHandFlyTask } from '@/api/workmanagement/droneDock';
const emits = defineEmits(['changeTakeOffForm']);
const props = defineProps({
@ -237,9 +238,16 @@
//
servicesTopic(querys);
services_replyTopic();
setTimeout(() => {
emits('changeTakeOffForm');
}, 1000);
saveHandFlyTask({
flightId: data.flight_id,
workspaceId: airPortStoreVal.getProject,
}).then((res) => {
if (res) {
setTimeout(() => {
emits('changeTakeOffForm', res.taskId);
}, 1000);
}
});
};
onMounted(() => {
//

@ -1,30 +1,104 @@
<template>
<div class="inspection-container">
<div class="inspection-header">
<SelectComponent />
<SelectComponent @selectChange="changeSelect" />
<div class="inspection-header-desc">
<div class="inspection-header-desc-item">
<!-- <a-badge status="success" text="Success" /> -->
<a-badge status="error" />
状态<span>未连接</span>
<a-badge status="success" v-if="status === ''" />
<a-badge status="error" v-else />
状态<span>{{ status }}</span>
</div>
<div class="inspection-header-desc-item">
FPS:<span>{{ socketData && socketData.fps ? socketData.fps : 0 }}</span>
</div>
<div class="inspection-header-desc-item">
总帧数:<span>{{
socketData && socketData.frame_count ? socketData.frame_count : 0
}}</span>
</div>
<div class="inspection-header-desc-item">
监测目标数:<span>{{
socketData && socketData.detections.length ? socketData.detections.length : 0
}}</span>
</div>
<div class="inspection-header-desc-item"> FPS:<span>123</span> </div>
<div class="inspection-header-desc-item"> 总帧数:<span>123</span> </div>
<div class="inspection-header-desc-item"> 监测目标数:<span>123</span> </div>
</div>
</div>
<div class="inspection-content">
<div class="inspection-content-left">
<StatisticsComponent />
<StatisticsComponent
:statisData="socketData && socketData.detections ? socketData.detections : []"
/>
</div>
<div class="inspection-content-right">
<VideoStreamComponent />
<VideoStreamComponent
:statisData="socketData && socketData.detections ? socketData.detections : []"
/>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { SelectComponent, StatisticsComponent, VideoStreamComponent } from './index';
import axios from 'axios';
import { onMounted, ref } from 'vue';
import io from 'socket.io-client';
import { getClient, createConnection, clientSubscribe, destroyConnection } from '@/utils/mqtt';
import { airPortStore } from '@/store/modules/airport';
let socket;
const airPortStoreVal = airPortStore();
const UAVinfo = airPortStoreVal.getUAV;
const socketData = ref();
const status = ref('未连接');
function connectWebSocket() {
console.log('connectWebSocket');
// Socket
socket = io('http://192.168.10.131:9025');
//
socket.on('connect', () => {
console.log('服务连接成功');
status.value = '已连接';
});
socket.on('disconnect', () => {
console.log('服务器断开');
status.value = '未连接';
});
//
socket.on('detection_results', (data) => {
// console.log('', data);
socketData.value = data;
// {
// "detections": [],
// "timestamp": 1756371710725,
// "fps": 18.2,
// "frame_count": 3269,
// "taskid": "03721e94-08da-42fc-aa0e-261ac0b4f2d9"
// }
});
//
socket.on('error', (error) => {
console.log('WebSocket连接错误', error);
});
}
const changeSelect = async (value?: any) => {
const topicUAVUrl = 'thing/product/' + UAVinfo.sn + '/osd';
//
clientSubscribe(topicUAVUrl, { qos: 1 });
};
const connected = ref(false);
const connectCallback = () => {
connected.value = true;
};
onMounted(() => {
// getData();
createConnection(connectCallback);
connectWebSocket();
});
</script>
<style lang="scss" scoped>
.inspection-container {

@ -5,26 +5,47 @@
</div>
<div class="map-container">
<div class="map-container-content">
<Map />
<Map :uavTrack="uavTrack" />
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted } from 'vue';
import { onMounted, watch, ref, computed } from 'vue';
import * as echarts from 'echarts';
import { Map } from '../index';
import { getClient, clientSubscribe, createConnection } from '@/utils/mqtt';
import { airPortStore } from '@/store/modules/airport';
const airPortStoreVal = airPortStore();
const UAVinfo = airPortStoreVal.getUAV;
const chartData = ref([]);
const props = defineProps({
statisData: {
type: Array,
default: () => [],
},
});
watch(
() => props.statisData,
(val) => {
if (val.length > 0) {
if (chartData.value.length >= 20) {
chartData.value.shift();
}
chartData.value.push(val.length);
updateChart();
}
},
);
let myChart;
const initChart = () => {
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
myChart = echarts.init(chartDom);
var option;
let date = [];
let data = [Math.random() * 300];
for (let i = 1; i < 40; i++) {
for (let i = 1; i < 20; i++) {
date.push(i);
data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));
}
option = {
tooltip: {
@ -79,15 +100,48 @@
},
]),
},
data: data,
data: [],
},
],
};
option && myChart.setOption(option);
};
//
function updateChart() {
console.log(chartData.value);
myChart.setOption({
series: [
{
data: chartData.value,
},
],
});
}
const topicUAVUrl = computed(() => {
return 'thing/product/' + UAVinfo.sn + '/osd';
});
const uavTrack = ref({});
const connected = ref(false);
const connectCallback = () => {
connected.value = true;
};
onMounted(() => {
initChart();
setTimeout(() => {
//
getClient().on('message', (topic, message) => {
const rs = JSON.parse(message);
if (rs) {
if (topic == topicUAVUrl.value) {
if (rs.data.latitude && rs.data.longitude) {
uavTrack.value = rs.data;
}
}
}
});
}, 1000);
});
</script>
<style lang="scss" scoped>

@ -4,6 +4,7 @@
<div class="title">
<VideoCameraOutlined />
原始视频流
<RedoOutlined title="刷新" @click="reloadLive" />
</div>
<div class="player">
<video
@ -21,6 +22,7 @@
<div class="title">
<VideoCameraOutlined />
检测后视频流
<RedoOutlined title="刷新" @click="reloadTestingLive" />
</div>
<div class="player">
<video
@ -40,24 +42,86 @@
import TCPlayer from 'tcplayer.js';
import 'tcplayer.js/dist/tcplayer.min.css'; //
import { airPortStore } from '@/store/modules/airport';
import { ref } from 'vue';
import { VideoCameraOutlined } from '@ant-design/icons-vue';
import { onMounted, watch, onBeforeUnmount } from 'vue';
import { VideoCameraOutlined, RedoOutlined } from '@ant-design/icons-vue';
const props = defineProps({
statisData: {
type: Array,
default: () => [],
},
});
const airPortStoreVal = airPortStore();
const live_info = airPortStoreVal.getLiveInfo;
//
let player;
const liveCode = ref('7');
const liveCode = live_info.url + '7.flv';
const playVideo = () => {
player = TCPlayer('player-container-original-live', {
sources: [
{
src: live_info.url + liveCode.value + '.flv', //
src: liveCode, //
},
],
licenseUrl: liveCode, // license license licenseUrl
});
};
//
let playerTesting;
const testingCode = live_info.url + '11.flv';
const testingPlayVideo = () => {
player = TCPlayer('player-container-testing-live', {
sources: [
{
src: testingCode, //
},
],
licenseUrl: live_info.url + liveCode.value + '.flv', // license license licenseUrl
licenseUrl: testingCode, // license license licenseUrl
});
};
const reloadLive = () => {
player.src(liveCode);
player.play();
};
const reloadTestingLive = () => {
if (playerTesting) {
playerTesting.src(testingCode);
playerTesting.play();
}
};
onMounted(() => {
playVideo();
testingPlayVideo();
setTimeout(() => {
if (player) {
player.play();
}
if (playerTesting) {
playerTesting.play();
}
}, 1000);
});
watch(
() => props.statisData,
(val) => {
reloadLive();
reloadTestingLive();
},
);
//
onBeforeUnmount(() => {
if (player) {
player.dispose();
player = null;
}
if (playerTesting) {
playerTesting.dispose();
playerTesting = null;
}
});
</script>
<style lang="scss" scoped>
.video-stream-container {
@ -85,6 +149,7 @@
border-bottom: 1px solid #4e5778;
}
.player {
height: 80%;
video {
margin-left: 10px;
}

@ -46,7 +46,7 @@
</div>
<!-- 智能巡检 -->
<div v-if="patrolShow" class="patrol-box">
<Patrol @changePatrol="patrolShow = false"/>
<Patrol type="plan" @changePatrol="patrolShow = false"/>
</div>
<!-- 航线库 -->

@ -1,5 +1,5 @@
import { defineApplicationConfig } from '@vben/vite-config';
import { mars3dPlugin } from "vite-plugin-mars3d"
import { mars3dPlugin } from 'vite-plugin-mars3d';
export default defineApplicationConfig({
overrides: {
@ -21,10 +21,7 @@ export default defineApplicationConfig({
//...
target: 'esnext',
commonjsOptions: {
include: [
/node_modules|lib/,
/node_modules|packages/
] //这里记得把lib目录加进来否则生产打包会报错
include: [/node_modules|lib/, /node_modules|packages/], //这里记得把lib目录加进来否则生产打包会报错
},
},
server: {
@ -43,6 +40,13 @@ export default defineApplicationConfig({
ws: true,
rewrite: (path) => path.replace(new RegExp(`^/upload`), ''),
},
'/sltest': {
target: 'http://192.168.10.131:9025/',
changeOrigin: true, //是否跨域
rewrite: (path) => path.replace(/^\/sltest/, ''), //如果后端接口有sltest前缀就不需要替换
// ws: true, //是否代理 websockets
// secure: true, //是否https接口
},
},
warmup: {
clientFiles: ['./index.html', './src/{views,components}/*'],
@ -60,10 +64,6 @@ export default defineApplicationConfig({
},
},
},
plugins: [
mars3dPlugin()
],
plugins: [mars3dPlugin()],
},
});

Loading…
Cancel
Save