husq
2023-09-29 9c9038b7b7967408d6d99babcd4e09a7936e6646
Merge branch 'demo' of http://s16s652780.51mypc.cn:49896/r/yskj/iot_drone_web into demo
4 files modified
127 ■■■■ changed files
src/api/media.ts 8 ●●●●● patch | view | raw | blame | history
src/components/MediaPanel.vue 31 ●●●● patch | view | raw | blame | history
src/components/g-map/DroneControlPanel.vue 88 ●●●● patch | view | raw | blame | history
src/router/index.ts patch | view | raw | blame | history
src/api/media.ts
@@ -2,7 +2,6 @@
import request, { IPage, IWorkspaceResponse } from '/@/api/http/request'
const HTTP_PREFIX = '/media/api/v1'
export interface MediaQueryParam{
  subFileType?:any
  payload?:any
@@ -10,12 +9,6 @@
  endTime?:string
  name?:string
}
// Get Media Files
export const getMediaFiles = async function (wid: string, pagination: IPage,params:MediaQueryParam): Promise<IWorkspaceResponse<any>> {
@@ -30,7 +23,6 @@
  const result = await request.get(url,{params})
  return result.data
}
// Download Media File
export const downloadMediaFile = async function (workspaceId: string, fileId: string): Promise<any> {
src/components/MediaPanel.vue
@@ -9,7 +9,8 @@
    </div>
    <div class="search-part">
      <a-select v-model:value="subFileTypeArr" allowClear @change="subFileTypeChange" :options="subFileTypeOptions"
            <a-select v-model:value="subFileTypeArr" allowClear @change="subFileTypeChange"
                      :options="subFileTypeOptions"
                :maxTagCount="searchPanelOptions.maxTagCount" mode="multiple"
                :size="searchPanelOptions.size" placeholder="所有类型" style="width: 300px">
      </a-select>
@@ -122,7 +123,7 @@
const showVideo = ref(false)
const videoPlayerId = ref('videoPlayerId')
// 文件前缀
const prefix = 'https://dev.jxpskj.com:9000/cloud-bucket'
const prefix = 'https://dev.jxpskj.com:8026/cloud-bucket'
// 搜索栏配置项
const searchPanelOptions = reactive({
  size: 'large',
@@ -370,6 +371,7 @@
    })
    Promise.all(promiseList).then(res => {
      console.log(res, '+++++++++++')
      res.forEach(e => {
        zip.file(e.name, e.data, { base64: true })
      })
@@ -393,10 +395,6 @@
      .then((response) => {
        const ext = url.split('.')[1]
        // 若文件名不以后缀结尾,则手动添加后缀
        if (!name.endsWith(ext)) {
          name = name + '.' + ext
        }
        resolve({
          name: name,
          data: response.data
@@ -444,17 +442,22 @@
function downloadMedia (media: MediaFile) {
  loading.value = true
  downloadMediaFile(workspaceId, media.file_id).then(res => {
    if (!res) {
      return
    }
    const data = new Blob([res])
  const url = prefix + '/' + media.object_key
  const data = new Blob([url])
    downloadFile(data, media.file_name)
    loading.value = false
  }).finally(() => {
  })
  // downloadMediaFile(workspaceId, media.file_id).then(res => {
  //     if (!res) {
  //         return
  //     }
  //
  //     const data = new Blob([url])
  //     downloadFile(data, media.file_name)
  //     loading.value = false
  // }).finally(() => {
  //     loading.value = false
  // })
}
</script>
src/components/g-map/DroneControlPanel.vue
@@ -9,38 +9,67 @@
    <div class="drone-control-box">
      <div class="box">
        <div class="row">
          <div class="drone-control"><Button :ghost="!flightController" size="small"  @click="onClickFightControl">{{ flightController ? '退出控制' : '进入控制'}}</Button></div>
                    <div class="drone-control">
                        <Button :ghost="!flightController" size="small" @click="onClickFightControl">
                            {{ flightController ? '退出控制' : '进入控制' }}
                        </Button>
                    </div>
        </div>
        <div class="row">
          <div class="drone-control-direction">
            <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_Q)" @onmouseup="onMouseUp">
              <template #icon><UndoOutlined /></template><span class="word">Q</span>
                            <template #icon>
                                <UndoOutlined/>
                            </template>
                            <span class="word">Q</span>
            </Button>
            <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_W)" @onmouseup="onMouseUp">
              <template #icon><UpOutlined/></template><span class="word">W</span>
                            <template #icon>
                                <UpOutlined/>
                            </template>
                            <span class="word">W</span>
            </Button>
            <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_E)" @onmouseup="onMouseUp">
              <template #icon><RedoOutlined /></template><span class="word">E</span>
                            <template #icon>
                                <RedoOutlined/>
                            </template>
                            <span class="word">E</span>
            </Button>
            <Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_UP)" @onmouseup="onMouseUp">
              <template #icon><ArrowUpOutlined /></template>
                            <template #icon>
                                <ArrowUpOutlined/>
                            </template>
            </Button>
            <br />
            <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_A)" @onmouseup="onMouseUp">
              <template #icon><LeftOutlined/></template><span class="word">A</span>
                            <template #icon>
                                <LeftOutlined/>
                            </template>
                            <span class="word">A</span>
            </Button>
            <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_S)" @onmouseup="onMouseUp">
              <template #icon><DownOutlined/></template><span class="word">S</span>
                            <template #icon>
                                <DownOutlined/>
                            </template>
                            <span class="word">S</span>
            </Button>
            <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_D)" @onmouseup="onMouseUp">
              <template #icon><RightOutlined/></template><span class="word">D</span>
                            <template #icon>
                                <RightOutlined/>
                            </template>
                            <span class="word">D</span>
            </Button>
            <Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_DOWN)" @onmouseup="onMouseUp">
              <template #icon><ArrowDownOutlined /></template>
                            <template #icon>
                                <ArrowDownOutlined/>
                            </template>
            </Button>
          </div>
          <Button type="primary" size="small" danger ghost @click="handleEmergencyStop" >
            <template #icon><PauseCircleOutlined/></template><span>结束</span>
                        <template #icon>
                            <PauseCircleOutlined/>
                        </template>
                        <span>结束</span>
          </Button>
        </div>
        <div class="row">
@@ -130,7 +159,8 @@
    </div>
    <div class="box">
      <div class="row">
        <Select v-model:value="payloadSelectInfo.value" style="width: 110px; marginRight: 5px" :options="payloadSelectInfo.options" @change="handlePayloadChange"/>
                    <Select v-model:value="payloadSelectInfo.value" style="width: 110px; marginRight: 5px"
                            :options="payloadSelectInfo.options" @change="handlePayloadChange"/>
        <div class="drone-control">
          <Button type="primary" size="small" @click="onAuthPayload">负载控制</Button>
        </div>
@@ -192,7 +222,8 @@
              </div>
              <div>
                <span class="form-label">缩放:</span>
                <a-input-number v-model:value="zoomFactorPopoverData.zoomFactor" :min="2" :max="200" />
                                    <a-input-number v-model:value="zoomFactorPopoverData.zoomFactor" :min="2"
                                                    :max="200"/>
              </div>
            </div>
          </template>
@@ -249,15 +280,35 @@
import { useMyStore } from '/@/store'
import { postDrcEnter, postDrcExit } from '/@/api/drc'
import { useMqtt, DeviceTopicInfo } from './use-mqtt'
import { DownOutlined, UpOutlined, LeftOutlined, RightOutlined, PauseCircleOutlined, UndoOutlined, RedoOutlined, ArrowUpOutlined, ArrowDownOutlined, CloseOutlined } from '@ant-design/icons-vue'
import {
  DownOutlined,
  UpOutlined,
  LeftOutlined,
  RightOutlined,
  PauseCircleOutlined,
  UndoOutlined,
  RedoOutlined,
  ArrowUpOutlined,
  ArrowDownOutlined,
  CloseOutlined
} from '@ant-design/icons-vue'
import { useManualControl, KeyCode } from './use-manual-control'
import { usePayloadControl } from './use-payload-control'
import { CameraMode, CameraType, CameraTypeOptions, ZoomCameraTypeOptions, CameraListItem } from '/@/types/live-stream'
import { useDroneControlWsEvent } from './use-drone-control-ws-event'
import { useDroneControlMqttEvent } from './use-drone-control-mqtt-event'
import { postFlightAuth, LostControlActionInCommandFLight, WaylineLostControlActionInCommandFlight } from '/@/api/drone-control/drone'
import {
  postFlightAuth,
  LostControlActionInCommandFLight,
  WaylineLostControlActionInCommandFlight
} from '/@/api/drone-control/drone'
import { useDroneControl } from './use-drone-control'
import { GimbalResetMode, GimbalResetModeOptions, LostControlActionInCommandFLightOptions, WaylineLostControlActionInCommandFlightOptions } from '/@/types/drone-control'
import {
  GimbalResetMode,
  GimbalResetModeOptions,
  LostControlActionInCommandFLightOptions,
  WaylineLostControlActionInCommandFlightOptions
} from '/@/types/drone-control'
import DroneControlPopover from './DroneControlPopover.vue'
import DroneControlInfoPanel from './DroneControlInfoPanel.vue'
import { noDebugCmdList as baseCmdList, DeviceCmdItem, DeviceCmd } from '/@/types/device-cmd'
@@ -297,6 +348,7 @@
  }
  cmdItem.loading = false
}
const emits = defineEmits(['update:modelValue'])
// 关闭弹窗
const closeDrone = () => {
@@ -421,8 +473,13 @@
  }
  enterFlightControl()
}
// 进入飞行控制
async function enterFlightControl () {
  if (!clientId.value) {
    message.error('无人机不在空中,不能进入指挥飞行模式。')
    return
  }
  try {
    const { code, data } = await postDrcEnter({
      client_id: clientId.value,
@@ -731,6 +788,7 @@
  .drone-control-box {
    display: flex;
    flex-wrap: 1;
    .box {
      width: 50%;
      padding: 5px;
src/router/index.ts