diff --git a/plugin/package.json b/plugin/package.json index 25383c0..2dd15ac 100644 --- a/plugin/package.json +++ b/plugin/package.json @@ -2,11 +2,22 @@ "name": "@it/docklivestreamplugin", "version": "1.0.0", "description": "该插件js插件包。功能包含SDK初始化、设置视频直播画面控件、发起和结束直播、拍照、视频录制、资源释放。", - "main": "index.js", + "main": "@it/docklivestreamplugin.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", - "license": "ISC" + "license": "ISC", + "dependencies": { + "@vitejs/plugin-vue": "^6.0.0", + "ant-design-vue": "^4.0.0-rc.6", + "axios": "^1.10.0", + "lodash-es": "^4.17.21", + "mqtt": "^5.13.3", + "path": "^0.12.7", + "qs": "^6.14.0", + "tcplayer.js": "^5.3.4", + "vue": "^3.5.17" + } } diff --git a/src/api/demo/provincetasks.ts b/src/api/demo/provincetasks.ts new file mode 100644 index 0000000..8cd532c --- /dev/null +++ b/src/api/demo/provincetasks.ts @@ -0,0 +1,11 @@ +import { defHttp } from '@/utils/http/axios'; +enum Api { + GetDataList = '/api/DroneDock/GetDroneDockInfos', +} + +export function GetDataList(params) { + return defHttp.get({ + url: Api.GetDataList, + params + }); +} \ No newline at end of file diff --git a/src/api/workmanagement/droneDock.ts b/src/api/workmanagement/droneDock.ts index 91e179f..394182f 100644 --- a/src/api/workmanagement/droneDock.ts +++ b/src/api/workmanagement/droneDock.ts @@ -3,6 +3,8 @@ import { defHttp } from '@/utils/http/axios'; enum Api { VerifyToken = '/api/DroneDock/VerifyToken', GetDroneDockflightInfos = '/api/DroneDock/GetDroneDockflightInfos', + GetTaskPicList = '/api/Manage/GetTaskPicList', + GetTaskVideoList = '/api/Manage/GetTaskVideoList', } export function getVerifyToken(token) { @@ -12,3 +14,15 @@ export function getVerifyToken(token) { export function getDroneDockflightInfos(id) { return defHttp.get({ url: Api.GetDroneDockflightInfos + '?taskid=' + id }); } + +export function getTaskPicList(params) { + return defHttp.get({ + url: Api.GetTaskPicList + '?flightId=' + params.flightId + '×tamp=' + params.timestamp, + }); +} + +export function getTaskVideoList(params) { + return defHttp.get({ + url: Api.GetTaskVideoList + '?flightId=' + params.flightId + '×tamp=' + params.timestamp, + }); +} diff --git a/src/plugin/video/index.ts b/src/plugin/video/index.ts index 073fe85..3e8efb7 100644 --- a/src/plugin/video/index.ts +++ b/src/plugin/video/index.ts @@ -1,13 +1,22 @@ import { createConnection, client, servicesTopic, destroyConnection } from './src/mqtt'; -import { airport, uav, liveInfo, buildGUID } from './src/config'; +import { airport, uav, liveInfo, buildGUID, base64ByURL } from './src/config'; import { GetUavPageByDocksn } from '@/api/demo/projecthome'; -import { getVerifyToken, getDroneDockflightInfos } from '@/api/workmanagement/droneDock'; +import { + getVerifyToken, + getDroneDockflightInfos, + getTaskPicList, + getTaskVideoList, +} from '@/api/workmanagement/droneDock'; import TCPlayer from 'tcplayer.js'; +import { useMessage } from '@/hooks/web/useMessage'; +import { errorName } from '@/utils/debugging/remote'; +const { createMessage } = useMessage(); const bid = buildGUID(); let video_id; let sn; let live_url; +let video_time; class LiveStreamPlugin { constructor() { @@ -52,13 +61,11 @@ class LiveStreamPlugin { console.log('LiveStreamPlugin startLiveStreamCall', serialNum, deviceType); sn = serialNum; createConnection('mqtt_' + serialNum); - video_id = - deviceType == 1 - ? serialNum + '/' + airport.camera_index + '/' + airport.video_index - : serialNum + '/' + uav.camera_index + '/' + uav.video_index; + // const liveUrl = liveInfo.rtmp + serialNum; let querys; if (deviceType == 1) { + video_id = serialNum + '/' + airport.camera_index + '/' + airport.video_index; querys = { bid: bid, method: 'live_start_push', @@ -82,6 +89,7 @@ class LiveStreamPlugin { await GetUavPageByDocksn(params).then((res) => { console.log('GetUavPageByDocksn', res); if (res.items.length > 0) { + video_id = res.items[0].sn + '/' + uav.camera_index + '/' + uav.video_index; querys = { bid: bid, method: 'live_start_push', @@ -106,8 +114,28 @@ class LiveStreamPlugin { client.on('message', (topic, message) => { const rs = JSON.parse(message); if (rs.bid == bid) { - console.log(rs); console.log('LiveStreamPlugin liveStartPush', rs); + if (rs.method == 'camera_recording_start') { + if (rs.data.result == 0) { + createMessage.success('开始录像成功'); + } else { + createMessage.error('开始录像失败,' + errorName(rs.data.result)); + } + } + if (rs.method == 'live_start_push') { + if (rs.data.result == 0) { + createMessage.success('发起视频直播成功'); + } else { + createMessage.error('发起视频直播失败,' + errorName(rs.data.result)); + } + } + if (rs.method == 'live_stop_push') { + if (rs.data.result == 0) { + createMessage.success('结束视频直播成功'); + } else { + createMessage.error('结束视频直播失败,' + errorName(rs.data.result)); + } + } } }); } @@ -138,19 +166,70 @@ class LiveStreamPlugin { * zpkzxx:照片扩展信息 */ console.log('LiveStreamPlugin takePicture', callback); - const querys = { + servicesTopic(sn, { bid: bid, - method: 'camera_photo_take', + method: 'camera_mode_switch', tid: buildGUID(), timestamp: new Date().getTime(), data: { + camera_mode: 0, payload_index: uav.camera_index, }, - }; - console.log(querys); - servicesTopic(sn, querys); - const data = {}; - callback(data); + }); + const time = new Date().getTime(); + setTimeout(() => { + const querys = { + bid: bid, + method: 'camera_photo_take', + tid: buildGUID(), + timestamp: time, + data: { + payload_index: uav.camera_index, + }, + }; + console.log(querys); + servicesTopic(sn, querys); + client.subscribe('thing/product/' + sn + '/events', { qos: 2 }, () => {}); + }, 1000); + // 接收消息 + let id = ''; + return new Promise((resolve, reject) => { + client.on('message', async (topic, message) => { + const rs = JSON.parse(message); + if (rs.method == 'camera_photo_take') { + if (rs.data.result == 0) { + createMessage.success('拍照成功'); + } else { + createMessage.error('拍照失败,' + errorName(rs.data.result)); + } + } + if ( + rs.method == 'flighttask_progress' && + rs.data.output.status == 'in_progress' && + id == '' + ) { + id = rs.data.output.ext.flight_id; + createMessage.info('正在获取数据,预计需要一分钟,请稍后'); + setTimeout(() => { + getTaskPicList({ + flightId: id, + timestamp: time, + }).then(async (res) => { + if (res) { + await base64ByURL(res.pictureLink).then((urlres) => { + let { blob } = urlres; + res.imgBlob = blob; + }); + createMessage.success('获取数据成功'); + } else { + createMessage.error('获取数据失败,请稍后重试'); + } + resolve(callback(res)); + }); + }, 50000); + } + }); + }); } startVideoRecording() { /** @@ -168,13 +247,26 @@ class LiveStreamPlugin { }); servicesTopic(sn, { bid: bid, - method: 'camera_recording_start', + method: 'camera_mode_switch', tid: buildGUID(), timestamp: new Date().getTime(), data: { + camera_mode: 1, payload_index: uav.camera_index, }, }); + setTimeout(() => { + video_time = new Date().getTime(); + servicesTopic(sn, { + bid: bid, + method: 'camera_recording_start', + tid: buildGUID(), + timestamp: video_time, + data: { + payload_index: uav.camera_index, + }, + }); + }, 1000); } endVideoRecording(callback: Function) { /** @@ -184,17 +276,59 @@ class LiveStreamPlugin { * true/false; */ console.log('LiveStreamPlugin endVideoRecording', callback); + const time = new Date().getTime(); + servicesTopic(sn, { bid: bid, method: 'camera_recording_stop', tid: buildGUID(), - timestamp: new Date().getTime(), + timestamp: time, data: { payload_index: uav.camera_index, }, }); - const data = {}; - callback(data); + client.subscribe('thing/product/' + sn + '/events', { qos: 2 }, () => {}); + // 接收消息 + let id = ''; + return new Promise((resolve, reject) => { + client.on('message', async (topic, message) => { + const rs = JSON.parse(message); + if (rs.method == 'camera_recording_stop') { + if (rs.data.result == 0) { + createMessage.success('结束录像成功'); + } else { + createMessage.error('结束录像失败,' + errorName(rs.data.result)); + } + } + if ( + rs.method == 'flighttask_progress' && + rs.data.output.status == 'in_progress' && + id == '' + ) { + id = rs.data.output.ext.flight_id; + createMessage.info('正在获取数据,预计需要五分钟,请稍后'); + setTimeout(() => { + getTaskVideoList({ + flightId: id, + timestamp: video_time, + }).then(async (res) => { + if (res) { + await base64ByURL(res.videoLink).then((urlres) => { + let { blob } = urlres; + console.log(blob); + res.videoBlob = blob; + console.log(res); + }); + createMessage.success('获取数据成功'); + } else { + createMessage.error('获取数据失败,请稍后重试'); + } + resolve(callback(res)); + }); + }, 300000); + } + }); + }); } disposeSDK() { /** diff --git a/src/plugin/video/src/config.ts b/src/plugin/video/src/config.ts index 3722a60..3f2aa1c 100644 --- a/src/plugin/video/src/config.ts +++ b/src/plugin/video/src/config.ts @@ -29,3 +29,24 @@ export function buildGUID(): string { } return guid; } + +// 图片地址 转为 blob 、base64格式 imgUrl类型为字符串string +export function base64ByURL(imgUrl) { + // 两大重点 Promise XMLHttpRequest + return new Promise((resolve) => { + var xhr = new XMLHttpRequest(); + xhr.open('get', imgUrl, true); + xhr.responseType = 'blob'; + xhr.onload = function () { + if (this.status == 200) { + let blob = this.response; + let oFileReader = new FileReader(); + oFileReader.onloadend = function (e) { + resolve({ blob, base64: e.target.result }); + }; + oFileReader.readAsDataURL(blob); + } + }; + xhr.send(); + }); +} diff --git a/src/views/demo/provincetasks/index.vue b/src/views/demo/provincetasks/index.vue new file mode 100644 index 0000000..5f2a685 --- /dev/null +++ b/src/views/demo/provincetasks/index.vue @@ -0,0 +1,49 @@ + + + + + + \ No newline at end of file diff --git a/src/views/demo/provincetasks/utils.ts b/src/views/demo/provincetasks/utils.ts new file mode 100644 index 0000000..78df161 --- /dev/null +++ b/src/views/demo/provincetasks/utils.ts @@ -0,0 +1,40 @@ +import { BasicColumn, FormSchema } from '@/components/Table'; +export const columns = [ + { + title: '业务类型', + dataIndex: 'bizidname', + }, + { + title: '下发任务名称', + dataIndex: 'taskname', + }, + { + title: '数据类型', + dataIndex: 'datacode', + }, + { + title: '地块编号', + dataIndex: 'dkbh', + }, + { + title: '地块名称', + dataIndex: 'dkmc', + }, + { + title: '地块面积', + dataIndex: 'dkmc', + }, + { + title: '备注', + dataIndex: 'bz', + } +]; + +export const searchFormSchema: FormSchema[] = [ + { + field: 'keyWord', + label: '名称', + component: 'Input', + colProps: { span: 6 }, + }, +]; diff --git a/src/views/demo/system/mediaLibrary/index.vue b/src/views/demo/system/mediaLibrary/index.vue index e70d46f..f366568 100644 --- a/src/views/demo/system/mediaLibrary/index.vue +++ b/src/views/demo/system/mediaLibrary/index.vue @@ -84,22 +84,50 @@ @@ -255,12 +283,9 @@ import Preview from './preview/index.vue'; import Comparison from './comparison/index.vue'; import Path from './path/index.vue'; - import { AddFolderModal } from './modal/modal'; - import { MoveFileModal } from './modal/modal'; - import { CompressFileModal } from './modal/modal'; - import { RenameModal } from './modal/modal'; + import { AddFolderModal, MoveFileModal, CompressFileModal, RenameModal } from './modal/modal'; import { PermissionBtn } from '@/components/PermissionBtn/index'; - import { columns, searchFormSchema } from './modal.data'; + import { columns, searchFormSchema, svg_showOnMap_0, svg_showOnMap_1 } from './modal.data'; import dayjs from 'dayjs'; import { cloneDeep } from 'lodash-es'; @@ -275,6 +300,7 @@ watch( () => tableType.value, (newval) => { + showTableData.value = getDataSource(); // 表格 const containers = document.querySelectorAll('.ant-table-container'); if (newval) { @@ -424,8 +450,9 @@ nowParentKey.value = f.id; floders.value = floders.value.splice(0, index + 1); clearSelectedRowKeys(); - reload(); - showTableData.value = getDataSource(); + reload().then((res) => { + showTableData.value = res; + }); } // 图片获取路径 function getImgurl(url) { @@ -549,6 +576,23 @@ }); } + // 加载到地图上 + function funShowOnMap(record) { + UpdatePicStatus({ + id: record.id, + fileTags: record.fileTags, + graffitiJson: record.graffitis, + display: record.display, + showOnMap: record.showOnMap == 1 ? 0 : 1, + }).then((res) => { + if (record.showOnMap == 1) { + createMessage.success('在地图上取消加载成功'); + } else { + createMessage.success('在地图上加载成功'); + } + reload(); + }); + } // 查看弹窗---------------------------------------------------------------------------- const open = ref(false); // 目前展示图片 @@ -563,7 +607,9 @@ id: nowParentKey.value, name: record.name, }); - reload(); + reload().then((res) => { + showTableData.value = res; + }); } else { GetMediaFile({ ...searchParams.value, @@ -683,6 +729,7 @@ function handleSuccessPath() { setTimeout(() => { openPathModal(nowShowImageData.value); + reload(); }, 500); } @@ -763,6 +810,12 @@ } } + .svg-container { + display: flex; + align-items: center; + justify-content: center; + } + ::v-deep .vben-basic-table { height: fit-content !important; } diff --git a/src/views/demo/system/mediaLibrary/modal.data.ts b/src/views/demo/system/mediaLibrary/modal.data.ts index b1d4654..1deb125 100644 --- a/src/views/demo/system/mediaLibrary/modal.data.ts +++ b/src/views/demo/system/mediaLibrary/modal.data.ts @@ -201,4 +201,30 @@ export const renameSchema: FormSchema[] = [ label: '新名称', required: true, } -]; \ No newline at end of file +]; + +export const svg_showOnMap_1 = ` + +`; + +export const svg_showOnMap_0 = ` + +`; \ No newline at end of file diff --git a/src/views/demo/system/mediaLibrary/modal/RenameModal.vue b/src/views/demo/system/mediaLibrary/modal/RenameModal.vue index 8dfb4b5..9dd098c 100644 --- a/src/views/demo/system/mediaLibrary/modal/RenameModal.vue +++ b/src/views/demo/system/mediaLibrary/modal/RenameModal.vue @@ -22,13 +22,16 @@ }); // 上级文件夹的id - let id = ref(); + const id = ref(); + const recordData: any = ref({}); const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { resetFields(); setModalProps({ confirmLoading: false }); + recordData.value = data.record; id.value = data.record?.id; + let editName: any = recordData.value.name.split('.').slice(0, -1).join('.'); setFieldsValue({ - ...data.record, + name: editName, }); }); @@ -36,9 +39,15 @@ async function handleSubmit() { try { const values = await validate(); + let newName = ''; + if (recordData.value.name.split('.').length <= 1) { + newName = values.name; + } else { + newName = values.name + '.' + recordData.value.name.split('.').pop(); + } let query = { id: id.value, - name: values.name, + name: newName, }; UpdatePicName(query).then((res) => { emits('handleSuccess'); diff --git a/src/views/demo/system/mediaLibrary/path/index.vue b/src/views/demo/system/mediaLibrary/path/index.vue index 9a17696..32a88ee 100644 --- a/src/views/demo/system/mediaLibrary/path/index.vue +++ b/src/views/demo/system/mediaLibrary/path/index.vue @@ -17,6 +17,7 @@ @closePathModal="closePathModal" @setNowShowImageData="setNowShowImageData" @handleSuccessPath="handleSuccessPath" + @funUpdateDisplayOrShowOnMapData="funUpdateDisplayOrShowOnMapData" /> @@ -27,6 +28,7 @@ :nowShowImageData="nowShowImageData" @setNowShowImageData="setNowShowImageData" @setAllImageData="setAllImageData" + :updateDisplayOrShowOnMapData="updateDisplayOrShowOnMapData" /> @@ -37,6 +39,7 @@ @setNowShowImageData="setNowShowImageData" @handlerLocation="handlerLocation" @handleSuccessPath="handleSuccessPath" + @funUpdateDisplayOrShowOnMapData="funUpdateDisplayOrShowOnMapData" /> @@ -78,6 +81,11 @@ // 当前展示的图片 const nowShowImageData = ref(); const allImageDataList = ref(); + // 修改display或者showOnMap + const updateDisplayOrShowOnMapData = ref(); + function funUpdateDisplayOrShowOnMapData(value) { + updateDisplayOrShowOnMapData.value = value; + } watch( () => props.nowShowImageData, diff --git a/src/views/demo/system/mediaLibrary/path/path.ts b/src/views/demo/system/mediaLibrary/path/path.ts index 0ae00a1..e125c58 100644 --- a/src/views/demo/system/mediaLibrary/path/path.ts +++ b/src/views/demo/system/mediaLibrary/path/path.ts @@ -1,5 +1,3 @@ export { default as PathLeftMenu } from './pathLeftMenu.vue'; export { default as PathMap } from './pathMap.vue'; export { default as PathImageInfo } from './pathImageInfo.vue'; -export { default as PathAnnotationInfo } from './pathAnnotationInfo.vue'; -export { default as PathAreaInfo } from './pathAreaInfo.vue'; diff --git a/src/views/demo/system/mediaLibrary/path/pathAnnotationInfo.vue b/src/views/demo/system/mediaLibrary/path/pathAnnotationInfo.vue deleted file mode 100644 index a2bfac6..0000000 --- a/src/views/demo/system/mediaLibrary/path/pathAnnotationInfo.vue +++ /dev/null @@ -1,678 +0,0 @@ - - - diff --git a/src/views/demo/system/mediaLibrary/path/pathAreaInfo.vue b/src/views/demo/system/mediaLibrary/path/pathAreaInfo.vue deleted file mode 100644 index 2165b03..0000000 --- a/src/views/demo/system/mediaLibrary/path/pathAreaInfo.vue +++ /dev/null @@ -1,373 +0,0 @@ - - - diff --git a/src/views/demo/system/mediaLibrary/path/pathImageInfo.vue b/src/views/demo/system/mediaLibrary/path/pathImageInfo.vue index ec990e5..979434c 100644 --- a/src/views/demo/system/mediaLibrary/path/pathImageInfo.vue +++ b/src/views/demo/system/mediaLibrary/path/pathImageInfo.vue @@ -445,46 +445,55 @@ -
- - - - - - - - - +
+ + + + + + + + + + +
item.display == 1 && item.showOnMap == 1); for (let index = 0; index < list.length; index++) { if (list[index].id == props.nowShowImageData.id) { if (direction == 'left') { @@ -781,6 +791,7 @@ } else { createMessage.success('在地图上取消加载成功'); } + emits('funUpdateDisplayOrShowOnMapData', props.nowShowImageData); emits('handleSuccessPath'); }); } @@ -1058,37 +1069,37 @@ //------------------------------------------------------------------------ // 鼠标聚焦 function mouseenter(rect, type) { - if (rect.status != 'edit') { - rect.status = 'mouse'; - document.body.style.cursor = 'pointer'; - } - if (rect.status == 'edit') { - if (type == 'top' || type == 'bottom') { - document.body.style.cursor = 'ns-resize'; - } - if (type == 'left' || type == 'right') { - document.body.style.cursor = 'ew-resize'; - } - if (type == 'leftTop' || type == 'rightBottom') { - document.body.style.cursor = 'nwse-resize'; - } - if (type == 'leftBottom' || type == 'rightTop') { - document.body.style.cursor = 'nesw-resize'; - } - } + // if (rect.status != 'edit') { + // rect.status = 'mouse'; + // document.body.style.cursor = 'pointer'; + // } + // if (rect.status == 'edit') { + // if (type == 'top' || type == 'bottom') { + // document.body.style.cursor = 'ns-resize'; + // } + // if (type == 'left' || type == 'right') { + // document.body.style.cursor = 'ew-resize'; + // } + // if (type == 'leftTop' || type == 'rightBottom') { + // document.body.style.cursor = 'nwse-resize'; + // } + // if (type == 'leftBottom' || type == 'rightTop') { + // document.body.style.cursor = 'nesw-resize'; + // } + // } } // 鼠标离开 function mouseleave(rect) { - if (rect.status == 'mouse' || rect.status == 'edit') { - if (rect.status == 'mouse') { - rect.status = 'success'; - } - if (graffitiFlag.value) { - document.body.style.cursor = 'crosshair'; - } else { - document.body.style.cursor = 'pointer'; - } - } + // if (rect.status == 'mouse' || rect.status == 'edit') { + // if (rect.status == 'mouse') { + // rect.status = 'success'; + // } + // if (graffitiFlag.value) { + // document.body.style.cursor = 'crosshair'; + // } else { + // document.body.style.cursor = 'pointer'; + // } + // } } // 编辑状态下的鼠标按下 const mouseEditType = ref(''); @@ -1264,7 +1275,7 @@ .imageChooseList { display: inline-flex; align-items: center; - justify-content: center; + // justify-content: center; overflow-x: auto; white-space: nowrap; width: 80%; diff --git a/src/views/demo/system/mediaLibrary/path/pathLeftMenu.vue b/src/views/demo/system/mediaLibrary/path/pathLeftMenu.vue index 83cd971..99744a6 100644 --- a/src/views/demo/system/mediaLibrary/path/pathLeftMenu.vue +++ b/src/views/demo/system/mediaLibrary/path/pathLeftMenu.vue @@ -105,43 +105,25 @@ - - -
- - - - - - -
-
+ + + +
+
+
+
+ +
@@ -181,6 +163,7 @@ CheckCircleOutlined, StopOutlined, } from '@ant-design/icons-vue'; + import { showOnMap_1, showOnMap_0 } from './svg'; import { UpdatePicStatus, Deletepic, @@ -198,6 +181,7 @@ 'closePathModal', 'setNowShowImageData', 'handleSuccessPath', + 'funUpdateDisplayOrShowOnMapData', ]); const showMenuInfoList = ref(props.allImageDataList); const showMenuInfoName = ref('地图照片'); @@ -227,35 +211,6 @@ const tagSelect = ref([]); const tagOptions: any = ref([]); - watch( - () => props.allImageDataList, - () => { - filterAfterImageDataList.value = props.allImageDataList; - // 标签选项 - let tagList: any = []; - tagOptions.value = []; - props.allImageDataList.forEach((item) => { - if (item.fileTags && item.fileTags.length > 0) { - item.fileTags.forEach((tag) => { - if (!tagList.includes(tag)) { - tagList.push(tag); - } - }); - } - }); - tagList.forEach((tag) => { - tagOptions.value.push({ - value: tag, - label: tag, - }); - }); - }, - { - deep: true, - immediate: true, - }, - ); - // 图片类型 const imageTypeSelect = ref([]); const imageOptions: any = ref([ @@ -283,7 +238,8 @@ // 按照媒体名称搜索 const searchValue = ref(''); function handleChangeImageSearch() { - let filterImageData = props.allImageDataList; + // let filterImageData = props.allImageDataList; + let filterImageData = props.allImageDataList.filter((item) => item.showOnMap == 1); // 标签筛选 if (tagSelect.value.length > 0) { tagSelect.value.forEach((tag) => { @@ -304,9 +260,38 @@ showMenuInfoList.value = filterAfterImageDataList.value; } + watch( + () => props.allImageDataList, + () => { + filterAfterImageDataList.value = props.allImageDataList; + // 标签选项 + let tagList: any = []; + tagOptions.value = []; + props.allImageDataList.forEach((item) => { + if (item.fileTags && item.fileTags.length > 0) { + item.fileTags.forEach((tag) => { + if (!tagList.includes(tag)) { + tagList.push(tag); + } + }); + } + }); + tagList.forEach((tag) => { + tagOptions.value.push({ + value: tag, + label: tag, + }); + }); + handleChangeImageSearch(); + }, + { + deep: true, + immediate: true, + }, + ); + // 加载到地图上 function funShowOnMapOrDisplay(show, type) { - console.log(show.showOnMap); if (type == 'showOnMap') { if (show.showOnMap == 1) { show.showOnMap = 0; @@ -336,6 +321,7 @@ } } emits('handleSuccessPath'); + emits('funUpdateDisplayOrShowOnMapData', show); }); } @@ -475,4 +461,9 @@ justify-content: center; border-radius: 5px; } + .svg-container { + display: flex; + align-items: center; + justify-content: center; + } diff --git a/src/views/demo/system/mediaLibrary/path/pathMap.vue b/src/views/demo/system/mediaLibrary/path/pathMap.vue index f99070a..c9eeed3 100644 --- a/src/views/demo/system/mediaLibrary/path/pathMap.vue +++ b/src/views/demo/system/mediaLibrary/path/pathMap.vue @@ -9,7 +9,6 @@ import { ref, watch, onMounted, defineEmits } from 'vue'; import * as mars3d from 'mars3d'; import * as Cesium from 'mars3d-cesium'; - import { circle, rect, triangle } from './svg'; import { CheckOutlined, AntDesignOutlined, @@ -23,36 +22,16 @@ AddWorkArea, UpdateWorkArea, } from '@/api/demo/mediaLibrary'; - import { - locateBack, - defaultIcon, - fireIcon, - peopleIcon, - warnIcon, - carIcon, - checkIcon, - closeIcon, - } from './svg'; import * as turf from '@turf/turf'; import { WktToGeojson, GeojsonToWkt } from '@/components/MapboxMaps/src/WktGeojsonTransform'; import dayjs from 'dayjs'; const props = defineProps([ - 'allAnnotationDataList', - 'nowShowAnnotationData', 'allImageDataList', 'nowShowImageData', - 'allAreaDataList', - 'nowShowAreaData', - ]); - const emits = defineEmits([ - 'setNowShowAnnotationData', - 'setNowShowImageData', - 'setNowShowAreaData', - 'setAllAnnotationData', - 'setAllImageData', - 'setAllAreaData', + 'updateDisplayOrShowOnMapData', ]); + const emits = defineEmits(['setNowShowImageData', 'setAllImageData']); const vChartRef: any = ref(); let map: mars3d.Map; // 地图对象 @@ -61,13 +40,13 @@ }); // 地图照片 // 地图照片-地面点 - let image_bottomPointGraphicData: any = []; + let bottomPointGraphicData: any = []; // 地图照片-飞行点 - let image_flightointGraphicData: any = []; + let flightointGraphicData: any = []; // 地图照片-地面点到展示图片的线 - let image_bottomImagePolylineGraphicData: any = []; + let bottomImagePolylineGraphicData: any = []; // 地图照片-展示图片 - let image_imageGraphicData: any = []; + let imageGraphicData: any = []; onMounted(() => { initMap(); @@ -306,32 +285,129 @@ } }; + watch( + () => props.updateDisplayOrShowOnMapData, + (newValue) => { + if (newValue) { + // 地图照片-地面点 + bottomPointGraphicData.forEach((graphicLayer) => { + if (graphicLayer.options.id == newValue.id + '_bottom') { + if (newValue.showOnMap == 1) { + graphicLayer.show = newValue.display == 1 ? true : false; + } else { + graphicLayers.removeGraphic(graphicLayer); + } + } + }); + // 地图照片-飞行点 + flightointGraphicData.forEach((graphicLayer) => { + if (graphicLayer.options.id == newValue.id + '_flight') { + if (newValue.showOnMap == 1) { + if (newValue.id == props.nowShowImageData.id) { + graphicLayer.show = newValue.display == 1 ? true : false; + } + } else { + graphicLayers.removeGraphic(graphicLayer); + } + } + }); + // 地图照片-地面点到展示图片的线 + bottomImagePolylineGraphicData.forEach((graphicLayer) => { + if (graphicLayer.options.id == newValue.id + '_polyline') { + if (newValue.showOnMap == 1) { + graphicLayer.show = newValue.display == 1 ? true : false; + } else { + graphicLayers.removeGraphic(graphicLayer); + } + } + }); + // 地图照片-展示图片 + imageGraphicData.forEach((graphicLayer) => { + if (graphicLayer.options.id == newValue.id + '_image') { + if (newValue.showOnMap == 1) { + graphicLayer.show = newValue.display == 1 ? true : false; + graphicLayer.setStyle({ + label: { + text: `${newValue.name}`, + }, + }); + } else { + graphicLayers.removeGraphic(graphicLayer); + } + } + }); + } + }, + { + deep: true, + }, + ); + + // watch( + // () => props.nowShowImageData, + // (newValue) => { + // if (newValue) { + // // 地图照片-地面点 + // bottomPointGraphicData.forEach((graphicLayer) => { + // if (graphicLayer.options.id == newValue.id + '_bottom') { + // graphicLayer.show = newValue.display == 1 ? true : false; + // } + // }); + // // 地图照片-飞行点 + // // flightointGraphicData.forEach((graphicLayer) => { + // // if (graphicLayer.options.id == newValue.id + '_flight') { + // // } + // // }); + // // 地图照片-地面点到展示图片的线 + // bottomImagePolylineGraphicData.forEach((graphicLayer) => { + // if (graphicLayer.options.id == newValue.id + '_polyline') { + // graphicLayer.show = newValue.display == 1 ? true : false; + // } + // }); + // // 地图照片-展示图片 + // imageGraphicData.forEach((graphicLayer) => { + // if (graphicLayer.options.id == newValue.id + '_image') { + // graphicLayer.show = newValue.display == 1 ? true : false; + // graphicLayer.setStyle({ + // label: { + // text: `${newValue.name}`, + // }, + // }); + // } + // }); + // } + // }, + // { + // deep: true, + // }, + // ); + // 地图照片-------------------------------------------------------------------- // 地图照片-初始化-遍历展示 const showAllImageDataList = async () => { // 删除旧数据 - image_bottomPointGraphicData?.forEach((graphicLayer) => { + bottomPointGraphicData?.forEach((graphicLayer) => { graphicLayers.removeGraphic(graphicLayer); }); - image_flightointGraphicData?.forEach((graphicLayer) => { + flightointGraphicData?.forEach((graphicLayer) => { graphicLayers.removeGraphic(graphicLayer); }); - image_bottomImagePolylineGraphicData?.forEach((graphicLayer) => { + bottomImagePolylineGraphicData?.forEach((graphicLayer) => { graphicLayers.removeGraphic(graphicLayer); }); - image_imageGraphicData?.forEach((graphicLayer) => { + imageGraphicData?.forEach((graphicLayer) => { graphicLayers.removeGraphic(graphicLayer); }); // 图层数据 - image_bottomPointGraphicData = []; - image_flightointGraphicData = []; - image_bottomImagePolylineGraphicData = []; - image_imageGraphicData = []; + bottomPointGraphicData = []; + flightointGraphicData = []; + bottomImagePolylineGraphicData = []; + imageGraphicData = []; // 地图照片-遍历 let rotation = 0; props.allImageDataList.forEach((item, index) => { - if (item.lng && item.lat && item.absoluteAltitude) { + if (item.lng && item.lat && item.absoluteAltitude && item.showOnMap == 1) { const image = new Image(); image.crossOrigin = 'Anonymous'; // image.src = item.preview_url; @@ -384,6 +460,7 @@ verticalOrigin: Cesium.VerticalOrigin.BOTTOM, }, hasEdit: false, + show: item.display == 1 ? true : false, }); if (index + 1 < props.allImageDataList.length) { const afterItem = props.allImageDataList[index + 1]; @@ -420,6 +497,7 @@ clampToGround: false, }, hasEdit: false, + show: item.display == 1 ? true : false, // 用于恢复默认 defaultPosition: position, // 地形高度 @@ -447,6 +525,7 @@ }, }, hasEdit: false, + show: item.display == 1 ? true : false, // 用于恢复默认 defaultImage: dataURL1, // 用于外侧修改图片 @@ -520,10 +599,10 @@ // 展示图片 添加到图层中 graphicLayers.addGraphic(imageGraphic); // 数据 - image_bottomPointGraphicData.push(bottomPointGraphic); - image_flightointGraphicData.push(flightointGraphic); - image_bottomImagePolylineGraphicData.push(bottomImagePolylineGraphic); - image_imageGraphicData.push(imageGraphic); + bottomPointGraphicData.push(bottomPointGraphic); + flightointGraphicData.push(flightointGraphic); + bottomImagePolylineGraphicData.push(bottomImagePolylineGraphic); + imageGraphicData.push(imageGraphic); }); }; } @@ -536,13 +615,13 @@ // 地图照片-恢复默认 function imageRestoreDefault() { // 飞行点 - for (let i = 0; i < image_flightointGraphicData.length; i++) { - let flightointGraphic = image_flightointGraphicData[i]; + for (let i = 0; i < flightointGraphicData.length; i++) { + let flightointGraphic = flightointGraphicData[i]; flightointGraphic.show = false; } // 地面点到展示图片的线 - for (let i = 0; i < image_bottomImagePolylineGraphicData.length; i++) { - let bottomImagePolylineGraphic = image_bottomImagePolylineGraphicData[i]; + for (let i = 0; i < bottomImagePolylineGraphicData.length; i++) { + let bottomImagePolylineGraphic = bottomImagePolylineGraphicData[i]; let defaultPosition = bottomImagePolylineGraphic.options.defaultPosition; let surfaceHeight = bottomImagePolylineGraphic.options.surfaceHeight; bottomImagePolylineGraphic.setStyle({ @@ -554,8 +633,8 @@ ]; } // 展示图片 - for (let i = 0; i < image_imageGraphicData.length; i++) { - let imageGraphic = image_imageGraphicData[i]; + for (let i = 0; i < imageGraphicData.length; i++) { + let imageGraphic = imageGraphicData[i]; let defaultImage = imageGraphic.options.defaultImage; imageGraphic.setStyle({ image: defaultImage, @@ -572,18 +651,16 @@ // 全部恢复默认 imageRestoreDefault(); // 飞行点 - for (let i = 0; i < image_flightointGraphicData.length; i++) { - if (image_flightointGraphicData[i].options.id.includes(props.nowShowImageData.id)) { - let flightointGraphic = image_flightointGraphicData[i]; + for (let i = 0; i < flightointGraphicData.length; i++) { + if (flightointGraphicData[i].options.id.includes(props.nowShowImageData.id)) { + let flightointGraphic = flightointGraphicData[i]; flightointGraphic.show = true; } } // 地面点到展示图片的线 - for (let i = 0; i < image_bottomImagePolylineGraphicData.length; i++) { - if ( - image_bottomImagePolylineGraphicData[i].options.id.includes(props.nowShowImageData.id) - ) { - let bottomImagePolylineGraphic = image_bottomImagePolylineGraphicData[i]; + for (let i = 0; i < bottomImagePolylineGraphicData.length; i++) { + if (bottomImagePolylineGraphicData[i].options.id.includes(props.nowShowImageData.id)) { + let bottomImagePolylineGraphic = bottomImagePolylineGraphicData[i]; let defaultPosition = bottomImagePolylineGraphic.options.defaultPosition; let surfaceHeight = bottomImagePolylineGraphic.options.surfaceHeight; bottomImagePolylineGraphic.setStyle({ @@ -600,9 +677,9 @@ } } // 展示图片 - for (let i = 0; i < image_imageGraphicData.length; i++) { - if (image_imageGraphicData[i].options.id.includes(props.nowShowImageData.id)) { - let imageGraphic = image_imageGraphicData[i]; + for (let i = 0; i < imageGraphicData.length; i++) { + if (imageGraphicData[i].options.id.includes(props.nowShowImageData.id)) { + let imageGraphic = imageGraphicData[i]; let chooseImage = imageGraphic.options.chooseImage; imageGraphic.setStyle({ image: chooseImage, @@ -652,73 +729,4 @@ width: 100%; height: 100%; } - - .annotationButtons { - position: absolute; - display: flex; - flex-wrap: wrap; - top: 10%; - right: 1%; - width: 30px; - height: 123px; - gap: 1px; - } - - .button_nochoose { - background: #ffffff; - z-index: 200; - width: 30px; - height: 30px; - // border-radius: 3px; - display: flex; - align-items: center; - justify-content: center; - - &:hover { - border: 2px solid #2b85e4; - outline: 1px solid #2b85e4; - } - } - .button_choose { - background: linear-gradient(to bottom left, #2b85e4 10px, transparent 1px), #ffffff; - background-size: - 100% 100%, - auto; - z-index: 200; - width: 30px; - height: 30px; - // border-radius: 3px; - display: flex; - align-items: center; - justify-content: center; - outline: 2px solid #2b85e4; - } - - .popoverAnnotation { - width: 18px; - height: 18px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 3px; - } - - .areaButtons { - position: absolute; - display: flex; - align-items: center; - justify-content: center; - top: 30%; - right: 1%; - width: 30px; - height: 30px; - } - - .popoverArea { - display: inline-flex; - align-items: center; - justify-content: flex-start; - width: 170px; - height: 35px; - } diff --git a/src/views/demo/system/mediaLibrary/path/svg.ts b/src/views/demo/system/mediaLibrary/path/svg.ts index 8351f18..29c7a8e 100644 --- a/src/views/demo/system/mediaLibrary/path/svg.ts +++ b/src/views/demo/system/mediaLibrary/path/svg.ts @@ -1,271 +1,25 @@ -export const line_start_cap_0 = ` - - - - - + `; -export const line_start_cap_1 = ` - - - - - -`; - -export const line_start_cap_2 = ` - - - - - - - - - - -`; - -export const line_start_cap_3 = ` - - - - - - - - - - -`; - -export const line_end_cap_0 = ` - - - - - -`; - -export const line_end_cap_1 = ` - - - - - -`; - -export const line_end_cap_2 = ` - - - - - - - - - - -`; - -export const line_end_cap_3 = ` - - - - - - - - - - -`; - -export const circle = ` - - -`; - -export const rect = ` - - -`; - -export const triangle = ` - - -`; - - -export const defaultIcon = ` - - - - - - - -`; -export const locateBack = ` - - - - - - - - -`; - -export const fireIcon = ` -`; -export const peopleIcon = ` - -`; -export const warnIcon = ` -`; -export const carIcon = ` - -`; -export const checkIcon = ` - -`; -export const closeIcon = ` -`; \ No newline at end of file + +`; \ No newline at end of file diff --git a/src/views/demo/system/mediaLibrary/preview/previewImage.vue b/src/views/demo/system/mediaLibrary/preview/previewImage.vue index 7a3e3f7..b33f465 100644 --- a/src/views/demo/system/mediaLibrary/preview/previewImage.vue +++ b/src/views/demo/system/mediaLibrary/preview/previewImage.vue @@ -1144,7 +1144,7 @@ .imageList { display: inline-flex; - // align-items: center; + align-items: center; // justify-content: center; width: 900px; height: 65px; diff --git a/src/views/demo/workmanagement/ceshi/index.vue b/src/views/demo/workmanagement/ceshi/index.vue index 813c961..696ad92 100644 --- a/src/views/demo/workmanagement/ceshi/index.vue +++ b/src/views/demo/workmanagement/ceshi/index.vue @@ -6,7 +6,8 @@ 结束录像 释放资源 获取航线任务 - 展示视频直播 + 展示机场直播 + 展示无人机直播 拍照
@@ -20,7 +21,7 @@ liveStreamPlugin.startLiveStreamCall('8UUXN5400A079H', 1); }; const startUAV = () => { - liveStreamPlugin.startLiveStreamCall('1581F8HGX254V00A0BUY', 0); + liveStreamPlugin.startLiveStreamCall('8UUXN5400A079H', 0); }; const startRecording = () => { liveStreamPlugin.startVideoRecording(); @@ -39,6 +40,9 @@ console.log(document.getElementById('live-div')); liveStreamPlugin.setLiveStreamControl(document.getElementById('live-div'), '1'); }; + const uavLive = () => { + liveStreamPlugin.setLiveStreamControl(document.getElementById('live-div'), '0'); + }; const takePhoto = () => { liveStreamPlugin.takePicture((res) => { console.log(res); diff --git a/src/views/demo/workmanagement/device/Aerocraft/index.vue b/src/views/demo/workmanagement/device/Aerocraft/index.vue index 59a0dde..d78fd50 100644 --- a/src/views/demo/workmanagement/device/Aerocraft/index.vue +++ b/src/views/demo/workmanagement/device/Aerocraft/index.vue @@ -134,7 +134,7 @@ const delDate = (record) => { const exportDevice = () => { ExportDevice().then(res => { const elink = document.createElement('a'); - elink.download = '飞行器信息.xlsx'; + elink.download = '飞行器信息.txt'; elink.style.display = 'none'; elink.href = URL.createObjectURL(res); document.body.appendChild(elink); diff --git a/src/views/demo/workmanagement/device/Airport/DeviceWarning/index.vue b/src/views/demo/workmanagement/device/Airport/DeviceWarning/index.vue index 87093d0..bf3ca42 100644 --- a/src/views/demo/workmanagement/device/Airport/DeviceWarning/index.vue +++ b/src/views/demo/workmanagement/device/Airport/DeviceWarning/index.vue @@ -49,8 +49,13 @@ const [registerTable, { reload, expandAll, getForm}] = useTable({ // 显示表格设置工具 showTableSetting: true, bordered: true, - beforeFetch(data) { - return data + beforeFetch(params) { + if(params.time){ + params.startTime = params.time[0] + params.endTime = params.time[1] + } + params.time = null + return params }, afterFetch(data) { }, diff --git a/src/views/demo/workmanagement/flightannotation/pathMap.vue b/src/views/demo/workmanagement/flightannotation/pathMap.vue index 08e2044..67c1223 100644 --- a/src/views/demo/workmanagement/flightannotation/pathMap.vue +++ b/src/views/demo/workmanagement/flightannotation/pathMap.vue @@ -116,7 +116,6 @@ import { ref, watch, onMounted, defineEmits } from 'vue'; import * as mars3d from 'mars3d'; import * as Cesium from 'mars3d-cesium'; - import { circle, rect, triangle } from './svg'; import { CheckOutlined, AntDesignOutlined, diff --git a/src/views/demo/workmanagement/flightoperation/src/AirportLive.vue b/src/views/demo/workmanagement/flightoperation/src/AirportLive.vue index c4c1dcf..b28dd7b 100644 --- a/src/views/demo/workmanagement/flightoperation/src/AirportLive.vue +++ b/src/views/demo/workmanagement/flightoperation/src/AirportLive.vue @@ -120,11 +120,7 @@ // tid: buildGUID(), // timestamp: new Date().getTime(), // data: { - // air_transfer_enable: 1, - // cameras: { - // zoom_factor: 2, - // ir_zoom_factor: 2, - // }, + // air_transfer_enable: true, // }, // }; // console.log(querys); diff --git a/src/views/demo/workmanagement/flightoperation/src/FlightControl.vue b/src/views/demo/workmanagement/flightoperation/src/FlightControl.vue index d98e9ec..a2e88cc 100644 --- a/src/views/demo/workmanagement/flightoperation/src/FlightControl.vue +++ b/src/views/demo/workmanagement/flightoperation/src/FlightControl.vue @@ -550,7 +550,7 @@ } } else { drc_eart_beat(); - createMessage.error('DRC连接失败,' + errorName(rs.data.result)); + createMessage.error('DRC连接中断,' + errorName(rs.data.result) + ',正在重新连接'); } } // 指点飞行