Commit 451a739352a9e336d63b361553915245ffb76f32
1 parent
83f72c07
perf: device location show all devcie marker point && add alarm effect
Showing
1 changed file
with
146 additions
and
13 deletions
| ... | ... | @@ -86,6 +86,18 @@ |
| 86 | 86 | import { defaultSchemas } from './cpns/TimePeriodForm/config'; |
| 87 | 87 | import { QueryWay, SchemaFiled, AggregateDataEnum } from './cpns/TimePeriodForm/config'; |
| 88 | 88 | import { dateUtil } from '/@/utils/dateUtil'; |
| 89 | + | |
| 90 | + interface DeviceInfo { | |
| 91 | + alarmStatus: 0 | 1; | |
| 92 | + deviceState: string; | |
| 93 | + tbDeviceId: string; | |
| 94 | + name: string; | |
| 95 | + organizationDTO: { name: string }; | |
| 96 | + deviceProfile: { default: boolean; enabled: boolean; name: string; transportType: string }; | |
| 97 | + deviceInfo: { longitude: string; latitude: string; address: string }; | |
| 98 | + } | |
| 99 | + type MarkerList = DeviceInfo & { marker: any }; | |
| 100 | + | |
| 89 | 101 | export default defineComponent({ |
| 90 | 102 | name: 'BaiduMap', |
| 91 | 103 | components: { |
| ... | ... | @@ -118,6 +130,8 @@ |
| 118 | 130 | const { toPromise } = useScript({ src: BAI_DU_MAP_URL }); |
| 119 | 131 | const [registerDetailDrawer, { openDrawer }] = useDrawer(); |
| 120 | 132 | const [registerModal, { openModal }] = useModal(); |
| 133 | + const BMapInstance = ref<Nullable<any>>(null); | |
| 134 | + | |
| 121 | 135 | const loading = ref(false); |
| 122 | 136 | |
| 123 | 137 | const [registerTable] = useTable({ |
| ... | ... | @@ -133,6 +147,39 @@ |
| 133 | 147 | pagination: { |
| 134 | 148 | showSizeChanger: false, |
| 135 | 149 | }, |
| 150 | + afterFetch: async (data: DeviceInfo[]) => { | |
| 151 | + const BMap = (window as any).BMap; | |
| 152 | + unref(BMapInstance).clearOverlays(); | |
| 153 | + const markerList: MarkerList[] = []; | |
| 154 | + data.forEach((item) => { | |
| 155 | + const { | |
| 156 | + deviceState, | |
| 157 | + deviceInfo: { longitude, latitude }, | |
| 158 | + } = item; | |
| 159 | + const point = new BMap.Point(longitude, latitude); | |
| 160 | + const rivet = deviceState === 'INACTIVE' ? djx : deviceState === 'ONLINE' ? zx : lx; | |
| 161 | + const myIcon = new BMap.Icon(rivet, new BMap.Size(20, 30)); | |
| 162 | + const marker = new BMap.Marker(point, { icon: myIcon }); | |
| 163 | + markerList.push({ ...item, marker }); | |
| 164 | + }); | |
| 165 | + | |
| 166 | + markerList.forEach((record) => { | |
| 167 | + unref(BMapInstance).addOverlay(record.marker); | |
| 168 | + const isAlarmStatus = !!record.alarmStatus; | |
| 169 | + if (isAlarmStatus) { | |
| 170 | + const alarmStatusClassName = 'device-status__alarm'; | |
| 171 | + const className = record.marker.Ec.getAttribute('class'); | |
| 172 | + record.marker.Ec.setAttribute('class', `${className} ${alarmStatusClassName}`); | |
| 173 | + } | |
| 174 | + | |
| 175 | + //标注监听事件 | |
| 176 | + record.marker.addEventListener('click', function () { | |
| 177 | + createDeviceInfoWindow(record); | |
| 178 | + }); | |
| 179 | + }); | |
| 180 | + | |
| 181 | + return data; | |
| 182 | + }, | |
| 136 | 183 | }); |
| 137 | 184 | |
| 138 | 185 | async function initMap() { |
| ... | ... | @@ -141,24 +188,87 @@ |
| 141 | 188 | const wrapEl = unref(wrapRef); |
| 142 | 189 | const BMap = (window as any).BMap; |
| 143 | 190 | if (!wrapEl) return; |
| 144 | - const map = new BMap.Map(wrapEl); | |
| 191 | + BMapInstance.value = new BMap.Map(wrapEl); | |
| 145 | 192 | function myFun(result) { |
| 146 | 193 | let mk = new BMap.Marker(result.center); |
| 147 | - map.addOverlay(mk); | |
| 148 | - map.panTo(result.center); | |
| 149 | - map.centerAndZoom(result.center, 15); | |
| 150 | - map.enableScrollWheelZoom(true); | |
| 194 | + unref(BMapInstance).addOverlay(mk); | |
| 195 | + unref(BMapInstance).panTo(result.center); | |
| 196 | + unref(BMapInstance).centerAndZoom(result.center, 15); | |
| 197 | + unref(BMapInstance).enableScrollWheelZoom(true); | |
| 151 | 198 | } |
| 152 | 199 | let myCity = new BMap.LocalCity(); |
| 153 | 200 | myCity.get(myFun); |
| 154 | 201 | } |
| 202 | + | |
| 203 | + const createDeviceInfoWindow = async (record: DeviceInfo) => { | |
| 204 | + const BMap = (window as any).BMap; | |
| 205 | + entityId = record.tbDeviceId; | |
| 206 | + globalRecord = record; | |
| 207 | + try { | |
| 208 | + deviceAttrs.value = (await getDeviceDataKeys(entityId)) || []; | |
| 209 | + } catch (error) {} | |
| 210 | + | |
| 211 | + const options = { | |
| 212 | + width: 330, // 信息窗口宽度 | |
| 213 | + height: 0, // 信息窗口高度 | |
| 214 | + }; | |
| 215 | + const { name, organizationDTO, deviceState, deviceProfile } = record; | |
| 216 | + const { address, longitude, latitude } = record.deviceInfo; | |
| 217 | + // 创建信息窗口对象 | |
| 218 | + const res = await getDeviceActiveTime(entityId); | |
| 219 | + | |
| 220 | + let { lastUpdateTs } = res[0]; | |
| 221 | + lastUpdateTs = moment(lastUpdateTs).format('YYYY-MM-DD HH:mm:ss'); | |
| 222 | + let infoWindow = new BMap.InfoWindow( | |
| 223 | + ` | |
| 224 | + <div style="display:flex;justify-content:space-between; margin:20px 0px;"> | |
| 225 | + <div style="font-size:16px;font-weight:bold">${name}</div> | |
| 226 | + ${ | |
| 227 | + deviceState === 'INACTIVE' | |
| 228 | + ? `<div style="display:flex;align-items:center;"><img style="width:15px;height:15px" src="${djh}" class="mr-1">待激活</div>` | |
| 229 | + : deviceState === 'ONLINE' | |
| 230 | + ? `<div style="display:flex;align-items:center; "> | |
| 231 | + <img style="width:15px;height:15px" src="${online}" class="mr-1">在线</div>` | |
| 232 | + : `<div style="display:flex;align-items:center;"><img style="width:15px;height:15px" src="${lx1}" class="mr-1">离线</div>` | |
| 233 | + } | |
| 234 | + </div> | |
| 235 | + <div>所属组织:${organizationDTO.name}</div> | |
| 236 | + <div style="margin-top:6px;">接入协议:${deviceProfile.transportType}</div> | |
| 237 | + <div style="margin-top:6px;"> | |
| 238 | + 设备位置:${address == '' ? '该设备暂无地理位置' : address} | |
| 239 | + </div> | |
| 240 | + <div style="margin-top:6px;"> | |
| 241 | + ${ | |
| 242 | + deviceState === 'ONLINE' ? '在线' : deviceState === 'INACTIVE' ? '创建' : '离线' | |
| 243 | + }时间:${lastUpdateTs} | |
| 244 | + </div> | |
| 245 | + <div style="display:flex;justify-content:end; margin-top:10px"> | |
| 246 | + <button onclick="openDeviceInfoDrawer()" style="margin-right:10px;color:#fff;background-color:#409eff;padding:4px; border-radius:4px;">设备信息</button> | |
| 247 | + <button onclick="openHistoryModal()" style="color:#fff;background-color:#409eff;padding:4px; border-radius:4px;">历史数据</button> | |
| 248 | + </div> | |
| 249 | + `, | |
| 250 | + options | |
| 251 | + ); | |
| 252 | + | |
| 253 | + const point = new BMap.Point( | |
| 254 | + longitude || 104.04666605565338, | |
| 255 | + latitude || 30.543516387560476 | |
| 256 | + ); | |
| 257 | + | |
| 258 | + if (!longitude || !latitude) | |
| 259 | + infoWindow = new BMap.InfoWindow('该设备暂无地理位置', options); // 创建信息窗口对象 | |
| 260 | + unref(BMapInstance).centerAndZoom(point, 15); | |
| 261 | + unref(BMapInstance).openInfoWindow(infoWindow, unref(BMapInstance).getCenter()); | |
| 262 | + }; | |
| 155 | 263 | // 点击表格某一行触发 |
| 156 | 264 | const deviceRowClick = async (record) => { |
| 265 | + createDeviceInfoWindow(record); | |
| 266 | + return; | |
| 157 | 267 | entityId = record.tbDeviceId; |
| 158 | 268 | globalRecord = record; |
| 159 | 269 | const BMap = (window as any).BMap; |
| 160 | - const wrapEl = unref(wrapRef); | |
| 161 | - const map = new BMap.Map(wrapEl); | |
| 270 | + // const wrapEl = unref(wrapRef); | |
| 271 | + // const map = new BMap.Map(wrapEl); | |
| 162 | 272 | // if (record.deviceInfo.address) { |
| 163 | 273 | // keys = await getDeviceDataKeys(entityId); |
| 164 | 274 | try { |
| ... | ... | @@ -176,8 +286,8 @@ |
| 176 | 286 | width: 330, // 信息窗口宽度 |
| 177 | 287 | height: 0, // 信息窗口高度 |
| 178 | 288 | }; |
| 179 | - map.centerAndZoom(point, 15); | |
| 180 | - map.enableScrollWheelZoom(true); | |
| 289 | + unref(BMapInstance).centerAndZoom(point, 15); | |
| 290 | + unref(BMapInstance).enableScrollWheelZoom(true); | |
| 181 | 291 | // 创建信息窗口对象 |
| 182 | 292 | const res = await getDeviceActiveTime(entityId); |
| 183 | 293 | |
| ... | ... | @@ -212,20 +322,20 @@ |
| 212 | 322 | options |
| 213 | 323 | ); |
| 214 | 324 | |
| 215 | - map.openInfoWindow(infoWindow, map.getCenter()); | |
| 325 | + unref(BMapInstance).openInfoWindow(infoWindow, unref(BMapInstance).getCenter()); | |
| 216 | 326 | let preMarker = null; |
| 217 | 327 | |
| 218 | 328 | const rivet = deviceState === 'INACTIVE' ? djx : deviceState === 'ONLINE' ? zx : lx; |
| 219 | 329 | let myIcon = new BMap.Icon(rivet, new BMap.Size(20, 30)); |
| 220 | 330 | let marker = new BMap.Marker(point, { icon: myIcon }); |
| 221 | 331 | if (marker) { |
| 222 | - map.removeOverlay(preMarker); | |
| 332 | + unref(BMapInstance).removeOverlay(preMarker); | |
| 223 | 333 | } |
| 224 | - map.addOverlay(marker); | |
| 334 | + unref(BMapInstance).addOverlay(marker); | |
| 225 | 335 | //标注监听事件 |
| 226 | 336 | marker.addEventListener('click', function (e) { |
| 227 | 337 | const point = e.point; |
| 228 | - map.openInfoWindow(infoWindow, point); | |
| 338 | + unref(BMapInstance).openInfoWindow(infoWindow, point); | |
| 229 | 339 | }); |
| 230 | 340 | //标注监听事件 |
| 231 | 341 | // } else { |
| ... | ... | @@ -428,3 +538,26 @@ |
| 428 | 538 | background-color: #fff; |
| 429 | 539 | } |
| 430 | 540 | </style> |
| 541 | +<style> | |
| 542 | + .device-status__alarm { | |
| 543 | + transform-origin: 10px 15px; | |
| 544 | + animation: 0.5s linear 0s infinite alternate Scale; | |
| 545 | + } | |
| 546 | + | |
| 547 | + @keyframes Scale { | |
| 548 | + 0% { | |
| 549 | + /* transform: translateY(0px); */ | |
| 550 | + transform: scale(1); | |
| 551 | + } | |
| 552 | + | |
| 553 | + 50% { | |
| 554 | + /* transform: translateY(5px); */ | |
| 555 | + transform: scale(1.5); | |
| 556 | + } | |
| 557 | + | |
| 558 | + 100% { | |
| 559 | + /* transform: translateY(10px); */ | |
| 560 | + transform: scale(2); | |
| 561 | + } | |
| 562 | + } | |
| 563 | +</style> | ... | ... |