diff --git a/package.json b/package.json index 437fe99..11506a6 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@amap/amap-jsapi-loader": "^1.0.1", "axios": "^1.6.2", "dayjs": "^1.11.10", + "mitt": "^3.0.1", "path": "^0.12.7", "prettier": "^3.1.0", "vue": "^3.3.4", diff --git a/src/assets/img/alarm-icon.png b/src/assets/img/alarm-icon.png new file mode 100644 index 0000000..4433361 Binary files /dev/null and b/src/assets/img/alarm-icon.png differ diff --git a/src/assets/img/helicopter.png b/src/assets/img/helicopter.png index ad29083..cbd2166 100644 Binary files a/src/assets/img/helicopter.png and b/src/assets/img/helicopter.png differ diff --git a/src/assets/img/position.png b/src/assets/img/position.png new file mode 100644 index 0000000..b719a87 Binary files /dev/null and b/src/assets/img/position.png differ diff --git a/src/assets/less/index.less b/src/assets/less/index.less index de0a954..2bbc9d1 100644 --- a/src/assets/less/index.less +++ b/src/assets/less/index.less @@ -98,9 +98,34 @@ background-color: rgba(30, 115, 194, 0.3); } +//直升机 .helicopter { width: 60px; - height: 60px; + height: 37px; background: url("../img/helicopter.png") no-repeat; background-size: 100% 100%; + margin-bottom: 4px; +} + +//高德信息弹窗 +.amap-info-contentContainer { + .amap-content-body { + background: #00152B; + border: 1px solid #129BFF; + + .amap-lib-infowindow { + background: #00152B; + + .amap-lib-infowindow-title { + color: #fff; + border-bottom: 1px solid #129BFF; + padding: 4px 0; + } + + .amap-lib-infowindow-content { + color: #fff; + padding: 4px 0; + } + } + } } \ No newline at end of file diff --git a/src/assets/mapUtils/commonFun.ts b/src/assets/mapUtils/commonFun.ts index 8d05918..875fd0f 100644 --- a/src/assets/mapUtils/commonFun.ts +++ b/src/assets/mapUtils/commonFun.ts @@ -6,7 +6,7 @@ import { mapIcon1, mapIcon2, mapIcon3, mapIcon4 } from '/@/components/chinaMap/c export function createIcon({ icon, iconSize, imageSize }) { return new AMap.Icon({ // 图标尺寸 - size: new AMap.Size(21, 44), + size: new AMap.Size(...iconSize), // 图标的取图地址 image: icon, // 图标所用图片大小 @@ -19,8 +19,8 @@ export function createIcon({ icon, iconSize, imageSize }) { * @type 1:油田医院,2:合作医院,3:医疗点 */ export function typeToIcon(type: string) { - const iconSize = [21, 44]; - const imageSize = [21, 44]; + const iconSize = [18, 44]; + const imageSize = [18, 44]; if (type == '1') { return createIcon({ icon: mapIcon1, iconSize, imageSize }); } @@ -33,4 +33,27 @@ export function typeToIcon(type: string) { if (type == '4') { return createIcon({ icon: mapIcon3, iconSize, imageSize }); } +} + +/** + * + */ +export function createCircle(option) { + const { lon, lat } = option; + return new AMap.Circle({ + center: [lon, lat], + radius: 100000, //半径 + borderWeight: 3, + strokeColor: '#FF33FF', + strokeOpacity: 1, + // strokeWeight: 6, + strokeOpacity: 0.2, + fillOpacity: 0.4, + strokeStyle: 'dashed', + strokeDasharray: [10, 10], + // 线样式还支持 'dashed' + fillColor: '#1791fc', + zIndex: 50, + ...option, + }); } \ No newline at end of file diff --git a/src/assets/mapUtils/map.ts b/src/assets/mapUtils/map.ts index a130506..32a7968 100644 --- a/src/assets/mapUtils/map.ts +++ b/src/assets/mapUtils/map.ts @@ -1,19 +1,27 @@ import china from '/@/assets/lngLat/china.ts'; import chinaInner from '/@/assets/lngLat/chinaInner.ts'; -import { typeToIcon } from '/@/assets/mapUtils/commonFun.ts'; -import { helicopter, mapbg } from '/@/components/chinaMap/chinaHooks.ts'; +import { createCircle, createIcon, typeToIcon } from '/@/assets/mapUtils/commonFun.ts'; +import { aircraftContent, alarmIcon } from '/@/components/chinaMap/chinaHooks.ts'; export const defaultOption = { center: [106.3, 37.87], //地图中心点 zoom: 4.3, //地图显示的缩放级别 mapStyle: 'darkblue', //地图样式 }; -export const mapPlugin = ['AMap.ToolBar', 'AMap.Driving', 'AMap.GeoJSON', 'AMap.MarkerCluster']; +export const mapPlugin = ['AMap.ToolBar', 'AMap.Driving', 'AMap.GeoJSON', 'AMap.MarkerCluster', 'AMap.PlaceSearch']; export const Map = { map: null, overlayGroup: null, // 地图中marker - aircraftGroup: null, //直升机marker - cluster: null, + circleGroup: null, //直升机背景圆 + cluster: null, //直升机marker点聚合图层 + airMarkerList: [], //直升机markerList + placeSearch: null, //地点查询 + marker: null, // 健康终端报警 + /** + * @desc 地图舒适化 + * @param el dom元素 id选择器 + * @param option 地图配置 + */ initMap({ el, option }) { const { zoom, center, mapStyle } = { ...defaultOption, ...option }; //基本地图加载 @@ -29,7 +37,9 @@ export const Map = { this.drawOutLine(); }); }, - // 中国外层边界线 + /** + * @desc 中国外层边界线 + */ drawOutLine() { let geojson = new AMap.GeoJSON({ geoJSON: china, @@ -47,7 +57,9 @@ export const Map = { }); this.map.add(geojson); }, - // 中国内层边界线 + /** + * @desc 中国内层边界线 + */ drawInnerLine() { let geojson = new AMap.GeoJSON({ geoJSON: chinaInner, @@ -61,10 +73,25 @@ export const Map = { }); this.map.add(geojson); }, - // 创建覆盖物组,用于批量处理点 (控制显隐,点击事件等) - createOverlay(result) { + // 清空当前地图上除了边界线的覆盖物 + removeOverlayGroup() { this.clearAircraft(); this.clearOverlay(); + this.clearAirRange(); + if (this.airMarkerList.length > 0) { + for (let i = 0; i < this.airMarkerList.length; i++) { + this.airMarkerList[i].setMap(null); + } + } + // this.map.remove(this.airMarkerList); + }, + // + /** + * @desc 创建覆盖物组,用于批量处理点 (控制显隐,点击事件等) + * @param result + */ + createOverlay(result) { + this.removeOverlayGroup(); this.overlayGroup = new AMap.OverlayGroup(); for (let i = 0; i < result.length; i++) { let { type, lon, lat } = result[i]; @@ -100,130 +127,125 @@ export const Map = { clearOverlay() { if (this.overlayGroup) { this.map.remove(this.overlayGroup); + this.overlayGroup.setMap(null); this.overlayGroup = null; } }, - //创建直升机marker + /** + * @desc 创建直升机marker + * @param result + */ createAircraft(result) { - this.clearAircraft(); - this.clearOverlay(); - // this.aircraftGroup = new AMap.OverlayGroup(); + this.removeOverlayGroup(); + this.clearActiveHospital(); if (!Array.isArray(result) && result.length == 0) return; - const content = ` -
-
-
-
-
-
-
- 4009-120-999 -
-
-
- `; - const markers = []; - for (let i = 0; i < result.length; i++) { - let { lon, lat } = result[i]; - const marker = new AMap.Marker({ - // 点的坐标 - position: [lon, lat], - //启用点击事件 如果需要点击事件,必须开启 - clickable: true, - title: `4009-120-999`, - content: content, - offset: new AMap.Pixel(-16, -30), - }); - markers.push(marker); - } - - // //将组 挂载到地图上 - // this.aircraftGroup.setMap(this.map); - // //将需要批量控制的点放到一个组中,通过控制组,就可以操作组内所有所有覆盖物 - // this.aircraftGroup.addOverlay(markers); - - if (this.cluster) { - // this.cluster.setMap(null); - this.map.remove(this.cluster); - // this.cluster = null; - this.cluster.setMap(null); - } - //使用renderCluserMarker属性实现聚合点的完全自定义绘制 - let sts = [ - { - url: mapbg, - size: new AMap.Size(32, 32), - offset: new AMap.Pixel(-16, -30), - textColor: '#fff', - textSize: 20, - }, - ]; + this.createAirRange(result); let that = this; - let arr = result.map((item) => ({ weight: 4, lnglat: [item.lon, item.lat] })); + let arr = result.map((item) => ({ weight: 4, lnglat: [item.lon, item.lat], params: item.name })); let count = 4; this.cluster = new AMap.MarkerClusterer( that.map, // 地图实例 arr, { renderMarker: (context) => { - var factor = Math.pow(context.count / count, 1 / 18); - var div = document.createElement('div'); - var Hue = 180 - factor * 180; - var bgColor = 'hsla(' + Hue + ',100%,50%,0.7)'; - var fontColor = 'hsla(' + Hue + ',100%,20%,1)'; - var borderColor = 'hsla(' + Hue + ',100%,40%,1)'; - var shadowColor = 'hsla(' + Hue + ',100%,50%,1)'; - var size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20); + let factor = Math.pow(context.count / count, 1 / 18); + let div = document.createElement('div'); + div.className = 'render-air'; + let Hue = 180 - factor * 180; + let size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20); div.style.width = div.style.height = size + 'px'; - div.innerHTML = content || context.count; - div.style.lineHeight = size + 'px'; - div.style.color = fontColor; + div.innerHTML = aircraftContent() || context.count; + div.style.color = '#fff'; div.style.fontSize = '14px'; - div.style.textAlign = 'center'; context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2)); context.marker.setContent(div); + this.airMarkerList.push(context.marker); + context.marker.on('click', () => { + console.log('data', context); + }); }, } ); - console.log('xx', this.cluster); this.cluster.setMap(this.map); - this.getRange(result); }, clearAircraft() { - if (this.aircraftGroup) { - this.map.remove(this.aircraftGroup); - this.aircraftGroup = null; + if (this.cluster) { + this.map.remove(this.cluster); + this.cluster = null; } }, - getRange(list) { - //绘制飞机的范围图 - var array = new Array(list.length); - for (var i = 0; i < list.length; i++) { - var circle = new AMap.Circle({ - center: [list[i].lon, list[i].lat], - radius: 100000, //半径 - borderWeight: 3, - strokeColor: '#FF33FF', - strokeOpacity: 1, - strokeWeight: 6, - strokeOpacity: 0.2, - fillOpacity: 0.4, - strokeStyle: 'dashed', - strokeDasharray: [10, 10], - // 线样式还支持 'dashed' - fillColor: '#1791fc', - zIndex: 50, - }); - circle.setMap(this.map); - array.push(circle); + /** + * @desc 飞机范围 + * @param list + */ + createAirRange(list) { + this.removeOverlayGroup(); + this.circleGroup = new AMap.OverlayGroup(); + for (let i = 0; i < list.length; i++) { + let circle = createCircle({ lon: list[i].lon, lat: list[i].lat }); + this.circleGroup.setMap(this.map); + this.circleGroup.addOverlay(circle); + } + }, + clearAirRange() { + if (this.circleGroup) { + this.map.remove(this.circleGroup); + this.circleGroup = null; + } + }, + /** + * @desc 地方医院医疗点显示 + * @param cityCode 城市code + * @param keywords 搜索名称 + */ + createActiveHospital(cityCode: string, keywords = '医院') { + this.removeOverlayGroup(); + this.clearActiveHospital(); + if (!cityCode) return; + // AMap.plugin(['AMap.PlaceSearch'], () => { + // //构造地点查询类 + // + // }); + this.placeSearch = new AMap.PlaceSearch({ + pageSize: 30, // 单页显示结果条数 + pageIndex: 1, // 页码 + city: cityCode, // 兴趣点城市 + citylimit: true, //是否强制限制在设置的城市内搜索 + map: this.map, // 展现结果的地图实例 + // panel: 'map_hospital', // 结果列表将在此容器中进行展示。 + autoFitView: false, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围 + }); + //关键字查询 + this.placeSearch.search(keywords); + }, + clearActiveHospital() { + if (this.placeSearch) { + // debugger; + this.placeSearch.clear(); + this.placeSearch = null; + } + }, + createMarker(option) { + this.clearMarker(); + let { lon, lat, zoom = 12 } = option; + const icon = createIcon({ icon: alarmIcon, iconSize: [36, 42], imageSize: [36, 42] }); + this.marker = new AMap.Marker({ + position: [lon, lat], + icon: icon, + offset: new AMap.Pixel(0, 0), //设置偏移量 + // label: { + // content: labelContent, + // offset: labelOffset, + // }, + }); + this.map.add(this.marker); + this.map.setZoomAndCenter(zoom, [lon, lat]); + }, + clearMarker() { + if (this.marker) { + this.marker.setMap(null); + this.marker = null; } - return array; }, }; diff --git a/src/components/body-d-left/bodyLeftHooks.ts b/src/components/body-d-left/bodyLeftHooks.ts index 27833ff..eb9f132 100644 --- a/src/components/body-d-left/bodyLeftHooks.ts +++ b/src/components/body-d-left/bodyLeftHooks.ts @@ -1,6 +1,44 @@ import { ref } from 'vue'; import * as echarts from 'echarts'; +export function useStatistics() { + const statistics = ref([ + { + name: '最新呼入电话', + value: '', + key: 'gross', + }, + { + name: '最新受理电话', + value: '', + key: 'alerdyreceive', + }, + { + name: '突发重大伤病应急', + value: '', + key: 'jqqz', + }, + { + name: '重大伤病应急就医', + value: '', + key: 'dbjy', + }, + ]); + + function setStatistics(data = {}) { + statistics.value.forEach((item) => { + const { key } = item; + item.value = data[key]; + }); + console.log('fffffff', statistics.value); + } + + return { + statistics, + setStatistics, + }; +} + export const timeTab = [ { name: '全部', diff --git a/src/components/body-d-left/oneL.vue b/src/components/body-d-left/oneL.vue index d1d2854..af9cc6d 100644 --- a/src/components/body-d-left/oneL.vue +++ b/src/components/body-d-left/oneL.vue @@ -12,9 +12,9 @@ >
-
- {{ item?.title }} - {{ item?.gross }} +
+ {{ item?.name }} + {{ item?.value }}
@@ -25,10 +25,10 @@ import { onMounted, ref } from 'vue'; import PublicTitle from '../publicTitle.vue'; import { list } from './left.api'; - import { timeTab, useSpin } from '/@/components/body-d-left/bodyLeftHooks.ts'; + import { timeTab, useSpin, useStatistics } from '/@/components/body-d-left/bodyLeftHooks.ts'; const typeTime = ref(timeTab); - const dataLists = ref([]); + const { statistics, setStatistics } = useStatistics(); const selectIndex = ref(0); const selectVal = ref('1'); const { setSpin, spinning } = useSpin(); @@ -42,10 +42,10 @@ try { const { code, result } = (await list({ condition: selectVal.value })) || {}; setSpin(!spinning.value); - if (code != 200) { + if (code != 200 || !Array.isArray(result)) { return; } - dataLists.value = result?.map((item) => ({ ...item, title: '最新呼入电话' })); + setStatistics(result[0]); } catch { setSpin(!spinning.value); } @@ -70,10 +70,6 @@ overflow-y: auto; position: relative; - > :nth-child(1) { - padding-top: 0 !important; - } - .spin { position: absolute; left: 50%; @@ -100,7 +96,7 @@ } } - .server-item:nth-child(2n) { + .server-item:nth-child(odd) { background-color: #0a0a0c; } } diff --git a/src/components/body-d-right/oneR.vue b/src/components/body-d-right/oneR.vue index 76e6521..77322ac 100644 --- a/src/components/body-d-right/oneR.vue +++ b/src/components/body-d-right/oneR.vue @@ -4,11 +4,12 @@
- {{ item?.realName }} - {{ item?.eventType_dictText }} + {{ item?.realName }} + {{ item?.eventType_dictText }}
{{ item?.warnTime }} +
@@ -25,23 +26,23 @@
姓名: - {{ userInfo.name }} + {{ userInfo?.realName }}
二级单位: - {{ userInfo.unit }} + {{ userInfo?.orgName1 }}
手机号码: - {{ userInfo.iphone }} + {{ userInfo?.phone }}
异常事件: - {{ userInfo.abnormal }} + {{ userInfo?.eventType_dictText }}
发生时间: - {{ userInfo.time }} + {{ userInfo?.warnTime }}
发生地点: @@ -54,23 +55,24 @@ + \ No newline at end of file diff --git a/src/utils/bus.ts b/src/utils/bus.ts new file mode 100644 index 0000000..5dc098c --- /dev/null +++ b/src/utils/bus.ts @@ -0,0 +1,5 @@ +// 引入mitt插件 index.ts +import mitt from "mitt" + +const $bus = mitt(); +export default $bus \ No newline at end of file