husq
2023-10-08 e9c3bec756225fcf21b6b4cb53f44d11d0b00aea
地理位置信息搜索、配置代理
11 files modified
1 files added
599 ■■■■■ changed files
env/.env 5 ●●●●● patch | view | raw | blame | history
env/.env.dev 7 ●●●●● patch | view | raw | blame | history
env/.env.production 2 ●●●●● patch | view | raw | blame | history
env/.env.stag 5 ●●●●● patch | view | raw | blame | history
src/api/gaode.ts 8 ●●●●● patch | view | raw | blame | history
src/api/http/config.ts 2 ●●● patch | view | raw | blame | history
src/api/http/request.ts 5 ●●●●● patch | view | raw | blame | history
src/components/GMap.vue 2 ●●● patch | view | raw | blame | history
src/components/cesiumMap/cesium.vue 181 ●●●●● patch | view | raw | blame | history
src/hooks/use-cesium-tsa.ts 156 ●●●● patch | view | raw | blame | history
src/pages/page-web/projects/project_list/list_page/list.vue 5 ●●●●● patch | view | raw | blame | history
vite.config.ts 221 ●●●●● patch | view | raw | blame | history
env/.env
@@ -1,2 +1,3 @@
VITE_API_URL = 'http://192.168.1.198:6789'
VITE_WS_API_URL = 'ws://192.168.1.198:6789/api/v1/ws'
VITE_API_URL = 'http://192.168.1.133:6789'
VITE_WS_API_URL = 'ws://192.168.1.133:6789/api/v1/ws'
VITE_BASE_API = '/uav'
env/.env.dev
@@ -1,3 +1,4 @@
VITE_API_URL = 'http://192.168.1.198:6789'
VITE_WS_API_URL = 'ws://192.168.1.198:6789/api/v1/ws'
VITE_APP_ENVIRONMENT=DEV
VITE_API_URL = 'http://192.168.1.133:6789'
VITE_WS_API_URL = 'ws://192.168.1.133:6789/api/v1/ws'
VITE_APP_ENVIRONMENT=DEV
VITE_BASE_API = '/uav'
env/.env.production
@@ -2,3 +2,5 @@
VITE_APP_APIGATEWAY_BACKEND_HOST=''
VITE_API_URL = 'https://dev.jxpskj.com:36789'
VITE_WS_API_URL = 'wss://dev.jxpskj.com:36789/api/v1/ws'
VITE_BASE_API = '/uav'
env/.env.stag
@@ -1,3 +1,4 @@
VITE_APP_ENVIRONMENT=STAG
VITE_API_URL = 'http://192.168.1.198:6789'
VITE_WS_API_URL = 'ws://192.168.1.198:6789/api/v1/ws'
VITE_API_URL = 'http://192.168.1.133:6789'
VITE_WS_API_URL = 'ws://192.168.1.133:6789/api/v1/ws'
VITE_BASE_API = '/uav'
src/api/gaode.ts
New file
@@ -0,0 +1,8 @@
import request, { CommonListResponse, IListWorkspaceResponse, IPage, IWorkspaceResponse } from '/@/api/http/request'
export const gaodeSearch = async function (params:any): Promise<IWorkspaceResponse<any>> {
  const url = 'map/amap/searchByKeyword'
  const result = await request.get(url, {
    params,
  })
  return result.data
}
src/api/http/config.ts
@@ -45,5 +45,5 @@
  // map
  // You can apply on the AMap website.
  amapKey: '5221d3ca929a7bf59c301be186c03791',
  amapSearchKey: '6c3ea75b215f0c0efcbcfdf13273991b'
}
src/api/http/request.ts
@@ -1,3 +1,4 @@
import axios from 'axios'
import { uuidv4 } from '/@/utils/uuid'
import { CURRENT_CONFIG } from './config'
@@ -10,19 +11,19 @@
function getAuthToken () {
  return localStorage.getItem(ELocalStorageKey.Token)
}
console.log(import.meta.env.VITE_API_URL, 'request.ts')
console.log(import.meta.env.VITE_BASE_API, 'request.ts')
const instance = axios.create({
  // withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
  },
  baseURL: import.meta.env.VITE_BASE_API,
  // timeout: 12000,
})
instance.interceptors.request.use(
  config => {
    config.headers[ELocalStorageKey.Token] = localStorage.getItem(ELocalStorageKey.Token)
    config.baseURL = import.meta.env.VITE_API_URL
    // config.headers[REQUEST_ID] = uuidv4()
    // config.baseURL = CURRENT_CONFIG.baseURL
    return config
src/components/GMap.vue
@@ -463,7 +463,7 @@
              <a-button :disabled="deviceInfo.device?.mode_code == 14 || !deviceInfo.device ? true : false"
                :class="[showAircraft ? 'active-color' : 'unactive-color']" class="width-100" type="primary" size="small"
                @click="openAircra">
                飞行控制
                监控
              </a-button>
            </a-col>
            <a-col span="11">
src/components/cesiumMap/cesium.vue
@@ -1,6 +1,17 @@
<template>
  <div class="height-100 width-100 cesium" id="cesiumContainer"></div>
  <div v-if="centerConfig.type && !centerConfig.latitude" class="pointLongitude">在地图上点击绘制项目中心点</div>
  <div class="search">
    <a-auto-complete
    v-model:value="searchText"
    style="width: 200px"
    placeholder="请输入地址"
    @select="enter"
    @change="searchLocation"
    :options='resultList'
  >
  </a-auto-complete>
  </div>
  <!-- <div class="switch">
    <div class="2d" v-if="dimension === 3" @click="switchModel('2D')">2D</div>
    <div class="3d" v-else @click="switchModel('3D')">3D</div>
@@ -8,115 +19,73 @@
</template>
<script setup lang="ts">
import * as Cesium from 'cesium'
import { onMounted, ref, onUnmounted, } from 'vue'
import { pointCenter, clickPoint } from '/@/hooks/use-center-point'
import { ref, } from 'vue'
import _ from 'lodash'
import { cesiumOperation } from '/@/hooks/use-cesium-tsa'
import { gaodeSearch } from '/@/api/gaode'
import { useMyStore } from '/@/store'
let viewer: Cesium.Viewer | null = null
let handler: Cesium.ScreenSpaceEventHandler
const dimension = ref(3)
const { appContext } = getCurrentInstance()
const global = appContext.config.globalProperties
// const viewer: { value: Cesium.Viewer | null | undefined } = ref()
import * as Cesium from 'cesium'
type result = {
  label: string,
  value: string,
  location: string,
  district:string,
}
const searchText = ref('')
const resultList = ref<result[]>([])
const store = useMyStore()
const centerConfig = computed(() => {
  return store.state.map.centerConfig
})
const init = () => {
  // Cesium Token
  const cesiumToken = import.meta.env.VITE_CESIUM_TOKEN
  Cesium.Ion.defaultAccessToken = cesiumToken
  Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45
  // 西南东北,默认显示中国
  Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(110, -25, 110, 90)
  viewer = new Cesium.Viewer('cesiumContainer', {
    infoBox: false, // 禁用沙箱,解决控制台报错
    animation: false, // 左下角的动画仪表盘
    baseLayerPicker: false, // 右上角的图层选择按钮
    geocoder: false, // 搜索框
    homeButton: false, // home按钮
    sceneModePicker: false, // 模式切换按钮
    timeline: false, // 底部的时间轴
    navigationHelpButton: false, // 右上角的帮助按钮,
    selectionIndicator: false, // 是否显示选择指示器
    baseLayer: false,
  })
  handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
  loadLAYER()
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) // 禁用双击
  // viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100
  viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000
  global.$viewer = viewer
}
// 加载图层、注解方法
const loadLAYER = () => {
  // 天地图Key
  const TDT_Token = 'c6eea7dad4fa1e2d1e32ec0e7c9735db'
  // 天地图地图
  const TDT_IMG_C = 'https://{s}.tianditu.gov.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
    '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
    '&style=default&format=tiles&tk=' + TDT_Token
  // 天地图注记
  const TDT_ZJ = 'https://{s}.tianditu.gov.cn/cia_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
    '&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
    '&style=default&format=tiles&tk=' + TDT_Token
  // 天地图图层加载
  const imageryProvider = new Cesium.WebMapTileServiceImageryProvider({
    url: TDT_IMG_C,
    layer: 'tdtImg_c',
    style: 'default',
    format: 'tiles',
    tileMatrixSetID: 'c',
    subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
    tilingScheme: new Cesium.GeographicTilingScheme(),
    tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'],
    maximumLevel: 50,
  })
  viewer?.imageryLayers.addImageryProvider(imageryProvider)
  // 天地图中文注记加载
  const annotation = new Cesium.WebMapTileServiceImageryProvider({
    url: TDT_ZJ,
    layer: 'tdtImg_c',
    style: 'default',
    format: 'tiles',
    tileMatrixSetID: 'c',
    subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
    tilingScheme: new Cesium.GeographicTilingScheme(),
    tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'],
    maximumLevel: 50,
  })
  viewer?.imageryLayers.addImageryProvider(annotation)
}
// 切换为二三维模式
const switchModel = (type: string) => {
  switch (type) {
    case '2D':
      viewer.scene.camera.setView({
        orientation: {
          pitch: Cesium.Math.toRadians(-60),
          heading: Cesium.Math.toRadians(0),
        }
      })
      dimension.value = 2
      break
    case '3D':
      viewer.scene.camera.setView({
        orientation: {
          pitch: Cesium.Math.toRadians(-90),
          heading: Cesium.Math.toRadians(0),
        }
      })
      dimension.value = 3
const search = async () => {
  resultList.value = []
  const params = {
    keyword: searchText.value
  }
  const res = await gaodeSearch(params)
  if (res.code !== 0) return
  if (res.data.tips.length > 0) {
    res.data.tips.shift()
    resultList.value = res.data.tips.map((v:any) => {
      return {
        value: `${v.name}(${v.district})`,
        label: v.name,
        location: v.location,
        district: v.district,
      }
    })
  }
}
onMounted(() => {
  init()
})
// 销毁地图模型
onUnmounted(() => {
  viewer = null
})
const searchLocation = _.debounce(search, 500)
const { flyTo, addPoint, removeById } = cesiumOperation()
const enter = (e:string) => {
  removeById('key')
  const filterItem = resultList.value.find(v => v.value === e)
  const [longitude, latitude] = filterItem?.location.split(',')
  const params = {
    longitude: longitude - 0,
    latitude: latitude - 0,
  }
  const pointParams = {
    point: {
      pixelSize: 20,
      outlineWidth: 4,
      color: Cesium.Color.GREEN,
      outlineColor: Cesium.Color.WHITE,
    },
    label: {
      text: filterItem?.label,
      outlineWidth: 20,
      font: '24px sans-serif',
      heightReference: 80,
      pixelOffset: new Cesium.Cartesian2(0, -35),
      fillColor: Cesium.Color.BROWN
    },
    id: 'key'
  }
  addPoint({ ...pointParams, ...params })
  flyTo(params)
}
</script>
<style scoped lang="scss">
@@ -139,7 +108,13 @@
  text-align: center;
  font-size: 16px;
}
.search {
  position: absolute;
  top: 40px;
  right: 20px;
  color: #fff;
  font-size: 16px;
}
.switch {
  position: absolute;
  background-color: #fff;
src/hooks/use-cesium-tsa.ts
@@ -1,68 +1,156 @@
import { ELocalStorageKey, EDeviceTypeName } from '/@/types'
import dockIcon from '/@/assets/icons/dock.png'
import rcIcon from '/@/assets/icons/rc.png'
import droneIcon from '/@/assets/icons/drone.png'
import * as Cesium from 'cesium'
import {
  getCurrentInstance,
} from 'vue'
interface billboardSetting {
    image: string,
    scale?: number,
    [key: string]: any
  image: string,
  scale?: number,
  [key: string]: any
}
interface pointSetting {
    pixelSize: number,
    outlineWidth: number,
    [key: string]: any
  pixelSize: number,
  outlineWidth: number,
  [key: string]: any
}
interface labelSetting {
    text: string,
    font: string,
    outlineWidth: number,
    [key: string]: any
  text: string | undefined,
  font: string,
  outlineWidth: number,
  [key: string]: any
}
interface pointOption {
    longitude: number
    latitude: number
    point?: pointSetting
    billboard?: billboardSetting
    label?: labelSetting
  longitude: number
  latitude: number
  point?: pointSetting
  billboard?: billboardSetting
  label?: labelSetting
  id?: string
}
// 定义全局的viewer变量防止重复生成
// eslint-disable-next-line no-var
var viewer: Cesium.Viewer | null = null
export function cesiumOperation () {
  let handler: Cesium.ScreenSpaceEventHandler
  const _init = () => {
    if (viewer) return
    // Cesium Token
    const cesiumToken = import.meta.env.VITE_CESIUM_TOKEN
    Cesium.Ion.defaultAccessToken = cesiumToken
    Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45
    // 西南东北,默认显示中国
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(110, -25, 110, 90)
    viewer = new Cesium.Viewer('cesiumContainer', {
      infoBox: false, // 禁用沙箱,解决控制台报错
      animation: false, // 左下角的动画仪表盘
      baseLayerPicker: false, // 右上角的图层选择按钮
      geocoder: false, // 搜索框
      homeButton: false, // home按钮
      sceneModePicker: false, // 模式切换按钮
      timeline: false, // 底部的时间轴
      navigationHelpButton: false, // 右上角的帮助按钮,
      selectionIndicator: false, // 是否显示选择指示器
      baseLayer: false,
    })
    handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) // 禁用双击
    // viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100
    viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000
    loadLAYER()
  }
  // 加载图层、注解方法
  const loadLAYER = () => {
    // 天地图Key
    const TDT_Token = 'c6eea7dad4fa1e2d1e32ec0e7c9735db'
    // 天地图地图
    const TDT_IMG_C = 'https://{s}.tianditu.gov.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
      '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
      '&style=default&format=tiles&tk=' + TDT_Token
    // 天地图注记
    const TDT_ZJ = 'https://{s}.tianditu.gov.cn/cia_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
      '&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
      '&style=default&format=tiles&tk=' + TDT_Token
    // 天地图图层加载
    const imageryProvider = new Cesium.WebMapTileServiceImageryProvider({
      url: TDT_IMG_C,
      layer: 'tdtImg_c',
      style: 'default',
      format: 'tiles',
      tileMatrixSetID: 'c',
      subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
      tilingScheme: new Cesium.GeographicTilingScheme(),
      tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'],
      maximumLevel: 50,
    })
    viewer?.imageryLayers.addImageryProvider(imageryProvider)
    // 天地图中文注记加载
    const annotation = new Cesium.WebMapTileServiceImageryProvider({
      url: TDT_ZJ,
      layer: 'tdtImg_c',
      style: 'default',
      format: 'tiles',
      tileMatrixSetID: 'c',
      subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
      tilingScheme: new Cesium.GeographicTilingScheme(),
      tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'],
      maximumLevel: 50,
    })
    viewer?.imageryLayers.addImageryProvider(annotation)
  }
export function cesiumOperation (viewer: any) {
  const cesiumExample = viewer
  const icons = new Map([
    [EDeviceTypeName.Aircraft, droneIcon],
    [EDeviceTypeName.Gateway, rcIcon],
    [EDeviceTypeName.Dock, dockIcon]
  ])
  // 清除所有标记点
  function removeAllPoint () {
    if (cesiumExample) {
      cesiumExample?.entities?.removeAll()
    if (viewer) {
      viewer?.entities?.removeAll()
    }
  }
  // 添加标记点
  function addPoint (pointOption:pointOption) {
  const addPoint = (pointOption: pointOption) => {
    if (!pointOption.longitude && !pointOption.latitude) return
    cesiumExample.entities.add({
    viewer?.entities.add({
      position: Cesium.Cartesian3.fromDegrees(pointOption.longitude, pointOption.latitude),
      billboard: pointOption.billboard,
      point: pointOption.point
      point: pointOption.point,
      label: pointOption.label,
      id: pointOption.id,
    })
  }
  // 通过点ID删除
  function removeById (id:string) {
    viewer?.entities.removeById(id)
    const pointEntity = viewer?.entities.getById(id)
    if (pointEntity && pointEntity !== undefined) {
      viewer?.entities.remove(pointEntity)
    }
  }
  // 飞行 flyto
  function flyTo (pointOption:pointOption, time: number = 3) {
  const flyTo = (pointOption: pointOption, time: number = 4) => {
    if (!pointOption.longitude && !pointOption.latitude) return
    const destination = Cesium.Cartesian3.fromDegrees(pointOption.longitude, pointOption.latitude, 1000)
    const destination = Cesium.Cartesian3.fromDegrees(pointOption.longitude, pointOption.latitude, 3000)
    const duration = time
    cesiumExample.camera.flyTo({
    viewer?.camera.flyTo({
      destination,
      duration
    })
  }
  onMounted(() => {
    if (viewer) return
    _init()
    const { appContext } = getCurrentInstance()
    const global = appContext.config.globalProperties
    global.$viewer = viewer
  })
  // 销毁地图模型
  onUnmounted(() => {
    viewer = null
  })
  return {
    addPoint,
    removeAllPoint,
    flyTo
    flyTo,
    removeById
  }
}
src/pages/page-web/projects/project_list/list_page/list.vue
@@ -2,7 +2,7 @@
 * @Author: husq 931347610@qq.com
 * @Date: 2023-09-13 18:21:08
 * @LastEditors: husq 931347610@qq.com
 * @LastEditTime: 2023-09-21 16:45:06
 * @LastEditTime: 2023-10-08 14:35:54
 * @FilePath: \Cloud-API-Demo-Web\src\pages\page-web\projects\project_list\list_page\list.vue
 * @Description:
 *
@@ -78,8 +78,7 @@
  router.push({ name: ERouterName.WORKSPACE })
  store.commit('SET_POINT_LIST', [])
}
const cesium = cesiumOperation(global.$viewer)
console.log(global, 'global')
const cesium = cesiumOperation()
const goAdd = () => {
  router.push({ name: ERouterName.ADD_PROJECT })
  store.commit('SET_POINT_LIST', [])
vite.config.ts
@@ -1,7 +1,7 @@
import vue from '@vitejs/plugin-vue'
// config alias
import path from 'path'
import { ConfigEnv, defineConfig, UserConfigExport } from 'vite'
import { ConfigEnv, defineConfig, UserConfigExport, loadEnv } from 'vite'
import ViteComponents, { AntDesignVueResolver } from 'vite-plugin-components'
// Introduce eslint plugin
import eslintPlugin from 'vite-plugin-eslint'
@@ -14,81 +14,164 @@
import AutoImport from 'unplugin-auto-import/vite'
import { CURRENT_CONFIG } from './src/api/http/config'
// https://vitejs.dev/config/
export default ({ command, mode }: ConfigEnv): UserConfigExport => defineConfig({
  plugins: [
    vue(),
    cesium(),
    eslintPlugin({
      fix: true
    }),
    ViteComponents({
      customComponentResolvers: [AntDesignVueResolver()],
    }),
    viteSvgIcons({
export default defineConfig(({ command, mode }) => {
  // 添加第三个参数空字符串时 '' ,会在env中包含所有环境变量;反之,只包含.env文件中配置的环境变量
  const env = loadEnv(command, process.cwd() + '/env')
  // eslint-disable-next-line no-useless-escape
  return {
    plugins: [
      vue(),
      cesium(),
      eslintPlugin({
        fix: true
      }),
      ViteComponents({
        customComponentResolvers: [AntDesignVueResolver()],
      }),
      viteSvgIcons({
      // 指定需要缓存的图标文件夹
      iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
      // 指定symbolId格式
      symbolId: 'icon-[dir]-[name]',
    }),
    viteVConsole({
      entry: path.resolve(__dirname, './src/main.ts'), // 入口文件
      localEnabled: command === 'serve', // serve开发环境下
      // enabled: command !== 'serve' || mode === 'test', // 打包环境下/发布测试包,
      config: { // vconsole 配置项
        maxLogNumber: 1000,
        theme: 'light'
      }
    }),
    AutoImport({
      dts: 'types/auto-imports.d.ts',
      imports: ['vue', 'vue-router'],
      // 解决eslint报错问题
      eslintrc: {
        iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
        // 指定symbolId格式
        symbolId: 'icon-[dir]-[name]',
      }),
      viteVConsole({
        entry: path.resolve(__dirname, './src/main.ts'), // 入口文件
        localEnabled: command === 'serve', // serve开发环境下
        // enabled: command !== 'serve' || mode === 'test', // 打包环境下/发布测试包,
        config: { // vconsole 配置项
          maxLogNumber: 1000,
          theme: 'light'
        }
      }),
      AutoImport({
        dts: 'types/auto-imports.d.ts',
        imports: ['vue', 'vue-router'],
        // 解决eslint报错问题
        eslintrc: {
        // 这里先设置成true然后npm run dev 运行之后会生成 .eslintrc-auto-import.json 文件之后,在改为false
        enabled: false,
        filepath: './.eslintrc-auto-import.json', // 生成的文件路径
        globalsPropValue: true,
      },
    }),
    PkgConfig(),
    OptimizationPersist()
          enabled: false,
          filepath: './.eslintrc-auto-import.json', // 生成的文件路径
          globalsPropValue: true,
        },
      }),
      PkgConfig(),
      OptimizationPersist()
    // [svgBuilder('./src/assets/icons/')] // All svg under src/icons/svg/ have been imported here, no need to import separately
  ],
  server: {
    open: true,
    host: '0.0.0.0',
    port: 8080,
    proxy: {
      '/uav': {
        // 代理请求之后的请求地址(你的真实接口地址)
        target: CURRENT_CONFIG.baseURL,
        rewrite: path => path.replace(/^\/uav/, ''),
        // 跨域
        changeOrigin: true
    ],
    server: {
      open: true,
      host: '0.0.0.0',
      port: 8080,
      proxy: {
        [env.VITE_BASE_API]: {
          // 代理请求之后的请求地址(你的真实接口地址)
          target: env.VITE_API_URL,
          rewrite: path => path.replace(new RegExp(`^${env.VITE_BASE_API}`), ''),
          // 跨域
          changeOrigin: true
        }
      }
    }
  },
  envDir: './env',
  resolve: {
    alias: [{
    },
    envDir: './env',
    resolve: {
      alias: [{
      // https://github.com/vitejs/vite/issues/279#issuecomment-635646269
      find: '/@',
      replacement: path.resolve(__dirname, './src'),
    }
    ]
  },
  css: {
    preprocessorOptions: {
      scss: {
        find: '/@',
        replacement: path.resolve(__dirname, './src'),
      }
      ]
    },
    css: {
      preprocessorOptions: {
        scss: {
        // example : additionalData: `@import "./src/design/styles/variables";`
        // dont need include file extend .scss
        additionalData: '@import "./src/styles/variables";'
      },
          additionalData: '@import "./src/styles/variables";'
        },
      }
    },
    base: './',
    build: {
      target: ['es2015'], // 最低支持 es2015
      sourcemap: true
    }
  },
  base: './',
  build: {
    target: ['es2015'], // 最低支持 es2015
    sourcemap: true
  }
})
// export default ({ command, mode }: ConfigEnv): UserConfigExport => defineConfig({
//   plugins: [
//     vue(),
//     cesium(),
//     eslintPlugin({
//       fix: true
//     }),
//     ViteComponents({
//       customComponentResolvers: [AntDesignVueResolver()],
//     }),
//     viteSvgIcons({
//       // 指定需要缓存的图标文件夹
//       iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
//       // 指定symbolId格式
//       symbolId: 'icon-[dir]-[name]',
//     }),
//     viteVConsole({
//       entry: path.resolve(__dirname, './src/main.ts'), // 入口文件
//       localEnabled: command === 'serve', // serve开发环境下
//       // enabled: command !== 'serve' || mode === 'test', // 打包环境下/发布测试包,
//       config: { // vconsole 配置项
//         maxLogNumber: 1000,
//         theme: 'light'
//       }
//     }),
//     AutoImport({
//       dts: 'types/auto-imports.d.ts',
//       imports: ['vue', 'vue-router'],
//       // 解决eslint报错问题
//       eslintrc: {
//         // 这里先设置成true然后npm run dev 运行之后会生成 .eslintrc-auto-import.json 文件之后,在改为false
//         enabled: false,
//         filepath: './.eslintrc-auto-import.json', // 生成的文件路径
//         globalsPropValue: true,
//       },
//     }),
//     PkgConfig(),
//     OptimizationPersist()
//     // [svgBuilder('./src/assets/icons/')] // All svg under src/icons/svg/ have been imported here, no need to import separately
//   ],
//   server: {
//     open: true,
//     host: '0.0.0.0',
//     port: 8080,
//     proxy: {
//       '/uav': {
//         // 代理请求之后的请求地址(你的真实接口地址)
//         target: CURRENT_CONFIG.baseURL,
//         rewrite: path => path.replace(/^\/uav/, ''),
//         // 跨域
//         changeOrigin: true
//       }
//     }
//   },
//   envDir: './env',
//   resolve: {
//     alias: [{
//       // https://github.com/vitejs/vite/issues/279#issuecomment-635646269
//       find: '/@',
//       replacement: path.resolve(__dirname, './src'),
//     }
//     ]
//   },
//   css: {
//     preprocessorOptions: {
//       scss: {
//         // example : additionalData: `@import "./src/design/styles/variables";`
//         // dont need include file extend .scss
//         additionalData: '@import "./src/styles/variables";'
//       },
//     }
//   },
//   base: './',
//   build: {
//     target: ['es2015'], // 最低支持 es2015
//     sourcemap: true
//   }
// })