|
|
@@ -0,0 +1,953 @@
|
|
|
+<!-- eslint-disable vue/no-deprecated-v-bind-sync -->
|
|
|
+<!-- eslint-disable vue/no-unused-components -->
|
|
|
+<template>
|
|
|
+ <div class="operation-plan" v-if="visible">
|
|
|
+ <img
|
|
|
+ src="../../img/back.png"
|
|
|
+ class="back-img"
|
|
|
+ v-if="pageType === 'view'"
|
|
|
+ @click="close"
|
|
|
+ />
|
|
|
+ <div class="operation-plan-header">
|
|
|
+ <div class="operation-plan-title">{{ pageTitle }}</div>
|
|
|
+ </div>
|
|
|
+ <el-scrollbar class="scrollbar">
|
|
|
+ <el-form
|
|
|
+ :disabled="pageType === 'view'"
|
|
|
+ hide-required-asterisk
|
|
|
+ :rules="rules"
|
|
|
+ :model="form"
|
|
|
+ ref="operationPlanForm"
|
|
|
+ >
|
|
|
+ <el-form-item label-position="top" prop="planName" label="计划名称">
|
|
|
+ <el-input
|
|
|
+ v-model="form.planName"
|
|
|
+ :maxlength="20"
|
|
|
+ clearable
|
|
|
+ placeholder="输入计划名称"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item
|
|
|
+ label-position="top"
|
|
|
+ class="select-tree"
|
|
|
+ prop="deviceCode"
|
|
|
+ label="执行设备"
|
|
|
+ >
|
|
|
+ <!-- todo 虚拟树 、日历部分抽取组件 -->
|
|
|
+ <select-tree
|
|
|
+ onlyLeafSelect
|
|
|
+ showPrefixIcon
|
|
|
+ filterable
|
|
|
+ expandOnClickNode
|
|
|
+ :disabled="pageType === 'view'"
|
|
|
+ :defaultProps="{ label: 'name', children: 'list' }"
|
|
|
+ nodeKey="code"
|
|
|
+ industryClass="common-iw-s operation-select-tree"
|
|
|
+ v-model="form.deviceCode"
|
|
|
+ :dataSource="uavTreeData"
|
|
|
+ @clear="clearDeviceCode"
|
|
|
+ @refresh="getDeviceAreaTreeData"
|
|
|
+ ></select-tree>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label-position="top" prop="airline" label="执行航线">
|
|
|
+ <el-select
|
|
|
+ placeholder="输入关键字"
|
|
|
+ :popper-append-to-body="false"
|
|
|
+ popper-class="operation-plan-select"
|
|
|
+ @change="setAirLineInMap"
|
|
|
+ filterable
|
|
|
+ v-model="form.airline"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in airlineList"
|
|
|
+ :value="item.flightRouteId"
|
|
|
+ :label="item.flightRouteName"
|
|
|
+ :key="item.flightRouteId"
|
|
|
+ ></el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-item-label">任务策略</div>
|
|
|
+ <div class="form-item-content">
|
|
|
+ <tab-select
|
|
|
+ :options="taskStrategyList"
|
|
|
+ :value.sync="form.currentTask"
|
|
|
+ :disabled="pageType === 'view'"
|
|
|
+ @change="setCurrentValue('currentTask')"
|
|
|
+ ></tab-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-if="form.currentTask === '0'" class="form-item-flex">
|
|
|
+ <el-form-item
|
|
|
+ label-position="top"
|
|
|
+ prop="executionTime"
|
|
|
+ label="执行时间"
|
|
|
+ class="no-bg"
|
|
|
+ >
|
|
|
+ <!-- <div class="form-item-label">执行时间</div>-->
|
|
|
+ <el-date-picker
|
|
|
+ popper-class="operation-plan-datetime"
|
|
|
+ :editable="false"
|
|
|
+ class="datetime"
|
|
|
+ :picker-options="pickerOptions"
|
|
|
+ v-model="form.executionTime"
|
|
|
+ format="yyyy-MM-dd HH:mm"
|
|
|
+ value-format="yyyy-MM-dd HH:mm:ss"
|
|
|
+ type="datetime"
|
|
|
+ clear-icon="el-icon-close custom-close-icon"
|
|
|
+ prefix-icon="icon iconfont icon-tongyong_icon_shijian"
|
|
|
+ placeholder="选择日期时间"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ <div v-if="form.currentTask === '1'" class="form-item-flex">
|
|
|
+ <el-form-item
|
|
|
+ label-position="top"
|
|
|
+ prop="executionDate"
|
|
|
+ label="执行日期"
|
|
|
+ class="no-bg"
|
|
|
+ >
|
|
|
+ <div class="form-item-flex">
|
|
|
+ <!-- <div class="form-item-label">执行日期</div>-->
|
|
|
+ <el-date-picker
|
|
|
+ v-model="form.executionDate"
|
|
|
+ class="c-date-editor search-date"
|
|
|
+ popper-class="c-date-editor-picker"
|
|
|
+ type="daterange"
|
|
|
+ range-separator="至"
|
|
|
+ :picker-options="pickerOptions"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ prefix-icon="iconfont_tools icon-tongyong-shaixuanriqi alarmfilte"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <div class="form-item-flex">
|
|
|
+ <div class="form-item-label form-item-label-no-bg">重复频率</div>
|
|
|
+ <div class="time-switch">
|
|
|
+ <div class="row">
|
|
|
+ <el-radio
|
|
|
+ @change="clearImmediate"
|
|
|
+ v-model="form.repeatFrequency"
|
|
|
+ label="0"
|
|
|
+ >每天
|
|
|
+ </el-radio>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="time-switch">
|
|
|
+ <div class="row">
|
|
|
+ <el-radio
|
|
|
+ @change="clearImmediate"
|
|
|
+ class="item-width"
|
|
|
+ v-model="form.repeatFrequency"
|
|
|
+ label="1"
|
|
|
+ >每周
|
|
|
+ </el-radio>
|
|
|
+ <el-checkbox
|
|
|
+ :indeterminate="weekAllIndeterminate"
|
|
|
+ @change="
|
|
|
+ handleMonthAllChange(
|
|
|
+ $event,
|
|
|
+ 'weeks',
|
|
|
+ 'weekList',
|
|
|
+ 'weekAllIndeterminate'
|
|
|
+ )
|
|
|
+ "
|
|
|
+ v-model="weekAll"
|
|
|
+ class="item-width"
|
|
|
+ >全部
|
|
|
+ </el-checkbox>
|
|
|
+ </div>
|
|
|
+ <div class="row-content">
|
|
|
+ <checkboxs
|
|
|
+ :value.sync="form.weeks"
|
|
|
+ :options="weekList"
|
|
|
+ @change="
|
|
|
+ handleListChange(
|
|
|
+ $event,
|
|
|
+ 'weekAll',
|
|
|
+ 'weekList',
|
|
|
+ 'weekAllIndeterminate'
|
|
|
+ )
|
|
|
+ "
|
|
|
+ ></checkboxs>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="time-switch">
|
|
|
+ <div class="row">
|
|
|
+ <el-radio
|
|
|
+ @change="clearImmediate"
|
|
|
+ class="item-width"
|
|
|
+ v-model="form.repeatFrequency"
|
|
|
+ label="2"
|
|
|
+ >每月
|
|
|
+ </el-radio>
|
|
|
+ <el-checkbox
|
|
|
+ :indeterminate="monthAllIndeterminate"
|
|
|
+ @change="
|
|
|
+ handleMonthAllChange(
|
|
|
+ $event,
|
|
|
+ 'months',
|
|
|
+ 'monthList',
|
|
|
+ 'monthAllIndeterminate'
|
|
|
+ )
|
|
|
+ "
|
|
|
+ v-model="monthAll"
|
|
|
+ class="item-width"
|
|
|
+ >全部
|
|
|
+ </el-checkbox>
|
|
|
+ </div>
|
|
|
+ <checkboxs
|
|
|
+ :value.sync="form.months"
|
|
|
+ :options="monthList"
|
|
|
+ @change="
|
|
|
+ handleListChange(
|
|
|
+ $event,
|
|
|
+ 'monthAll',
|
|
|
+ 'monthList',
|
|
|
+ 'monthAllIndeterminate'
|
|
|
+ )
|
|
|
+ "
|
|
|
+ ></checkboxs>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item-flex">
|
|
|
+ <el-form-item
|
|
|
+ label-position="top"
|
|
|
+ prop="flyTime"
|
|
|
+ label="执行时间"
|
|
|
+ class="no-bg"
|
|
|
+ >
|
|
|
+ <!-- <div class="form-item-label">执行时间</div>-->
|
|
|
+ <div class="form-picker-item">
|
|
|
+ <div class="form-picker-item-content">
|
|
|
+ <el-time-picker
|
|
|
+ popper-class="operation-plan-time-panel"
|
|
|
+ class="time-picker"
|
|
|
+ format="HH:mm"
|
|
|
+ value-format="HH:mm:ss"
|
|
|
+ v-model="form.flyTime"
|
|
|
+ :editable="false"
|
|
|
+ placeholder="选择时间"
|
|
|
+ >
|
|
|
+ </el-time-picker>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-item-label">数据上传</div>
|
|
|
+ <div class="form-item-content">
|
|
|
+ <tab-select
|
|
|
+ :options="dataUploadModes"
|
|
|
+ :value.sync="form.uploadMode"
|
|
|
+ :disabled="pageType === 'view'"
|
|
|
+ ></tab-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-item-label">录屏</div>
|
|
|
+ <div class="form-item-content">
|
|
|
+ <tab-select
|
|
|
+ :options="screenRecordModes"
|
|
|
+ :value.sync="form.screenRecord"
|
|
|
+ disabled
|
|
|
+ ></tab-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ </el-scrollbar>
|
|
|
+ <div class="operation-plan-footer" v-if="pageType !== 'view'">
|
|
|
+ <base-button
|
|
|
+ type="primary"
|
|
|
+ class="submit-btn footer-btn"
|
|
|
+ @click="submitForm"
|
|
|
+ >确定
|
|
|
+ </base-button>
|
|
|
+ <base-button class="footer-btn" @click="close">取消</base-button>
|
|
|
+ </div>
|
|
|
+ <air-line-card
|
|
|
+ :type="airLineType"
|
|
|
+ v-if="(airLineType === '1' || airLineType === '2') && form.airline"
|
|
|
+ :lineInfo="lineInfo"
|
|
|
+ ></air-line-card>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import BaseButton from '@component-gallery/base-components/base-button/BaseButton.vue'
|
|
|
+import eventPath from '@component-gallery/build-event-bus-path'
|
|
|
+import AirLineCard from '../airLineCard/AirLineCard'
|
|
|
+import SelectTree from '../selectTree/SelectTree'
|
|
|
+import TabSelect from '../tabSelect/TabSelect'
|
|
|
+import Checkboxs from '../checkboxs/CheckboxInterval'
|
|
|
+import { requestSDK } from '@ct/iframe-connect-sdk'
|
|
|
+import {
|
|
|
+ operationPlanType,
|
|
|
+ taskStrategyList,
|
|
|
+ dataUploadModes,
|
|
|
+ screenRecordModes,
|
|
|
+ weekList,
|
|
|
+ monthList,
|
|
|
+ rules,
|
|
|
+ setUserInfo
|
|
|
+} from '../../dict/dict'
|
|
|
+import {
|
|
|
+ getDeviceAreaTree,
|
|
|
+ getAirLineList,
|
|
|
+ findAirPlanById,
|
|
|
+ editAirPlan,
|
|
|
+ addAirPlan,
|
|
|
+ getAirLineInfo,
|
|
|
+ getPlanName
|
|
|
+} from '../../service'
|
|
|
+import CommonMessage from '@component-gallery/utils/funCommon/message/common-message'
|
|
|
+import {
|
|
|
+ findDeviceNodeByCode,
|
|
|
+ setAirLineAndPoint,
|
|
|
+ setOrthoImage,
|
|
|
+ handleAirLineAndPointData,
|
|
|
+ handleOrthophotoData,
|
|
|
+ getHeights,
|
|
|
+ getLinkLines,
|
|
|
+ planMapFocusArea,
|
|
|
+ planMapFocusEntity
|
|
|
+} from '../../dict/plan-map'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'OperationPlan',
|
|
|
+ props: {
|
|
|
+ pageType: {
|
|
|
+ type: String,
|
|
|
+ default: 'add'
|
|
|
+ },
|
|
|
+ mapId: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ planId: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ planName: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ snapshotId: {
|
|
|
+ type: [String, null],
|
|
|
+ default: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ inject: ['mapRef'],
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ visible: true,
|
|
|
+ weekAll: false,
|
|
|
+ monthAll: false,
|
|
|
+ weekAllIndeterminate: false,
|
|
|
+ monthAllIndeterminate: false,
|
|
|
+ form: {
|
|
|
+ planName: '', // 计划名称
|
|
|
+ deviceCode: '', // 设备编码
|
|
|
+ airline: '', // 航线
|
|
|
+ currentTask: '2', // 任务策略
|
|
|
+ // autoContinueFly: '1', // 自动断点续飞
|
|
|
+ uploadMode: '2', // 数据上传
|
|
|
+ screenRecord: '1', // 录屏
|
|
|
+ executionTime: '', // 执行时间
|
|
|
+ executionDate: '', // 执行日期
|
|
|
+ flyTime: '', // 执行时间
|
|
|
+ repeatFrequency: '0', // 重复频率
|
|
|
+ weeks: [], // 周
|
|
|
+ months: [] // 月
|
|
|
+ },
|
|
|
+ airlineList: [],
|
|
|
+ airDeviceList: [],
|
|
|
+ deviceTree: [],
|
|
|
+ uavTreeData: [],
|
|
|
+ rules,
|
|
|
+ airLineAndPointMap: {},
|
|
|
+ orthoImageMap: {},
|
|
|
+ airLineType: null, // 当前航点航线类型
|
|
|
+ lineInfo: {}, // 当前航线信息
|
|
|
+ pickerOptions: {
|
|
|
+ disabledDate(time) {
|
|
|
+ const today = new Date()
|
|
|
+ const startOfDay = new Date(
|
|
|
+ today.getFullYear(),
|
|
|
+ today.getMonth(),
|
|
|
+ today.getDate()
|
|
|
+ ).getTime()
|
|
|
+ return time.getTime() < startOfDay
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ components: {
|
|
|
+ BaseButton,
|
|
|
+ AirLineCard,
|
|
|
+ SelectTree,
|
|
|
+ TabSelect,
|
|
|
+ Checkboxs
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ pageTitle() {
|
|
|
+ return operationPlanType[this.pageType].title
|
|
|
+ },
|
|
|
+ taskStrategyList() {
|
|
|
+ return taskStrategyList
|
|
|
+ },
|
|
|
+ dataUploadModes() {
|
|
|
+ return dataUploadModes
|
|
|
+ },
|
|
|
+ screenRecordModes() {
|
|
|
+ return screenRecordModes
|
|
|
+ },
|
|
|
+ weekList() {
|
|
|
+ return weekList
|
|
|
+ },
|
|
|
+ monthList() {
|
|
|
+ return monthList
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async created() {
|
|
|
+ this.getDeviceAreaTreeData()
|
|
|
+ const typeMap = ['edit', 'view', 'copy']
|
|
|
+ // todo 数组优化逻辑
|
|
|
+ if (typeMap.includes(this.pageType)) {
|
|
|
+ await this.getAirPlanByInfo()
|
|
|
+ }
|
|
|
+ if (this.pageType === 'add') {
|
|
|
+ await this.getDefaultPlanName()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ 'form.deviceCode': {
|
|
|
+ handler(val, oldVal) {
|
|
|
+ if (val !== oldVal) {
|
|
|
+ this.getAirLineListSource()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.initEvent()
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ let mapRef = this.mapRef.getMapRef(this.mapId)
|
|
|
+ mapRef.mapInstance.scene.globe.depthTestAgainstTerrain = false
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 清除deviceCode
|
|
|
+ clearDeviceCode() {
|
|
|
+ this.form.airline = ''
|
|
|
+ this.lineInfo = {}
|
|
|
+ this.airLineType = null
|
|
|
+ this.clearAirLineMap('1')
|
|
|
+ this.clearAirLineMap('2')
|
|
|
+ },
|
|
|
+ initEvent() {
|
|
|
+ /**
|
|
|
+ * 监听打开事件
|
|
|
+ * visible: 是否显示
|
|
|
+ * type: 页面类型 add/edit/view
|
|
|
+ * */
|
|
|
+ this.$globalEventBus.$on(
|
|
|
+ `${eventPath.commonCompUavFlyManage}_open-peration-plan`,
|
|
|
+ (options) => {
|
|
|
+ this.visible = options.visible
|
|
|
+ }
|
|
|
+ )
|
|
|
+ this.$globalEventBus.$on(
|
|
|
+ `${eventPath.commonCompMap}__init-map-resolve`,
|
|
|
+ ({ status }) => {
|
|
|
+ if (status) {
|
|
|
+ this.setAirLineInMap(this.form.airline)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+ },
|
|
|
+ // 设置当前选中值
|
|
|
+ setCurrentValue(key) {
|
|
|
+ if (key === 'currentTask') {
|
|
|
+ this.form.executionTime = '' // 执行时间
|
|
|
+ this.form.executionDate = '' // 执行日期
|
|
|
+ this.form.flyTime = '' // 执行时间
|
|
|
+ this.form.repeatFrequency = '0' // 重复频率
|
|
|
+ this.form.weeks = [] // 周
|
|
|
+ this.form.months = [] // 月
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 处理月半选中状态
|
|
|
+ handleListChange(value, allKey, listKey, indetermineKey) {
|
|
|
+ let checkedCount = value.length
|
|
|
+ this[allKey] = checkedCount === this[listKey].length
|
|
|
+ this[indetermineKey] =
|
|
|
+ checkedCount > 0 && checkedCount < this[listKey].length
|
|
|
+ },
|
|
|
+ clearImmediate() {
|
|
|
+ this.form.weeks = []
|
|
|
+ this.form.months = []
|
|
|
+ this.weekAll = false
|
|
|
+ this.monthAll = false
|
|
|
+ this.weekAllIndeterminate = false
|
|
|
+ this.monthAllIndeterminate = false
|
|
|
+ },
|
|
|
+ // 处理月全选
|
|
|
+ handleMonthAllChange(val, valueKey, listKey, indetermineKey) {
|
|
|
+ this.form[valueKey] = val ? this[listKey].map((item) => item.value) : []
|
|
|
+ this[indetermineKey] = false
|
|
|
+ },
|
|
|
+ // 获取无人机机场数据
|
|
|
+ getDeviceAreaTreeData(fn) {
|
|
|
+ const params = {
|
|
|
+ needDevice: true,
|
|
|
+ orderStatus: '1',
|
|
|
+ queryType: 1
|
|
|
+ }
|
|
|
+ getDeviceAreaTree(params)
|
|
|
+ .then((res) => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.uavTreeData = res.data || []
|
|
|
+ this.$nextTick(() => {
|
|
|
+ fn && fn()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((e) => {
|
|
|
+ this.uavTreeData = []
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 获取航线列表
|
|
|
+ async getAirLineListSource() {
|
|
|
+ // this.form.deviceCode = '00000000002'
|
|
|
+ if (!this.form.deviceCode) {
|
|
|
+ this.airlineList = []
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const params = {
|
|
|
+ deviceCodes: this.form.deviceCode
|
|
|
+ }
|
|
|
+ const res = await getAirLineList(params)
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.airlineList = res.rows || []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取计划详情
|
|
|
+ async getAirPlanByInfo() {
|
|
|
+ const res = await findAirPlanById({ planId: this.planId })
|
|
|
+ if (res.code === 200) {
|
|
|
+ const data = res.data
|
|
|
+ this.form.planName = data.planName
|
|
|
+ this.form.deviceCode = data.uavNestCode || data.deviceCode
|
|
|
+ this.form.airline = data.flightRouteId
|
|
|
+ this.form.uploadMode = data.gainDataMode + ''
|
|
|
+ this.form.screenRecord = data.gainVideo + ''
|
|
|
+ this.form.currentTask = data.planType + ''
|
|
|
+ this.form.executionTime = data.regularExecutionDate
|
|
|
+ this.form.flyTime = data.cycleExecutionTime
|
|
|
+ this.form.repeatFrequency = data.cycleExecutionUnit
|
|
|
+ if (this.form.currentTask === '1') {
|
|
|
+ this.form.executionDate = [data.planStartTime, data.planEndTime]
|
|
|
+ }
|
|
|
+ // todo 优化为map
|
|
|
+ const intervalValuesMap = {
|
|
|
+ 1: {
|
|
|
+ valueKey: 'weeks',
|
|
|
+ listKey: 'weekList',
|
|
|
+ allKey: 'weekAll',
|
|
|
+ indeterminateKey: 'weekAllIndeterminate'
|
|
|
+ },
|
|
|
+ 2: {
|
|
|
+ valueKey: 'months',
|
|
|
+ listKey: 'monthList',
|
|
|
+ allKey: 'monthAll',
|
|
|
+ indeterminateKey: 'monthAllIndeterminate'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const intervalKey = intervalValuesMap[this.form.repeatFrequency]
|
|
|
+ if (intervalKey?.valueKey) {
|
|
|
+ this.form[intervalKey.valueKey] = data.intervalValues?.split(',')
|
|
|
+ this.handleListChange(
|
|
|
+ this.form[intervalKey.valueKey],
|
|
|
+ intervalKey.allKey,
|
|
|
+ intervalKey.listKey,
|
|
|
+ intervalKey.indeterminateKey
|
|
|
+ )
|
|
|
+ }
|
|
|
+ if (this.pageType === 'copy') {
|
|
|
+ this.form.planName = this.planName
|
|
|
+ this.form.currentTask = '2' // 复制时需启用为立即执行策略
|
|
|
+ this.form.executionTime = '' // 复制时需清空执行时间
|
|
|
+ this.form.flyTime = ''
|
|
|
+ this.form.executionDate = []
|
|
|
+ this.form.weeks = [] // 复制时需清空日历值
|
|
|
+ this.form.months = []
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ this.pageType === 'view' ||
|
|
|
+ this.pageType === 'edit' ||
|
|
|
+ this.pageType === 'copy'
|
|
|
+ ) {
|
|
|
+ await this.getAirLineListSource()
|
|
|
+ await this.setAirLineInMap(data.flightRouteId)
|
|
|
+ }
|
|
|
+ console.log(this.form, '获取计划详情')
|
|
|
+ // this.form.autoContinueFly = data.auto
|
|
|
+ }
|
|
|
+ await this.getInfo(res.data)
|
|
|
+ },
|
|
|
+ submitForm() {
|
|
|
+ this.$refs.operationPlanForm.validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ let intervalValues = []
|
|
|
+ if (this.form.repeatFrequency === '1') {
|
|
|
+ intervalValues = this.form.weeks
|
|
|
+ }
|
|
|
+ if (this.form.repeatFrequency === '2') {
|
|
|
+ intervalValues = this.form.months
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ (this.form.repeatFrequency === '1' ||
|
|
|
+ this.form.repeatFrequency === '2') &&
|
|
|
+ !intervalValues?.length
|
|
|
+ ) {
|
|
|
+ CommonMessage.w('重复频率需勾选具体时间。')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const currentNode = findDeviceNodeByCode(
|
|
|
+ this.uavTreeData,
|
|
|
+ this.form.deviceCode
|
|
|
+ )
|
|
|
+ const params = {
|
|
|
+ planId: this.pageType === 'edit' ? this.planId : null, // 计划ID
|
|
|
+ name: this.form.planName, // 计划名称
|
|
|
+ flightRouteId: this.form.airline, // 航线ID
|
|
|
+ gainDataMode: this.form.uploadMode, // 数据上传 0-暂不保存,2-保存到服务器,4-边飞边传
|
|
|
+ gainVideo: this.form.screenRecord, // 录屏
|
|
|
+ auto: '1', // 0-否, 1-是(默认1-是,传1)
|
|
|
+ planType: this.form.currentTask, // 任务策略
|
|
|
+ cycleExecutionUnit: this.form.repeatFrequency, // 重复频率 0 日, 1 周, 2 月
|
|
|
+ deviceCode: this.form.deviceCode, // 设备编码
|
|
|
+ uavNestCode: currentNode?.uavNestCode, // 机场编码
|
|
|
+ uavCode: currentNode?.deviceCode, // 无人机编码
|
|
|
+ accessNode: currentNode?.accessNode // 接入节点
|
|
|
+ }
|
|
|
+ // 单次定时
|
|
|
+ if (params.planType === '0') {
|
|
|
+ params.regularExecutionDate = this.form.executionTime // 执行时间 planType = 0必填,立即执行
|
|
|
+ }
|
|
|
+ // 重复定时
|
|
|
+ if (params.planType === '1') {
|
|
|
+ params.startTime = this.form.executionDate[0]
|
|
|
+ params.endTime = this.form.executionDate[1]
|
|
|
+ params.cycleExecutionTime = this.form.flyTime // 执行日期 planType = 1 必填
|
|
|
+ if (params.cycleExecutionUnit === '0') {
|
|
|
+ params.dayInterval = 1 // 每日时传入间隔时间为1
|
|
|
+ }
|
|
|
+ params.intervalValues = intervalValues // 月
|
|
|
+ }
|
|
|
+ this.requestAddOrEdit(params)
|
|
|
+ } else {
|
|
|
+ console.log(valid, '表单验证失败')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ close() {
|
|
|
+ this.clearDeviceCode()
|
|
|
+ this.$emit('close')
|
|
|
+ },
|
|
|
+ // 请求新增或编辑
|
|
|
+ requestAddOrEdit(params) {
|
|
|
+ // todo 合并
|
|
|
+ const requestMap = {
|
|
|
+ add: {
|
|
|
+ request: addAirPlan,
|
|
|
+ message: '新增计划成功'
|
|
|
+ },
|
|
|
+ copy: {
|
|
|
+ request: addAirPlan,
|
|
|
+ message: '新增计划成功'
|
|
|
+ },
|
|
|
+ edit: {
|
|
|
+ request: editAirPlan,
|
|
|
+ message: '修改计划成功'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ requestMap[this.pageType].request(params).then((res) => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ if (res.data.code === 400) {
|
|
|
+ CommonMessage.w(
|
|
|
+ res.data.msg || '同一条航线,每天仅限执行一次飞行任务'
|
|
|
+ )
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.clearDeviceCode()
|
|
|
+ CommonMessage.s(requestMap[this.pageType].message)
|
|
|
+ this.$emit('close', {
|
|
|
+ needRefresh: true
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 清除航线和航点 clearType: 1-清除航点航线,2-清除正射影像
|
|
|
+ clearAirLineMap(clearType) {
|
|
|
+ const clearKey =
|
|
|
+ clearType === '1' ? 'airLineAndPointMap' : 'orthoImageMap'
|
|
|
+ // todo 清除逻辑整合
|
|
|
+ const mapRef = this.mapRef.getMapRef(this.mapId)
|
|
|
+ // todo 改为Object.keys
|
|
|
+ const keys = Object.keys(this[clearKey])
|
|
|
+ keys.forEach((key) => {
|
|
|
+ if (this[clearKey][key]) {
|
|
|
+ try {
|
|
|
+ this[clearKey][key].customRemove(mapRef, this[clearKey][key])
|
|
|
+ } catch (e) {
|
|
|
+ console.error(e)
|
|
|
+ }
|
|
|
+ this[clearKey][key] = null
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 设置数据格式
|
|
|
+ * @param value
|
|
|
+ */
|
|
|
+ async setAirLineInMap(value) {
|
|
|
+ const currentAirLine = this.airlineList.find(
|
|
|
+ (item) => item.flightRouteId === value
|
|
|
+ )
|
|
|
+ this.airLineType = null
|
|
|
+ this.clearAirLineMap('2')
|
|
|
+ this.clearAirLineMap('1')
|
|
|
+ if (!value) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const currentNode = findDeviceNodeByCode(
|
|
|
+ this.uavTreeData,
|
|
|
+ this.form.deviceCode
|
|
|
+ )
|
|
|
+ const params = {
|
|
|
+ flightRouteId: value,
|
|
|
+ uavNestCode: currentNode?.uavNestCode,
|
|
|
+ uavCode: currentNode?.deviceCode
|
|
|
+ }
|
|
|
+ /* if (currentAirLine) {
|
|
|
+ params.snapshotId = currentAirLine.snapshotId
|
|
|
+ }
|
|
|
+ */
|
|
|
+
|
|
|
+ params.snapshotId = this.snapshotId
|
|
|
+
|
|
|
+ // todo 优化代码行数、不超过1000行
|
|
|
+ const res = await getAirLineInfo(params)
|
|
|
+ if (res.code !== 200) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const uavNestPoint = [
|
|
|
+ +res.data.uavNestLongitude,
|
|
|
+ +res.data.uavNestLatitude
|
|
|
+ ]
|
|
|
+ const uavPoint = [+res.data.uavLongitude, +res.data.uavLatitude]
|
|
|
+ const orthoUavPoint = currentNode?.uavNestCode ? uavNestPoint : uavPoint
|
|
|
+ const currentLine = res.data
|
|
|
+ const type = currentLine.type
|
|
|
+ this.airLineType = type
|
|
|
+ // type 为 1 航点航线 type 为 2 正射影像
|
|
|
+ if (!currentLine?.kmzJson) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let mapRef = this.mapRef.getMapRef(this.mapId)
|
|
|
+ mapRef.mapInstance.scene.globe.depthTestAgainstTerrain = true
|
|
|
+ if (type === '1') {
|
|
|
+ // 处理航线和点线的数据
|
|
|
+ this.handleAirLineAndPointLineData(
|
|
|
+ currentLine,
|
|
|
+ currentNode,
|
|
|
+ orthoUavPoint,
|
|
|
+ mapRef
|
|
|
+ )
|
|
|
+ }
|
|
|
+ if (type === '2') {
|
|
|
+ // 处理正射影像线的数据
|
|
|
+ this.handleOrthophotoLineData(
|
|
|
+ currentLine,
|
|
|
+ currentNode,
|
|
|
+ orthoUavPoint,
|
|
|
+ mapRef
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 处理航点航线的数据
|
|
|
+ * @param currentLine 当前航线数据
|
|
|
+ * @param currentNode 当前设备数据
|
|
|
+ * @param orthoUavPoint 机巢/无人机坐标
|
|
|
+ * @param mapRef 地图实例
|
|
|
+ */
|
|
|
+ async handleAirLineAndPointLineData(
|
|
|
+ currentLine,
|
|
|
+ currentNode,
|
|
|
+ orthoUavPoint,
|
|
|
+ mapRef
|
|
|
+ ) {
|
|
|
+ // 处理航点航线的数据
|
|
|
+ const { linePoints, lineInfo } = handleAirLineAndPointData(currentLine)
|
|
|
+ // 将线点坐标转换为经纬度格式
|
|
|
+ const positions = linePoints.map((item) => {
|
|
|
+ return { lng: Number(item[0]), lat: Number(item[1]) }
|
|
|
+ })
|
|
|
+ // 获取第一个线点的高度值
|
|
|
+ const heightVal = linePoints[0][2]
|
|
|
+ // 将kmzJson格式的字符串转换为json对象
|
|
|
+ const airLineJson = JSON.parse(currentLine.kmzJson)
|
|
|
+ // 获取高程信息
|
|
|
+ const { heightRes } = await getHeights(
|
|
|
+ positions,
|
|
|
+ airLineJson,
|
|
|
+ mapRef,
|
|
|
+ heightVal,
|
|
|
+ currentNode.altitude
|
|
|
+ )
|
|
|
+ // 根据高度信息对线点进行处理
|
|
|
+ let newLinePoints = linePoints.map((item, index) => {
|
|
|
+ let linePoint_ = heightRes[index]
|
|
|
+ return [Number(item[0]), Number(item[1]), Number(linePoint_['ASLT'])]
|
|
|
+ })
|
|
|
+ // 更新线信息
|
|
|
+ this.lineInfo = lineInfo
|
|
|
+ // 清除飞行线图层
|
|
|
+ this.clearAirLineMap('1')
|
|
|
+ // 创建线点数组
|
|
|
+ let points = [orthoUavPoint, ...newLinePoints, orthoUavPoint]
|
|
|
+ // 起飞点到首航点坐标
|
|
|
+ const firstPoints = getLinkLines(
|
|
|
+ airLineJson,
|
|
|
+ currentNode,
|
|
|
+ positions[0],
|
|
|
+ heightRes
|
|
|
+ )
|
|
|
+ // 返航点坐标到起飞点坐标
|
|
|
+ const lastPoints = getLinkLines(
|
|
|
+ airLineJson,
|
|
|
+ currentNode,
|
|
|
+ positions[positions.length - 1],
|
|
|
+ heightRes
|
|
|
+ )
|
|
|
+ const linkLines = firstPoints.concat(lastPoints)
|
|
|
+ // 绘制航线航点
|
|
|
+ this.airLineAndPointMap = setAirLineAndPoint(
|
|
|
+ mapRef,
|
|
|
+ points,
|
|
|
+ this.lineInfo,
|
|
|
+ linkLines
|
|
|
+ )
|
|
|
+ // 创建聚焦区域点数组
|
|
|
+ let focusAreaPonits = linePoints
|
|
|
+ focusAreaPonits.push([
|
|
|
+ orthoUavPoint[0],
|
|
|
+ orthoUavPoint[1],
|
|
|
+ orthoUavPoint[2]
|
|
|
+ ])
|
|
|
+ // 设置聚焦区域
|
|
|
+ planMapFocusArea(focusAreaPonits, mapRef)
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 处理正射影响的数据
|
|
|
+ * @param currentLine 当前航线数据
|
|
|
+ * @param currentNode 当前设备数据
|
|
|
+ * @param orthoUavPoint 机巢/无人机坐标
|
|
|
+ * @param mapRef 地图实例
|
|
|
+ */
|
|
|
+ async handleOrthophotoLineData(
|
|
|
+ currentLine,
|
|
|
+ currentNode,
|
|
|
+ orthoUavPoint,
|
|
|
+ mapRef
|
|
|
+ ) {
|
|
|
+ const { linePoints, polygonPoints, lineInfo } =
|
|
|
+ // 处理航迹数据
|
|
|
+ handleOrthophotoData(currentLine)
|
|
|
+ const positions = linePoints.map((item) => {
|
|
|
+ // 生成经纬度数组
|
|
|
+ return { lng: Number(item[0]), lat: Number(item[1]) }
|
|
|
+ })
|
|
|
+ // 获取高度值
|
|
|
+ const heightVal = linePoints[0][2]
|
|
|
+ // 解析当前航迹为JSON对象
|
|
|
+ const airLineJson = JSON.parse(currentLine.kmzJson)
|
|
|
+ // 获取高度信息
|
|
|
+ const { heightRes } = await getHeights(
|
|
|
+ positions,
|
|
|
+ airLineJson,
|
|
|
+ mapRef,
|
|
|
+ heightVal,
|
|
|
+ currentNode.altitude
|
|
|
+ )
|
|
|
+ // 生成新的航迹点数组
|
|
|
+ let newLinePoints = linePoints.map((item, index) => {
|
|
|
+ // 获取对应位置的高度信息
|
|
|
+ let linePoint_ = heightRes[index]
|
|
|
+ return [Number(item[0]), Number(item[1]), Number(linePoint_['ASLT'])]
|
|
|
+ })
|
|
|
+ // 获取连接线数组
|
|
|
+ const linkLines = getLinkLines(
|
|
|
+ airLineJson,
|
|
|
+ currentNode,
|
|
|
+ positions[0],
|
|
|
+ heightRes
|
|
|
+ )
|
|
|
+ // 更新航迹信息
|
|
|
+ this.lineInfo = lineInfo
|
|
|
+ // 清除地图上的航迹
|
|
|
+ this.clearAirLineMap('2')
|
|
|
+ // 设置正射影像地图
|
|
|
+ this.orthoImageMap = setOrthoImage(
|
|
|
+ mapRef,
|
|
|
+ newLinePoints,
|
|
|
+ [polygonPoints],
|
|
|
+ orthoUavPoint,
|
|
|
+ this.lineInfo,
|
|
|
+ linkLines
|
|
|
+ )
|
|
|
+ let entity =
|
|
|
+ this.orthoImageMap.orthoAirLineInstance0._dataSource._entityCollection
|
|
|
+ // 规划地图聚焦区域
|
|
|
+ planMapFocusEntity(entity, mapRef)
|
|
|
+ },
|
|
|
+ async getInfo(data) {
|
|
|
+ const { user } = await requestSDK('getInfo')
|
|
|
+ setUserInfo({ user, id: this.pageType === 'edit' ? data.id : '' })
|
|
|
+ },
|
|
|
+ // 获取默认计划名称
|
|
|
+ async getDefaultPlanName() {
|
|
|
+ const { user } = await requestSDK('getInfo')
|
|
|
+ const params = {
|
|
|
+ tenantId: user.tenantId,
|
|
|
+ industryCode: user.industryCode
|
|
|
+ }
|
|
|
+ getPlanName(params).then((res) => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.form.planName = res.data
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+@import '../../style/operation-plan';
|
|
|
+</style>
|
|
|
+<style lang="scss">
|
|
|
+@import '../../style/tooltip';
|
|
|
+@import '../../style/operation-plan-no-scoped';
|
|
|
+.operation-select-tree {
|
|
|
+ width: px-to-rem(320) !important;
|
|
|
+}
|
|
|
+</style>
|