husq
2023-09-05 be84102dc381d0c1925e477f15a431d6c327c0d6
项目添加中设置中心点功能
11 files modified
193 ■■■■ changed files
src/api/project-page/index.ts 7 ●●●●● patch | view | raw | blame | history
src/components/cesiumMap/cesium.vue 31 ●●●● patch | view | raw | blame | history
src/event-bus/index.ts 1 ●●●● patch | view | raw | blame | history
src/pages/page-web/projects/project_list/add_page/add.vue 49 ●●●●● patch | view | raw | blame | history
src/pages/page-web/projects/project_list/add_page/components/WeatherDrawer.vue 19 ●●●● patch | view | raw | blame | history
src/pages/page-web/projects/project_list/add_page/type.ts 7 ●●●● patch | view | raw | blame | history
src/pages/page-web/projects/project_list/list_page/components/ProjectList.vue 28 ●●●● patch | view | raw | blame | history
src/pages/page-web/projects/project_list/list_page/list.vue 10 ●●●●● patch | view | raw | blame | history
src/store/index.ts 2 ●●●●● patch | view | raw | blame | history
src/store/map.ts 33 ●●●●● patch | view | raw | blame | history
src/styles/flex.style.scss 6 ●●●● patch | view | raw | blame | history
src/api/project-page/index.ts
@@ -55,3 +55,10 @@
  const result = await request.get(url, { params: { id } })
  return result.data
}
// 项目阻飞编辑
export const editProjectBlock = async function (params:any): Promise<IWorkspaceResponse<any>> {
  const url = `api/${HTTP_PREFIX}/projectBlocking/edit`
  const result = await request.post(url, params)
  return result.data
}
src/components/cesiumMap/cesium.vue
@@ -2,7 +2,7 @@
 * @Author: 胡思旗 931347610@qq.com
 * @Date: 2023-08-22 17:50:30
 * @LastEditors: husq 931347610@qq.com
 * @LastEditTime: 2023-09-01 16:48:42
 * @LastEditTime: 2023-09-05 14:12:49
 * @FilePath: \Cloud-API-Demo-Web\src\components\cesiumMap\cesium.vue
 * @Description:
 *
@@ -10,12 +10,18 @@
-->
<template>
      <div class="height-100 width-100 cesium" id="cesiumContainer" @click="getCoordinate"></div>
  <div v-if="centerConfig.type && !centerConfig.latitude" class="pointLongitude">在地图上点击绘制项目中心点</div>
</template>
<script setup lang="ts">
import * as Cesium from 'cesium'
import { onMounted, ref, onUnmounted } from 'vue'
import { useMyStore } from '/@/store'
const viewer: { value: Cesium.Viewer | null | undefined } = ref()
const store = useMyStore()
const centerConfig = computed(() => {
  return store.state.map.centerConfig
})
const init = () => {
  // Cesium Token
  const cesiumToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhMjdmNGUxZC02YzY3LTQyZWUtOTNmYy1hNTI0MDRkZDY2ZmEiLCJpZCI6MTYxODgyLCJpYXQiOjE2OTI3NTQyNDV9.Pm7xTwPmKowPzFgJ0TsIKOtthigq86BLJX4c8M97Hhw'
@@ -79,6 +85,7 @@
const camera = () => {}
// 获取地图点击坐标
const getCoordinate = () => {
  if (!centerConfig.value.type) return
  let longitude: number, latitude: number
  viewer.value?.screenSpaceEventHandler.setInputAction((e: any) => {
    const cartesian = viewer.value?.camera.pickEllipsoid(e.position, viewer.value?.scene.globe.ellipsoid)
@@ -86,12 +93,16 @@
      const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
      longitude = Cesium.Math.toDegrees(cartographic.longitude)
      latitude = Cesium.Math.toDegrees(cartographic.latitude)
      const data = {
        longitude,
        latitude,
      }
      store.commit('SET_CENTER_CONFIG_LATITUDE', data)
      console.log(store, '设置成功')
    }
    Point(longitude, latitude)
    return { longitude, latitude }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}
const Point = (longitude:number, latitude:number) => {
  const entity = viewer.value?.entities.add({
    position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
@@ -123,5 +134,17 @@
    display: none !important;
  }
}
.pointLongitude {
    background-color: rgba(20, 20, 20, 0.792);
    position: absolute;
    z-index: 30;
    bottom: 30px;
    color: #fff;
    left: 0;
    right: 0;
    margin: 0 80px;
    padding: 15px 0;
    text-align: center;
    font-size: 16px;
  }
</style>
src/event-bus/index.ts
@@ -9,5 +9,4 @@
};
const emitter: Emitter<Events> = mitt<Events>()
export default emitter
src/pages/page-web/projects/project_list/add_page/add.vue
@@ -1,13 +1,3 @@
<!--
 * @Author: husq 931347610@qq.com
 * @Date: 2023-08-30 14:43:37
 * @LastEditors: husq 931347610@qq.com
 * @LastEditTime: 2023-09-04 09:35:15
 * @FilePath: \Cloud-API-Demo-Web\src\pages\page-web\projects\project_list\add_page\add.vue
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
-->
<template>
    <div class="project_add">
        <div class="side-header">
@@ -43,7 +33,8 @@
                        <p>天气阻飞设置</p>
                        <div class="btn">
                            <a-button type="text" @click="openDrawer('weatherDrawer')">
                                <span class="button_name">{{ formState.projectBlocking.cloudBlockingConfigEnable == 1 ?
                                <span class="button_name">{{ formState.projectBlocking &&
                                    formState.projectBlocking.cloudBlockingConfigEnable == '1' ?
                                    '已开启'
                                    : '未开启' }}</span>
                                <template #icon><right-outlined
@@ -142,11 +133,11 @@
                        </template>
                    </a-table>
                </a-form-item>
                <a-form-item>
                <a-form-item :name="FormProject.LATITUDE">
                    <div class="application flex-display flex-align-center flex-justify-between">
                        <p>项目作业中心点</p>
                        <div>
                            <a-button type="text">
                            <a-button type="text" @click="configCenter">
                                <span class="button_add">设置项目中心点</span>
                                <template #icon>
                                    <AimOutlined :style="{ fontSize: '14px', color: '#2d8cf0' }" />
@@ -154,7 +145,8 @@
                            </a-button>
                        </div>
                    </div>
                    <div class="latitude">经纬度:35.6761919°N 139.65031.6°E</div>
                    <div class="latitude" v-if="latitude && latitude != 0">
                        经纬度:{{ latitude }}°N {{ longitude }}°E</div>
                </a-form-item>
            </a-form>
            <WeatherDrawer v-model:show="drawerConfig.weatherDrawer" title="以下设置仅在当前项目中生效">
@@ -179,21 +171,29 @@
import ComWeather from './components/WeatherDrawer.vue'
import ComUser from './components/UserDrawer.vue'
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface'
import { message } from 'ant-design-vue'
import { Form, message } from 'ant-design-vue'
import { cloneDeep } from 'lodash'
import { add, detail, edit as projectEdit } from '/@/api/project-page/index'
import { useMyStore } from '/@/store/index'
const router = useRouter()
const store = useMyStore()
const route = useRoute()
const dataSource = ref([])
const deviceSource = ref([])
const editableData: UnwrapRef<Record<string, ProjectUser>> = reactive({})
const editDeviceData: UnwrapRef<Record<string, ProjectDevice>> = reactive({})
const longitude = computed(() => {
  return store.state.map.centerConfig.longitude
})
const latitude = computed(() => {
  return store.state.map.centerConfig.latitude
})
const formState = ref<FormState>({
  [FormProject.PROJECT_NAME]: '',
  [FormProject.PROJECT_STATUS]: '',
  [FormProject.PROJCECT_INTRO]: '',
  [FormProject.LONGITUDE]: 0,
  [FormProject.LATITUDE]: 0,
  [FormProject.LONGITUDE]: null,
  [FormProject.LATITUDE]: null,
  [FormProject.USERLIST]: [],
  [FormProject.PROJECT_BLOCKING]: {
    [blocking.CLOUDBLOCKINGCONFIGENABLE]: '1',
@@ -249,6 +249,8 @@
  if (res.code !== 5000) return
  message.success('修改成功')
  router.go(-1)
  store.commit('SET_CENTER_CONFIG_TYPE', false)
  store.commit('SET_CENTER_CONFIG_LATITUDE', { latitude: null, longitude: null })
}
// 新增项目
const addProject = async () => {
@@ -256,14 +258,17 @@
  if (res.code !== 5000) return
  message.success('保存成功')
  router.go(-1)
  store.commit('SET_CENTER_CONFIG_TYPE', false)
  store.commit('SET_CENTER_CONFIG_LATITUDE', { latitude: null, longitude: null })
}
const goBack = () => {
  router.go(-1)
  store.commit('SET_CENTER_CONFIG_TYPE', false)
  store.commit('SET_CENTER_CONFIG_LATITUDE', { latitude: null, longitude: null })
}
// 天气组飞侧边栏
const openDrawer = (name: string) => {
  for (const key in drawerConfig.value) {
    console.log(key)
    if (key === name) {
      drawerConfig.value[key] = true
    } else {
@@ -273,6 +278,8 @@
}
// 表单验证提交
const submit = () => {
  formState.value[FormProject.LATITUDE] = latitude.value
  formState.value[FormProject.LONGITUDE] = longitude.value
  projectForm.value.validate().then(async () => {
    if (route.query.id) {
      editProject()
@@ -283,6 +290,12 @@
    console.log(error)
  })
}
// 设置项目中心点
const configCenter = () => {
  if (store.state.map.centerConfig.type === true) return
  store.commit('SET_CENTER_CONFIG_TYPE', true)
}
onMounted(() => {
  getDetail()
})
src/pages/page-web/projects/project_list/add_page/components/WeatherDrawer.vue
@@ -3,7 +3,7 @@
    <div class="option">
      <div class="option-item" :style="[model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]!==1?'border:none' : '']">
        <span class="mr10">云端天气组飞设置</span>
        <a-switch :checkedValue="'1'" :unCheckedValue="'2'" v-model:checked="model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]" />
        <a-switch :checkedValue="'1'" :unCheckedValue="'2'" v-model:checked="model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]" @change="changeEdit" />
        <div v-if="model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]==1">
          <p class="mt10 describe">当风速或雨量大于设置值时,将对机场的飞行器进行阻飞。</p>
        </div>
@@ -15,7 +15,7 @@
      </div>
      <div class="option-item" v-if="model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]=='1'">
        <span class="mr10">天气预报</span>
        <a-switch :checkedValue="'1'" :unCheckedValue="'2'" v-model:checked="model.projectBlocking[blocking.WEATHERREPORTENABLE]" />
        <a-switch :checkedValue="'1'" :unCheckedValue="'2'" @change="changeEdit" v-model:checked="model.projectBlocking[blocking.WEATHERREPORTENABLE]" />
        <p class="mt10 describe">天气阻飞将使用天气预报,同时也会使用机场风速计和雨量计数据。</p>
      </div>
      <div class="option-item-edit" v-if="model.projectBlocking[blocking.CLOUDBLOCKINGCONFIGENABLE]=='1'">
@@ -75,7 +75,9 @@
import { weatherRules, FormWeather, rainSelect, WeatherEnum, } from './type'
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface'
import Select from '/@/components/Search/Select.vue'
import { editProjectBlock } from '/@/api/project-page/index'
import { useVModel } from '/@/hooks/use-v-model'
import { message } from 'ant-design-vue'
interface FormState {
  [FormWeather.WINDSPEEDREPORT]: number
  [FormWeather.WINDSPEED]: number
@@ -87,6 +89,7 @@
    required: true
  },
})
const route = useRoute()
const emit = defineEmits(['update:modelValue'])
const model = useVModel(props, 'modelValue', emit)
const edit = ref(false)
@@ -99,14 +102,24 @@
const submit = () => {
  weatherFormRef.value
    .validate()
    .then(() => {
    .then(async () => {
      edit.value = false
      model.value.projectBlocking = { ...model.value.projectBlocking, ...FormWeatherModel.value }
      if (route.query.id) {
        const res = await editProjectBlock(model.value.projectBlocking)
        if (res.code !== 5000) return message.error(res.message)
      }
    })
    .catch((error: ValidateErrorEntity<FormState>) => {
      console.log('error', error)
    })
}
const changeEdit = async () => {
  if (!route.query.id) return
  model.value.projectBlocking = { ...model.value.projectBlocking, ...FormWeatherModel.value }
  const res = await editProjectBlock(model.value.projectBlocking)
  if (res.code !== 5000) return message.error(res.message)
}
const cancel = () => {
  FormWeatherModel.value = model.value.projectBlocking
  edit.value = false
src/pages/page-web/projects/project_list/add_page/type.ts
@@ -36,8 +36,8 @@
  [FormProject.PROJECT_NAME]: string
  [FormProject.PROJECT_STATUS]: string
  [FormProject.PROJCECT_INTRO]: string
  [FormProject.LONGITUDE]: number
  [FormProject.LATITUDE]: number
  [FormProject.LONGITUDE]?: number | null
  [FormProject.LATITUDE]?: number | null
  [FormProject.DEVICELIST]?: deviceList[]
  [FormProject.USERLIST]: number[]
  [FormProject.PROJECT_BLOCKING]: projectBlocking
@@ -120,4 +120,7 @@
  [FormProject.PROJECT_NAME]: [
    { required: true, message: '请输入项目名称', trigger: 'blur' },
  ],
  [FormProject.LATITUDE]: [
    { required: true, type: 'number', message: '请设置项目中心点', trigger: 'blur' },
  ],
}
src/pages/page-web/projects/project_list/list_page/components/ProjectList.vue
@@ -2,14 +2,15 @@
 * @Author: 胡思旗 931347610@qq.com
 * @Date: 2023-08-28 15:23:47
 * @LastEditors: husq 931347610@qq.com
 * @LastEditTime: 2023-09-01 17:29:16
 * @LastEditTime: 2023-09-05 10:17:17
 * @FilePath: \Cloud-API-Demo-Web\src\pages\page-web\projects\project_list\list_page\components\ProjectList.vue
 * @Description:项目列表组件
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
-->
<template>
    <div class="project-box">
  <div class="project-box flex-common">
    <a-spin :spinning="model" style="width: 100%;">
        <div class="project-card" v-for="item in cardList" :key="item.id">
            <div class="project-left">
                <div class="head mb10 flex-display flex-align-center flex-justify-between">
@@ -52,6 +53,7 @@
                </div>
            </div>
        </div>
    </a-spin>
    </div>
</template>
@@ -63,14 +65,23 @@
import { del, edit } from '/@/api/project-page'
import { Modal, message } from 'ant-design-vue'
const router = useRouter()
const emit = defineEmits(['refreshList'])
const emit = defineEmits(['refreshList', 'update:modelValue'])
const props = defineProps({
  cardList: {
    type: Array as () => projectCard[],
    required: true,
  },
  modelValue: [String, Number, Boolean]
})
const model = computed({
  get () {
    return props.modelValue
  },
  set (val) {
    emit('update:modelValue', val)
  }
})
const spinning = ref<boolean>(true)
// 删除方法
const deleteItem = (item:projectCard) => {
  Modal.confirm({
@@ -112,7 +123,6 @@
}
const goEdit = (item:any) => {
  console.log(item)
  router.push({
    name: ERouterName.EDIT_PROJECT,
    query: { id: item.id }
@@ -123,6 +133,14 @@
<style scoped lang="scss">
.project-box {
  width: 100%;
  height: 100%;
  :deep(.ant-spin-nested-loading) {
    width: 100%;
    height: 100%;
  }
    .project-card {
        cursor: pointer;
        width: 100%;
src/pages/page-web/projects/project_list/list_page/list.vue
@@ -24,11 +24,7 @@
      </div>
    </div>
    <div class="wrap_card">
      <a-spin :spinning="spinning" :delay="delayTime">
        <List @refreshList="init" :cardList="cardList" />
      </a-spin>
      <List @refreshList="init" v-model="spinning" :cardList="cardList"></List>
    </div>
    <!-- <button @click="goDetail">列表详情</button> -->
  </div>
@@ -61,7 +57,6 @@
})
// ant 加载
const spinning = ref<boolean>(false)
const delayTime = 500
const goDetail = () => {
  router.push({ name: ERouterName.WORKSPACE })
@@ -169,4 +164,5 @@
    flex: 1;
    overflow-y: auto;
  }
}</style>
}
</style>
src/store/index.ts
@@ -7,6 +7,7 @@
import { WaylineFile } from '/@/types/wayline'
import getter from './getters'
import { DevicesCmdExecuteInfo } from '/@/types/device-cmd'
import map from './map'
const initStateFunc = () => ({
  Layers: [
@@ -244,6 +245,7 @@
  actions,
  modules: {
    getter,
    map
  },
}
src/store/map.ts
@@ -1,5 +1,32 @@
const map = {
  state: {
import { MutationTree } from 'vuex'
const state = () => ({
  // 项目中心点设置
  centerConfig: {
    // true为开启在地图中获取坐标
    type: false,
    latitude: null as number | null,
    longitude: null as number | null,
  },
  // 所有项目中心点
  pointList: [],
})
interface longitude {
  longitude:number
  latitude: number
  }
export type RootStateType = ReturnType<typeof state>
const mutations: MutationTree<RootStateType> = {
  // 开启设置地图坐标标识
  SET_CENTER_CONFIG_TYPE (state, type: boolean) {
    state.centerConfig.type = type
  },
  // 设置经纬度
  SET_CENTER_CONFIG_LATITUDE (state, data:longitude) {
    state.centerConfig.longitude = data.longitude
    state.centerConfig.latitude = data.latitude
  }
}
export default {
  state,
  mutations
}
src/styles/flex.style.scss
@@ -1,7 +1,11 @@
.flex-display {
  display: flex;
}
.flex-common {
  display: flex;
  align-items: center;
  justify-content: center;
}
// .border-bottom {
//   position: relative;
//   box-sizing: border-box;