Merge remote-tracking branch 'origin/test' into test
| | |
| | | }); |
| | | }; |
| | | |
| | | // 获取返航最高 高度 |
| | | export const getWaylineMaxTerrainHeight = data => { |
| | | return request({ |
| | | url: `/drone-odm/odmTaskInfo/odmTaskInfo/getWaylineMaxTerrainHeight`, |
| | | method: 'post', |
| | | data, |
| | | }) |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | |
| | | method: 'post', |
| | | }) |
| | | } |
| | | // 导出工单 |
| | | export const exportTheTicket = params => { |
| | | return request({ |
| | | url: `/drone-device-core/jobEvent/downloadEvent`, |
| | | method: 'get', |
| | | responseType: 'blob', |
| | | params, |
| | | }) |
| | | } |
| | |
| | | |
| | | resetCurRouteLineData() |
| | | |
| | | const { pointPlacemark, polygonList, templateType, startPoint, execute_height_mode, auto_flight_speed } = |
| | | const { pointPlacemark, polygonList, templateType, startPoint, execute_height_mode, auto_flight_speed, take_off_security_height } = |
| | | await analysisPointLineKmz(kmzUrl) |
| | | |
| | | curRouteLineData.value = { |
| | |
| | | execute_height_mode, |
| | | auto_flight_speed, |
| | | wayline_type, |
| | | take_off_security_height, |
| | | infos: infos |
| | | } |
| | | |
| | |
| | | height: 50, |
| | | }, |
| | | }) |
| | | // 获取最后一点高度 |
| | | console.log(pointList, '查看数组最后一点高度') |
| | | store.commit('setLastHeight', Number(pointList[pointList.length - 1].height)) |
| | | // 获取航线拆分所有点 |
| | | store.commit('setPositionsArr', pointList) |
| | | // 获取安全起飞高度 |
| | | store.commit('setSafeHeight', curRouteLineData.value.take_off_security_height) |
| | | flyVisual({ |
| | | positionsData:pointList.map(i => [Number(i.longitude), Number(i.latitude), Number(i.height)]), |
| | | viewer, |
| | |
| | | execute_height_mode: '', |
| | | auto_flight_speed: '', |
| | | wayline_type: '', |
| | | take_off_security_height: '' |
| | | } |
| | | } |
| | | |
| | |
| | | htsjzx: 100, //数据中心 |
| | | htlsrwxq: 100, //历史任务详情 |
| | | }, |
| | | lastHeight: 0, // 获取最后一点高度 |
| | | safeHeight: 0, // 获取选择航线高度 |
| | | positionsArr: [], // 获取选择航线点数据 |
| | | }, |
| | | mutations: { |
| | | setLastHeight(state, data) { |
| | | state.lastHeight = data |
| | | setSafeHeight (state, data) { |
| | | state.safeHeight = data |
| | | }, |
| | | setPositionsArr(state, data) { |
| | | state.positionsArr = data |
| | | }, |
| | | setDownloadProgress(state, data) { |
| | | state.downloadProgress = data |
| | |
| | | <div class="algorithItem" v-if="!showDetail"> |
| | | <div class="item" v-for="(item, index) in AlgorithmData" :key="index" |
| | | :class="{ 'active-bg': activeItem === item.dictValue }" @click="jumpDatail(item)"> |
| | | <img class="imgicon" :src="`${baseUrl}/后台-算法仓库/${item.dictValue}.png`" alt="" /> |
| | | <img class="imgicon" :src="`${baseUrl}/manage-sf-icon-source/${item.dictKey}.png`" alt="" /> |
| | | <div class="item-title">{{ item.dictValue }}</div> |
| | | <div :class="!statusSign && item.dictValue === nameSign ? 'stopStatus' : 'normalStatus'" |
| | | @click.stop="changeStatus(item)"> |
| | |
| | | // 处理数据 |
| | | AlgorithmData.value = res.data.data['SF'] |
| | | } |
| | | console.log('算法',AlgorithmData.value); |
| | | |
| | | }) |
| | | } |
| | | const activeItem = ref(null) |
| | |
| | | prop: 'login_time', |
| | | type: 'date', |
| | | viewDisplay: true, //查看显示 |
| | | editDisabled: true, |
| | | labelWidth: 145, |
| | | overHidden: true, |
| | | format: 'YYYY-MM-DD HH:mm:ss', |
| | |
| | | type: 'date', |
| | | hide: true, |
| | | viewDisplay: true, //查看显示 |
| | | editDisabled: true, |
| | | overHidden: true, |
| | | labelWidth: 145, |
| | | width: 160, |
| | |
| | | { name: '任务时间', value: '', field: 'cycle_time_value' }, |
| | | { name: '关联算法', value: '', field: 'ai_type_str' }, |
| | | { name: '任务描述', value: '', field: 'remark' }, |
| | | { name: '自定义识别区', value: '', field: 'enable_custom_area' }, |
| | | // { name: '任务执行次数', value: '', field: 'job_num' }, |
| | | ]) |
| | | // 机巢状态 |
| | |
| | | droneEventList.filter(({ value }) => actionActuatorFunc === value) |
| | | ) |
| | | } |
| | | if (item.name === '自定义识别区') { |
| | | item.value = res.data.data.enable_custom_area ? '是': '否' |
| | | } |
| | | getJobsAllFiles({ |
| | | wayLineJobId: detailsData.value.way_lines.map(item => item.job_id).join(','), |
| | | resultTypes: [0, 2, 4, 5], |
| | |
| | | <el-input class="ztzf-layer-input inputName" v-model="formData.name" placeholder="请输入" /> |
| | | </div> |
| | | </div> |
| | | <div class="itemRow" v-if="layerParams.addAnEditingFolder === 1 && layerParams.fileType !==2 && !itSLandPlanning"> |
| | | <div class="itemRow" v-if="(layerParams.addAnEditingFolder === 1 && layerParams.fileType !==2) || (layerParams.addAnEditingFolder === 2 && layerParams.fileType !==2) && !itSLandPlanning"> |
| | | <div class="label">关联算法</div> |
| | | <div> |
| | | <el-select |
| | |
| | | </el-select> |
| | | <el-select |
| | | v-model="formData.algorithm_name" |
| | | |
| | | class="ztzf-layer-search" |
| | | placeholder="请选择" |
| | | clearable |
| | |
| | | <div class="detailInfo" v-if="layerParams.editFolder"> |
| | | <div class="infpItem" v-if="!itSLandPlanning"> |
| | | <div class="itemData"> |
| | | <div class="title">围栏总数量</div> |
| | | <div class="title">{{ layerParams.fileType === 1 ? '识别区' : '禁飞区' }}总数量</div> |
| | | |
| | | <div class="num"> |
| | | <span>{{ formData.total_count }}</span> 个 |
| | | </div> |
| | | </div> |
| | | <div class="itemData"> |
| | | <div class="title">围栏总面积</div> |
| | | <div class="title">{{ layerParams.fileType === 1 ? '识别区' : '禁飞区' }}总面积</div> |
| | | <div class="num"> |
| | | <span class="areaStyle">{{ formData.total_area }}</span> m² |
| | | </div> |
| | |
| | | width: 324px; |
| | | |
| | | overflow: hidden; |
| | | background: rgba(0, 0, 0, 0.8); |
| | | background: rgba(0,0,0,0.51); |
| | | backdrop-filter: blur(4px); |
| | | border-radius: 8px 8px 8px 8px; |
| | | padding: 16px 12px; |
| | | |
| | |
| | | </div> |
| | | <div class="btnGroups"> |
| | | <el-button v-if="activeName !== '国土空间规划'" class="ztzf-button" @click="addFence">{{ |
| | | props.activeName === '电子围栏' ? '新增围栏' : '新增禁飞区' |
| | | props.activeName === '自定义识别区' ? '新增识别区' : '新增禁飞区' |
| | | }}</el-button> |
| | | <el-button v-if="activeName !== '国土空间规划'" class="ztzf-button" @click="addFolder" |
| | | >新增文件夹</el-button |
| | |
| | | <el-button v-else class="ztzf-button" @click="synchronize"> 同步 </el-button> |
| | | </template> --> |
| | | |
| | | <el-button class="ztzf-button" @click="selectAll">全选</el-button> |
| | | <!-- <el-button class="ztzf-button" @click="selectAll">全选</el-button> --> |
| | | <el-button class="ztzf-button" @click="selectAll"> |
| | | {{ checkedKeys.length === getAllFenceKeys().length ? '取消全选' : '全选' }} |
| | | </el-button> |
| | | </div> |
| | | <div |
| | | class="tableListBox" |
| | |
| | | node-key="id" |
| | | default-expand-all |
| | | :expand-on-click-node="false" |
| | | :check-on-click-node="false" |
| | | :filter-node-method="filterNode" |
| | | @check="handleCheck" |
| | | :props="{ |
| | |
| | | ); |
| | | }; |
| | | const handleCheck = (checkedNodesData, checkedKeysData) => { |
| | | layerParams.value.isSingleLocating = false |
| | | const filteredNodes = checkedKeysData.checkedNodes.filter(node => node.level === 3); |
| | | checkedNodes.value = checkedNodesData.checkedNodes; |
| | | checkedNodes.value = filteredNodes |
| | | checkedKeys.value = filteredNodes.map(node => node.id); |
| | | coverData.value = filteredNodes; |
| | | emit('update:coverData', coverData.value); |
| | | }; |
| | | // 全选方法 |
| | | const selectAll = () => { |
| | | if (treeRef.value) { |
| | | const allFenceKeys = treeData.value.flatMap( |
| | | folder => folder.children.map(fence => fence.id) // folder 是 level 2,children 是 level 3 |
| | | const getAllFenceKeys = () => { |
| | | return treeData.value.flatMap( |
| | | folder => folder.children.map(fence => fence.id) |
| | | ); |
| | | |
| | | }; |
| | | const selectAll = () => { |
| | | layerParams.value.isSingleLocating = false |
| | | if (treeRef.value) { |
| | | const allFenceKeys = getAllFenceKeys(); |
| | | const allFenceNodes = treeData.value.flatMap(folder => folder.children); |
| | | |
| | | if (checkedKeys.value.length === allFenceKeys.length) { |
| | | // 取消全选:清空 keys 和数据 |
| | | // 取消全选 |
| | | treeRef.value.setCheckedKeys([]); |
| | | checkedKeys.value = []; |
| | | checkedNodes.value = []; |
| | | coverData.value = []; |
| | | } else { |
| | | // 全选:仅设置 level 3 节点的 id |
| | | // 全选 |
| | | treeRef.value.setCheckedKeys(allFenceKeys); |
| | | checkedKeys.value = allFenceKeys; |
| | | checkedNodes.value = allFenceNodes; |
| | |
| | | }; |
| | | // 定位按钮事件 |
| | | const handleLocation = node => { |
| | | checkedKeys.value = []; |
| | | checkedNodes.value = []; |
| | | coverData.value = []; |
| | | if (node.data.level === 2) { |
| | | layerParams.value.isSingleLocating = false; |
| | | } else if (node.data.level === 3) { |
| | | layerParams.value.isSingleLocating = true; |
| | | } |
| | | |
| | | const currentCheckedKeys = [...checkedKeys.value]; |
| | | const currentCheckedNodes = [...checkedNodes.value]; |
| | | EventBus.emit('focusOnNode', node.data); |
| | | if (node.data.level === 2) { |
| | | const folderChildren = node.data.children || []; |
| | | // const childrenIds = folderChildren.map(child => child.id); |
| | | // treeRef.value.setCheckedKeys(childrenIds); |
| | | // checkedKeys.value = childrenIds; |
| | | // checkedNodes.value = folderChildren; |
| | | coverData.value = folderChildren; |
| | | emit('update:coverData', coverData.value); |
| | | } else { |
| | | emit('update:coverData', [node.data]); |
| | | const childrenIds = folderChildren.map(child => child.id); |
| | | // 合并已选中的节点和当前文件夹的子节点 |
| | | const newCheckedKeys = [...new Set([...currentCheckedKeys, ...childrenIds])]; |
| | | const newCheckedNodes = [...currentCheckedNodes, ...folderChildren]; |
| | | treeRef.value.setCheckedKeys(newCheckedKeys); |
| | | checkedKeys.value = newCheckedKeys; |
| | | checkedNodes.value = newCheckedNodes; |
| | | coverData.value = newCheckedNodes; |
| | | } |
| | | // 如果是单个节点(level 3),仅添加到选中列表(如果未选中) |
| | | else if (!currentCheckedKeys.includes(node.data.id)) { |
| | | layerParams.value.isSingleLocating = true |
| | | currentCheckedKeys.push(node.data.id); |
| | | currentCheckedNodes.push(node.data); |
| | | treeRef.value.setCheckedKeys(currentCheckedKeys); |
| | | checkedKeys.value = currentCheckedKeys; |
| | | checkedNodes.value = currentCheckedNodes; |
| | | coverData.value = currentCheckedNodes; |
| | | } |
| | | emit('update:coverData', coverData.value); |
| | | }; |
| | | // 编辑按钮事件 |
| | | const handleEdit = node => { |
| | | if (node.data.level == 2) { |
| | | layerParams.value.editFolder = true; |
| | | layerParams.value.addAnEditingFolder = 2; |
| | | if (props.activeName === '电子围栏') { |
| | | if (props.activeName === '自定义识别区') { |
| | | layerParams.value.fileType = 1; |
| | | } else if (props.activeName === '自定义禁飞区') { |
| | | layerParams.value.fileType = 2; |
| | |
| | | coverData.value = []; |
| | | layerParams.value.editNest = true; |
| | | layerParams.value.decideWhetherToAddOrEdit = 2; |
| | | if (props.activeName === '电子围栏') { |
| | | if (props.activeName === '自定义识别区') { |
| | | layerParams.value.fenceType = 1; // 电子围栏类型标识 |
| | | } else if (props.activeName === '自定义禁飞区') { |
| | | layerParams.value.fenceType = 2; // 自定义禁飞区类型标识 |
| | |
| | | deleteFolderApi(id).then(res => { |
| | | ElMessage.success('删除成功'); |
| | | gettreeDataApi(); |
| | | // 通知父组件删除该文件夹下所有围栏的地图实体 |
| | | EventBus.emit('deleteMapEntitiesByFolderId', id); |
| | | }); |
| | | } else if (node.data.level === 3) { |
| | |
| | | deleteFenceApi(id).then(res => { |
| | | ElMessage.success('删除成功'); |
| | | gettreeDataApi(); |
| | | // 通知父组件删除对应的地图实体 |
| | | EventBus.emit('deleteMapEntityById', id); |
| | | }); |
| | | } |
| | |
| | | const addFence = () => { |
| | | layerParams.value.addNest = true; |
| | | layerParams.value.decideWhetherToAddOrEdit = 1; |
| | | if (props.activeName === '电子围栏') { |
| | | if (props.activeName === '自定义识别区') { |
| | | layerParams.value.fenceType = 1; // 电子围栏类型标识 |
| | | } else if (props.activeName === '自定义禁飞区') { |
| | | layerParams.value.fenceType = 2; // 自定义禁飞区类型标识 |
| | |
| | | const addFolder = () => { |
| | | layerParams.value.addFolder = true; |
| | | layerParams.value.addAnEditingFolder = 1; |
| | | if (props.activeName === '电子围栏') { |
| | | if (props.activeName === '自定义识别区') { |
| | | layerParams.value.fileType = 1; |
| | | } else if (props.activeName === '自定义禁飞区') { |
| | | layerParams.value.fileType = 2; |
| | | } |
| | | }; |
| | | |
| | | function uploadFlightFile(file, t) { |
| | | const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1); |
| | | if (!['zip'].includes(fileSuffix)) { |
| | |
| | | z-index: 99; |
| | | width: 382px; |
| | | overflow: hidden; |
| | | background: rgba(0, 0, 0, 0.8); |
| | | background: rgba(0,0,0,0.51); |
| | | backdrop-filter: blur(4px); |
| | | border-radius: 8px 8px 8px 8px; |
| | | padding: 16px 0 16px 12px; |
| | | display: flex; |
| | |
| | | <template> |
| | | <div class="rightContainer"> |
| | | <div class="contenttitle">{{ layerParams.fenceType === 1 ? '围栏' : '禁飞区' }}信息</div> |
| | | <div class="contenttitle">{{ layerParams.fenceType === 1 ? '识别区' : '禁飞区' }}信息</div> |
| | | <div class="centerBox"> |
| | | <div class="itemRow"> |
| | | <div class="label">文件夹名称</div> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="itemRow"> |
| | | <div class="label">{{ layerParams.fenceType === 1 ? '围栏' : '禁飞区' }}名称</div> |
| | | <div class="label">{{ layerParams.fenceType === 1 ? '识别区' : '禁飞区' }}名称</div> |
| | | <div> |
| | | <el-input |
| | | :disabled="isDisabled" |
| | |
| | | </div> |
| | | </div> |
| | | <div class="itemRow"> |
| | | <div class="label">{{ layerParams.fenceType === 1 ? '围栏' : '禁飞区' }}备注</div> |
| | | <div class="label">{{ layerParams.fenceType === 1 ? '识别区' : '禁飞区' }}备注</div> |
| | | <div> |
| | | <el-input |
| | | :disabled="isDisabled" |
| | |
| | | <div class="detailInfo"> |
| | | <div class="infpItem" v-if="layerParams.editNest && layerParams.fenceType === 1"> |
| | | <div class="itemData"> |
| | | <div class="title">围栏面积</div> |
| | | <div class="title">识别区面积</div> |
| | | <div class="num"> |
| | | <span class="areaStyle">{{ fenceArea }}</span> m² |
| | | </div> |
| | |
| | | width: 324px; |
| | | |
| | | overflow: hidden; |
| | | background: rgba(0, 0, 0, 0.8); |
| | | background: rgba(0,0,0,0.51); |
| | | backdrop-filter: blur(4px); |
| | | border-radius: 8px 8px 8px 8px; |
| | | padding: 16px 12px; |
| | | |
| | |
| | | </div> |
| | | <!-- 地图 --> |
| | | <div class="mapContainer"> |
| | | <!-- <div class="tool-tip warning" v-show="isShowWaringTip"> |
| | | <span class="icon"> |
| | | <el-icon><WarningFilled /></el-icon> |
| | | </span> |
| | | <span>测区不支持交叉面,无法生成航线</span> |
| | | </div> --> |
| | | <div class="tool-tip" v-if="layerParams.addNest">点击地图生成测绘区域</div> |
| | | <div id="layMap" class="ztzf-cesium"></div> |
| | | <leftList |
| | |
| | | const areaCode = userInfo.value?.detail?.areaCode || ''; |
| | | // 红色警告交叉面提示窗 |
| | | const isShowWaringTip = ref(false); |
| | | const activeName = ref('电子围栏'); |
| | | const activeName = ref('自定义识别区'); |
| | | const activeType = ref('0'); |
| | | let tbJwdList = []; |
| | | const selectDataList = ref([]); |
| | |
| | | let curPolygonPosition = []; |
| | | const tabData = ref([ |
| | | { |
| | | name: '电子围栏', |
| | | name: '自定义识别区', |
| | | type: '0', |
| | | }, |
| | | { |
| | |
| | | editFolderData: null, |
| | | editingIsProhibited: false, //禁止编辑 |
| | | isDetailShow: false, |
| | | isSingleLocating:false |
| | | }); |
| | | |
| | | const handleClick = tab => { |
| | |
| | | }; |
| | | const getdataFolderApi = () => { |
| | | let id; |
| | | if (activeName.value === '电子围栏') { |
| | | if (activeName.value === '自定义识别区') { |
| | | id = 1; |
| | | } else if (activeName.value === '自定义禁飞区') { |
| | | id = 2; |
| | |
| | | const handleCoverDataUpdate = data => { |
| | | selectDataList.value = data; |
| | | if (selectDataList.value.length > 0) { |
| | | |
| | | loadDataToMap(selectDataList.value); |
| | | } else { |
| | | viewer.entities.removeAll(); |
| | |
| | | zIndex: 99, |
| | | }); |
| | | }); |
| | | |
| | | |
| | | if (!layerParams.value.isSingleLocating) { |
| | | focusOnAllFeatures(); |
| | | } |
| | | viewInstance.value?.addLeftClickEvent(null, handleFenceClick); |
| | | }; |
| | | const focusOnAllFeatures = () => { |
| | |
| | | flyVisual({ |
| | | positionsData, |
| | | viewer, |
| | | multiple: 13, // 缩放倍数 |
| | | multiple:activeName.value == '国土空间规划' ? 13 :4, // 缩放倍数 |
| | | pitch: -90 |
| | | }); |
| | | }; |
| | |
| | | const handleFenceClick = movement => { |
| | | if (!viewer) return; |
| | | layerParams.value.editDetailData = null; |
| | | const pickedObject = viewer.scene.pick(movement.position); |
| | | if (Cesium.defined(pickedObject) && pickedObject.id?.customType === 'fence_polygon') { |
| | | const selectedEntity = pickedObject.id; |
| | | const selectedData = selectedEntity.customInfo; |
| | | |
| | | if(activeName.value !== '国土空间规划') { |
| | | const pickedObjects = viewer.scene.drillPick(movement.position, 10); |
| | | // 遍历所有被点击的实体,找到围栏类型(customType: 'fence_polygon') |
| | | let selectedEntity = null; |
| | | for (let i = 0; i < pickedObjects.length; i++) { |
| | | const pick = pickedObjects[i]; |
| | | if (Cesium.defined(pick.id) && pick.id?.customType === 'fence_polygon') { |
| | | selectedEntity = pick.id; |
| | | break; |
| | | } |
| | | } |
| | | // viewer.entities.values.forEach(entity => { |
| | | // if (entity.customType === 'fence_polygon') { |
| | | // entity.polygon.material = entity === selectedEntity |
| | |
| | | // : Cesium.Color.YELLOW.withAlpha(0.5); |
| | | // } |
| | | // }); |
| | | if (selectedEntity) { |
| | | const selectedData = selectedEntity.customInfo; |
| | | if (activeName.value !== '国土空间规划') { |
| | | layerParams.value.editNest = true; // 显示右侧编辑组件 |
| | | layerParams.value.decideWhetherToAddOrEdit = 2; // 标记为编辑模式 |
| | | // 根据围栏类型设置fenceType |
| | | if (activeName.value === '电子围栏') { |
| | | layerParams.value.editNest = true; |
| | | layerParams.value.decideWhetherToAddOrEdit = 2; |
| | | if (activeName.value === '自定义识别区') { |
| | | layerParams.value.fenceType = 1; |
| | | } else if (activeName.value === '自定义禁飞区') { |
| | | layerParams.value.fenceType = 2; |
| | |
| | | layerParams.value.editingIsProhibited = true; |
| | | } |
| | | } |
| | | }else { |
| | | |
| | | |
| | | } |
| | | |
| | | }; |
| | | let publicCesiumInstance = null; |
| | | let viewer = null; |
| | |
| | | dom: 'layMap', |
| | | flatMode: false, |
| | | terrain: true, |
| | | layerMode: 4, |
| | | contour: false, |
| | | layerMode: 4, //轮廓线 |
| | | dockOptions:{showDock:true}//机巢 |
| | | }); |
| | | viewer = publicCesiumInstance.getViewer(); |
| | | viewInstance.value = publicCesiumInstance; |
| | | viewInstance.value?.flyToContour(); |
| | | const nanChangPosition = Cesium.Cartesian3.fromDegrees( |
| | | 115.892151, // 经度 |
| | | 28.676493, // 纬度 |
| | |
| | | } |
| | | }; |
| | | provide('layerParams', layerParams); |
| | | // onMounted(() => { |
| | | // initMap(); |
| | | // cesiumContextMenu(); |
| | | // getdataFolderApi(); |
| | | // EventBus.on('deleteMapEntityById', deleteMapEntityById); |
| | | // EventBus.on('deleteMapEntitiesByFolderId', deleteMapEntitiesByFolderId); |
| | | |
| | | // }); |
| | | onMounted(() => { |
| | | initMap(); |
| | | cesiumContextMenu(); |
| | | getdataFolderApi(); |
| | | // 监听定位事件 |
| | | EventBus.on('focusOnNode', (nodeData) => { |
| | | focusOnNode(nodeData); |
| | | }); |
| | | EventBus.on('deleteMapEntityById', deleteMapEntityById); |
| | | EventBus.on('deleteMapEntitiesByFolderId', deleteMapEntitiesByFolderId); |
| | | }); |
| | | |
| | | //定位到指定节点 |
| | | const focusOnNode = (nodeData) => { |
| | | |
| | | if (!viewer || !nodeData?.geo_data) return; |
| | | |
| | | // 解析节点坐标 |
| | | const positions = parseGeoDataToPositions(nodeData.geo_data, nodeData.altitude); |
| | | if (positions.length < 3) { |
| | | |
| | | return; |
| | | } |
| | | flyVisual({ |
| | | positionsData: positions.map(pos => [pos.lng, pos.lat, pos.height || 0]), |
| | | viewer, |
| | | multiple:activeName.value == '国土空间规划' ? 13 :7, // 缩放倍数 |
| | | pitch: -90 |
| | | }); |
| | | |
| | | }; |
| | | onBeforeUnmount(() => { |
| | | destroyMap(); |
| | | cesiumContextMenu(false); |
| | |
| | | position: relative; |
| | | width: 100%; |
| | | height: 80vh; |
| | | .warning { |
| | | position: absolute; |
| | | top: 234px; |
| | | color: #fff; |
| | | background: rgba(140, 0, 0, 0.4); |
| | | |
| | | .icon { |
| | | display: flex; |
| | | align-items: center; |
| | | color: #ff1f1f; |
| | | } |
| | | } |
| | | #layMap { |
| | | width: 100%; |
| | | height: 100%; |
| | |
| | | <el-button type="danger" plain icon="el-icon-delete" v-if="permission.user_delete && !auditMode" |
| | | @click="handleDelete">删 除 |
| | | </el-button> |
| | | <el-button type="primary" plain icon="el-icon-operation" |
| | | v-if="userInfo.role_name.includes('admin') && !auditMode" @click="handleAudit">审 核 |
| | | </el-button> |
| | | <!-- <el-button type="primary" plain icon="el-icon-operation"--> |
| | | <!-- v-if="userInfo.role_name.includes('admin') && !auditMode" @click="handleAudit">审 核--> |
| | | <!-- </el-button>--> |
| | | <el-button type="success" plain icon="el-icon-check" |
| | | v-if="userInfo.role_name.includes('admin') && auditMode" @click="handleAuditPass">通 过 |
| | | </el-button> |
| | |
| | | <el-button type="info" plain v-if="permission.user_reset && !auditMode" icon="el-icon-refresh" |
| | | @click="handleReset">密码重置 |
| | | </el-button> |
| | | <el-button type="info" plain v-if="userInfo.role_name.includes('admin') && !auditMode" |
| | | icon="el-icon-setting" @click="handlePlatform">平台配置 |
| | | </el-button> |
| | | <!-- <el-button type="info" plain v-if="userInfo.role_name.includes('admin') && !auditMode"--> |
| | | <!-- icon="el-icon-setting" @click="handlePlatform">平台配置--> |
| | | <!-- </el-button>--> |
| | | <el-button type="info" plain v-if="userInfo.role_name.includes('admin') && !auditMode" |
| | | icon="el-icon-coordinate" @click="handleLock">账号解封 |
| | | </el-button> |
| | |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="安全返航真高" prop="rth_altitude" class="safe-height"> |
| | | <el-input-number v-model="form.rth_altitude" :min="50" :max="300"></el-input-number> |
| | | <el-input-number v-model="form.rth_altitude" :min="50" :max="500"></el-input-number> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-col :span="6"> |
| | | <el-form-item label="关联算法" prop="ai_types"> |
| | | <el-select v-model="form.ai_types" placeholder="请选择关联算法" multiple> |
| | | <el-option v-for="item in ai_types" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="自定义识别区" prop="enable_custom_area" class="safe-height"> |
| | | <el-checkbox v-model="form.enable_custom_area"></el-checkbox> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <el-col :span="6"> |
| | | <el-form-item label="安全返航真高" prop="rth_altitude" class="safe-height"> |
| | | <el-input-number :disabled="detailTitle === '工单详情'" v-model="form.rth_altitude" :min="50" |
| | | :max="300"></el-input-number> |
| | | :max="500"></el-input-number> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-col :span="6"> |
| | | <el-form-item label="关联算法" prop="ai_types"> |
| | | <el-select v-model="form.ai_types" placeholder="请选择关联算法" multiple :disabled="detailTitle === '工单详情'"> |
| | | <el-option v-for="item in ai_types" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="自定义识别区" prop="enable_custom_area" class="safe-height"> |
| | | <el-checkbox v-model="form.enable_custom_area"></el-checkbox> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="安全返航真高" prop="rth_altitude" class="safe-height"> |
| | | <el-input-number :disabled="true" v-model="form.rth_altitude" :min="50" :max="300"></el-input-number> |
| | | <el-input-number :disabled="true" v-model="form.rth_altitude" :min="50" :max="500"></el-input-number> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-col :span="6"> |
| | | <el-form-item label="关联算法" prop="ai_types"> |
| | | <el-select v-model="form.ai_types" placeholder="请选择关联算法" multiple :disabled="true"> |
| | | <el-option v-for="item in ai_types" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="自定义识别区" prop="enable_custom_area" class="safe-height"> |
| | | <el-checkbox v-model="form.enable_custom_area"></el-checkbox> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | orderLogExport, |
| | | jobStatusNum, |
| | | userPublish, |
| | | deleteOrderLog |
| | | deleteOrderLog, |
| | | getWaylineMaxTerrainHeight |
| | | } from '@/api/tickets/orderLog' |
| | | import { getTicketInfo } from '@/api/tickets/ticket' |
| | | import { getDictionaryByCode } from '@/api/system/dictbiz' |
| | |
| | | return CircleClose |
| | | }, |
| | | ...mapGetters(['userInfo', 'permission']), |
| | | lastHeight () { |
| | | const height = this.$store.state.common.lastHeight |
| | | return Number(height) || 0 // 确保是数字类型 |
| | | safeHeight () { |
| | | const safeHeight = this.$store.state.common.safeHeight |
| | | return Number(safeHeight) || 0 // 确保是数字类型 |
| | | }, |
| | | positionsArr () { |
| | | const positionsArr = this.$store.state.common.positionsArr |
| | | return positionsArr || [] // 确保是数字类型 |
| | | }, |
| | | filteredTabs () { |
| | | // rejection_and_draft 权限控制“已驳回”和“草稿”tab |
| | |
| | | const maxItem = checkedList.reduce((max, item) => { |
| | | return item.drone_height > max.drone_height ? item : max; |
| | | }); |
| | | console.log(maxItem.drone_height, '高度'); |
| | | console.log(this.lastHeight, '最后一点高度'); |
| | | let result = _.round((maxItem.drone_height + this.form.rth_altitude), 2); |
| | | // 返航绝对高度 |
| | | let backHeight = this.form.rth_altitude // + maxItem.drone_height |
| | | console.log(backHeight,'backHeight') |
| | | // 安全起飞高度 |
| | | let positions = this.positionsArr |
| | | positions.unshift({latitude: maxItem.latitude, longitude: maxItem.longitude, height:maxItem.drone_height }) |
| | | positions.push({latitude: maxItem.latitude, longitude: maxItem.longitude, height:maxItem.drone_height}) |
| | | let resultHeight = 0 |
| | | await getWaylineMaxTerrainHeight(positions).then(res => { |
| | | resultHeight = this.safeHeight > (res.data.data + 30) ? this.safeHeight : (res.data.data + 30) |
| | | }) |
| | | let valueHeight = _.round(backHeight - resultHeight, 2) |
| | | console.log('打印比较值', valueHeight) |
| | | |
| | | let resultHeight = this.lastHeight - maxItem.drone_height |
| | | let resultH = _.round(resultHeight, 2) |
| | | |
| | | if (this.lastHeight > result) { |
| | | this.$confirm(`当前返航高度存在安全隐患,建议调整为${resultH}米以上后进行发布`, '提示', { |
| | | if (valueHeight < 0) { |
| | | this.$confirm(`当前返航高度存在安全隐患,建议调整为${resultHeight}米以上后进行发布`, '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | |
| | | collapse-tags-tooltip |
| | | clearable |
| | | @check="handleCheck" |
| | | @node-click="handleSFNodeClick" |
| | | @clear="handleClear" |
| | | /> |
| | | </el-form-item> |
| | |
| | | @click="openReviewDialog" |
| | | >批量审核 |
| | | </el-button> |
| | | |
| | | <el-button |
| | | v-if="permissionList.exportBtn" |
| | | type="success" |
| | |
| | | </el-button> |
| | | </template> |
| | | |
| | | <template v-if="row.status === 4 && activeTab === 'completed'"> |
| | | <el-button type="text" icon="el-icon-download" @click="exportTheTick(row)" |
| | | >导出 |
| | | </el-button> |
| | | </template> |
| | | <template v-if="permission.tickets_repeat_review"> |
| | | <el-button |
| | | v-if="row.status === 4 && row.isReview !== 1" |
| | |
| | | getStepInfo, |
| | | getReviewById, |
| | | getCreateEventJob, |
| | | exportTheTicket |
| | | } from '@/api/tickets/ticket'; |
| | | import { getSFDictionaryTree } from '@/api/job/task'; |
| | | import { export_json_to_excel } from '@/utils/exportExcel'; |
| | |
| | | { label: '工单编号', prop: 'orderNumber', width: 170 }, |
| | | { label: '工单名称', prop: 'orderName', width: 150, overHidden: true, tooltip: true }, |
| | | { label: '所属部门', prop: 'department', overHidden: true, tooltip: true }, |
| | | { label: '发起时间', prop: 'startTime', width: 160, overHidden: true }, |
| | | { label: '发起任务时间', prop: 'startTime', width: 160, overHidden: true }, |
| | | { label: '关联算法', prop: 'aiType', overHidden: true, tooltip: true }, |
| | | { |
| | | label: '工单类型', |
| | |
| | | try { |
| | | const currentTab = this.tabs.find(tab => tab.name === this.activeTab); |
| | | const params = { |
| | | word_order_types: this.filters.type || undefined, |
| | | // word_order_types: this.filters.type || undefined, |
| | | ai_types: this.filters.type || undefined, // 算法使用该字段筛选 |
| | | status: |
| | | currentTab?.name === 'myTickets' |
| | | ? undefined |
| | |
| | | orderName: item.event_name, |
| | | department: |
| | | this.departments.find(d => d.value === item.dept_id)?.label || item.dept_name, |
| | | startTime: item.create_time, |
| | | startTime: item.job_create_time || '/', |
| | | aiType: item.ai_types, |
| | | content: item.content, // 将后端返回的 content 映射为 content |
| | | type: item.work_order_type_dict_key, |
| | |
| | | ? `${longitude.toFixed(6)}, ${latitude.toFixed(6)}` |
| | | : '未知位置', |
| | | address: item.address, |
| | | creator: item.event_num?.slice(0, 2) === 'AI' ? 'AI 小飞' : item.create_user, |
| | | creator: item.event_num?.slice(0, 2) === 'AI' ? '智飞agent' : item.create_user, |
| | | handler: item.update_user || '未分配', |
| | | status: Number(item.status || 0), |
| | | // 保存原始字段 |
| | |
| | | }); |
| | | } |
| | | }, |
| | | // 导出工单报表 |
| | | exportTheTick(row){ |
| | | const params = { |
| | | num:row.orderNumber |
| | | } |
| | | exportTheTicket(params).then(res=>{ |
| | | const elink = document.createElement('a') |
| | | elink.download = row.orderName + '.docx' |
| | | elink.style.display = 'none' |
| | | const blob = new Blob([res.data]) |
| | | elink.href = URL.createObjectURL(blob) |
| | | document.body.appendChild(elink) |
| | | elink.click() |
| | | document.body.removeChild(elink) |
| | | }) |
| | | this.$message.success('数据导出成功'); |
| | | } |
| | | }, |
| | | activated() { |
| | | this.handleReset(); |