Commit f196007987c1b0d22c9f5e3c8306bf4f55aa283e
Merge branch 'ft' into 'main_dev'
perf(src/packages): 优化高德地图标点弹窗和数据展示 See merge request yunteng/thingskit-view!133
Showing
19 changed files
with
232 additions
and
41 deletions
| @@ -235,6 +235,7 @@ const updateVChart = async (newData: SocketReceiveMessageType) => { | @@ -235,6 +235,7 @@ const updateVChart = async (newData: SocketReceiveMessageType) => { | ||
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any, targetComponent: any) => { | 237 | const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any, targetComponent: any) => { |
| 238 | + props.chartConfig.option.queryCondition.timeRange=[targetComponent.requestParams.Params.startTs,targetComponent.requestParams.Params.endTs] | ||
| 238 | //联动支持分组 | 239 | //联动支持分组 |
| 239 | /** | 240 | /** |
| 240 | * 修复多个分组,然后下拉框联动,会影响另一个组件 | 241 | * 修复多个分组,然后下拉框联动,会影响另一个组件 |
| @@ -12,7 +12,7 @@ export type dataJsonType = typeof dataJson //data.json类型 | @@ -12,7 +12,7 @@ export type dataJsonType = typeof dataJson //data.json类型 | ||
| 12 | export type dataJsonMarkersType = typeof dataJson.markers[number] //data.json markers类型 | 12 | export type dataJsonMarkersType = typeof dataJson.markers[number] //data.json markers类型 |
| 13 | 13 | ||
| 14 | //标注数据格式 | 14 | //标注数据格式 |
| 15 | -export const fileterDevice = (items: any) => { | 15 | +export const filterDevice = (items: any) => { |
| 16 | const values = items.reduce((acc: any, curr: any) => { | 16 | const values = items.reduce((acc: any, curr: any) => { |
| 17 | acc.push({ | 17 | acc.push({ |
| 18 | name: curr.alias, | 18 | name: curr.alias, |
| @@ -88,6 +88,10 @@ export const option = { | @@ -88,6 +88,10 @@ export const option = { | ||
| 88 | amapLon: 104.108689, | 88 | amapLon: 104.108689, |
| 89 | amapLat: 30.66176, | 89 | amapLat: 30.66176, |
| 90 | amapZindex: 11, | 90 | amapZindex: 11, |
| 91 | + typeMarker: '', | ||
| 92 | + mpBorderConfig: { | ||
| 93 | + value: 'Border01', | ||
| 94 | + }, | ||
| 91 | marker: { | 95 | marker: { |
| 92 | fillColor: '#E98984FF', | 96 | fillColor: '#E98984FF', |
| 93 | fillOpacity: 0.5, | 97 | fillOpacity: 0.5, |
| @@ -71,19 +71,64 @@ | @@ -71,19 +71,64 @@ | ||
| 71 | <setting-item name="类型"> | 71 | <setting-item name="类型"> |
| 72 | <n-select size="small" v-model:value="optionData.mapOptions.mapMarkerType" :options="MarkerOptions" /> | 72 | <n-select size="small" v-model:value="optionData.mapOptions.mapMarkerType" :options="MarkerOptions" /> |
| 73 | </setting-item> | 73 | </setting-item> |
| 74 | - <setting-item name="颜色"> | 74 | + <setting-item v-if="optionData.mapOptions.mapMarkerType === MarkerEnum.CIRCLE_MARKER" name="颜色"> |
| 75 | <n-color-picker v-model:value="optionData.mapOptions.marker.fillColor" size="small"></n-color-picker> | 75 | <n-color-picker v-model:value="optionData.mapOptions.marker.fillColor" size="small"></n-color-picker> |
| 76 | </setting-item> | 76 | </setting-item> |
| 77 | </setting-item-box> | 77 | </setting-item-box> |
| 78 | + <setting-item-box name="图标选择" v-if="optionData.mapOptions.mapMarkerType === MarkerEnum.MARKER"> | ||
| 79 | + <setting-item name="图标选择"> | ||
| 80 | + <NSelect | ||
| 81 | + size="small" | ||
| 82 | + placeholder="请选择您要使用的图标" | ||
| 83 | + style="width: 250px" | ||
| 84 | + :value="typeMarkerValue" | ||
| 85 | + :options="typeMarkerOptions" | ||
| 86 | + :render-label="renderOption" | ||
| 87 | + clearable | ||
| 88 | + filterable | ||
| 89 | + @update:value="selectHandle" | ||
| 90 | + /> | ||
| 91 | + </setting-item> | ||
| 92 | + </setting-item-box> | ||
| 93 | + <setting-item-box name="弹窗选择" v-if="optionData.mapOptions.mapMarkerType === MarkerEnum.MARKER"> | ||
| 94 | + <setting-item name="弹窗选择"> | ||
| 95 | + <!-- <NSelect | ||
| 96 | + size="small" | ||
| 97 | + placeholder="请选择您要使用的弹窗" | ||
| 98 | + style="width: 250px" | ||
| 99 | + :value="mapSelectBorderValue" | ||
| 100 | + :options="mapSelectBorderOption.option" | ||
| 101 | + @update:value="mapSelectBorderHandle" | ||
| 102 | + clearable | ||
| 103 | + filterable | ||
| 104 | + /> --> | ||
| 105 | + <NSelect | ||
| 106 | + size="small" | ||
| 107 | + placeholder="请选择您要使用的弹窗" | ||
| 108 | + style="width: 250px" | ||
| 109 | + :value="mapSelectBorderValue" | ||
| 110 | + :options="mapBorderOptions" | ||
| 111 | + :render-label="renderMapBorderOption" | ||
| 112 | + clearable | ||
| 113 | + filterable | ||
| 114 | + @update:value="selectMapBorderHandle" | ||
| 115 | + /> | ||
| 116 | + </setting-item> | ||
| 117 | + </setting-item-box> | ||
| 78 | </collapse-item> | 118 | </collapse-item> |
| 79 | </template> | 119 | </template> |
| 80 | 120 | ||
| 81 | <script setup lang="ts"> | 121 | <script setup lang="ts"> |
| 82 | -import { PropType } from 'vue' | 122 | +import { PropType, ref, computed, h, onMounted, reactive } from 'vue' |
| 83 | import { option, MarkerEnum, ThemeEnum, LangEnum, ViewModeEnum, FeaturesEnum } from './config' | 123 | import { option, MarkerEnum, ThemeEnum, LangEnum, ViewModeEnum, FeaturesEnum } from './config' |
| 84 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | 124 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' |
| 125 | +import { NEllipsis, NImage, NSelect, NSpace, SelectOption } from 'naive-ui' | ||
| 85 | 126 | ||
| 86 | -defineProps({ | 127 | +interface BaseSelectBorderIF extends SelectOption { |
| 128 | + config?: string | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +const props = defineProps({ | ||
| 87 | optionData: { | 132 | optionData: { |
| 88 | type: Object as PropType<typeof option>, | 133 | type: Object as PropType<typeof option>, |
| 89 | required: true | 134 | required: true |
| @@ -187,10 +232,10 @@ const featuresOptions = [ | @@ -187,10 +232,10 @@ const featuresOptions = [ | ||
| 187 | ] | 232 | ] |
| 188 | 233 | ||
| 189 | const MarkerOptions = [ | 234 | const MarkerOptions = [ |
| 190 | - { | ||
| 191 | - value: MarkerEnum.CIRCLE_MARKER, | ||
| 192 | - label: '圆形标点' | ||
| 193 | - }, | 235 | + // { |
| 236 | + // value: MarkerEnum.CIRCLE_MARKER, | ||
| 237 | + // label: '圆形标点' | ||
| 238 | + // }, | ||
| 194 | { | 239 | { |
| 195 | value: MarkerEnum.MARKER, | 240 | value: MarkerEnum.MARKER, |
| 196 | label: '定位标点' | 241 | label: '定位标点' |
| @@ -200,4 +245,101 @@ const MarkerOptions = [ | @@ -200,4 +245,101 @@ const MarkerOptions = [ | ||
| 200 | label: '隐藏标点' | 245 | label: '隐藏标点' |
| 201 | } | 246 | } |
| 202 | ] | 247 | ] |
| 248 | + | ||
| 249 | +onMounted(() => { | ||
| 250 | + props.optionData.mapOptions.typeMarker = getMarkerImagePath(props.optionData.mapOptions.typeMarker || 'position1.png') | ||
| 251 | + typeMarkerValue.value = props.optionData.mapOptions.typeMarker || 'position1.png' | ||
| 252 | + mapSelectBorderValue.value = | ||
| 253 | + `${props.optionData.mapOptions.mpBorderConfig.value.toLocaleLowerCase()}.png` || 'border01.png' | ||
| 254 | +}) | ||
| 255 | + | ||
| 256 | +const typeMarkerValue = ref<string | null>('position1.png') | ||
| 257 | + | ||
| 258 | +const mapSelectBorderValue = ref<string | null>('border01.png') | ||
| 259 | + | ||
| 260 | +const isHref = (url: string) => { | ||
| 261 | + try { | ||
| 262 | + new URL(url) | ||
| 263 | + return true | ||
| 264 | + } catch (error) { | ||
| 265 | + return false | ||
| 266 | + } | ||
| 267 | +} | ||
| 268 | + | ||
| 269 | +// import.meta.glob 这个不能封装,必须是字符串,不能通过传值传进去 | ||
| 270 | +const typeMarkerOptions = computed(() => { | ||
| 271 | + const pathList = import.meta.glob('./images/marker/*') | ||
| 272 | + return Object.keys(pathList).map(item => { | ||
| 273 | + const imgName = item.split('/').at(-1) | ||
| 274 | + return { | ||
| 275 | + label: imgName, | ||
| 276 | + value: imgName | ||
| 277 | + } as SelectOption | ||
| 278 | + }) | ||
| 279 | +}) | ||
| 280 | +// | ||
| 281 | + | ||
| 282 | +const getMarkerImagePath = (name: string) => { | ||
| 283 | + return isHref(name) ? name : new URL(`./images/marker/${name}`, import.meta.url).href | ||
| 284 | +} | ||
| 285 | + | ||
| 286 | +const renderOption = (option: SelectOption) => { | ||
| 287 | + return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [ | ||
| 288 | + h(NImage, { | ||
| 289 | + width: 25, | ||
| 290 | + src: getMarkerImagePath(option.value as string), | ||
| 291 | + previewDisabled: true, | ||
| 292 | + style: { height: '25px' } | ||
| 293 | + } as Recordable), | ||
| 294 | + h(NEllipsis, null, () => option.label) | ||
| 295 | + ]) | ||
| 296 | +} | ||
| 297 | + | ||
| 298 | +const selectHandle = (value: string) => { | ||
| 299 | + typeMarkerValue.value = value | ||
| 300 | + props.optionData.mapOptions.typeMarker = getMarkerImagePath(value) | ||
| 301 | +} | ||
| 302 | + | ||
| 303 | +const needBorder = ['border01.png', 'border02.png', 'border03.png', 'border05.png', 'border07.png'] | ||
| 304 | + | ||
| 305 | +// import.meta.glob 这个不能封装,必须是字符串,不能通过传值传进去 | ||
| 306 | +const mapBorderOptions = computed(() => { | ||
| 307 | + const pathList = import.meta.glob('../../../../../../assets/images/chart/decorates/*') | ||
| 308 | + return Object.keys(pathList) | ||
| 309 | + .map(item => { | ||
| 310 | + const imgName = item.split('/').at(-1) as string | ||
| 311 | + if (needBorder.includes(imgName)) { | ||
| 312 | + return { | ||
| 313 | + label: imgName, | ||
| 314 | + value: imgName | ||
| 315 | + } as SelectOption | ||
| 316 | + } | ||
| 317 | + }) | ||
| 318 | + .filter(Boolean) as SelectOption[] | ||
| 319 | +}) | ||
| 320 | +// | ||
| 321 | + | ||
| 322 | +const getMapBorderImagePath = (name: string) => { | ||
| 323 | + return isHref(name) ? name : new URL(`../../../../../../assets/images/chart/decorates/${name}`, import.meta.url).href | ||
| 324 | +} | ||
| 325 | + | ||
| 326 | +const renderMapBorderOption = (option: SelectOption) => { | ||
| 327 | + return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [ | ||
| 328 | + h(NImage, { | ||
| 329 | + width: 25, | ||
| 330 | + src: getMapBorderImagePath(option.value as string), | ||
| 331 | + previewDisabled: true, | ||
| 332 | + style: { height: '25px' } | ||
| 333 | + } as Recordable), | ||
| 334 | + h(NEllipsis, null, () => option.label) | ||
| 335 | + ]) | ||
| 336 | +} | ||
| 337 | + | ||
| 338 | +const selectMapBorderHandle = (value: string) => { | ||
| 339 | + mapSelectBorderValue.value = value | ||
| 340 | + const toLowerValue = value.toLocaleLowerCase() | ||
| 341 | + ;(props.optionData.mapOptions.mpBorderConfig as BaseSelectBorderIF) = { | ||
| 342 | + value: toLowerValue[0]?.toUpperCase() + toLowerValue?.substr(1)?.split('.')[0] | ||
| 343 | + } | ||
| 344 | +} | ||
| 203 | </script> | 345 | </script> |
| 1 | { | 1 | { |
| 2 | "markers": [ | 2 | "markers": [ |
| 3 | { | 3 | { |
| 4 | - "name": "模拟11111111111", | 4 | + "name": "模拟数据1", |
| 5 | "value": 20, | 5 | "value": 20, |
| 6 | "position": [103.856504, 30.687278], | 6 | "position": [103.856504, 30.687278], |
| 7 | "extraInfo": { | 7 | "extraInfo": { |
| 8 | "tbDeviceId": "@xxxxxxxxxxx", | 8 | "tbDeviceId": "@xxxxxxxxxxx", |
| 9 | - "name": "模拟11111111111", | ||
| 10 | - "alias": "模拟11111111111", | 9 | + "name": "模拟数据1", |
| 10 | + "alias": "模拟数据1", | ||
| 11 | "organizationDTO": { | 11 | "organizationDTO": { |
| 12 | - "name": "模拟11111111111" | 12 | + "name": "模拟数据1" |
| 13 | }, | 13 | }, |
| 14 | "deviceState": "INACTIVE", | 14 | "deviceState": "INACTIVE", |
| 15 | "deviceProfile": { | 15 | "deviceProfile": { |
| @@ -23,15 +23,15 @@ | @@ -23,15 +23,15 @@ | ||
| 23 | } | 23 | } |
| 24 | }, | 24 | }, |
| 25 | { | 25 | { |
| 26 | - "name": "模拟22222222222", | 26 | + "name": "模拟数据2", |
| 27 | "value": 30, | 27 | "value": 30, |
| 28 | "position": [104.095368, 30.716787], | 28 | "position": [104.095368, 30.716787], |
| 29 | "extraInfo": { | 29 | "extraInfo": { |
| 30 | "tbDeviceId": "@xxxxxxxxxxxxxxx", | 30 | "tbDeviceId": "@xxxxxxxxxxxxxxx", |
| 31 | - "name": "模拟22222222222", | ||
| 32 | - "alias": "模拟22222222222", | 31 | + "name": "模拟数据2", |
| 32 | + "alias": "模拟数据2", | ||
| 33 | "organizationDTO": { | 33 | "organizationDTO": { |
| 34 | - "name": "模拟22222222222" | 34 | + "name": "模拟数据2" |
| 35 | }, | 35 | }, |
| 36 | "deviceState": "INACTIVE", | 36 | "deviceState": "INACTIVE", |
| 37 | "deviceProfile": { | 37 | "deviceProfile": { |
1.24 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position10.png
0 → 100644
1.2 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position11.png
0 → 100644
1.12 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position12.png
0 → 100644
1.93 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position13.png
0 → 100644
1.43 KB
1.4 KB
904 Bytes
1.02 KB
970 Bytes
1.51 KB
1.3 KB
897 Bytes
1.61 KB
| @@ -6,16 +6,17 @@ | @@ -6,16 +6,17 @@ | ||
| 6 | </template> | 6 | </template> |
| 7 | 7 | ||
| 8 | <script setup lang="ts"> | 8 | <script setup lang="ts"> |
| 9 | -import { ref, PropType, toRefs, watch } from 'vue' | 9 | +import { ref, PropType, toRefs, watch, render, h } from 'vue' |
| 10 | import AMapLoader from '@amap/amap-jsapi-loader' | 10 | import AMapLoader from '@amap/amap-jsapi-loader' |
| 11 | import { CreateComponentType } from '@/packages/index.d' | 11 | import { CreateComponentType } from '@/packages/index.d' |
| 12 | import { useChartDataFetch } from '@/hooks' | 12 | import { useChartDataFetch } from '@/hooks' |
| 13 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | 13 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' |
| 14 | -import { MarkerEnum, ThemeEnum, dataExtraInfoType, dataJsonType, dataJsonMarkersType, fileterDevice } from './config' | 14 | +import { MarkerEnum, ThemeEnum, dataExtraInfoType, dataJsonType, dataJsonMarkersType, filterDevice } from './config' |
| 15 | import { isArray } from '@/utils' | 15 | import { isArray } from '@/utils' |
| 16 | import djh from './images/djh.png' | 16 | import djh from './images/djh.png' |
| 17 | import online from './images/online.png' | 17 | import online from './images/online.png' |
| 18 | import lx1 from './images/lx1.png' | 18 | import lx1 from './images/lx1.png' |
| 19 | +import positionImg from './images/marker/position1.png' | ||
| 19 | import { getDeviceActiveTime, getDeviceList } from '@/api/external/common/index' | 20 | import { getDeviceActiveTime, getDeviceList } from '@/api/external/common/index' |
| 20 | import dayjs from 'dayjs' | 21 | import dayjs from 'dayjs' |
| 21 | import SearchBox from './components/SearchBox.vue' | 22 | import SearchBox from './components/SearchBox.vue' |
| @@ -44,7 +45,9 @@ let { | @@ -44,7 +45,9 @@ let { | ||
| 44 | viewMode, | 45 | viewMode, |
| 45 | pitch, | 46 | pitch, |
| 46 | skyColor, | 47 | skyColor, |
| 47 | - marker | 48 | + marker, |
| 49 | + typeMarker, | ||
| 50 | + mpBorderConfig | ||
| 48 | } = toRefs(props.chartConfig.option.mapOptions) | 51 | } = toRefs(props.chartConfig.option.mapOptions) |
| 49 | 52 | ||
| 50 | //官方没有高德地图api的ts,所以类型全用的any | 53 | //官方没有高德地图api的ts,所以类型全用的any |
| @@ -84,8 +87,7 @@ const initMap = (newData: any) => { | @@ -84,8 +87,7 @@ const initMap = (newData: any) => { | ||
| 84 | `amap://styles/${amapStyleKeyCustom.value !== '' ? amapStyleKeyCustom.value : amapStyleKey.value}` | 87 | `amap://styles/${amapStyleKeyCustom.value !== '' ? amapStyleKeyCustom.value : amapStyleKey.value}` |
| 85 | ) | 88 | ) |
| 86 | } | 89 | } |
| 87 | - //点击地图任意地方关闭infoWindow窗体 | ||
| 88 | - mapIns.on('click', () => { | 90 | + mapIns.on('mouseout', () => { |
| 89 | mapIns.clearInfoWindow() | 91 | mapIns.clearInfoWindow() |
| 90 | }) | 92 | }) |
| 91 | }) | 93 | }) |
| @@ -102,26 +104,38 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => { | @@ -102,26 +104,38 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => { | ||
| 102 | const res = await getDeviceActiveTime(tbDeviceId) //查询设备最后离线时间 | 104 | const res = await getDeviceActiveTime(tbDeviceId) //查询设备最后离线时间 |
| 103 | let { lastUpdateTs } = res[0] | 105 | let { lastUpdateTs } = res[0] |
| 104 | const lastUpdateFormatTs = dayjs(lastUpdateTs).format('YYYY-MM-DD HH:mm:ss') | 106 | const lastUpdateFormatTs = dayjs(lastUpdateTs).format('YYYY-MM-DD HH:mm:ss') |
| 107 | + //render方式渲染小组件里的边框组件 | ||
| 108 | + const BorderInstance = await import(`../../../../Decorates/Borders/${mpBorderConfig.value.value}/index.vue`) | ||
| 109 | + const config = await import(`../../../../Decorates/Borders/${mpBorderConfig.value.value}/config.ts`) | ||
| 110 | + const BorderConfigInstance = new config.default() | ||
| 111 | + const id = Date.now().toString() | ||
| 112 | + setTimeout(() => { | ||
| 113 | + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
| 114 | + render(h(BorderInstance.default, { chartConfig: BorderConfigInstance }), document.getElementById(id)!) | ||
| 115 | + }, 100) | ||
| 116 | + // | ||
| 105 | return ` | 117 | return ` |
| 106 | - <div style="width:15vw;height:18vh;background-color:white;"> | ||
| 107 | - <div style="margin:0px 10px"> | 118 | + <div id="${id}" style="width:25vw;height:29vh;position:relative;top:30px;"> |
| 119 | + <div style="position: absolute;top: 52px;left: 105px;"> | ||
| 108 | <div style="display:flex;justify-content:space-between; margin:20px 0px;"> | 120 | <div style="display:flex;justify-content:space-between; margin:20px 0px;"> |
| 109 | - <div style="font-size:16px;font-weight:bold">${alias || name}</div> | 121 | + <div style="width:12vw;text-overflow: ellipsis;overflow: hidden; word-break: break-all;white-space: nowrap;font-size:18px;font-weight:bold;color:white">${ |
| 122 | + alias || name | ||
| 123 | + }</div> | ||
| 110 | ${ | 124 | ${ |
| 111 | deviceState === 'INACTIVE' | 125 | deviceState === 'INACTIVE' |
| 112 | - ? `<div style="display:flex;align-items:center;"><img style="width:15px;height:15px" src="${djh}" class="mr-1">待激活</div>` | 126 | + ? `<div style="display:flex;align-items:center;color:#999999"><img style="width:15px;height:15px;margin-right:5px" src="${djh}">待激活</div>` |
| 113 | : deviceState === 'ONLINE' | 127 | : deviceState === 'ONLINE' |
| 114 | - ? `<div style="display:flex;align-items:center; "> | ||
| 115 | - <img style="width:15px;height:15px" src="${online}" class="mr-1">在线</div>` | ||
| 116 | - : `<div style="display:flex;align-items:center;"><img style="width:15px;height:15px" src="${lx1}" class="mr-1">离线</div>` | 128 | + ? `<div style="display:flex;align-items:center;color:green"> |
| 129 | + <img style="width:15px;height:15px;margin-right:5px" src="${online}" class="mr-1">在线</div>` | ||
| 130 | + : `<div style="display:flex;align-items:center;color:#F5222D"><img style="width:15px;height:15px;margin-right:5px" src="${lx1}">离线</div>` | ||
| 117 | } | 131 | } |
| 118 | </div> | 132 | </div> |
| 119 | - <div>所属组织:${organizationDTO.name}</div> | ||
| 120 | - <div style="margin-top:6px;">接入协议:${deviceProfile.transportType}</div> | ||
| 121 | - <div style="margin-top:6px;"> | 133 | + <div style="color:white;">所属组织:${organizationDTO.name}</div> |
| 134 | + <div style="margin-top:6px;color:white">接入协议:${deviceProfile.transportType}</div> | ||
| 135 | + <div style="margin-top:6px;color:white"> | ||
| 122 | 设备位置:${!deviceInfo.address ? '该设备暂无地理位置' : deviceInfo.address} | 136 | 设备位置:${!deviceInfo.address ? '该设备暂无地理位置' : deviceInfo.address} |
| 123 | </div> | 137 | </div> |
| 124 | - <div style="margin-top:6px;"> | 138 | + <div style="margin-top:6px;color:white"> |
| 125 | ${ | 139 | ${ |
| 126 | deviceState === 'ONLINE' ? '在线' : deviceState === 'INACTIVE' ? '创建' : '离线' | 140 | deviceState === 'ONLINE' ? '在线' : deviceState === 'INACTIVE' ? '创建' : '离线' |
| 127 | }时间:${lastUpdateFormatTs} | 141 | }时间:${lastUpdateFormatTs} |
| @@ -145,7 +159,7 @@ const handleCloseDrawer = () => (modelShow.value = false) | @@ -145,7 +159,7 @@ const handleCloseDrawer = () => (modelShow.value = false) | ||
| 145 | const handleSearchParams = async (searchPage: any, params: any) => { | 159 | const handleSearchParams = async (searchPage: any, params: any) => { |
| 146 | try { | 160 | try { |
| 147 | const { items } = await getDeviceList(searchPage, params) | 161 | const { items } = await getDeviceList(searchPage, params) |
| 148 | - const values = fileterDevice(items) | 162 | + const values = filterDevice(items) |
| 149 | if (!values) return | 163 | if (!values) return |
| 150 | dataHandle(values) | 164 | dataHandle(values) |
| 151 | } finally { | 165 | } finally { |
| @@ -153,22 +167,23 @@ const handleSearchParams = async (searchPage: any, params: any) => { | @@ -153,22 +167,23 @@ const handleSearchParams = async (searchPage: any, params: any) => { | ||
| 153 | } | 167 | } |
| 154 | } | 168 | } |
| 155 | 169 | ||
| 156 | -//地图点击 | 170 | +//地图鼠标hover |
| 157 | const mapClick = (markerInstance: any, markerItem: dataJsonMarkersType) => { | 171 | const mapClick = (markerInstance: any, markerItem: dataJsonMarkersType) => { |
| 158 | markerInstance.setExtData({ | 172 | markerInstance.setExtData({ |
| 159 | extraInfo: markerItem.extraInfo | 173 | extraInfo: markerItem.extraInfo |
| 160 | }) | 174 | }) |
| 161 | - markerInstance.setLabel({ | ||
| 162 | - content: markerItem.extraInfo.alias || markerItem.extraInfo.name | ||
| 163 | - }) | ||
| 164 | - markerInstance.on('click', async (e: any) => { | 175 | + markerInstance.on('mouseover', async (e: any) => { |
| 165 | const { extraInfo } = e.target.getExtData() | 176 | const { extraInfo } = e.target.getExtData() |
| 177 | + if (extraInfo.tbDeviceId.startsWith('@')) return //假的模拟数据则终止弹窗 | ||
| 166 | let infoWindow = new AMapIns.InfoWindow({ | 178 | let infoWindow = new AMapIns.InfoWindow({ |
| 167 | content: await createInfoWindow(extraInfo), | 179 | content: await createInfoWindow(extraInfo), |
| 168 | - offset: new AMapIns.Pixel(0, -50) | 180 | + offset: new AMapIns.Pixel(3, -30) |
| 169 | }) | 181 | }) |
| 170 | infoWindow.open(mapIns, e.target.getPosition()) | 182 | infoWindow.open(mapIns, e.target.getPosition()) |
| 171 | }) | 183 | }) |
| 184 | + markerInstance.on('mouseout', () => { | ||
| 185 | + mapIns.clearInfoWindow() | ||
| 186 | + }) | ||
| 172 | } | 187 | } |
| 173 | 188 | ||
| 174 | const dataHandle = (newData: dataJsonType) => { | 189 | const dataHandle = (newData: dataJsonType) => { |
| @@ -185,7 +200,8 @@ const dataHandle = (newData: dataJsonType) => { | @@ -185,7 +200,8 @@ const dataHandle = (newData: dataJsonType) => { | ||
| 185 | newData.markers.forEach((markerItem: dataJsonMarkersType) => { | 200 | newData.markers.forEach((markerItem: dataJsonMarkersType) => { |
| 186 | const markerInstance = new AMapIns.Marker({ | 201 | const markerInstance = new AMapIns.Marker({ |
| 187 | position: [markerItem.position[0], markerItem.position[1]], | 202 | position: [markerItem.position[0], markerItem.position[1]], |
| 188 | - offset: new AMapIns.Pixel(-13, -30) | 203 | + offset: new AMapIns.Pixel(-13, -30), |
| 204 | + icon: typeMarker.value || positionImg | ||
| 189 | }) | 205 | }) |
| 190 | // markers.push(markerInstance) 原作者这种方式添加,属于JS API 1.4.8版本的 | 206 | // markers.push(markerInstance) 原作者这种方式添加,属于JS API 1.4.8版本的 |
| 191 | // markerInstance.setMap(mapIns) | 207 | // markerInstance.setMap(mapIns) |
| @@ -243,6 +259,29 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { | @@ -243,6 +259,29 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { | ||
| 243 | }) | 259 | }) |
| 244 | </script> | 260 | </script> |
| 245 | 261 | ||
| 262 | +<style> | ||
| 263 | +.amap-info-outer { | ||
| 264 | + background-color: rgba(0, 0, 0, 0) !important; | ||
| 265 | +} | ||
| 266 | +.amap-info-close { | ||
| 267 | + display: none !important; | ||
| 268 | +} | ||
| 269 | +.amap-info-content { | ||
| 270 | + overflow: hidden !important; | ||
| 271 | +} | ||
| 272 | +.amap-info-content .go-border-box { | ||
| 273 | + position: absolute; | ||
| 274 | + transform: scale(0.7); | ||
| 275 | + top: -10px; | ||
| 276 | + /* opacity: 0,8; */ | ||
| 277 | + /* background-color: rgba(0, 0, 0, 0.1); */ | ||
| 278 | + background-color:rgba(255,255,255,0.1) | ||
| 279 | +} | ||
| 280 | +.amap-info-content .go-border-box svg { | ||
| 281 | + /* background-color: rgba(0, 0, 0, 0.1); */ | ||
| 282 | + /* background-color: rgba(255, 255, 255, 0.8); */ | ||
| 283 | +} | ||
| 284 | +</style> | ||
| 246 | <style lang="scss" scoped> | 285 | <style lang="scss" scoped> |
| 247 | .chart-amap { | 286 | .chart-amap { |
| 248 | position: relative; | 287 | position: relative; |
| @@ -82,7 +82,9 @@ import { fetchConfigComponent, fetchChartComponent } from '@/packages/index' | @@ -82,7 +82,9 @@ import { fetchConfigComponent, fetchChartComponent } from '@/packages/index' | ||
| 82 | import { componentInstall, loadingStart, loadingFinish, loadingError } from '@/utils' | 82 | import { componentInstall, loadingStart, loadingFinish, loadingError } from '@/utils' |
| 83 | import { ChartGlobImage } from '@/components/Pages/ChartGlobImage' | 83 | import { ChartGlobImage } from '@/components/Pages/ChartGlobImage' |
| 84 | import { Icon } from '@iconify/vue' | 84 | import { Icon } from '@iconify/vue' |
| 85 | - | 85 | +// THINGS_KIT 修改搜索未过滤隐藏的组件 |
| 86 | +import { hideAsideComponentsObj } from '../../external/components/ChartsOptionContent/config' | ||
| 87 | +// | ||
| 86 | const props = defineProps({ | 88 | const props = defineProps({ |
| 87 | menuOptions: { | 89 | menuOptions: { |
| 88 | type: Array, | 90 | type: Array, |
| @@ -136,6 +138,9 @@ const searchHandle = (key: string | null) => { | @@ -136,6 +138,9 @@ const searchHandle = (key: string | null) => { | ||
| 136 | searchRes.value = List.filter( | 138 | searchRes.value = List.filter( |
| 137 | (e: ConfigType) => !e.disabled && (!key || e.title.toLowerCase().includes(key.toLowerCase())) | 139 | (e: ConfigType) => !e.disabled && (!key || e.title.toLowerCase().includes(key.toLowerCase())) |
| 138 | ) | 140 | ) |
| 141 | + // THINGS_KIT 修改搜索未过滤隐藏的组件 | ||
| 142 | + searchRes.value = searchRes.value.filter((e: ConfigType) =>!hideAsideComponentsObj['all'].includes(e.chartKey)) | ||
| 143 | + // | ||
| 139 | setTimeout(() => { | 144 | setTimeout(() => { |
| 140 | loading.value = undefined | 145 | loading.value = undefined |
| 141 | }, 500) | 146 | }, 500) |