Merge branch 'feature/v6.0/6.0.3' into prod
21 files modified
1 files renamed
2 files added
| | |
| | | VITE_APP_URL = https://wrj.shuixiongit.com/api |
| | | #VITE_APP_URL= http://192.168.1.168 |
| | | #VITE_APP_URL= http://192.168.1.33 |
| | | #VITE_APP_URL= http://192.168.1.204 |
| | | #新大屏地址 |
| | | VITE_APP_DASHBOARD_URL = 'https://wrj.shuixiongit.com/command-center-dashboard/' |
| | | |
| | |
| | | |
| | | |
| | | <script setup> |
| | | import { useDownloadWs } from '@/page/index/useDownloadWs'; |
| | | useDownloadWs() |
| | | </script> |
| | | |
| | | <style> |
| | |
| | | }, |
| | | }); |
| | | }; |
| | | // 历史轨迹记录 |
| | | export const getHistoryTrack = (params) => { |
| | | return request({ |
| | | url: '/drone-device-core/log/droneFlightLog/page', |
| | | method: 'get', |
| | | params |
| | | }) |
| | | } |
| | | // 导出飞行日志 |
| | | export const exportFlyLog = data => { |
| | | return request({ |
| | | url: '/drone-device-core/log/droneFlightLogInfo/export', |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| | | // 收藏 |
| | | export const addStar = data => { |
| | | return request({ |
| | | url: '/drone-device-core/log/favorite/add', |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| | | // 收藏列表 |
| | | export const starPage = (params) => { |
| | | return request({ |
| | | url: '/drone-device-core/log/favorite/page', |
| | | method: 'post', |
| | | params |
| | | }) |
| | | } |
| | | export const updateDroneFlight = (data) => { |
| | | return request({ |
| | | url: '/drone-device-core/log/droneFlightLog/updateDroneFlight', |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| | | export const cancelStar = data => { |
| | | return request({ |
| | | url: '/drone-device-core/log/favorite/cancel/'+data, |
| | | method: 'get', |
| | | }) |
| | | } |
| | | export const droneFlightLogInfoPage = params => { |
| | | return request({ |
| | | url: '/drone-device-core/log/droneFlightLogInfo/page', |
| | | method: 'get', |
| | | params |
| | | }) |
| | | } |
| | |
| | | }); |
| | | }; |
| | | |
| | | |
| | | export const newGetWorkspacesPage = params => { |
| | | return request({ |
| | | url: `/drone-device-core/wayline/api/v1/wayline-groups/page`, |
| | | method: 'get', |
| | | params, |
| | | }) |
| | | } |
| | | |
| | | export const getWaylineFileListByArea = (areaCode) => { |
| | | return request({ |
| | |
| | | export default { |
| | | tip: false, |
| | | searchShow: true, |
| | | searchMenuSpan: 6, |
| | | // searchGutter: 10, |
| | | searchMenuPosition: 'right', |
| | | searchMenuSpan: 12, |
| | | border: true, |
| | | index: true, |
| | | viewBtn: true, |
| New file |
| | |
| | | <template> |
| | | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useGlobalWS } from '@/page/index/useGlobalWS'; |
| | | useGlobalWS() |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | |
| | | </style> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <GlobalWS/> |
| | | <!-- <wechat></wechat> --> |
| | | </div> |
| | | </template> |
| | |
| | | import logo from './logo.vue' |
| | | import top from './top/index.vue' |
| | | import sidebar from './sidebar/index.vue' |
| | | import GlobalWS from '@/page/index/GlobalWS.vue'; |
| | | |
| | | export default { |
| | | mixins: [index], |
| | | components: { |
| | | GlobalWS, |
| | | top, |
| | | logo, |
| | | tags, |
| File was renamed from src/page/index/useDownloadWs.js |
| | |
| | | import { computed, onBeforeUnmount, onMounted } from 'vue'; |
| | | import { getWebsocketUrl } from '@/utils/websocket/config' |
| | | import { useConnectWebSocket } from '@/utils/websocket/connect-websocket' |
| | | import { useStore } from 'vuex' |
| | | import dayjs from 'dayjs' |
| | | import { aLinkDownloadUtil } from '@/utils/util' |
| | | import EventBus from '@/utils/eventBus' |
| | | import { computed, onBeforeUnmount, onMounted } from 'vue'; |
| | | import { setStore,getStore } from '@/utils/store'; |
| | | import { getDownloadStatusApi } from '@/api/dataCenter/dataCenter'; |
| | | import { getStore, setStore } from '@/utils/store' |
| | | |
| | | export const useDownloadWs = () => { |
| | | export const useGlobalWS = () => { |
| | | const store = useStore() |
| | | const loginUserInfo = computed(() => store.state.user.userInfo) |
| | | const downloadProgress = computed(() => store.state.common.downloadProgress) |
| | | let currentWebSocket = null |
| | | function messageHandler(payload) { |
| | | const {type,status,progress,download_url} = payload |
| | | |
| | | // 下载进度处理 |
| | | function downloadProcessing(payload) { |
| | | const {type,status,progress,download_url} = payload?.data || {} |
| | | let setProgress = 0 |
| | | if (status === 'PENDING'){ |
| | | setProgress = 1 |
| | |
| | | ...downloadProgress.value, |
| | | [type]: setProgress, |
| | | }) |
| | | if (status === 'COMPLETED' && ['htsjzx','htlsrwxq'].includes(type)) { |
| | | if (status === 'COMPLETED' && ['dpsjzx','dplsrwxq'].includes(type)) { |
| | | const name = `数据中心-${dayjs().format('YYYYMMDDHHmmss')}.zip` |
| | | const currentUrl = getStore({name: 'downloadUrl'}) |
| | | if (currentUrl === download_url && download_url!== undefined) return |
| | |
| | | } |
| | | } |
| | | |
| | | const logOut = () => { |
| | | store.commit('SET_THEME_NAME', '') |
| | | store.dispatch('LogOut').then(() => { |
| | | router.push({ path: '/login' }) |
| | | setTimeout(() => location.reload()) |
| | | }) |
| | | } |
| | | function messageHandler(payload) { |
| | | switch (payload.biz_code) { |
| | | case 'JOB_ISREFRESH': |
| | | store.commit('jobUpdateKeyAdd') |
| | | break |
| | | case 'DEVICE_ISREFRESH': |
| | | store.commit('deviceUpdateKeyAdd') |
| | | break |
| | | case 'DOWNLOAD_PROGRESS': |
| | | downloadProcessing(payload) |
| | | break |
| | | case 'LOGOUT_USER': |
| | | logOut() |
| | | break |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | let webSocketUrl = getWebsocketUrl() + `&model_type=3&workspace-id=${loginUserInfo.value.user_id}` |
| | | currentWebSocket = useConnectWebSocket((result)=>{ |
| | | const payload = JSON.parse(result) |
| | | messageHandler(payload.data) |
| | | messageHandler(payload) |
| | | }, webSocketUrl) |
| | | EventBus.on('useDownloadWs-messageHandler',messageHandler) |
| | | EventBus.on('useGlobalWS-messageHandler',messageHandler) |
| | | }) |
| | | |
| | | onBeforeUnmount(() => { |
| | | currentWebSocket?.close() |
| | | EventBus.off('useDownloadWs-messageHandler',messageHandler) |
| | | EventBus.off('useGlobalWS-messageHandler',messageHandler) |
| | | }) |
| | | return {} |
| | | } |
| | |
| | | downloadProgress:{ |
| | | htsjzx: 100, //数据中心 |
| | | htlsrwxq: 100, //历史任务详情 |
| | | } |
| | | }, |
| | | deviceUpdateKey: 0, //设备刷新key |
| | | jobUpdateKey: 0, //任务刷新key |
| | | }, |
| | | mutations: { |
| | | deviceUpdateKeyAdd(state, data) { |
| | | state.deviceUpdateKey = state.deviceUpdateKey + 1 |
| | | }, |
| | | jobUpdateKeyAdd(state, data) { |
| | | state.jobUpdateKey = state.jobUpdateKey + 1 |
| | | }, |
| | | setDownloadProgress(state, data) { |
| | | state.downloadProgress = data |
| | | }, |
| | |
| | | disabled: true, |
| | | }, |
| | | { |
| | | label: '4g 增强', |
| | | label: '4G 增强', |
| | | status: '--', |
| | | operateText: '开启', |
| | | cmdKey: DeviceCmd.SdrWorkModeSwitch, |
| | |
| | | <el-form :model="searchForm" inline> |
| | | <div class="search-first"> |
| | | <el-form-item label="行政区划:" > |
| | | <el-tree-select |
| | | <el-tree-select |
| | | :disabled="viewDetailsDisabled" |
| | | popper-class="custom-tree-select" |
| | | v-model="searchForm.areaCode" |
| | |
| | | </el-form-item> |
| | | <el-form-item label="文件类别:"> |
| | | <el-select |
| | | |
| | | |
| | | :disabled="disabled || foldersDisabled || viewDetailsDisabled" |
| | | :teleported="false" |
| | | v-model="searchForm.photoType" |
| | |
| | | machineData.value = ''; |
| | | const droneList = await getDeviceRegion({ areaCode: data.id }); |
| | | machineData.value = droneList?.data?.data; |
| | | |
| | | |
| | | // 默认选中值 |
| | | if (signDevice_sn.value) { |
| | | searchForm.deviceSn = signDevice_sn.value; |
| | |
| | | deptData.value = []; |
| | | getDeptsByAreaCode(); |
| | | handleSearch(); |
| | | |
| | | |
| | | }; |
| | | // 所属部门信息 |
| | | const getDeptsByAreaCode = () => { |
| | |
| | | } |
| | | // 切换文件夹 |
| | | const handleswitchFolders =()=>{ |
| | | emit('handleswitchFolders'); |
| | | emit('handleswitchFolders'); |
| | | } |
| | | // 返回按钮 |
| | | const handleBack = ()=>{ |
| | | emit('handleBack'); |
| | | emit('handleBack'); |
| | | } |
| | | onMounted(() => { |
| | | requestDockInfo(); |
| | | getDownloadStatusApi({type: 'htsjzx'}).then(res =>{ |
| | | if (!['CANCELLED','COMPLETED'].includes(res.data.data?.status || 'COMPLETED')){ |
| | | EventBus.emit('useDownloadWs-messageHandler',res.data.data) |
| | | EventBus.emit('useGlobalWS-messageHandler',res.data.data) |
| | | } |
| | | }) |
| | | }); |
| | |
| | | }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column property="recordName" label="任务名称" show-overflow-tooltip /> |
| | | <el-table-column property="name" label="任务名称" show-overflow-tooltip /> |
| | | <el-table-column property="regionName" label="所属区域"> |
| | | <template #default="scope"> |
| | | <span>{{scope.row.city_name ? scope.row.city_name :'--'}},{{scope.row.area_name ? scope.row.area_name :'--'}}</span> |
| | |
| | | .then(res => { |
| | | folderList.value = res.data.data.records.map(i => ({ ...i, checked: false })) |
| | | total.value = res.data.data.total |
| | | |
| | | }) |
| | | .finally(() => { |
| | | loadings.value = false; |
| | |
| | | searchGutter: 30, |
| | | tip: false, |
| | | searchShow: true, |
| | | searchMenuSpan: 6, |
| | | searchGutter: 30, |
| | | searchMenuPosition: 'right', |
| | | searchMenuSpan: 10, |
| | | border: true, |
| | | index: true, |
| | | indexLabel: '序号', |
| | |
| | | searchGutter: 30, |
| | | tip: false, |
| | | searchShow: true, |
| | | searchMenuSpan: 6, |
| | | // searchMenuSpan: 16, |
| | | searchMenuPosition: 'right', |
| | | searchMenuSpan: 8, |
| | | border: true, |
| | | index: true, |
| | | indexLabel: '序号', |
| | |
| | | searchSpan: 4, |
| | | labelWidth: 145, |
| | | width: 120, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入设备型号', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '设备SN', |
| | |
| | | searchSpan: 4, |
| | | // editDisabled: true, |
| | | editDisplay: false, //编辑显示 |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入设备SN', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | // { |
| | | // label: '机巢编号', |
| | | // prop: 'machine_nest_sn', |
| | | // labelWidth: 145, |
| | | // editDisabled: true, |
| | | // rules: [ |
| | | // { |
| | | // required: false, |
| | | // message: '请输入机巢编号', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | // }, |
| | | |
| | | { |
| | | label: '设备位置',// '行政区划', |
| | | prop: 'area_name', |
| | |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | // { |
| | | // label: '设备位置', |
| | | // prop: 'address', |
| | | // labelWidth: 145, |
| | | // width: 100, |
| | | // overHidden: true, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入设备位置', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | // }, |
| | | { |
| | | label: '4G增强', |
| | | prop: 'link_workmode', |
| | | labelWidth: 145, |
| | | width: 160, |
| | | overHidden: true, |
| | | editDisplay: false, //编辑显示 |
| | | viewDisplay: false, |
| | | align: 'center', |
| | | formatter: (row, column, cellValue) => { |
| | | const statusMap = { |
| | | 0: '关', |
| | | 1: '开', |
| | | }; |
| | | return statusMap[cellValue] || '/'; |
| | | } |
| | | }, |
| | | |
| | | { |
| | | label: '负载设备', |
| | |
| | | width: 160, |
| | | overHidden: true, |
| | | editDisplay: false, //编辑显示 |
| | | // editDisabled: true, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入负载设备', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | |
| | | }, |
| | | { |
| | | // hide: true, |
| | |
| | | type: 'date', |
| | | format: 'YYYY-MM-DD', |
| | | editDisplay: false, //编辑显示 |
| | | // editDisabled: true, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入流量到期时间', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '固件版本', |
| | |
| | | labelWidth: 145, |
| | | width: 110, |
| | | editDisplay: false, //编辑显示 |
| | | // editDisabled: true, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入固件版本', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '固件升级', |
| | |
| | | viewDisabled: true, |
| | | addDisabled: true, |
| | | editDisplay: false, //编辑显示 |
| | | // editDisabled: true, |
| | | addDisplay: false, |
| | | viewDisplay: false, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入固件升级', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '所属单位', |
| | |
| | | import CancelTaskDialog from '../CancelTaskDialog.vue' |
| | | import { useStore } from 'vuex' |
| | | import { cloneDeep } from 'lodash' |
| | | import { inject, onBeforeUnmount } from 'vue'; |
| | | import { inject, onBeforeUnmount, watch } from 'vue'; |
| | | import ElTooltipCopy from '@/components/ElTooltipCopy.vue'; |
| | | const store = useStore() |
| | | const singleUavHome = computed(() => store.state.home.singleUavHome) |
| | |
| | | |
| | | |
| | | const changeKey = inject('changeKey') |
| | | // 轮询查询是否刷新 |
| | | const polling = setInterval(async () => { |
| | | const res = await statusChangedApi() |
| | | if (res.data.data.DEVICE_REFRESH || res.data.data.JOB_REFRESH) { |
| | | getJobList() |
| | | changeKey.value++ |
| | | } |
| | | }, 4000) |
| | | const jobUpdateKey = computed(() => store.state.common.jobUpdateKey) |
| | | const deviceUpdateKey = computed(() => store.state.common.deviceUpdateKey) |
| | | |
| | | watch([jobUpdateKey,deviceUpdateKey],()=>{ |
| | | getJobList() |
| | | changeKey.value++ |
| | | }) |
| | | |
| | | |
| | | onBeforeUnmount(() => { |
| | | clearInterval(polling) |
| | |
| | | color: '#363636', |
| | | fontSize: 12, |
| | | }, |
| | | itemWidth: 2, // 减小图例标记的宽度 |
| | | itemHeight: 6, // 减小图例标记的高度 |
| | | itemWidth: 8, // 减小图例标记的宽度 |
| | | itemHeight: 8, // 减小图例标记的高度 |
| | | itemGap: 8, // 减小图例项之间的间距 |
| | | formatter: '{name}', // 简化图例文本 |
| | | }, |
| | |
| | | center: ['30%', '50%'], |
| | | data: [], |
| | | label: { |
| | | show: true, |
| | | show: false, |
| | | position: 'outside', |
| | | formatter: '{c}', |
| | | fontSize: 12, |
| | | color: '#000', |
| | | }, |
| | | labelLine: { |
| | | show: true, |
| | | show: false, |
| | | length: 10, |
| | | length2: 10, |
| | | lineStyle: { |
| New file |
| | |
| | | <!-- 飞行日志 --> |
| | | <template> |
| | | <div class="flight"> |
| | | <div class="ztzf-search-mange"> |
| | | <el-form :model="params" inline> |
| | | <div class="search-contain"> |
| | | <div> |
| | | <el-form-item label="任务名称:"> |
| | | <el-input v-model="params.jobName" placeholder="请输入任务名称" clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="任务编号:"> |
| | | <el-input v-model="params.jobInfoNum" placeholder="请输入任务编号" clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="日期:"> |
| | | <el-date-picker |
| | | v-model="rangTime" |
| | | type="daterange" |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | clearable |
| | | @change="changeselect" |
| | | /> |
| | | </el-form-item> |
| | | </div> |
| | | <div class="btns"> |
| | | <el-button type="primary" @click="getList" :icon="Search">搜索</el-button> |
| | | <el-button @click="cancelSearch" :icon="Delete">清空</el-button> |
| | | </div> |
| | | </div> |
| | | </el-form> |
| | | </div> |
| | | <div class="mange-table"> |
| | | <!-- <el-tabs v-model="tabType" class="demo-tabs" @tab-click="handleTabClick">--> |
| | | <!-- <el-tab-pane label="全部" name="全部"></el-tab-pane>--> |
| | | <!-- <el-tab-pane label="我的收藏" name="收藏"></el-tab-pane>--> |
| | | <!-- --> |
| | | <!-- </el-tabs>--> |
| | | <el-table border :data="tableList" class="custom-header"> |
| | | <el-table-column label="序号" type="index" width="60"></el-table-column> |
| | | <el-table-column prop="job_name" label="任务名称" align="center" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="job_info_num" label="任务编号" align="center" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="title" label="飞行类型" align="center" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="device_name" label="无人机" align="center"></el-table-column> |
| | | <el-table-column prop="start_time" label="开始时间" align="center"> |
| | | <template #default="scope"> |
| | | {{ timeFormatConvert(scope.row.start_time) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="end_time" label="结束时间" align="center"> |
| | | <template #default="scope"> |
| | | {{ timeFormatConvert(scope.row.end_time) }} |
| | | </template> |
| | | </el-table-column> |
| | | <!-- <el-table-column prop="end_time" label="标签" align="center">--> |
| | | <!-- <template #default="scope">--> |
| | | <!-- <el-select v-model="scope.row.label_id" @change="handleUpdateLabel(scope.row)" clearable>--> |
| | | <!-- <el-option--> |
| | | <!-- v-for="item in tagList"--> |
| | | <!-- :key="item.id"--> |
| | | <!-- :label="item.label_name"--> |
| | | <!-- :value="item.id"--> |
| | | <!-- ></el-option>--> |
| | | <!-- </el-select>--> |
| | | <!-- </template>--> |
| | | <!-- </el-table-column>--> |
| | | <el-table-column label="操作" width="300" align="center"> |
| | | <template #default="scope"> |
| | | <el-button icon="el-icon-view" type="text" @click="handleDetail(scope.row)">查看</el-button> |
| | | <el-button icon="el-icon-delete" type="text" @click="handleDelete(scope.row)">删除</el-button> |
| | | <!-- <el-button type="text" @click="handleStar(scope.row)">--> |
| | | <!-- <el-icon><Star /></el-icon>--> |
| | | <!-- {{ scope.row.is_favorite ? '取消收藏':'收藏' }}</el-button>--> |
| | | <el-button type="text" @click="handleExport(scope.row)"><el-icon><Download /></el-icon>导出</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <div class="pagination"> |
| | | <el-pagination class="ztzf-pagination" popper-class="custom-pagination-dropdown" background |
| | | :page-sizes="[10, 20, 30, 40, 50, 100]" :size="size" v-model:current-page="params.page" |
| | | v-model:page-size="params.page_size" layout="total, sizes, prev, pager, next, jumper" :total="total" |
| | | @size-change="handleSizeChange" @current-change="handleCurrentChange" /> |
| | | </div> |
| | | </div> |
| | | <el-dialog class="ztzf-dialog" append-to-body v-model="isShowView" title="查看" |
| | | :width="pxToRem(1000)" :close-on-click-modal="false" :destroy-on-close="true"> |
| | | <!-- <div class="content"> --> |
| | | <el-table border :data="tableDataDetails" height="466"> |
| | | <el-table-column label="序号" type="index" width="60"></el-table-column> |
| | | <el-table-column prop="flight_type" label="飞行类型" align="center" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="latitude" label="经度" align="center"></el-table-column> |
| | | <el-table-column prop="longitude" label="纬度" align="center"></el-table-column> |
| | | <el-table-column prop="height" label="高度" align="center"></el-table-column> |
| | | <el-table-column prop="elevation" label="海拔高度" align="center"></el-table-column> |
| | | </el-table> |
| | | <div class="pagination" style="display: flex;justify-content: end;margin-top: 10px;"> |
| | | <el-pagination class="ztzf-pagination" popper-class="custom-pagination-dropdown" background |
| | | :page-sizes="[10, 20, 30, 40, 50, 100]" :size="size" v-model:current-page="detailParams.current" |
| | | v-model:page-size="detailParams.size" layout="total, sizes, prev, pager, next, jumper" :total="detailTotal" |
| | | @size-change="handleSizeChangeDetails" @current-change="handleCurrentChangeDetails" /> |
| | | <!-- </div> --> |
| | | </div> |
| | | </el-dialog> |
| | | </template> |
| | | <script setup> |
| | | import { getHistoryTrack, cancelStar, addStar, updateDroneFlight, droneFlightLogInfoPage } from '@/api/logs'; |
| | | // import { flightLogPage } from '@/api/airspace/airspace'; |
| | | import { downloadXls } from '@/utils/util'; |
| | | import { exportBlob } from '@/api/common' |
| | | import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'; |
| | | import { Delete, Search } from '@element-plus/icons-vue'; |
| | | |
| | | const total = ref(0) |
| | | let rangTime = ref([]) |
| | | const params = ref({ |
| | | isFavorite: false, |
| | | page: 1, |
| | | page_size: 10, |
| | | startTime: '', |
| | | endTime: '', |
| | | jobName: '', |
| | | jobInfoNum: '', |
| | | }); |
| | | |
| | | let tableList = ref([]) |
| | | |
| | | let isShowView = ref(false) |
| | | |
| | | let tabType = ref('全部') |
| | | |
| | | function timeFormatConvert(time) { |
| | | if (!time) return '/' |
| | | const date = new Date(time); |
| | | return date.toLocaleString(); |
| | | } |
| | | |
| | | function cancelSearch() { |
| | | rangTime.value = [] |
| | | params.value = { |
| | | startTime: '', |
| | | endTime: '', |
| | | isFavorite: tabType.value === '收藏' ? true : false, |
| | | page: '1', |
| | | page_size: '10', |
| | | jobName: '', |
| | | jobInfoNum: '', |
| | | } |
| | | getList() |
| | | } |
| | | |
| | | function getList() { |
| | | params.value.startTime = rangTime.value?.length ? rangTime.value[0].getTime() : '' |
| | | params.value.endTime = rangTime.value?.length? new Date( |
| | | rangTime.value[1].getFullYear(), |
| | | rangTime.value[1].getMonth(), |
| | | rangTime.value[1].getDate(), |
| | | 23, 59, 59 |
| | | ).getTime() : '' |
| | | getHistoryTrack(params.value).then(res => { |
| | | tableList.value = res.data.data.list || [] |
| | | total.value = res.data.data.pagination.total || 0 |
| | | }) |
| | | } |
| | | |
| | | function handleAll() { |
| | | params.value.isFavorite = false |
| | | params.value.page = 1 |
| | | tabType.value = '全部' |
| | | getList() |
| | | } |
| | | // 查看 |
| | | let tableDataDetails = ref([]) |
| | | let detailTotal = ref(0) |
| | | let detailParams = ref({ |
| | | current: 1, |
| | | size: 10, |
| | | flightId: '' |
| | | }) |
| | | function handleDetail(row) { |
| | | isShowView.value = true |
| | | detailParams.value.current = 1 |
| | | detailParams.value.flightId = row.id |
| | | detailTotal.value = 0 |
| | | droneFlightLogInfoPage(detailParams.value).then(res => { |
| | | tableDataDetails.value = res.data.data.records |
| | | detailTotal.value = res.data.data.total |
| | | }) |
| | | } |
| | | // 分页 |
| | | function handleSizeChangeDetails(val) { |
| | | detailParams.value.size = val |
| | | detailParams.value.current = 1 |
| | | droneFlightLogInfoPage(detailParams.value).then(res => { |
| | | tableDataDetails.value = res.data.data.records |
| | | detailTotal.value = res.data.data.total |
| | | }) |
| | | } |
| | | function handleCurrentChangeDetails(val) { |
| | | detailParams.value.current = val |
| | | droneFlightLogInfoPage(detailParams.value).then(res => { |
| | | tableDataDetails.value = res.data.data.records |
| | | detailTotal.value = res.data.data.total |
| | | }) |
| | | } |
| | | |
| | | |
| | | function handleStartList() { |
| | | params.value.isFavorite = true |
| | | tabType.value = '收藏' |
| | | params.value.page = 1 |
| | | getList() |
| | | } |
| | | |
| | | // function handleTabClick() { |
| | | // if (tabType.value === '全部') { |
| | | // handleAll() |
| | | // } else if (tabType.value === '收藏') { |
| | | // handleStartList() |
| | | // } |
| | | // } |
| | | |
| | | // 收藏 |
| | | function handleStar(row) { |
| | | if (row.is_favorite) { |
| | | cancelStar(row.id).then(res => { |
| | | ElMessage.success('取消收藏成功') |
| | | getList() |
| | | }) |
| | | } else { |
| | | addStar({ flight_log_id: row.id }).then(res => { |
| | | ElMessage.success('收藏成功') |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | // 打标签 |
| | | function handleUpdateLabel(row) { |
| | | updateDroneFlight({ id: row.id, label_id: row.label_id }).then(res => { |
| | | // getList() |
| | | ElMessage.success('设置标签成功') |
| | | }) |
| | | } |
| | | |
| | | // 删除 |
| | | function handleDelete(row) { |
| | | ElMessageBox.confirm('确定删除该条数据?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }).then(() => { |
| | | updateDroneFlight({ is_deleted: 1, id: row.id }).then(res => { |
| | | ElMessage.success('删除成功') |
| | | getList() |
| | | }) |
| | | }).catch(() => { |
| | | ElMessage({ |
| | | type: 'info', |
| | | message: '已取消删除' |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | // 导出 |
| | | function handleExport(row) { |
| | | exportBlob( |
| | | `/drone-device-core/log/droneFlightLogInfo/export/${row.id}` |
| | | ).then(res => { |
| | | downloadXls(res.data, `${row.job_name}.xlsx`) |
| | | }) |
| | | } |
| | | |
| | | // 日期选择 |
| | | // const changeselect = () => { |
| | | // params.value.startTime = rangTime.value[0] ? rangTime.value[0].getTime() : '' |
| | | // params.value.endTime = rangTime.value[1]? rangTime.value[1].getTime() : '' |
| | | // getList() |
| | | // }; |
| | | |
| | | function handleSizeChange(val) { |
| | | params.value.page_size = val |
| | | getList() |
| | | } |
| | | function handleCurrentChange(val) { |
| | | params.value.page = val |
| | | getList() |
| | | } |
| | | let tagList = ref([]) |
| | | function tagManageList() { |
| | | flightLogPage({ current:1, size: 99 }).then(res => { |
| | | tagList.value = res.data.data.records || [] |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // tagManageList() |
| | | getList() |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .flight { |
| | | height: 0; |
| | | flex: 1; |
| | | margin: 0 10px 10px 10px; |
| | | background-color: #ffffff; |
| | | padding: 10px 20px; |
| | | border-radius: 5px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | //.search-box { |
| | | // height: 30px; |
| | | //} |
| | | |
| | | :deep(.el-input) { |
| | | .el-input__wrapper { |
| | | width: 200px; |
| | | } |
| | | } |
| | | |
| | | // 表格 |
| | | .mange-table { |
| | | height: 0; |
| | | flex: 1; |
| | | margin-top: 18px; |
| | | overflow: auto; |
| | | } |
| | | :deep(.el-pagination) { |
| | | display: flex; |
| | | justify-content: right; |
| | | } |
| | | |
| | | :deep(.el-pagination button) { |
| | | background: center center no-repeat none !important; |
| | | color: #8eb8ea !important; |
| | | } |
| | | :deep(.ztzf-select){ |
| | | .el-select__selection { |
| | | width: 200px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .content { |
| | | padding: 20px; |
| | | |
| | | .view-table { |
| | | width: 100%; |
| | | border-collapse: collapse; |
| | | border: 1px solid #EBEEF5; |
| | | |
| | | tr { |
| | | &:not(:last-child) { |
| | | border-bottom: 1px solid #EBEEF5; |
| | | } |
| | | |
| | | td { |
| | | padding: 12px 10px; |
| | | |
| | | &.label { |
| | | width: 140px; |
| | | text-align: right; |
| | | // color: #909399; |
| | | // background-color: #F5F7FA; |
| | | border-right: 1px solid #EBEEF5; |
| | | } |
| | | |
| | | &.value { |
| | | width: 180px; |
| | | // color: #303133; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .content-edit { |
| | | .el-form { |
| | | .el-form-item { |
| | | width: 300px; |
| | | :deep(.el-form-item__label) { |
| | | width: 120px; |
| | | } |
| | | |
| | | } |
| | | .btns { |
| | | display: flex; |
| | | justify-content: center |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | viewInstance.value.removeMouseHandler('drawCustomPolygon'); |
| | | } |
| | | |
| | | const emit = defineEmits(['upDateDrawState']); |
| | | const emit = defineEmits(['upDateDrawState',]); |
| | | |
| | | function updatePolygon() { |
| | | let polygon = savePolygonPosition.reduce((pre, cur) => { |
| | |
| | | return pre; |
| | | }, []); |
| | | polygon.push(polygon[0]); |
| | | console.log('绘制', `POLYGON((${polygon.join(',')}))`); |
| | | |
| | | // 接口 |
| | | sdfwUpdate({ |
| | | ids: selectionIds.value, |
| | |
| | | }) |
| | | } |
| | | |
| | | |
| | | function cancel() { |
| | | remove(); |
| | | removeMenuPanel(); |
| | |
| | | :row-class-name="tableRowClassName" |
| | | :data="tableData" |
| | | @row-click="handleLocationPolygon" |
| | | @current-change="handleTableRowChange" |
| | | |
| | | > |
| | | <el-table-column type="index" align="center" :width="pxToRemNum(30)" label="序号"> |
| | | <template #default="{ $index }"> |
| | | {{ |
| | | ($index + 1 + (params.page - 1) * params.pageSize).toString().padStart(2, '0') |
| | | }} |
| | | </template> |
| | | <template #default="{ $index }"> |
| | | {{ ($index + 1).toString().padStart(2, '0') }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="dkbh" align="center" label="图斑名称" show-overflow-tooltip /> |
| | | <el-table-column prop="is_exception" :width="pxToRemNum(50)" align="center" label="图斑状态"> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div class="pagination-container"> |
| | | <el-pagination |
| | | :current-page="params.page" |
| | | :page-size="params.pageSize" |
| | | background |
| | | layout="prev, pager, next, ..." |
| | | :pager-count="3" |
| | | prev-text="上一页" |
| | | next-text="下一页" |
| | | :total="total" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | | <!--绘制按钮--> |
| | |
| | | ref="drawPolygonRef" |
| | | v-if="isEditing" |
| | | @upDateDrawState="handleUpDateDrawState" |
| | | |
| | | /> |
| | | <!-- 完成/取消 --> |
| | | <div class="btnGroups" v-if="props.title === '图斑编辑'"> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { flyVisual } from '@/utils/cesium/mapUtil' |
| | | import { pxToRem, pxToRemNum } from '@/utils/rem' |
| | | import DrawPolygon from '@/views/resource/components/DrawPolygon.vue'; |
| | | import { ElMessage, ElMessageBox } from 'element-plus'; |
| | |
| | | page: 1, |
| | | pageSize: 10, |
| | | }); |
| | | const isInit = ref(true); |
| | | // 图斑管理表格 |
| | | const getTableList = () => { |
| | | const requestParams = { |
| | | patchesInfoId: props.detailid, |
| | | page: params.value.page, |
| | | pageSize: params.value.pageSize, |
| | | |
| | | }; |
| | | tableMapListApi(requestParams).then(res => { |
| | | tableData.value = res.data.data.records?.map(item => ({ |
| | | AlltableMapListApi(requestParams).then(res => { |
| | | tableData.value = res.data.data?.map(item => ({ |
| | | ...item, |
| | | dkfw: item.sdfw && item.is_exception == 1 ? item.sdfw : item.dkfw, |
| | | })); |
| | | total.value = res.data.data.total || res.data.data.length; |
| | | tbJwdList = []; |
| | | viewer?.entities.removeAll(); |
| | | if (!AlltableData.value) { |
| | | if (!tableData.value) { |
| | | viewInstance.value?.flyToContour(); |
| | | } else { |
| | | entitiesAddSpot(); |
| | | } |
| | | }); |
| | | }; |
| | | // 所有图斑数据 |
| | | const getAlltableMapListApi = () => { |
| | | loading.value = true; |
| | | const requestParams = { |
| | | patchesInfoId: props.detailid, |
| | | }; |
| | | AlltableMapListApi(requestParams).then(res => { |
| | | AlltableData.value = res.data.data?.map(item => ({ |
| | | ...item, |
| | | dkfw: item.sdfw && item.is_exception == 1 ? item.sdfw : item.dkfw, |
| | | })); |
| | | |
| | | tbJwdList = []; |
| | | viewer?.entities.removeAll(); |
| | | if (AlltableData.value.length < 1) { |
| | | viewInstance.value?.flyToContour(); |
| | | } else { |
| | | entitiesAddSpot(); |
| | | } |
| | | loading.value = false; |
| | | }); |
| | | }; |
| | | const handleSizeChange = val => { |
| | | params.value.pageSize = val; |
| | | params.value.page = 1; |
| | | getTableList(); |
| | | }; |
| | | const handleCurrentChange = val => { |
| | | params.value.page = val; |
| | | getTableList(); |
| | | }; |
| | | |
| | | |
| | | // 地图 |
| | | const initMap = () => { |
| | |
| | | viewer.scene.globe.depthTestAgainstTerrain = true; |
| | | viewInstance.value.switchContour(true); |
| | | }; |
| | | // 仅弹框初始化时执行的定位逻辑 |
| | | const initMapLocation = () => { |
| | | if (tbJwdList.length === 0 || !homeViewer.value) return; |
| | | |
| | | // 计算所有图斑的包围球(用于初始化定位) |
| | | const allPositions = tbJwdList.flatMap(item => |
| | | Cesium.Cartesian3.fromDegreesArray(item.grouped) |
| | | ); |
| | | const boundingSphere = Cesium.BoundingSphere.fromPoints(allPositions); |
| | | |
| | | // 初始化定位(仅执行一次) |
| | | homeViewer.value.camera.flyToBoundingSphere(boundingSphere, { |
| | | duration: 0, |
| | | offset: new Cesium.HeadingPitchRange( |
| | | Cesium.Math.toRadians(0), |
| | | Cesium.Math.toRadians(-90) |
| | | ), |
| | | }); |
| | | }; |
| | | // 初始化所有图斑 |
| | | const entitiesAddSpot = () => { |
| | | viewer?.entities.removeAll(); |
| | | AlltableData.value.forEach(item => { |
| | | // 取出当中经纬度 |
| | | tbJwdList = []; // 重置经纬度列表 |
| | | |
| | | tableData.value.forEach(item => { |
| | | const numbersWithCommas = item.dkfw.match(/\d+(\.\d+)?/g); |
| | | if (!numbersWithCommas) return; |
| | | // 绘制图斑 |
| | | const grouped = numbersWithCommas.map(item => Number(item)); |
| | | // 为框选存储对比值 |
| | | tbJwdList.push({ |
| | | ...item, |
| | | grouped: grouped, |
| | | }); |
| | | viewInstance.value.removeById('polygon_dk' + item.id); |
| | | // 根据 is_exception 设置颜色 |
| | | const color = |
| | | item.is_exception == 2 ? Cesium.Color.RED.withAlpha(0.5) : Cesium.Color.YELLOW.withAlpha(0.5); |
| | | const outlineColor = item.is_exception == 2 ? Cesium.Color.RED : Cesium.Color.YELLOW; |
| | | |
| | | const grouped = numbersWithCommas.map(Number); |
| | | tbJwdList.push({ ...item, grouped }); // 存储经纬度用于后续操作 |
| | | |
| | | // 绘制图斑(保留原有逻辑,仅移除定位相关代码) |
| | | const fillColor = item.is_exception === 2 |
| | | ? Cesium.Color.RED.withAlpha(0.5) |
| | | : Cesium.Color.YELLOW.withAlpha(0.5); |
| | | const outlineColor = item.is_exception === 2 |
| | | ? Cesium.Color.RED |
| | | : Cesium.Color.YELLOW; |
| | | |
| | | homeViewer.value?.entities?.add({ |
| | | id: 'polygon_dk' + item.id, |
| | | id: `polygon_dk${item.id}`, |
| | | customType: 'pattern_spot_polygon', |
| | | customInfo: { |
| | | ...item, |
| | | }, |
| | | customInfo: item, |
| | | polygon: { |
| | | hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(grouped)), |
| | | material: color, |
| | | material: fillColor, |
| | | outline: true, |
| | | outlineColor: outlineColor, |
| | | outlineWidth: 2, |
| | |
| | | polyline: { |
| | | positions: Cesium.Cartesian3.fromDegreesArray(grouped), |
| | | width: 2, |
| | | material: color, |
| | | material: outlineColor, |
| | | clampToGround: true, |
| | | }, |
| | | zIndex: 99, |
| | | }); |
| | | |
| | | if (tbJwdList.length > 0) { |
| | | const positions = tbJwdList.flatMap(item => Cesium.Cartesian3.fromDegreesArray(item.grouped)); |
| | | const boundingSphere = Cesium.BoundingSphere.fromPoints(positions); |
| | | homeViewer.value?.camera.flyToBoundingSphere(boundingSphere, { |
| | | duration: 0, |
| | | offset: new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-90)), |
| | | }); |
| | | } |
| | | viewInstance.value?.removeLeftClickEvent('spotHighlighting'); |
| | | viewInstance.value?.addLeftClickEvent(null, spotHighlighting, 'spotHighlighting'); |
| | | }); |
| | | |
| | | // 仅在初始化阶段执行定位(关键:通过isInit控制) |
| | | if (isInit.value) { |
| | | initMapLocation(); |
| | | isInit.value = false; // 初始化完成,后续不再执行定位 |
| | | } |
| | | |
| | | // 保留图斑点击高亮事件(原有逻辑不变) |
| | | viewInstance.value?.removeLeftClickEvent('spotHighlighting'); |
| | | viewInstance.value?.addLeftClickEvent(null, spotHighlighting, 'spotHighlighting'); |
| | | }; |
| | | |
| | | // 高亮当前选中图斑,并定位 |
| | |
| | | |
| | | updateMapSpotInfo(nowEntity); |
| | | } |
| | | |
| | | // 更新上一个和这一个信息 |
| | | function updateMapSpotInfo(nowEntity) { |
| | | const nowData = nowEntity.customInfo; |
| | | if (!nowEntity) return; |
| | | if (nowEntity.customInfo.id === lastEntity?.customInfo.id) return; |
| | | // 设置新的 |
| | | nowEntity.polygon.material = Cesium.Color.RED.withAlpha(0); |
| | | nowEntity.polyline.material = Cesium.Color.RED; |
| | | // 重置上一个 |
| | | if (lastEntity) { |
| | | const lastData = lastEntity.customInfo; |
| | | const originalFillColor = |
| | |
| | | : Cesium.Color.YELLOW.withAlpha(0.5); |
| | | const originalOutlineColor = |
| | | lastData.is_exception == 2 ? Cesium.Color.RED : Cesium.Color.YELLOW; |
| | | |
| | | lastEntity.polygon.material = originalFillColor; |
| | | lastEntity.polygon.outlineColor = originalOutlineColor; |
| | | lastEntity.polyline.material = originalOutlineColor; |
| | |
| | | lastEntity = nowEntity; |
| | | const numbersWithCommas = nowData.dkfw.match(/\d+(\.\d+)?/g); |
| | | if (numbersWithCommas) { |
| | | // 解析经纬度数组 |
| | | const groupedArr = numbersWithCommas.reduce((acc, val, index, src) => { |
| | | if (index % 2 === 0) acc.push(src.slice(index, index + 2)); |
| | | return acc; |
| | | }, []); |
| | | const polygonCenter = getCenterPoint(groupedArr); |
| | | // 相机定位 |
| | | homeViewer.value.scene.camera.setView({ |
| | | destination: Cesium.Cartesian3.fromDegrees( |
| | | Number(polygonCenter.lng), |
| | | Number(polygonCenter.lat), |
| | | 1500 |
| | | ), |
| | | zIndex: 100, |
| | | |
| | | const positionsData = []; |
| | | for (let i = 0; i < numbersWithCommas.length; i += 2) { |
| | | const lon = Number(numbersWithCommas[i]); |
| | | const lat = Number(numbersWithCommas[i + 1]); |
| | | positionsData.push([lon, lat, 10]); |
| | | } |
| | | flyVisual({ |
| | | positionsData: positionsData, |
| | | viewer: homeViewer.value, |
| | | multiple: 15, |
| | | |
| | | }); |
| | | } |
| | | // flyMapSpot(nowEntity?.customInfo) |
| | | } |
| | | // 清空选中的数据 |
| | | const clearSelect = () => { |
| | |
| | | viewer?.entities.removeAll(); |
| | | }; |
| | | // 编辑 |
| | | |
| | | const handleSelectionChange = row => { |
| | | let curRowIsSelect = row; |
| | | curRowIsSelect && handleLocationPolygon(row); |
| | | // 如果是同一个图斑且正在编辑,则取消编辑 |
| | | if (selectionIds.value === row.id && isEditing.value) { |
| | | isEditing.value = false; |
| | | handleUpDateDrawState(false); |
| | | selectionIds.value = null; |
| | | selectionList.value = []; |
| | | return; |
| | | } |
| | | |
| | | // 定位到选中的图斑 |
| | | handleLocationPolygon(row); |
| | | |
| | | // 仅异常图斑可编辑 |
| | | if (row.is_exception !== 2) { |
| | | ElMessage.warning('仅异常图斑支持编辑绘制'); |
| | | return; |
| | | } |
| | | |
| | | // 设置编辑状态 |
| | | selectionIds.value = row.id; |
| | | selectionList.value = row; |
| | | |
| | | if (isEditing.value) { |
| | | //当前已编辑 → 取消编辑(关闭绘制、重置状态) |
| | | isEditing.value = false; |
| | | handleUpDateDrawState(false); // 通知DrawPolygon取消绘制 |
| | | } else { |
| | | // 当前未编辑 → 开启编辑(仅异常图斑可编辑) |
| | | if (row.is_exception === 2 && curRowIsSelect) { |
| | | isEditing.value = true; |
| | | handleUpDateDrawState(true); // 通知DrawPolygon开启绘制 |
| | | } else { |
| | | ElMessage.warning('仅异常图斑支持编辑绘制'); |
| | | isEditing.value = false; |
| | | } |
| | | } |
| | | isEditing.value = true; |
| | | handleUpDateDrawState(true); |
| | | }; |
| | | const handleUpDateDrawState = show => { |
| | | isEditing.value = show; // 同步编辑状态 |
| | |
| | | } |
| | | }; |
| | | // 删除 |
| | | const handleDelete = row => { |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm('确认删除当前行图斑?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | |
| | | deletePatches({ ids: row.id }).then(res => { |
| | | if (res.data.code !== 0) return ElMessage.warning('删除失败'); |
| | | ElMessage.success('删除成功'); |
| | | getTableList(); |
| | | getspotManagementTableApi(); |
| | | getAlltableMapListApi(); |
| | | tableData.value = tableData.value.filter(item => item.id !== row.id); |
| | | //从地图上移除对应的图斑实体 |
| | | const entityId = `polygon_dk${row.id}`; |
| | | viewer?.entities.removeById(entityId); |
| | | const exceptionCountItem = infoList.value.find(item => item.name === '异常图斑数量'); |
| | | if (exceptionCountItem && row.is_exception === 2) { |
| | | exceptionCountItem.value = Math.max(0, parseInt(exceptionCountItem.value) - 1); |
| | | } |
| | | const totalCountItem = infoList.value.find(item => item.name === '图斑数量'); |
| | | if (totalCountItem) { |
| | | totalCountItem.value = Math.max(0, parseInt(totalCountItem.value) - 1); |
| | | } |
| | | |
| | | // 清除选中状态 |
| | | if (selectionIds.value === row.id) { |
| | | selectionIds.value = null; |
| | | selectionList.value = []; |
| | | isEditing.value = false; |
| | | handleUpDateDrawState(false); |
| | | } |
| | | |
| | | }); |
| | | }); |
| | | }; |
| | |
| | | publicCesiumInstance = null; |
| | | }; |
| | | |
| | | |
| | | watch(uploadPatchDialog, newVal => { |
| | | if (newVal) { |
| | | |
| | | isInit.value = true; |
| | | setTimeout(() => { |
| | | initMap(); |
| | | getTableList(); |
| | | getAlltableMapListApi(); |
| | | initMap(); |
| | | getTableList(); |
| | | getspotManagementTableApi(); |
| | | }, 0); |
| | | } else { |
| | | tableData.value = []; |
| | | isEditing.value = false; |
| | | handleUpDateDrawState(false); |
| | | destroyMap(); |
| | | isInit.value = false; |
| | | clearSelect(); |
| | | } |
| | | refreshonload(); |
| | | }); |
| | |
| | | font-size: 16px !important; |
| | | color: #363636 !important; |
| | | } |
| | | :global(.spotDialog .el-dialog__body) { |
| | | padding: 2rem 2rem 0 !important; |
| | | |
| | | } |
| | | .container { |
| | | display: flex; |
| | | flex-direction: column; |
| | |
| | | // 表格主体 |
| | | .el-table__body { |
| | | tr:hover > td { |
| | | background-color: rgba(0, 0, 0, 0.6) !important; |
| | | background-color: rgba(64, 158, 255,0.3) !important; |
| | | } |
| | | |
| | | td { |
| | |
| | | |
| | | // 选中行 |
| | | .current-row td { |
| | | background-color: rgba(0, 0, 0, 0.6) !important; |
| | | |
| | | background-color: rgba(64, 158, 255,0.3) !important; |
| | | } |
| | | } |
| | | :deep(.el-table__body) { |
| | |
| | | labelWidth: 120, |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: false, |
| | | width: 80, |
| | | rules: [ |
| | | { |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: '部署模式', |
| | | type: 'radio', |
| | | prop: 'deploymentMode', |
| | | labelWidth: 120, |
| | | value: 0, |
| | | dicData: [ |
| | | { |
| | | label: '统一部署', |
| | | value: 0, |
| | | }, |
| | | { |
| | | label: '独立部署', |
| | | value: 1, |
| | | }, |
| | | ], |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请选择部署模式', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '备注', |
| | | prop: 'remark', |
| | | type: 'textarea', |
| | | span: 24, |
| | | labelWidth: 120, |
| | | rules: [ |
| | | { |
| | |
| | | <el-form-item label="姓名:"> |
| | | <el-input |
| | | class="ztzf-input" |
| | | :style="{ width: pxToRem(230) }" |
| | | :style="{ width: pxToRem(350) }" |
| | | v-model="userInfo.realName" |
| | | disabled |
| | | /> |
| | |
| | | margin: 16px; |
| | | padding: 10px; |
| | | background-color: #ffffff; |
| | | height: 100%; |
| | | } |
| | | .titleBoxs { |
| | | margin: 0 24px; |
| | |
| | | :deep(.el-form-item__label) { |
| | | color: #000 !important; |
| | | } |
| | | :deep(.el-button) { |
| | | width: 150px !important; |
| | | } |
| | | // :deep(.el-button) { |
| | | // width: 150px !important; |
| | | // } |
| | | .info { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | justify-content: center; |
| | | align-items: center; |
| | | padding: 0 80px 0 50px; |
| | | .section:first-child{ |
| | | margin-right: 50px;} |
| | | } |
| | | .password { |
| | | padding: 0 120px 0 50px; |
| | | } |
| | | .butn { |
| | | // position: absolute; |
| | | // bottom: 20px; |
| | | // left: 50%; |
| | | // transform: translate(-50%); |
| | | display: flex; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | |
| | | img { |
| | | width: 96px; |
| | | height: 32px; |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <!-- <el-col :span="6">--> |
| | | <!-- <el-form-item label="安全返航真高" prop="rth_altitude">--> |
| | | <!-- <el-input-number--> |
| | | <!-- v-model="form.rth_altitude"--> |
| | | <!-- :min="30"--> |
| | | <!-- :max="300"--> |
| | | <!-- ></el-input-number>--> |
| | | <!-- </el-form-item>--> |
| | | <!-- </el-col>--> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="danger" @click="submitForm(1)">发起</el-button> |
| | | <el-button type="primary" @click="submitForm(0)">存草稿</el-button> |
| | | <el-button @click="dialogVisible = false" :icon="CircleClose">取消</el-button> |
| | | <el-button type="danger" @click="submitForm(1)" icon="el-icon-position">发起</el-button> |
| | | <el-button type="primary" @click="submitForm(0)" icon="el-icon-document-add">存草稿</el-button> |
| | | <el-button @click="dialogVisible = false" icon="el-icon-circle-close">取消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | type="danger" |
| | | v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" |
| | | @click="submitForm(1)" |
| | | icon="el-icon-position" |
| | | >发布</el-button |
| | | > |
| | | <el-button |
| | | type="primary" |
| | | v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" |
| | | @click="submitForm(0)" |
| | | icon="el-icon-plus" |
| | | >保存</el-button |
| | | > |
| | | <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user" |
| | |
| | | type="danger" |
| | | v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" |
| | | @click="submitForm(1)" |
| | | icon="el-icon-position" |
| | | >发布</el-button |
| | | > |
| | | <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user" |
| | |
| | | type="primary" |
| | | v-if="form.status == 1 && hasPaddingBtnPermission()" |
| | | @click="orderLogPass(form.id)" |
| | | icon="el-icon-check" |
| | | >通过</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | v-if="form.status == 1 && hasRejectionBtnPermission()" |
| | | @click="orderLogReject(form.id)" |
| | | icon="el-icon-close" |
| | | >驳回</el-button |
| | | > |
| | | <el-button @click="detailVisibleCopy = false">取消</el-button> |
| | | <el-button @click="detailVisibleCopy = false" icon="el-icon-circle-close">取消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | } from '@/api/tickets/orderLog'; |
| | | import { getTicketInfo } from '@/api/tickets/ticket'; |
| | | import { getDictionaryByCode } from '@/api/system/dictbiz'; |
| | | import { getWaylineFileListByArea } from '@/api/resource/wayline'; |
| | | import { getWaylineFileListByArea, newGetWorkspacesPage } from '@/api/resource/wayline'; |
| | | import { export_json_to_excel } from '@/utils/exportExcel'; |
| | | import { getFlyingNestBy } from '@/api/device/device'; |
| | | import { mapGetters } from 'vuex'; |
| | |
| | | import 'dayjs/locale/zh-cn'; // 导入中文语言包 |
| | | import weekday from 'dayjs/plugin/weekday'; |
| | | import elTooltipCopy from '@/components/ElTooltipCopy.vue'; |
| | | import { CircleClose } from '@element-plus/icons-vue'; |
| | | import { CircleClose, Promotion, Select } from '@element-plus/icons-vue'; |
| | | |
| | | dayjs.extend(weekday); |
| | | dayjs.locale('zh-cn'); |
| | |
| | | }, |
| | | //获取航线列表 |
| | | async asyncgetWaylineFileListByArea(name) { |
| | | var wayLineListResponse = await getWaylineFileListByArea(this.userInfo.detail.areaCode); |
| | | this.wayLineList = wayLineListResponse.data.data; |
| | | const formData = { |
| | | name: '', |
| | | waylineType: undefined, |
| | | current: 1, |
| | | size: 99999999, |
| | | descs: 'update_time', |
| | | } |
| | | var wayLineListResponse = await newGetWorkspacesPage(formData); |
| | | this.wayLineList = wayLineListResponse.data.data.records |
| | | |
| | | this.initMapLine(); |
| | | }, |
| | |
| | | |
| | | //按照航线来 |
| | | const params = { |
| | | type: [2, 4, 5].includes(currentLine.wayline_type) ? 2 : 0, |
| | | type: ['2', '4', '5'].includes(currentLine.wayline_type) ? 2 : 0, |
| | | wayline_id: waylineId, |
| | | polygon, |
| | | }; |
| | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | :deep(.el-input-number) { |
| | | width: 200px; |
| | | } |
| | | :deep(.el-form-item__label) { |
| | | width: 100px !important; |
| | | } |
| | | ::v-deep(.el-tabs) { |
| | | height: 100%; |
| | | display: flex; |
| | |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer-new"> |
| | | <el-button type="danger" :loading="submitLoading" @click="submitForm">发布</el-button> |
| | | <el-button type="infoprimary" plain :loading="draftLoading" @click="saveDraft" |
| | | <el-button type="danger" :loading="submitLoading" @click="submitForm" icon="el-icon-position">发布</el-button> |
| | | <el-button type="infoprimary" plain :loading="draftLoading" @click="saveDraft" icon="el-icon-document-add" |
| | | >存草稿</el-button |
| | | > |
| | | |
| | | <el-button @click="handleCancel" :icon="CircleClose">取 消</el-button> |
| | | <el-button @click="handleCancel" icon="el-icon-circle-close">取 消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | :src="getThumbUrl(currentDetail.mediaUrl)" |
| | | :preview-src-list="[getPreviewUrl(currentDetail.mediaUrl)]" |
| | | fit="contain" |
| | | style="width: 700px; height: 520px; cursor: pointer" |
| | | style="pxToRemNum(width: 700px); pxToRemNum(height: 520px); cursor: pointer" |
| | | > |
| | | <template #placeholder> |
| | | <div class="image-placeholder"> |
| | |
| | | type="primary" |
| | | :loading="approveLoading" |
| | | @click="approveTicket" |
| | | icon="el-icon-check" |
| | | >通过</el-button |
| | | > |
| | | <el-button |
| | |
| | | type="danger" |
| | | :loading="rejectLoading" |
| | | @click="rejectTicket" |
| | | icon="el-icon-close" |
| | | >不通过</el-button |
| | | > |
| | | <el-button @click="detailVisible = false":icon="CircleClose">取消</el-button> |
| | | <el-button @click="detailVisible = false" icon="el-icon-circle-close">取消</el-button> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 0"> |
| | | <el-button |
| | |
| | | type="primary" |
| | | :loading="dispatchLoading" |
| | | @click="approveAndDispatch" |
| | | icon="el-icon-check" |
| | | >受理</el-button |
| | | > |
| | | <el-button |
| | |
| | | type="danger" |
| | | :loading="rejectLoading" |
| | | @click="rejectTicket" |
| | | icon="el-icon-close" |
| | | >不受理</el-button |
| | | > |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | <el-button @click="detailVisible = false" icon="el-icon-circle-close">取消</el-button> |
| | | </template> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <!-- 处理中 --> |
| | |
| | | type="primary" |
| | | :loading="completeLoading" |
| | | @click="completeTicket" |
| | | icon="el-icon-circle-check" |
| | | >完成工单</el-button |
| | | > |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | <el-button @click="detailVisible = false" icon="el-icon-circle-close">取消</el-button> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 4"> |
| | | <!-- 已完成 --> |
| | | <!-- <el-button v-if="hasProcessedAndOverBtnPermission()" type="primary" :loading="finalizeLoading" |
| | | @click="finalizeTicket">完结工单</el-button> --> |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | <el-button @click="detailVisible = false" icon="el-icon-circle-close">取消</el-button> |
| | | </template> |
| | | </div> |
| | | <div |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dispatchDialogVisible = false">取消</el-button> |
| | | <el-button @click="dispatchDialogVisible = false" icon="el-icon-circle-close">取消</el-button> |
| | | <el-button type="primary" :loading="dispatchLoading" @click="submitDispatch" |
| | | >确认派发</el-button |
| | | > |
| | |
| | | |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleBatchApprove">通过</el-button> |
| | | <el-button type="danger" @click="handleBatchReject">不通过</el-button> |
| | | <el-button @click="cancleBatchReject">取消</el-button> |
| | | <el-button type="primary" @click="handleBatchApprove" icon="el-icon-check">通过</el-button> |
| | | <el-button type="danger" @click="handleBatchReject" icon="el-icon-close">不通过</el-button> |
| | | <el-button @click="cancleBatchReject" icon="el-icon-circle-close">取消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { pxToRem, pxToRemNum } from '@/utils/rem' |
| | | import { getSmallImg, getShowImg } from '@/utils/util'; |
| | | import { ElMessageBox, ElLoading } from 'element-plus'; |
| | | import { calculateDefaultRange } from '@/utils/util'; |
| | |
| | | opacity: 0.3 !important; |
| | | } |
| | | .PopUpTableScrolls { |
| | | height: 600px; |
| | | max-height: 600px; |
| | | overflow-y: scroll; |
| | | overflow-x: hidden; |
| | | } |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="todo-items" v-if="todos.length > 0" v-loading="loading" element-loading-background="rgba(255, 255, 255, 0.5)"> |
| | | <div class="todo-items" v-if="todos.length > 0" v-loading="loading" element-loading-background="rgba(255, 255, 255, 0.8)"> |
| | | <div v-for="(item, index) in todos" :key="index" class="todo-item" :style="getStatusStyle(item.status)" |
| | | @click="jumporder(item)"> |
| | | <div class="status-indicator"><img :src="getStatus(item.status)" alt=""></div> |
| | |
| | | ]) |
| | | |
| | | const titleClick = async (item, index) => { |
| | | todos.value =[] |
| | | checked.value = item.name |
| | | await getListMatter() |
| | | } |