| | |
| | | const debug = false; |
| | | |
| | | let ip1 = 'http://114.215.109.124:8805/'; |
| | | // let ip1 = 'http://47.100.191.150:9029/'; |
| | | |
| | | if (debug) { |
| | | ip1 = 'http://192.168.0.138:8082/'; |
| | |
| | | let params = `page=${page}&perPage=${pageSize}`; |
| | | params += type ? `&type=${type}` : ''; |
| | | return $http.get(`air/mission/type?${params}`).then((res) => res.data); |
| | | }, |
| | | |
| | | putNewMission(mission) { |
| | | return $http.post(`air/mission/create`, mission).then((res) => res.data); |
| | | }, |
| | | |
| | | deleteMission(missionCode) { |
| | | let params = `missionCode=${missionCode}`; |
| | | return $http.post(`air/mission/delete?${params}`).then((res) => res.data); |
| | | } |
| | | }; |
| | |
| | | BaseCard: typeof import('./components/BaseCard.vue')['default'] |
| | | BaseMap: typeof import('./components/map/BaseMap.vue')['default'] |
| | | CardButton: typeof import('./components/CardButton.vue')['default'] |
| | | CardDialog: typeof import('./components/CardDialog.vue')['default'] |
| | | CoreHeader: typeof import('./components/core/CoreHeader.vue')['default'] |
| | | CoreMenu: typeof import('./components/core/CoreMenu.vue')['default'] |
| | | DataSummary: typeof import('./components/monitor/DataSummary.vue')['default'] |
| | |
| | | ElCol: typeof import('element-plus/es')['ElCol'] |
| | | ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] |
| | | ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] |
| | | ElDialog: typeof import('element-plus/es')['ElDialog'] |
| | | ElDropdown: typeof import('element-plus/es')['ElDropdown'] |
| | | ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] |
| | | ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'] |
| | |
| | | HistoricalTrajectory: typeof import('./components/animation/HistoricalTrajectory.vue')['default'] |
| | | LineChart: typeof import('./components/monitor/LineChart.vue')['default'] |
| | | MapToolbox: typeof import('./components/map/MapToolbox.vue')['default'] |
| | | MIssionCreate: typeof import('./components/mission/MIssionCreate.vue')['default'] |
| | | MissionImport: typeof import('./components/mission/MissionImport.vue')['default'] |
| | | MissionManage: typeof import('./components/mission/MissionManage.vue')['default'] |
| | | OptionDevice: typeof import('./components/search/OptionDevice.vue')['default'] |
| | | OptionMission: typeof import('./components/search/OptionMission.vue')['default'] |
| | | OptionTime: typeof import('./components/search/OptionTime.vue')['default'] |
| | |
| | | RouterView: typeof import('vue-router')['RouterView'] |
| | | SearchBar: typeof import('./components/search/SearchBar.vue')['default'] |
| | | SliderBar: typeof import('./components/SliderBar.vue')['default'] |
| | | TrajectoryState: typeof import('./components/animation/TrajectoryState.vue')['default'] |
| | | } |
| | | export interface ComponentCustomProperties { |
| | | vLoading: typeof import('element-plus/es')['ElLoadingDirective'] |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog |
| | | :model-value="modelValue" |
| | | @update-modelvalue="handleChange" |
| | | :show-close="false" |
| | | align-center |
| | | > |
| | | <template #header="{ close, titleId, titleClass }"> |
| | | <BaseCard direction="top-left" borderless="t"> |
| | | <template #content> |
| | | <el-row justify="space-between" align="middle"> |
| | | <el-row align="middle"> |
| | | <font-awesome-icon icon="fa fa-list" class="m-r-4" /> |
| | | <span :id="titleId" :class="titleClass">{{ title }}</span> |
| | | </el-row> |
| | | <font-awesome-icon |
| | | icon="fa fa-times" |
| | | class="cursor-p m-r-4" |
| | | @click="close" |
| | | /> |
| | | </el-row> |
| | | </template> |
| | | </BaseCard> |
| | | </template> |
| | | <BaseCard size="medium"> |
| | | <template #content> |
| | | <slot></slot> |
| | | </template> |
| | | </BaseCard> |
| | | </el-dialog> |
| | | </template> |
| | | <script> |
| | | export default { |
| | | props: { |
| | | title: String, |
| | | modelValue: Boolean |
| | | }, |
| | | emits: ['update:modelValue'], |
| | | methods: { |
| | | handleChange(value) { |
| | | this.$emit('update:modelValue', value); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | |
| | | </div> |
| | | <div class="label-date margin-left-2"> |
| | | <span class="label-date-title">åé</span> |
| | | <el-select v-model="speed" size="small" class="w-80"> |
| | | <el-select v-model="speed" size="small" class="w-60"> |
| | | <el-option label="1.0X" :value="1" /> |
| | | <el-option label="4.0X" :value="4" /> |
| | | <el-option label="8.0X" :value="8" /> |
| | |
| | | </BaseCard> |
| | | </template> |
| | | <script> |
| | | import { mapActions } from 'pinia'; |
| | | import { MapAnimation } from '@/utils/map/animation'; |
| | | import { FactorDatas } from '@/model/FactorDatas'; |
| | | import { useMapAnimationStore } from '@/stores/map-animation'; |
| | | |
| | | const mapAnimation = new MapAnimation(); |
| | | |
| | | export default { |
| | | props: {}, |
| | | emits: ['change'], |
| | | props: { |
| | | factorDatas: FactorDatas, |
| | | factorType: String |
| | | }, |
| | | emits: ['change', 'stop'], |
| | | data() { |
| | | return { |
| | | speed: 1, |
| | | // å¨ç»ç¶æï¼0ï¼åæ¢ï¼1ï¼ææ¾ï¼2ï¼æå |
| | | status: 0 |
| | | }; |
| | | }, |
| | | watch: { |
| | | speed(nV, oV) { |
| | | if (nV != oV) { |
| | | this.changeSpeed(nV); |
| | | } |
| | | }, |
| | | factorType(nV, oV) { |
| | | if (nV != oV) { |
| | | mapAnimation.setFactorType(nV); |
| | | } |
| | | } |
| | | }, |
| | | computed: { |
| | | btnStop() { |
| | |
| | | } |
| | | }, |
| | | methods: { |
| | | ...mapActions(useMapAnimationStore, ['start', 'pause', 'stop']), |
| | | handleStop() { |
| | | if (this.status != 0) { |
| | | this.status = 0; |
| | | this.stopAnimation(); |
| | | this.handleChange(); |
| | | } |
| | | }, |
| | | handlePlayOrPause() { |
| | | if (this.status == 1) { |
| | | this.status = 2; |
| | | this.pauseAnimation(); |
| | | } else { |
| | | this.status = 1; |
| | | this.startAnimation(); |
| | | } |
| | | this.handleChange(); |
| | | }, |
| | | handleChange() { |
| | | console.log(this.status); |
| | | this.$emit('change', this.status); |
| | | }, |
| | | |
| | | newTimeTask() { |
| | | mapAnimation.setDynamicSpeed(false); //å
³é卿ç»å¶éåº¦è°æ´ |
| | | mapAnimation.moveAnimation(this.factorDatas, this.factorType); |
| | | }, |
| | | startAnimation() { |
| | | this.changeSpeed(this.speed); |
| | | if (!mapAnimation.runStatus()) { |
| | | this.newTimeTask(); |
| | | } else { |
| | | mapAnimation.start(); |
| | | } |
| | | this.start(); |
| | | }, |
| | | changeSpeed(speed) { |
| | | mapAnimation.changeSpeed(speed); |
| | | }, |
| | | pauseAnimation() { |
| | | mapAnimation.pause(); |
| | | this.pause(); |
| | | }, |
| | | stopAnimation() { |
| | | mapAnimation.stop(); |
| | | this.stop(); |
| | | } |
| | | }, |
| | | mounted() {} |
| | | mounted() { |
| | | mapAnimation.setOnStopCallback(() => { |
| | | this.$emit('stop'); |
| | | }); |
| | | } |
| | | }; |
| | | </script> |
| | | <style scoped> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <BaseCard size="middle-s" direction="down"> |
| | | <template #content> |
| | | <span style="margin: 36px; font-size: large">{{ stateText }}</span> |
| | | </template> |
| | | </BaseCard> |
| | | </template> |
| | | <script> |
| | | export default { |
| | | props: { |
| | | status: { |
| | | type: Number, |
| | | default: 0 |
| | | } |
| | | }, |
| | | computed: { |
| | | stateText() { |
| | | switch (this.status) { |
| | | case 0: |
| | | return '轨迹å¨ç»å·²åæ¢'; |
| | | case 1: |
| | | return '轨迹å¨ç»ææ¾ä¸...'; |
| | | case 2: |
| | | return '轨迹å¨ç»å·²æå'; |
| | | default: |
| | | return '轨迹å¨ç»å·²åæ¢'; |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | |
| | | <template> |
| | | <div class="map-title ff-title flexbox-col align-items p-events-auto"> |
| | | <div class="map-title-content"> |
| | | <div class="map-title ff-title flexbox-col align-items"> |
| | | <div class="map-title-content p-events-auto"> |
| | | <div class="ff-border-bottom"></div> |
| | | <div class="ff-border-top"> |
| | | <div class="ff-border-content flexbox-col align-items"> |
| | |
| | | methods: {} |
| | | }; |
| | | </script> |
| | | <style scoped></style> |
| | | <style scoped> |
| | | .map-title { |
| | | /* background-color: aliceblue; */ |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="map-mode-change p-events-auto"> |
| | | <div v-show="status == 0" class="map-mode-change p-events-auto"> |
| | | <template v-for="(item, index) in menu" :key="item.path"> |
| | | <a :class="btnClz(item.selected)" @click="navTo(index)"> |
| | | <div>{{ item.name }}</div> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapState } from 'pinia'; |
| | | import { useMapAnimationStore } from '@/stores/map-animation'; |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | |
| | | ] |
| | | }; |
| | | }, |
| | | computed: {}, |
| | | computed: { |
| | | ...mapState(useMapAnimationStore, ['status']) |
| | | }, |
| | | methods: { |
| | | btnClz(selected) { |
| | | return ( |
| | |
| | | display: none; |
| | | opacity: 0 !important; |
| | | } |
| | | |
| | | .amap-marker-label { |
| | | font-size: 13px; |
| | | text-align: center; |
| | | color: white; |
| | | background-color: transparent; |
| | | text-shadow: black 2px 2px 2px; |
| | | border-radius: 2px; |
| | | border: 0px; |
| | | padding: 4px; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <el-dropdown |
| | | class="p-events-auto dropdown-wrap" |
| | | class="p-events-auto" |
| | | trigger="click" |
| | | size="small" |
| | | @command="handleCommand" |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .dropdown-wrap { |
| | | position: absolute; |
| | | top: 10px; |
| | | left: 2px; |
| | | } |
| | | |
| | | .el-button { |
| | | margin: initial !important; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-button |
| | | type="primary" |
| | | class="el-button-custom" |
| | | @click="dialogVisible = !dialogVisible" |
| | | > |
| | | æ°å»ºä»»å¡ |
| | | </el-button> |
| | | <CardDialog v-model="dialogVisible" title="æ°å»ºèµ°èªä»»å¡"> |
| | | <el-form |
| | | :inline="false" |
| | | :model="formObj" |
| | | ref="formRef" |
| | | :rules="rules" |
| | | label-position="right" |
| | | label-width="150px" |
| | | > |
| | | <slot name="form-item" :formObj="formObj"></slot> |
| | | <el-form-item> |
| | | <el-button |
| | | :disabled="!edit" |
| | | type="primary" |
| | | @click="onSubmit" |
| | | :loading="loading" |
| | | >æäº¤</el-button |
| | | > |
| | | <el-button v-if="useCancel" @click="onCancel">åæ¶</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </CardDialog> |
| | | </template> |
| | | <script setup> |
| | | import { onActivated, onDeactivated, ref, reactive, watch } from 'vue'; |
| | | import missionApi from '@/api/missionApi'; |
| | | import { useFormConfirm } from '@/composables/formConfirm'; |
| | | import { useFetchData } from '@/composables/fetchData'; |
| | | |
| | | const dialogVisible = ref(false); |
| | | const { loading, fetchData } = useFetchData(); |
| | | const baseRules = reactive({ |
| | | _usertype: [ |
| | | { |
| | | required: true, |
| | | message: 'ç¨æ·ç±»åä¸è½ä¸ºç©º', |
| | | trigger: 'change' |
| | | } |
| | | ], |
| | | _locations: [ |
| | | { |
| | | required: true, |
| | | message: 'è¡æ¿åºåä¸è½ä¸ºç©º', |
| | | trigger: 'change' |
| | | } |
| | | ], |
| | | _scenetype: [ |
| | | { |
| | | required: true, |
| | | message: 'åºæ¯ç±»åä¸è½ä¸ºç©º', |
| | | trigger: 'change' |
| | | } |
| | | ] |
| | | }); |
| | | // åå»ºä»»å¡ |
| | | function createMission() {} |
| | | const { formObj, formRef, edit, onSubmit, onCancel, onReset, clear } = |
| | | useFormConfirm({ |
| | | submit: { |
| | | do: createMission |
| | | }, |
| | | cancel: { |
| | | do: () => (dialogVisible.value = false) |
| | | } |
| | | }); |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-button |
| | | type="primary" |
| | | icon="Memo" |
| | | class="el-button-custom p-events-auto" |
| | | @click="dialogVisible = !dialogVisible" |
| | | > |
| | | ä»»å¡ç®¡ç |
| | | </el-button> |
| | | <el-dialog v-model="dialogVisible" :show-close="false" align-center> |
| | | <template #header="{ close, titleId, titleClass }"> |
| | | <BaseCard direction="top-left" borderless="t"> |
| | | <template #content> |
| | | <el-row justify="space-between" align="middle"> |
| | | <el-row align="middle"> |
| | | <font-awesome-icon icon="fa fa-list" class="m-r-4" /> |
| | | <span :id="titleId" :class="titleClass">èµ°èªä»»å¡ç®¡ç</span> |
| | | </el-row> |
| | | <font-awesome-icon |
| | | icon="fa fa-times" |
| | | class="cursor-p m-r-4" |
| | | @click="close" |
| | | /> |
| | | </el-row> |
| | | </template> |
| | | </BaseCard> |
| | | </template> |
| | | <BaseCard size="medium"> |
| | | <template #content> |
| | | <el-row class="mission-table"> |
| | | <el-col :span="20"> |
| | | <el-table |
| | | :data="missionList" |
| | | table-layout="fixed" |
| | | size="small" |
| | | :show-overflow-tooltip="true" |
| | | border |
| | | row-class-name="t-row" |
| | | cell-class-name="t-cell" |
| | | header-row-class-name="t-header-row" |
| | | header-cell-class-name="t-header-cell" |
| | | > |
| | | <el-table-column |
| | | type="index" |
| | | label="åºå·" |
| | | align="center" |
| | | width="50" |
| | | /> |
| | | <el-table-column |
| | | prop="missionCode" |
| | | label="ä»»å¡ç¼å·" |
| | | align="center" |
| | | /> |
| | | <el-table-column |
| | | prop="startTime" |
| | | label="å¼å§æ¶é´" |
| | | align="center" |
| | | :formatter="timeFormatter" |
| | | /> |
| | | <el-table-column |
| | | prop="endTime" |
| | | label="ç»ææ¶é´" |
| | | align="center" |
| | | :formatter="timeFormatter" |
| | | /> |
| | | <el-table-column label="管ç" width="70" align="center"> |
| | | <template #default="{ row }"> |
| | | <el-button |
| | | type="primary" |
| | | size="small" |
| | | class="el-button-custom" |
| | | @click="deleteMission(row)" |
| | | >å é¤</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-col> |
| | | <el-col :span="4" class="flex-col"> |
| | | <div> |
| | | <el-button type="primary" class="el-button-custom"> |
| | | æ°å»ºä»»å¡ |
| | | </el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" class="el-button-custom"> |
| | | æ°æ®å¯¼å
¥ |
| | | </el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" class="el-button-custom"> |
| | | ä¸è½½æ¨¡æ¿ |
| | | </el-button> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </BaseCard> |
| | | </el-dialog> |
| | | </template> |
| | | <script> |
| | | import moment from 'moment'; |
| | | import { mapState } from 'pinia'; |
| | | import { useMissionStore } from '@/stores/mission'; |
| | | |
| | | export default { |
| | | props: {}, |
| | | data() { |
| | | return { |
| | | dialogVisible: false |
| | | }; |
| | | }, |
| | | computed: { |
| | | ...mapState(useMissionStore, ['missionList']) |
| | | }, |
| | | methods: { |
| | | createMission() {}, |
| | | deleteMission(row) {}, |
| | | timeFormatter(row, col, cellValue, index) { |
| | | return moment(cellValue).format('YYYY-MM-DD HH:mm:ss'); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | <style> |
| | | .el-dialog { |
| | | --el-dialog-bg-color: transparent !important; |
| | | --el-dialog-title-font-size: var(--el-font-size-medium); |
| | | --el-dialog-content-font-size: 14px; |
| | | --el-dialog-padding-primary: 0px !important; |
| | | } |
| | | |
| | | .el-dialog__title { |
| | | color: var(--font-color); |
| | | } |
| | | </style> |
| | | <style scoped> |
| | | .flex-col { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 4px; |
| | | align-items: flex-end; |
| | | } |
| | | |
| | | .mission-table { |
| | | height: 60vh; |
| | | } |
| | | </style> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapStores } from 'pinia'; |
| | | import missionApi from '@/api/missionApi'; |
| | | import { useFetchData } from '@/composables/fetchData'; |
| | | import { useMissionStore } from '@/stores/mission'; |
| | | |
| | | export default { |
| | | setup() { |
| | |
| | | index: undefined |
| | | }; |
| | | }, |
| | | computed: { |
| | | ...mapStores(useMissionStore) |
| | | }, |
| | | methods: { |
| | | fetchMission() { |
| | | this.fetchData((page, pageSize) => { |
| | |
| | | .fethchMission({ type: this.type, page, pageSize }) |
| | | .then((res) => { |
| | | this.missionList = res.data; |
| | | this.missionStore.missionList = res.data; |
| | | // if (this.missionList.length > 0) { |
| | | // this.handleChange(0); |
| | | // } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { onActivated, onDeactivated, ref, watch } from 'vue'; |
| | | import { useCloned } from '@vueuse/core'; |
| | | // import { useMessageBoxTip, useMessageBox } from './messageBox'; |
| | | |
| | | // 表åç确认ååæ¶ |
| | | export function useFormConfirm({ |
| | | defaultForm = undefined, |
| | | submit = { |
| | | do: () => {} |
| | | }, |
| | | cancel = { |
| | | do: () => {} |
| | | }, |
| | | reset = { |
| | | do: () => {} |
| | | } |
| | | }) { |
| | | if (!submit.title) submit.title = 'æäº¤'; |
| | | if (!submit.msg) submit.msg = '确认æ¯å¦æäº¤ï¼'; |
| | | if (!cancel.title) cancel.title = 'åæ¶'; |
| | | if (!cancel.msg) cancel.msg = 'æ¯å¦æ¾å¼å·²ç¼è¾çå
容ï¼'; |
| | | |
| | | // const formProps = defineProps({ |
| | | // // æ¯å¦å¨æäº¤æå忏
空表å |
| | | // clearAftSubmit: Boolean |
| | | // }); |
| | | |
| | | //表åå
容 |
| | | const formObj = ref(defaultForm ? defaultForm : {}); |
| | | let formObjClone = useCloned(formObj, { manual: true }); |
| | | //表åç»ä»¶å¼ç¨ |
| | | const formRef = ref(null); |
| | | |
| | | // 表åç¼è¾ç¶æ |
| | | const edit = ref(false); |
| | | let isReset = false; |
| | | const active = ref(true); |
| | | |
| | | // è¥ç»ä»¶å®ä¾æ¯ <KeepAlive> ç¼åæ çä¸é¨åï¼å½ç»ä»¶è¢«æå
¥å° DOM 䏿¶è°ç¨ |
| | | onActivated(() => { |
| | | active.value = true; |
| | | }); |
| | | // è¥ç»ä»¶å®ä¾æ¯ <KeepAlive> ç¼åæ çä¸é¨åï¼å½ç»ä»¶ä» DOM ä¸è¢«ç§»é¤æ¶è°ç¨ |
| | | onDeactivated(() => { |
| | | active.value = false; |
| | | }); |
| | | |
| | | // å½è¡¨åè¢«åæ¶æ¿æ´»åï¼æ¸
ç©ºè¡¨åæ°æ® |
| | | watch(active, (nValue) => { |
| | | if (!nValue) { |
| | | clear(); |
| | | } |
| | | }); |
| | | |
| | | // 表å被修æ¹è¿, æ´æ°ç¼è¾ç¶æ |
| | | watch( |
| | | formObj, |
| | | (nv, ov) => { |
| | | if (!isReset && nv != ov) { |
| | | formObjClone = useCloned(nv, { manual: true }); |
| | | } |
| | | if (!isReset && nv === ov) { |
| | | edit.value = true; |
| | | } |
| | | isReset = false; |
| | | }, |
| | | { deep: true } |
| | | ); |
| | | |
| | | // é置表å |
| | | const _reset = function () { |
| | | formRef.value.clearValidate(); |
| | | edit.value = false; |
| | | isReset = true; |
| | | formObj.value = useCloned(formObjClone.cloned, { |
| | | manual: true |
| | | }).cloned.value; |
| | | }; |
| | | |
| | | // æ¸
空表å |
| | | const clear = function () { |
| | | isReset = true; |
| | | formRef.value.resetFields(); |
| | | edit.value = false; |
| | | }; |
| | | |
| | | // æäº¤æåå |
| | | const submited = function () { |
| | | // if (formProps.clearAftSubmit) clear(); |
| | | edit.value = false; |
| | | formObjClone = useCloned(formObj, { manual: true }); |
| | | }; |
| | | |
| | | // æäº¤è¡¨å |
| | | const onSubmit = function (messageBox = true) { |
| | | formRef.value.validate(async (valid) => { |
| | | if (valid) { |
| | | if (messageBox) { |
| | | // useMessageBoxTip({ |
| | | // confirmMsg: submit.msg, |
| | | // confirmTitle: submit.title, |
| | | // onConfirm: async () => { |
| | | // const res = await submit.do(); |
| | | // submited(); |
| | | // return res; |
| | | // } |
| | | // }); |
| | | } else { |
| | | await submit.do(); |
| | | submited(); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // åæ¶æäº¤ |
| | | const onCancel = function () { |
| | | if (edit.value) { |
| | | // å¼¹åºç¡®è®¤æ¡ |
| | | // useMessageBox({ |
| | | // confirmMsg: cancel.msg, |
| | | // confirmTitle: cancel.title, |
| | | // onConfirm: () => { |
| | | // // clear(); |
| | | // return cancel.do(); |
| | | // } |
| | | // }); |
| | | } else { |
| | | cancel.do(); |
| | | } |
| | | }; |
| | | |
| | | // é置表å |
| | | const onReset = function (tips) { |
| | | if (edit.value) { |
| | | if (tips) { |
| | | // å¼¹åºç¡®è®¤æ¡ |
| | | // useMessageBox({ |
| | | // confirmMsg: 'æ¯å¦é置表åå
容ï¼', |
| | | // confirmTitle: 'é置表å', |
| | | // onConfirm: () => { |
| | | // _reset(); |
| | | // return reset.do(); |
| | | // } |
| | | // }); |
| | | } else { |
| | | _reset(); |
| | | reset.do(); |
| | | } |
| | | } else { |
| | | reset.do(); |
| | | } |
| | | }; |
| | | |
| | | return { formObj, formRef, edit, onSubmit, onCancel, onReset, clear }; |
| | | } |
| | |
| | | import App from './App.vue'; |
| | | import router from './router'; |
| | | |
| | | import './utils/expand/expand'; |
| | | |
| | | /* import the fontawesome core */ |
| | | import { library } from '@fortawesome/fontawesome-svg-core'; |
| | | /* import font awesome icon component */ |
| | | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'; |
| | | /* import specific icons */ |
| | | // import { all } from '@awesome.me/kit-KIT_CODE/icons'; |
| | | import { fas } from '@fortawesome/free-solid-svg-icons'; |
| | | // import { faTwitter, faFontAwesome } from '@fortawesome/free-brands-svg-icons' |
| | | // import { faTwitter, faFontAwesome } from '@fortawesome/free-regular-svg-icons' |
| | | |
| | | /* add icons to the library */ |
| | | library.add(fas); |
| | |
| | | if (this.isPause) { |
| | | return; |
| | | } |
| | | if (index >= t.count) { |
| | | // ç»å¶3Då¾å½¢æ¶ï¼æå°éè¦2ä¸ªç¹æå¯ç»å¶å¾å½¢ |
| | | // å æ¤æ¤å¤ç´¢å¼åªå°åæ°ç¬¬äºä¸ªç¹å°±ç»æ |
| | | if (index >= t.count - 1) { |
| | | this._endTask(this.intervalFlag); |
| | | return; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { ref } from 'vue'; |
| | | import { defineStore } from 'pinia'; |
| | | |
| | | export const useMapAnimationStore = defineStore('mapAnimation', () => { |
| | | // // å¨ç»ç¶æï¼0ï¼åæ¢ï¼1ï¼ææ¾ï¼2ï¼æå |
| | | const status = ref(0); |
| | | |
| | | function start() { |
| | | status.value = 1; |
| | | } |
| | | function pause() { |
| | | status.value = 2; |
| | | } |
| | | function stop() { |
| | | status.value = 0; |
| | | } |
| | | |
| | | return { status, start, pause, stop }; |
| | | }); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { ref } from 'vue'; |
| | | import { defineStore } from 'pinia'; |
| | | |
| | | // èµ°èªä»»å¡ |
| | | export const useMissionStore = defineStore('mission', () => { |
| | | const missionList = ref([]); |
| | | |
| | | return { missionList }; |
| | | }); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | Date.prototype.format = function (fmt) { |
| | | var o = { |
| | | 'M+': this.getMonth() + 1, //æä»½ |
| | | 'd+': this.getDate(), //æ¥ |
| | | 'h+': this.getHours(), //å°æ¶ |
| | | 'm+': this.getMinutes(), //å |
| | | 's+': this.getSeconds(), //ç§ |
| | | 'q+': Math.floor((this.getMonth() + 3) / 3), //å£åº¦ |
| | | S: this.getMilliseconds() //æ¯«ç§ |
| | | }; |
| | | if (/(y+)/.test(fmt)) { |
| | | fmt = fmt.replace( |
| | | RegExp.$1, |
| | | (this.getFullYear() + '').substr(4 - RegExp.$1.length) |
| | | ); |
| | | } |
| | | for (var k in o) { |
| | | if (new RegExp('(' + k + ')').test(fmt)) { |
| | | fmt = fmt.replace( |
| | | RegExp.$1, |
| | | RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length) |
| | | ); |
| | | } |
| | | } |
| | | return fmt; |
| | | }; |
| | |
| | | import Layer from '@/utils/map/3dLayer'; |
| | | import sector from '@/utils/map/sector'; |
| | | import { map } from '@/utils/map/index_old'; |
| | | import util from "@/utils/map/util"; |
| | | import util from '@/utils/map/util'; |
| | | import car_driving from '@/assets/mipmap/car_driving.png'; |
| | | import boat_driving from '@/assets/mipmap/boat_driving.png'; |
| | | |
| | |
| | | // éè¿ç»åæ ç¹æå¤§è·ç¦»(ç±³) |
| | | this.maxD = 500; |
| | | // å½åç»å¶ççæµå åç±»å |
| | | this.factorType = 0; |
| | | this.factorType; |
| | | this.factorDatas; |
| | | // è½½å
፱Ȍ |
| | | this.vehicleType = 0; // 0: 车è¾ï¼1ï¼æ 人æºï¼2ï¼æ äººè¹ |
| | |
| | | var fData2 = factorDatas.getByIndex(i + 1, i + 2); |
| | | |
| | | // 计ç®å¨ç»è½¨è¿¹ |
| | | for (let i = 0; i < count - 1; i++) { |
| | | for (let i = 0; i < count; i++) { |
| | | // path |
| | | var length = d * (i + 1); |
| | | if (isNaN(angle)) { |
| | |
| | | animationData, |
| | | function (data, index, count) { |
| | | var length = data.length(); |
| | | var start = length - count + 1; |
| | | var start = length - count; |
| | | // 1.è·åæ°æ® |
| | | var d = data.getByIndex(0, start + index + 1); |
| | | var f = d.factor[that.factorType + 1 + '']; |
| | | var f = d.factor[that.factorType]; |
| | | // 2.ç»å¶å¾å½¢ |
| | | if (length > count || index > 0) { |
| | | // 3då¾å½¢ |
| | | // var lnglat = d.lnglats_GD[d.lnglats_GD.length - 1]; |
| | | Layer.drawMesh(d, f); |
| | | // MapUtil.drawLine(lnglat) |
| | | |
| | | // é£åé£é |
| | | sector.drawSector(d, start + index); |
| | | // if (d.factor['17'] != undefined && d.factor['16'] != undefined) { |
| | | // var windDir = d.factor['17'].datas; |
| | | // windDir = windDir[windDir.length - 1].factorData; |
| | | // var windSpeed = d.factor['16'].datas; |
| | | // windSpeed = windSpeed[windSpeed.length - 1].factorData; |
| | | // MapUtil.drawSector4(lnglat, windDir, windSpeed); |
| | | // } |
| | | sector.drawSectorAna(d, start + index); |
| | | } |
| | | |
| | | var pos = d.lnglats_GD[d.lnglats_GD.length - 1]; |
| | |
| | | |
| | | var _defaultDeg = 30, |
| | | _sector = undefined, |
| | | _sectorViews = {}; |
| | | _sectorViews = new Map(), |
| | | // å¨ç»è½¨è¿¹ |
| | | _sectorViewsAna = new Map(); |
| | | |
| | | export default { |
| | | clearSector() { |
| | | var list = []; |
| | | for (const key in _sectorViews) { |
| | | list.push(_sectorViews[key]); |
| | | } |
| | | if (list.length > 0) { |
| | | map.remove(list); |
| | | _sectorViews = {}; |
| | | } |
| | | if (_sector) { |
| | | object3Dlayer.remove(_sector); |
| | | } |
| | | }, |
| | | drawSector(fDatas, i) { |
| | | const zoomStyleMapping = { |
| | | 14: 0, |
| | | 15: 0, |
| | | 16: 0, |
| | | 17: 0, |
| | | 18: 0, |
| | | 19: 0, |
| | | 20: 0 |
| | | }; |
| | | |
| | | function sectorParams(fDatas, i) { |
| | | const lnglat = fDatas.lnglats_GD[i]; |
| | | let windDir = fDatas.factor[17].datas[i].factorData; |
| | | let windSpeed = fDatas.factor[16].datas[i].factorData; |
| | | if (!windDir) windDir = 0; |
| | | if (!windSpeed) windSpeed = 0; |
| | | |
| | | if (windSpeed > 10) { |
| | | return; |
| | | } |
| | | if (_sector != undefined) { |
| | | this.clearSector(); |
| | | } |
| | | |
| | | // eslint-disable-next-line no-undef |
| | | var sector = new AMap.Object3D.Mesh(); |
| | | sector.transparent = true; |
| | | sector.backOrFront = 'both'; |
| | | |
| | | var unit = 5; |
| | | // if (windSpeed > 10) { |
| | | // return; |
| | | // } |
| | | |
| | | var sDeg = windDir - _defaultDeg; //æå½¢èµ·å§è§åº¦ï¼ä»¥ä¸æ¹ä½ä¸º0åº¦ï¼ |
| | | // sDeg = sDeg < 0 ? sDeg + 360 : sDeg |
| | |
| | | var lnglat2_4 = calculate.getLatLon(lnglat, distance2, eDeg); |
| | | var list2 = calculate.parse2LngLat([lnglat2_2, lnglat2_3, lnglat2_4]); |
| | | |
| | | distance = distance.toFixed(0); |
| | | distance2 = distance2.toFixed(0); |
| | | |
| | | return { sDeg, eDeg, lnglat, distance, distance2, list, list2 }; |
| | | } |
| | | |
| | | /** |
| | | * å¯ç¼©æ¾çæ è®° |
| | | * æ æ³ä¿®æ¹positionï¼å®ç½æªæ¾å°ç¸å
³apiï¼ |
| | | */ |
| | | function elasticMarker(position, content) { |
| | | // eslint-disable-next-line no-undef |
| | | return new AMap.ElasticMarker({ |
| | | zoom: [14, 20], |
| | | position: position, |
| | | styles: [ |
| | | { |
| | | icon: { |
| | | img: imgLocation, |
| | | size: [16, 16], //å¯è§åºåçå¤§å° |
| | | ancher: [8, 16], //éç¹ |
| | | fitZoom: 18, //æåéççº§å« |
| | | scaleFactor: 1, //å°å¾æ¾å¤§ä¸çº§çç¼©æ¾æ¯ä¾ç³»æ° |
| | | maxScale: 2, //æå¤§æ¾å¤§æ¯ä¾ |
| | | minScale: 1 //æå°æ¾å¤§æ¯ä¾ |
| | | }, |
| | | label: { |
| | | content: content, |
| | | offset: [-35, 0], |
| | | position: 'BM', |
| | | minZoom: 15 |
| | | } |
| | | } |
| | | ], |
| | | zoomStyleMapping: zoomStyleMapping |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * ææ¬æ è®° |
| | | * å¯ä¿®æ¹position |
| | | */ |
| | | function textMaker(position, text) { |
| | | // eslint-disable-next-line no-undef |
| | | return new AMap.Text({ |
| | | text: text, |
| | | position: position, |
| | | style: { |
| | | 'font-size': '13px', |
| | | 'text-align': 'center', |
| | | color: 'white', |
| | | 'background-color': 'transparent', |
| | | 'text-shadow': 'black 2px 2px 2px', |
| | | 'border-radius': '2px', |
| | | border: '0px', |
| | | padding: '4px' |
| | | } |
| | | }); |
| | | } |
| | | |
| | | function drawSectorMesh(sDeg, eDeg, lnglat, distance, distance2) { |
| | | // eslint-disable-next-line no-undef |
| | | var sector = new AMap.Object3D.Mesh(); |
| | | sector.transparent = true; |
| | | sector.backOrFront = 'both'; |
| | | |
| | | var unit = 5; |
| | | |
| | | var p0 = calculate.lngLatToGeodeticCoord([lnglat])[0]; |
| | | var geometry = sector.geometry; |
| | | |
| | | var count = distance / unit; |
| | | var unitDeg = (eDeg - sDeg) / count; |
| | | |
| | | for (let i = 0; i < count; i++) { |
| | | var angle1 = sDeg + unitDeg * i; |
| | | var angle2 = sDeg + unitDeg * (i + 1); |
| | |
| | | } |
| | | object3Dlayer.add(sector); |
| | | _sector = sector; |
| | | } |
| | | |
| | | distance = distance.toFixed(0); |
| | | distance2 = distance2.toFixed(0); |
| | | const zoomStyleMapping = { |
| | | 14: 0, |
| | | 15: 0, |
| | | 16: 0, |
| | | 17: 0, |
| | | 18: 0, |
| | | 19: 0, |
| | | 20: 0 |
| | | }; |
| | | function drawTextMaker(list, list2, distance, distance2) { |
| | | //10åéæå½¢ |
| | | // eslint-disable-next-line no-undef |
| | | var text15 = new AMap.ElasticMarker({ |
| | | zoom: [14, 20], |
| | | position: list[2], |
| | | styles: [ |
| | | { |
| | | icon: { |
| | | img: imgLocation, |
| | | size: [16, 16], //å¯è§åºåçå¤§å° |
| | | ancher: [8, 16], //éç¹ |
| | | fitZoom: 18, //æåéççº§å« |
| | | scaleFactor: 1, //å°å¾æ¾å¤§ä¸çº§çç¼©æ¾æ¯ä¾ç³»æ° |
| | | maxScale: 2, //æå¤§æ¾å¤§æ¯ä¾ |
| | | minScale: 1 //æå°æ¾å¤§æ¯ä¾ |
| | | }, |
| | | label: { |
| | | content: '<div>10åé</div>', |
| | | offset: [-35, 0], |
| | | position: 'BM', |
| | | minZoom: 15 |
| | | const a = _sectorViews.get('text10-t'); |
| | | if (a == undefined) { |
| | | const text10t = textMaker(list[2], '10åé'); |
| | | _sectorViews.set('text10-t', text10t); |
| | | const textM10t = textMaker(list[1], distance + 'm'); |
| | | _sectorViews.set('textM10-t', textM10t); |
| | | map.add([text10t, textM10t]); |
| | | } else { |
| | | _sectorViews.get('text10-t').setPosition(list[2]); |
| | | _sectorViews.get('textM10-t').setPosition(list[1]); |
| | | _sectorViews.get('textM10-t').setText(distance + 'm'); |
| | | } |
| | | //5åéæå½¢ |
| | | const b = _sectorViews.get('text5-t'); |
| | | if (b == undefined) { |
| | | const text5t = textMaker(list2[1], '5åé'); |
| | | _sectorViews.set('text5-t', text5t); |
| | | const textM5t = textMaker(list2[0], distance2 + 'm'); |
| | | _sectorViews.set('textM5-t', textM5t); |
| | | map.add([text5t, textM5t]); |
| | | } else { |
| | | _sectorViews.get('text5-t').setPosition(list2[1]); |
| | | _sectorViews.get('textM5-t').setPosition(list2[0]); |
| | | _sectorViews.get('textM5-t').setText(distance2 + 'm'); |
| | | } |
| | | } |
| | | ], |
| | | zoomStyleMapping: zoomStyleMapping |
| | | }); |
| | | _sectorViews['text10'] = text15; |
| | | // eslint-disable-next-line no-undef |
| | | var textM = new AMap.ElasticMarker({ |
| | | zoom: [14, 20], |
| | | position: list[1], |
| | | styles: [ |
| | | { |
| | | icon: { |
| | | img: imgLocation, |
| | | size: [16, 16], //å¯è§åºåçå¤§å° |
| | | ancher: [8, 16], //éç¹ |
| | | fitZoom: 18, //æåéççº§å« |
| | | scaleFactor: 1, //å°å¾æ¾å¤§ä¸çº§çç¼©æ¾æ¯ä¾ç³»æ° |
| | | maxScale: 2, //æå¤§æ¾å¤§æ¯ä¾ |
| | | minScale: 1 //æå°æ¾å¤§æ¯ä¾ |
| | | }, |
| | | label: { |
| | | content: `<div>${distance}m</div>`, |
| | | offset: [-35, 0], |
| | | position: 'BM', |
| | | minZoom: 15 |
| | | } |
| | | } |
| | | ], |
| | | zoomStyleMapping: zoomStyleMapping |
| | | }); |
| | | _sectorViews['textM'] = textM; |
| | | map.add(_sectorViews['text10']); |
| | | map.add(_sectorViews['textM']); |
| | | |
| | | function drawElasticMarker(list, list2, distance, distance2) { |
| | | //10åéæå½¢ |
| | | const text10 = elasticMarker(list[2], '<div>10åé</div>'); |
| | | _sectorViews.set('text10', text10); |
| | | const textM = elasticMarker(list[1], `<div>${distance}m</div>`); |
| | | _sectorViews.set('textM10', textM); |
| | | map.add([text10, textM]); |
| | | |
| | | //5åéæå½¢ |
| | | let pList = list2; |
| | | // eslint-disable-next-line no-undef |
| | | var text5 = new AMap.ElasticMarker({ |
| | | position: pList[1], |
| | | styles: [ |
| | | { |
| | | icon: { |
| | | img: imgLocation, |
| | | size: [16, 16], //å¯è§åºåçå¤§å° |
| | | ancher: [8, 16], //éç¹ |
| | | fitZoom: 18, //æåéççº§å« |
| | | scaleFactor: 1, //å°å¾æ¾å¤§ä¸çº§çç¼©æ¾æ¯ä¾ç³»æ° |
| | | maxScale: 2, //æå¤§æ¾å¤§æ¯ä¾ |
| | | minScale: 1 //æå°æ¾å¤§æ¯ä¾ |
| | | const text5 = elasticMarker(list2[1], '<div>5åé</div>'); |
| | | _sectorViews.set('text5', text5); |
| | | const textM5 = elasticMarker(list2[0], `<div>${distance2}m</div>`); |
| | | _sectorViews.set('textM5', textM5); |
| | | map.add([text5, textM5]); |
| | | } |
| | | |
| | | export default { |
| | | clearSector() { |
| | | var list = []; |
| | | for (const iterator of _sectorViews) { |
| | | list.push(iterator[1]); |
| | | } |
| | | for (const iterator of _sectorViewsAna) { |
| | | list.push(iterator[1]); |
| | | } |
| | | if (list.length > 0) { |
| | | map.remove(list); |
| | | _sectorViews.clear(); |
| | | } |
| | | this.clearSectorMesh(); |
| | | }, |
| | | label: { |
| | | content: `<div>5åé</div>`, |
| | | offset: [-35, 0], |
| | | position: 'BM', |
| | | minZoom: 15 |
| | | clearSectorMesh() { |
| | | if (_sector) { |
| | | object3Dlayer.remove(_sector); |
| | | } |
| | | } |
| | | ], |
| | | zoomStyleMapping: zoomStyleMapping |
| | | }); |
| | | _sectorViews['text5'] = text5; |
| | | // eslint-disable-next-line no-undef |
| | | var textM5 = new AMap.ElasticMarker({ |
| | | position: pList[0], |
| | | styles: [ |
| | | { |
| | | icon: { |
| | | img: imgLocation, |
| | | size: [16, 16], //å¯è§åºåçå¤§å° |
| | | ancher: [8, 16], //éç¹ |
| | | fitZoom: 18, //æåéççº§å« |
| | | scaleFactor: 1, //å°å¾æ¾å¤§ä¸çº§çç¼©æ¾æ¯ä¾ç³»æ° |
| | | maxScale: 2, //æå¤§æ¾å¤§æ¯ä¾ |
| | | minScale: 1 //æå°æ¾å¤§æ¯ä¾ |
| | | }, |
| | | label: { |
| | | content: `<div>${distance2}m</div>`, |
| | | offset: [-35, 0], |
| | | position: 'BM', |
| | | minZoom: 15 |
| | | drawSector(fDatas, i) { |
| | | if (_sector != undefined) { |
| | | this.clearSector(); |
| | | } |
| | | } |
| | | ], |
| | | zoomStyleMapping: zoomStyleMapping |
| | | }); |
| | | _sectorViews['textM5'] = textM5; |
| | | map.add(_sectorViews['textM5']); |
| | | map.add(_sectorViews['text5']); |
| | | const { sDeg, eDeg, lnglat, distance, distance2, list, list2 } = |
| | | sectorParams(fDatas, i); |
| | | drawSectorMesh(sDeg, eDeg, lnglat, distance, distance2); |
| | | drawElasticMarker(list, list2, distance, distance2); |
| | | }, |
| | | |
| | | drawSectorAna(fDatas, i) { |
| | | this.clearSectorMesh(); |
| | | const { sDeg, eDeg, lnglat, distance, distance2, list, list2 } = |
| | | sectorParams(fDatas, i); |
| | | drawSectorMesh(sDeg, eDeg, lnglat, distance, distance2); |
| | | drawTextMaker(list, list2, distance, distance2); |
| | | } |
| | | }; |
| | |
| | | <BaseMap></BaseMap> |
| | | <div class="overlay-container"> |
| | | <CoreHeader></CoreHeader> |
| | | <el-row class="dropdown-wrap"> |
| | | <MapToolbox></MapToolbox> |
| | | <MissionManage></MissionManage> |
| | | </el-row> |
| | | <CoreMenu></CoreMenu> |
| | | <router-view></router-view> |
| | | </div> |
| | |
| | | /* padding: 4px; */ |
| | | pointer-events: none; |
| | | } |
| | | |
| | | .dropdown-wrap { |
| | | position: absolute; |
| | | top: 10px; |
| | | left: 2px; |
| | | gap: 4px; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="p-events-none m-t-2"> |
| | | <el-row v-show="status == 0" justify="center"> |
| | | <el-row justify="center" align="middle" class="top-wrap"> |
| | | <SearchBar |
| | | v-show="status == 0" |
| | | :search-time="searchTime" |
| | | @search="fetchHistroyData" |
| | | ></SearchBar> |
| | | <TrajectoryState v-show="status != 0" :status="status"></TrajectoryState> |
| | | </el-row> |
| | | <el-row class="m-t-2"> |
| | | <FactorRadio |
| | |
| | | class="m-t-2" |
| | | :factor="factorDatas.factor[factorType]" |
| | | ></FactorLegend> |
| | | </el-row> |
| | | <el-row class="historical" justify="center"> |
| | | <HistoricalTrajectory |
| | | :factor-datas="factorDatas" |
| | | :factor-type="factorType" |
| | | @change="(e) => (status = e)" |
| | | @stop="draw" |
| | | ></HistoricalTrajectory> |
| | | </el-row> |
| | | <TrendAnalysis |
| | | class="trend-analysis" |
| | |
| | | :factor-datas="factorDatas" |
| | | :device-type="deviceType" |
| | | ></DataSheet> |
| | | <el-row class="historical" justify="center"> |
| | | <HistoricalTrajectory |
| | | @change="(e) => (status = e)" |
| | | ></HistoricalTrajectory> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | }, |
| | | watch: { |
| | | factorType(nValue, oValue) { |
| | | if (nValue != oValue) { |
| | | if (nValue != oValue && this.status == 0) { |
| | | this.draw(); |
| | | } |
| | | } |
| | |
| | | marks.drawMassMarks(this.factorDatas, e, (index) => { |
| | | // æ¥è¯¢èå´å
ççæµç«ç¹ |
| | | // SceneUtil.searchByCoordinate(lnglat[0], lnglat[1], distance); |
| | | // 3. è¶å¿å¾è·³è½¬å®ä½ |
| | | // const progress = FChart.locate(lineChart.chart, lineChart.option, i, _factor.factorName); |
| | | // 4. è¡¨æ ¼æ°æ®è·³è½¬å®ä½ |
| | | // Table.locate(i); |
| | | this.drawSector(index); |
| | | this.locateIndex = index; |
| | | }); |
| | |
| | | }; |
| | | </script> |
| | | <style scoped> |
| | | .top-wrap { |
| | | height: 40px; |
| | | } |
| | | |
| | | .trend-analysis { |
| | | position: absolute; |
| | | left: 0; |
| | |
| | | |
| | | .historical { |
| | | position: absolute; |
| | | bottom: 0; |
| | | bottom: 10px; |
| | | left: 0; |
| | | right: 0; |
| | | } |