Commit 4e663db6bac49033d048c22d3991af5109d65982

Authored by ww
1 parent 00f944c0

feat: implement visual baord MapComponent

... ... @@ -37,11 +37,22 @@ export const copyTransTreeFun = (arr: any[]) => {
37 37 };
38 38
39 39 // 百度地图url
  40 +const ak = '7uOPPyAHn2Y2ZryeQqHtcRqtIY374vKa';
  41 +
40 42 const register_BAI_DU_MAP_URL = (ak: string) => {
41 43 return `https://api.map.baidu.com/getscript?v=3.0&ak=${ak}`;
42 44 };
43 45
44   -export const BAI_DU_MAP_URL = register_BAI_DU_MAP_URL('7uOPPyAHn2Y2ZryeQqHtcRqtIY374vKa');
  46 +const registerBaiDuMapGlLib = (ak: string) => {
  47 + return `//api.map.baidu.com/getscript?type=webgl&v=1.0&ak=${ak}&services=&t=${Date.now()}`;
  48 +};
  49 +
  50 +export const BAI_DU_MAP_TRACK_ANIMATION =
  51 + '//mapopen.bj.bcebos.com/github/BMapGLLib/TrackAnimation/src/TrackAnimation.min.js';
  52 +
  53 +export const BAI_DU_MAP_GL_LIB = registerBaiDuMapGlLib(ak);
  54 +
  55 +export const BAI_DU_MAP_URL = register_BAI_DU_MAP_URL(ak);
45 56
46 57 // 数字加上每三位加上逗号
47 58 export function toThousands(num) {
... ...
... ... @@ -4,10 +4,8 @@
4 4 };
5 5 </script>
6 6 <script lang="ts" setup>
7   - import { computed, nextTick, onMounted, ref, unref } from 'vue';
  7 + import { computed, onMounted, ref, unref } from 'vue';
8 8 import { RadioRecord } from '../../detail/config/util';
9   - import { useScript } from '/@/hooks/web/useScript';
10   - import { BAI_DU_MAP_URL } from '/@/utils/fnUtils';
11 9 import { MapComponentLayout, MapComponentValue } from './map.config';
12 10 import {
13 11 ClockCircleOutlined,
... ... @@ -15,31 +13,107 @@
15 13 PauseCircleOutlined,
16 14 } from '@ant-design/icons-vue';
17 15 import { Button, Tooltip } from 'ant-design-vue';
  16 + import { FrontComponent } from '../../const/const';
  17 + import { buildUUID } from '/@/utils/uuid';
18 18
19   - withDefaults(
  19 + // useVisualBoardContext();
  20 +
  21 + const startMethodName = `trackPlayMethod_${buildUUID()}`;
  22 +
  23 + const wrapId = `bai-map-${buildUUID()}`;
  24 +
  25 + enum TrackAnimationStatus {
  26 + PLAY = 1,
  27 + DONE = 2,
  28 + PAUSE = 3,
  29 + }
  30 +
  31 + const props = withDefaults(
20 32 defineProps<{
21 33 value?: MapComponentValue;
22 34 layout?: MapComponentLayout;
23 35 radio?: RadioRecord;
  36 + random?: boolean;
24 37 }>(),
25   - {}
  38 + {
  39 + random: true,
  40 + }
26 41 );
27 42
28 43 const wrapRef = ref<HTMLDivElement | null>(null);
29   - const { toPromise } = useScript({ src: BAI_DU_MAP_URL });
  44 + const trackAni = ref<Nullable<any>>(null);
  45 + let mapInstance: Nullable<Recordable> = null;
30 46
31 47 async function initMap() {
32   - await toPromise();
33   - await nextTick();
34 48 const wrapEl = unref(wrapRef);
35 49 if (!wrapEl) return;
36   - const BMap = (window as any).BMap;
37   - const map = new BMap.Map(wrapEl);
38   - const point = new BMap.Point(116.404, 39.915);
39   - map.centerAndZoom(point, 15);
40   - map.enableScrollWheelZoom(true);
  50 + const BMapGL = (window as any).BMapGL;
  51 + mapInstance = new BMapGL.Map(wrapId);
  52 + const point = new BMapGL.Point(116.404, 39.915);
  53 + mapInstance!.centerAndZoom(point, 15);
  54 + mapInstance!.enableScrollWheelZoom(true);
  55 + props.layout?.componentType === FrontComponent.MAP_COMPONENT_TRACK_HISTORY && randomAnimation();
41 56 }
42 57
  58 + const randomAnimation = () => {
  59 + const path = [
  60 + {
  61 + lng: 116.297611,
  62 + lat: 40.047363,
  63 + },
  64 + {
  65 + lng: 116.302839,
  66 + lat: 40.048219,
  67 + },
  68 + {
  69 + lng: 116.308301,
  70 + lat: 40.050566,
  71 + },
  72 + {
  73 + lng: 116.305732,
  74 + lat: 40.054957,
  75 + },
  76 + {
  77 + lng: 116.304754,
  78 + lat: 40.057953,
  79 + },
  80 + {
  81 + lng: 116.306487,
  82 + lat: 40.058312,
  83 + },
  84 + {
  85 + lng: 116.307223,
  86 + lat: 40.056379,
  87 + },
  88 + ];
  89 +
  90 + const point: any[] = [];
  91 + const BMapGL = (window as any).BMapGL;
  92 +
  93 + for (const { lng, lat } of path) {
  94 + point.push(new BMapGL.Point(lng, lat));
  95 + }
  96 +
  97 + const pl = new BMapGL.Polyline(point);
  98 + const BMapGLLib = (window as any).BMapGLLib;
  99 +
  100 + const dynamicPlayMethod = {
  101 + [startMethodName]() {
  102 + trackAni.value = new BMapGLLib.TrackAnimation(mapInstance, pl, {
  103 + overallView: true,
  104 + tilt: 30,
  105 + duration: 20000,
  106 + delay: 300,
  107 + });
  108 + trackAni.value!.start();
  109 + },
  110 + };
  111 +
  112 + (window as any)[startMethodName] = dynamicPlayMethod[startMethodName];
  113 +
  114 + setTimeout(`${startMethodName}()`);
  115 + };
  116 +
43 117 onMounted(() => {
44 118 initMap();
45 119 });
... ... @@ -50,20 +124,23 @@
50 124
51 125 const handleTrackSwitch = () => {};
52 126
53   - const pauseFlag = ref(true);
  127 + const getTrackPlayStatus = computed(() => {
  128 + return (trackAni.value || {})._status;
  129 + });
54 130
55 131 const handlePlay = () => {
56   - pauseFlag.value = false;
57   - };
58   -
59   - const handlePause = () => {
60   - pauseFlag.value = true;
  132 + if (unref(getTrackPlayStatus) === TrackAnimationStatus.DONE) unref(trackAni).start();
  133 + else if (unref(getTrackPlayStatus) === TrackAnimationStatus.PLAY) unref(trackAni).pause();
  134 + else if (unref(getTrackPlayStatus) === TrackAnimationStatus.PAUSE) unref(trackAni).continue();
61 135 };
62 136 </script>
63 137
64 138 <template>
65 139 <div class="w-full h-full flex justify-center items-center flex-col">
66   - <div class="w-[95%] flex">
  140 + <div
  141 + class="w-full flex"
  142 + v-if="props.layout?.componentType === FrontComponent.MAP_COMPONENT_TRACK_HISTORY"
  143 + >
67 144 <Button type="text" class="!px-2 flex-auto !text-left truncate" @click="handleTrackSwitch">
68 145 <div class="w-full truncate text-gray-500 flex items-center">
69 146 <ClockCircleOutlined />
... ... @@ -75,15 +152,14 @@
75 152 </Tooltip>
76 153 </div>
77 154 </Button>
78   - <Button v-show="pauseFlag" type="text" class="!px-2 !text-gray-500" @click="handlePlay">
79   - <PlayCircleOutlined />
80   - <span>播放轨迹</span>
81   - </Button>
82   - <Button v-show="!pauseFlag" type="text" class="!px-2 !text-gray-500" @click="handlePause">
83   - <PauseCircleOutlined />
84   - <span>暂停播放</span>
  155 + <Button type="text" class="!px-2 !text-gray-500" @click="handlePlay">
  156 + <PlayCircleOutlined v-show="getTrackPlayStatus !== TrackAnimationStatus.PLAY" />
  157 + <PauseCircleOutlined v-show="getTrackPlayStatus === TrackAnimationStatus.PLAY" />
  158 + <span>
  159 + {{ getTrackPlayStatus !== TrackAnimationStatus.PLAY ? '播放轨迹' : '暂停播放' }}
  160 + </span>
85 161 </Button>
86 162 </div>
87   - <div ref="wrapRef" class="w-[95%] h-[95%]"></div>
  163 + <div ref="wrapRef" :id="wrapId" class="w-full h-full"></div>
88 164 </div>
89 165 </template>
... ...
... ... @@ -11,26 +11,25 @@ export interface MapComponentValue {
11 11 }
12 12
13 13 interface Config {
14   - layout?: MapComponentLayout;
15   - value?: MapComponentValue;
  14 + componentType?: FrontComponent;
16 15 }
17 16
18 17 export const MaphistoryTrackConfig: Config = {
19   - layout: {
20   - componentType: FrontComponent.MAP_COMPONENT_TRACK_HISTORY,
21   - },
  18 + componentType: FrontComponent.MAP_COMPONENT_TRACK_HISTORY,
22 19 };
23 20
24 21 export const MapRealTrackConfig: Config = {
25   - layout: {
26   - componentType: FrontComponent.MAP_COMPONENT_TRACK_HISTORY,
27   - },
  22 + componentType: FrontComponent.MAP_COMPONENT_TRACK_REAL,
28 23 };
29 24
30 25 export const transfromMapComponentConfig: ComponentConfig['transformConfig'] = (
31   - _componentConfig,
  26 + componentConfig: Config,
32 27 _record,
33 28 _dataSourceRecord
34 29 ) => {
35   - return {};
  30 + return {
  31 + layout: {
  32 + ...componentConfig,
  33 + },
  34 + };
36 35 };
... ...
... ... @@ -45,12 +45,17 @@
45 45 import backIcon from '/@/assets/images/back.png';
46 46 import { useCalcGridLayout } from '../hook/useCalcGridLayout';
47 47 import { FrontComponent } from '../const/const';
  48 + import { useScript } from '/@/hooks/web/useScript';
  49 + import { BAI_DU_MAP_GL_LIB, BAI_DU_MAP_TRACK_ANIMATION } from '/@/utils/fnUtils';
48 50
49 51 const ROUTE = useRoute();
50 52
51 53 const ROUTER = useRouter();
52 54
53   - // unref(ROUTE).name = unref(ROUTE).fullPath;
  55 + const { toPromise: injectBaiDuMapLib } = useScript({ src: BAI_DU_MAP_GL_LIB });
  56 + const { toPromise: injectBaiDuMapTrackAniMationLib } = useScript({
  57 + src: BAI_DU_MAP_TRACK_ANIMATION,
  58 + });
54 59
55 60 const { createMessage, createConfirm } = useMessage();
56 61
... ... @@ -370,7 +375,9 @@
370 375 historyDataModalMethod.openModal(true, record);
371 376 };
372 377
373   - onMounted(() => {
  378 + onMounted(async () => {
  379 + await injectBaiDuMapLib();
  380 + await injectBaiDuMapTrackAniMationLib();
374 381 getDataBoardComponent();
375 382 });
376 383 </script>
... ... @@ -566,4 +573,8 @@
566 573 .board-detail:deep(.ant-page-header-content) {
567 574 padding-top: 20px;
568 575 }
  576 +
  577 + :deep(.vue-resizable-handle) {
  578 + z-index: 99;
  579 + }
569 580 </style>
... ...