|  | @@ -4,10 +4,8 @@ |  | @@ -4,10 +4,8 @@ | 
| 4 | }; | 4 | }; | 
| 5 | </script> | 5 | </script> | 
| 6 | <script lang="ts" setup> | 6 | <script lang="ts" setup> | 
| 7 | -  import { computed, nextTick, onMounted, ref, unref } from 'vue'; | 7 | +  import { computed, onMounted, ref, unref } from 'vue'; | 
| 8 | import { RadioRecord } from '../../detail/config/util'; | 8 | import { RadioRecord } from '../../detail/config/util'; | 
| 9 | -  import { useScript } from '/@/hooks/web/useScript'; |  |  | 
| 10 | -  import { BAI_DU_MAP_URL } from '/@/utils/fnUtils'; |  |  | 
| 11 | import { MapComponentLayout, MapComponentValue } from './map.config'; | 9 | import { MapComponentLayout, MapComponentValue } from './map.config'; | 
| 12 | import { | 10 | import { | 
| 13 | ClockCircleOutlined, | 11 | ClockCircleOutlined, | 
|  | @@ -15,31 +13,107 @@ |  | @@ -15,31 +13,107 @@ | 
| 15 | PauseCircleOutlined, | 13 | PauseCircleOutlined, | 
| 16 | } from '@ant-design/icons-vue'; | 14 | } from '@ant-design/icons-vue'; | 
| 17 | import { Button, Tooltip } from 'ant-design-vue'; | 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 | defineProps<{ | 32 | defineProps<{ | 
| 21 | value?: MapComponentValue; | 33 | value?: MapComponentValue; | 
| 22 | layout?: MapComponentLayout; | 34 | layout?: MapComponentLayout; | 
| 23 | radio?: RadioRecord; | 35 | radio?: RadioRecord; | 
|  |  | 36 | +      random?: boolean; | 
| 24 | }>(), | 37 | }>(), | 
| 25 | -    {} | 38 | +    { | 
|  |  | 39 | +      random: true, | 
|  |  | 40 | +    } | 
| 26 | ); | 41 | ); | 
| 27 |  | 42 |  | 
| 28 | const wrapRef = ref<HTMLDivElement | null>(null); | 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 | async function initMap() { | 47 | async function initMap() { | 
| 32 | -    await toPromise(); |  |  | 
| 33 | -    await nextTick(); |  |  | 
| 34 | const wrapEl = unref(wrapRef); | 48 | const wrapEl = unref(wrapRef); | 
| 35 | if (!wrapEl) return; | 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 | onMounted(() => { | 117 | onMounted(() => { | 
| 44 | initMap(); | 118 | initMap(); | 
| 45 | }); | 119 | }); | 
|  | @@ -50,20 +124,23 @@ |  | @@ -50,20 +124,23 @@ | 
| 50 |  | 124 |  | 
| 51 | const handleTrackSwitch = () => {}; | 125 | const handleTrackSwitch = () => {}; | 
| 52 |  | 126 |  | 
| 53 | -  const pauseFlag = ref(true); | 127 | +  const getTrackPlayStatus = computed(() => { | 
|  |  | 128 | +    return (trackAni.value || {})._status; | 
|  |  | 129 | +  }); | 
| 54 |  | 130 |  | 
| 55 | const handlePlay = () => { | 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 | </script> | 136 | </script> | 
| 63 |  | 137 |  | 
| 64 | <template> | 138 | <template> | 
| 65 | <div class="w-full h-full flex justify-center items-center flex-col"> | 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 | <Button type="text" class="!px-2 flex-auto !text-left truncate" @click="handleTrackSwitch"> | 144 | <Button type="text" class="!px-2 flex-auto !text-left truncate" @click="handleTrackSwitch"> | 
| 68 | <div class="w-full truncate text-gray-500 flex items-center"> | 145 | <div class="w-full truncate text-gray-500 flex items-center"> | 
| 69 | <ClockCircleOutlined /> | 146 | <ClockCircleOutlined /> | 
|  | @@ -75,15 +152,14 @@ |  | @@ -75,15 +152,14 @@ | 
| 75 | </Tooltip> | 152 | </Tooltip> | 
| 76 | </div> | 153 | </div> | 
| 77 | </Button> | 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 | </Button> | 161 | </Button> | 
| 86 | </div> | 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 | </div> | 164 | </div> | 
| 89 | </template> | 165 | </template> |