张延森 3 år sedan
förälder
incheckning
bc641a2249

+ 7
- 34
src/components/GeoMap/CarsMarker.js Visa fil

@@ -3,27 +3,22 @@ import carsImg from '@/assets/images/screen/map-cars.png';
3 3
 import videoStartImg from '@/assets/images/screen/map-video-start.png';
4 4
 import videoStopImg from '@/assets/images/screen/map-video-stop.png';
5 5
 
6
-
7
-
8
-export default (AMap, map, opts = {}) => {
6
+export default function getCarsMarker(AMap, map, opts = {}) {
9 7
   const marker = new AMap.Marker({
10
-    map,
11 8
     icon: markerImg,
12 9
     anchor: 'top-center',
13 10
     offset: new AMap.Pixel(0, 0),
14 11
     ...opts,
15 12
   });
16 13
 
17
-  let show = false;
18
-
19
-  // 
20
-  const { carsName, carsRural } = opts?.extData;
14
+  //
15
+  const { machineryId, name, orgName } = opts?.extData;
21 16
 
22 17
   marker.setLabel({
23 18
     direction: 'top',
24 19
     offset: new AMap.Pixel(0, 0),
25 20
     content: `
26
-    <div class="SquareBox-box-carsMarker" onclick="openVideo()">
21
+    <div class="SquareBox-box-carsMarker" onclick="openVideo('${machineryId}')">
27 22
     <div class="border_corner-carsMarker border_corner_left_top-left" ></div>
28 23
     <div class="border_corner-carsMarker border_corner_right_top-right" ></div>
29 24
     <div class="border_corner-carsMarker border_corner_left_bottom-left" ></div>
@@ -42,9 +37,9 @@ export default (AMap, map, opts = {}) => {
42 37
 
43 38
       <div  class="map-button-border">
44 39
       
45
-        <div class="carsName">名称:${carsName}</div>
40
+        <div class="carsName">名称:${name}</div>
46 41
         <div class="map-button-border-carsRural carsName">
47
-        <div >归属:${carsRural}</div>
42
+        <div >归属:${orgName}</div>
48 43
         <span> \>> </span>
49 44
         </div>
50 45
   
@@ -55,27 +50,5 @@ export default (AMap, map, opts = {}) => {
55 50
   </div> `,
56 51
   });
57 52
 
58
-
59
-  // marker.on('click', () => {
60
-  //   if (show) {
61
-  //     marker.setLabel({ content: '' });
62
-  //     show = false;
63
-  //     return;
64
-  //   }
65
-
66
-
67
-  //   if (!content) {
68
-  //     marker.setLabel({ content: '' });
69
-  //   } else {
70
-  //     marker.setLabel({
71
-  //       direction: 'top',
72
-  //       offset: new AMap.Pixel(0, 0),
73
-  //       content: `<div class='geo-map-marker-label' ><div class='geo-map-marker-label-text'>${ruralName}</div></div>`,
74
-  //     });
75
-  //   }
76
-
77
-  //   show = true;
78
-  // });
79
-
80 53
   return marker;
81
-};
54
+}

+ 7
- 35
src/components/GeoMap/RuralMarker.js Visa fil

@@ -1,55 +1,27 @@
1 1
 import ruralMarkerImg from '@/assets/images/screen/map-rural.png';
2 2
 
3
-
4
-
5
-
6
-export default (AMap, map, opts = {}) => {
3
+export default function getRuralMarker(AMap, map, opts = {}) {
7 4
   const marker = new AMap.Marker({
8
-    map,
9 5
     icon: ruralMarkerImg,
10 6
     anchor: 'top-center',
11 7
     offset: new AMap.Pixel(0, 0),
12 8
     ...opts,
13 9
   });
14 10
 
15
-  let show = false;
16
-
17 11
   // 合作社数据
18
-  const { ruralName, ruralAddress, ruralNumber, ruralPhone, } = opts?.extData;
12
+  const { name, address, machineNum, phone } = opts?.extData;
19 13
 
20 14
   marker.setLabel({
21 15
     direction: 'top',
22 16
     offset: new AMap.Pixel(0, 0),
23 17
     content: `
24 18
     <div class='geo-map-rural-box' >
25
-      <div class="borderBox"><span class='geo-map-rural-text-span borderBox'>名 称</span>:${ruralName}</div>
26
-      <div class="borderBox"><span class='geo-map-rural-text-span borderBox'>地 址</span>:${ruralAddress}</div>
27
-      <div class="borderBox">农机数量:${ruralNumber}</div>
28
-      <div class="borderBox">联系电话:${ruralPhone}</div>
19
+      <div class="borderBox"><span class='geo-map-rural-text-span borderBox'>名 称</span>:${name}</div>
20
+      <div class="borderBox"><span class='geo-map-rural-text-span borderBox'>地 址</span>:${address}</div>
21
+      <div class="borderBox">农机数量:${machineNum} 辆</div>
22
+      <div class="borderBox">联系电话:${phone}</div>
29 23
     </div>`,
30 24
   });
31 25
 
32
-
33
-  // marker.on('click', () => {
34
-  //   if (show) {
35
-  //     marker.setLabel({ content: '' });
36
-  //     show = false;
37
-  //     return;
38
-  //   }
39
-
40
-
41
-  //   if (!content) {
42
-  //     marker.setLabel({ content: '' });
43
-  //   } else {
44
-  //     marker.setLabel({
45
-  //       direction: 'top',
46
-  //       offset: new AMap.Pixel(0, 0),
47
-  //       content: `<div class='geo-map-marker-label' ><div class='geo-map-marker-label-text'>${ruralName}</div></div>`,
48
-  //     });
49
-  //   }
50
-
51
-  //   show = true;
52
-  // });
53
-
54 26
   return marker;
55
-};
27
+}

+ 38
- 61
src/components/GeoMap/index.jsx Visa fil

@@ -1,81 +1,57 @@
1
-import React, { useEffect, useRef, useState } from 'react';
1
+import React, { useEffect, useMemo, useRef, useState } from 'react';
2 2
 import { Modal, Button } from 'antd';
3
-import loader from '@/components/AMap/loader';
4
-import getMarker from './marker';
5
-import getRuralMarker from './RuralMarker';
6
-import getCarsMarker from './CarsMarker';
7
-
8
-import geoPolygon from './geoPolygon';
3
+import useMap from './map';
4
+import { useMarker, useMarkerVisible } from './marker';
9 5
 import Styles from './style.less';
10 6
 import RadioGroup from '../ScreenBox/Radio/RadioGroup';
11 7
 
12
-const plugins = [];
13
-
14 8
 export default (props) => {
15
-  const { machineTypeList } = props;
9
+  const { machineTypeList, orgList, machineList } = props;
16 10
 
17 11
   const container = useRef();
18
-  const amapRef = useRef();
19
-  const [map, setMap] = useState();
20
-
12
+  const currentMachineRef = useRef();
13
+  const [machineType, setMachineType] = useState('t0');
21 14
   const [isModalVisible, setIsModalVisible] = useState(false);
22
-  const [machineType, setMachineType] = useState();
23 15
 
16
+  // 修改地图的默认样式
24 17
   useEffect(() => {
25
-    loader(plugins).then((AMap) => {
26
-      amapRef.current = AMap;
27
-      const mapInst = new AMap.Map(container.current, {
28
-        mapStyle: 'amap://styles/669a7d8709a9bab0945747a1a1db3327',
29
-        // mapStyle: 'amap://styles/blue',
30
-        zoom: 10,
31
-        resizeEnable: true,
32
-        center: [112.092716, 32.681642],
33
-      });
18
+    const t = setInterval(() => {
19
+      const el = document.querySelector('.amap-ctrl-zoomin');
20
+      if (el) {
21
+        clearInterval(t);
22
+        el.style.color = '#fff';
23
+        document.querySelector('.amap-ctrl-zoomout').style.color = '#fff';
24
+      }
25
+    }, 500);
26
+
27
+    return () => clearInterval(t);
28
+  }, []);
34 29
 
35
-      // 遮罩层;
36
-      geoPolygon(AMap, mapInst);
30
+  // 构造地图
31
+  const { amapRef, map } = useMap(container);
37 32
 
38
-      //
39
-      setMap(mapInst);
40
-    });
33
+  // 把合作社跟农机合并到一起, 合作社的 typeId 设置为 t0
34
+  const list = useMemo(() => {
35
+    // org 没有 typeId, 因此所有 org 的节点都会带有 typeId = 't0'
36
+    return (orgList || []).map((item) => ({ typeId: 't0', ...item })).concat(machineList || []);
37
+  }, [orgList, machineList]);
41 38
 
42
-    window.openVideo = function () {
43
-      console.log(' window.foo 全局方法');
44
-      setIsModalVisible(true);
45
-    };
46
-
47
-    return () => (window.openVideo = undefined);
48
-  }, []);
39
+  // 生成所有的 marker
40
+  const markerListRef = useMarker(amapRef, map, list);
41
+  // 监听选择
42
+  useMarkerVisible(map, markerListRef, machineType);
49 43
 
44
+  // 把农机 marker 的点击事件挂载到 window 下面作为全局 function
50 45
   useEffect(() => {
51
-    if (!map) return;
52
-
53
-    // 先搞一个 marker demo
54
-    getMarker(amapRef.current, map, {
55
-      position: [112.092716, 32.681642],
56
-      extData: { value: '68辆' },
57
-    });
46
+    if (!machineList || !machineList.length) return;
58 47
 
59
-    // 合作社图标定位
60
-    getRuralMarker(amapRef.current, map, {
61
-      position: [111.909659, 32.651123],
62
-      extData: {
63
-        ruralName: 'ABC合作社',
64
-        ruralAddress: '南阳市邓州市林扒镇',
65
-        ruralNumber: '9辆',
66
-        ruralPhone: '13613949434',
67
-      },
68
-    });
48
+    window.openVideo = function (machineryId) {
49
+      currentMachineRef.current = machineList.filter((x) => x.machineryId === machineryId)[0];
50
+      setIsModalVisible(true);
51
+    };
69 52
 
70
-    // 农机监控
71
-    getCarsMarker(amapRef.current, map, {
72
-      position: [112.115574, 32.65235],
73
-      extData: {
74
-        carsName: '播种机0001',
75
-        carsRural: 'ABC合作社',
76
-      },
77
-    });
78
-  }, [map]);
53
+    return () => (window.openVideo = undefined);
54
+  }, [machineList]);
79 55
 
80 56
   return (
81 57
     <div className={Styles['geo-map-container']}>
@@ -94,6 +70,7 @@ export default (props) => {
94 70
       </div>
95 71
 
96 72
       <div className={Styles['geo-map-body']}>
73
+        {/* 渲染地图 */}
97 74
         <div ref={container} />
98 75
       </div>
99 76
 

+ 33
- 0
src/components/GeoMap/map.js Visa fil

@@ -0,0 +1,33 @@
1
+import React, { useEffect, useMemo, useRef, useState } from 'react';
2
+import loader from '@/components/AMap/loader';
3
+import geoPolygon from './geoPolygon';
4
+
5
+const plugins = ['AMap.ToolBar'];
6
+export default (containerRef) => {
7
+  const amapRef = useRef();
8
+  const [map, setMap] = useState();
9
+
10
+  useEffect(() => {
11
+    loader(plugins).then((AMap) => {
12
+      amapRef.current = AMap;
13
+      const mapInst = new AMap.Map(containerRef.current, {
14
+        mapStyle: 'amap://styles/669a7d8709a9bab0945747a1a1db3327',
15
+        // mapStyle: 'amap://styles/blue',
16
+        zoom: 10,
17
+        resizeEnable: true,
18
+        center: [112.092716, 32.681642],
19
+      });
20
+
21
+      // 缩放按钮
22
+      mapInst.addControl(new AMap.ToolBar());
23
+
24
+      // 遮罩层;
25
+      geoPolygon(AMap, mapInst);
26
+
27
+      //
28
+      setMap(mapInst);
29
+    });
30
+  }, []);
31
+
32
+  return { amapRef, map };
33
+};

+ 34
- 37
src/components/GeoMap/marker.js Visa fil

@@ -1,39 +1,36 @@
1
-import markerImg from '@/assets/images/screen/map-marker.png';
2
-
3
-
4
-export default (AMap, map, opts = {}) => {
5
-  const marker = new AMap.Marker({
6
-    map,
7
-    icon: markerImg,
8
-    anchor: 'top-center',
9
-    offset: new AMap.Pixel(0, 0),
10
-    ...opts,
11
-  });
12
-
13
-  let show = false;
14
-  const content = opts?.extData?.value;
15
-
16
-
17
-  marker.on('click', () => {
18
-    if (show) {
19
-      marker.setLabel({ content: '' });
20
-      show = false;
21
-      return;
22
-    }
23
-
24
-
25
-    if (!content) {
26
-      marker.setLabel({ content: '' });
27
-    } else {
28
-      marker.setLabel({
29
-        direction: 'top',
30
-        offset: new AMap.Pixel(0, 0),
31
-        content: `<div class='geo-map-marker-label' ><div class='geo-map-marker-label-text'>${content}</div></div>`,
1
+import React, { useEffect, useMemo, useRef, useState } from 'react';
2
+import getRuralMarker from './RuralMarker';
3
+import getCarsMarker from './CarsMarker';
4
+
5
+export function useMarker(amapRef, map, list) {
6
+  const markerListRef = useRef();
7
+
8
+  // 农机列表
9
+  useEffect(() => {
10
+    if (!amapRef.current) return;
11
+
12
+    if (list && list.length) {
13
+      markerListRef.current = list.map((item) => {
14
+        const fnMarker = item.typeId === 't0' ? getRuralMarker : getCarsMarker;
15
+        return fnMarker(amapRef.current, null, {
16
+          position: item.lnglat,
17
+          extData: item,
18
+        });
32 19
       });
33 20
     }
34
-
35
-    show = true;
36
-  });
37
-
38
-  return marker;
39
-};
21
+  }, [map, list]);
22
+
23
+  return markerListRef;
24
+}
25
+
26
+export function useMarkerVisible(map, markerListRef, typeId) {
27
+  useEffect(() => {
28
+    console.log(typeId, markerListRef.current);
29
+    if (!map || !markerListRef.current) return;
30
+
31
+    markerListRef.current.forEach((marker) => {
32
+      const item = marker.getExtData();
33
+      marker.setMap(item.typeId === typeId ? map : null);
34
+    });
35
+  }, [map, typeId]);
36
+}

+ 2
- 2
src/components/GeoMap/style.less Visa fil

@@ -9,14 +9,14 @@
9 9
 
10 10
   .radio-group {
11 11
     position: absolute;
12
-    top: 5%;
12
+    top: 8%;
13 13
     left: 5%;
14 14
     z-index: 1000;
15 15
   }
16 16
 
17 17
   .geo-map-body {
18 18
     height: calc(100% - 54px);
19
-    padding: 0 20px;
19
+    // padding: 0 20px;
20 20
     background-color: #061e3f;
21 21
     border-right: 1px solid rgba(61, 129, 240, 0.5);
22 22
     border-left: 1px solid rgba(61, 129, 240, 0.5);

+ 9
- 0
src/global.less Visa fil

@@ -75,6 +75,15 @@ ol {
75 75
   flex: 1;
76 76
 }
77 77
 
78
+// 修改大屏地图的 zoom 空间样式
79
+.amap-toolbar {
80
+  background-color: rgba(255, 255, 255, 0.3);
81
+}
82
+
83
+.amap-toolbar span:first-child {
84
+  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
85
+}
86
+
78 87
 .amap-marker-label {
79 88
   background: transparent;
80 89
   border: none;

+ 78
- 4
src/pages/MonitoringScreen/index.jsx Visa fil

@@ -49,9 +49,83 @@ export default (props) => {
49 49
   ]);
50 50
 
51 51
   const [machineTypeList, setMachineTypeList] = useState([
52
-    { id: 1, name: '收割机' },
53
-    { id: 2, name: '播种机' },
54
-    { id: 3, name: '农药机' },
52
+    { id: 't0', name: '合作社' },
53
+    { id: 't1', name: '收割机' },
54
+    { id: 't2', name: '播种机' },
55
+    { id: 't3', name: '农药机' },
56
+  ]);
57
+
58
+  const [orgList, setOrgList] = useState([
59
+    {
60
+      orgId: 1,
61
+      name: '合作社1',
62
+      address: '合作社地址1',
63
+      phone: '13823838438',
64
+      machineNum: 12,
65
+      lnglat: [111.888505, 32.854667],
66
+    },
67
+    {
68
+      orgId: 2,
69
+      name: '合作社2',
70
+      address: '合作社地址2',
71
+      phone: '13823838438',
72
+      machineNum: 68,
73
+      lnglat: [111.921464, 32.467361],
74
+    },
75
+    {
76
+      orgId: 3,
77
+      name: '合作社3',
78
+      address: '合作社地址3',
79
+      phone: '13823838438',
80
+      machineNum: 3,
81
+      lnglat: [112.367784, 32.815435],
82
+    },
83
+    {
84
+      orgId: 4,
85
+      name: '合作社4',
86
+      address: '合作社地址4',
87
+      phone: '13823838438',
88
+      machineNum: 42,
89
+      lnglat: [112.311479, 32.580836],
90
+    },
91
+  ]);
92
+
93
+  const [machineList, setMachineList] = useState([
94
+    {
95
+      machineryId: 'm1',
96
+      name: '农机1',
97
+      typeId: 't1',
98
+      orgName: '合作社1',
99
+      lnglat: [111.867906, 32.799276],
100
+    },
101
+    {
102
+      machineryId: 'm2',
103
+      name: '农机2',
104
+      typeId: 't2',
105
+      orgName: '合作社1',
106
+      lnglat: [112.087632, 32.66527],
107
+    },
108
+    {
109
+      machineryId: 'm3',
110
+      name: '农机3',
111
+      typeId: 't1',
112
+      orgName: '合作社2',
113
+      lnglat: [112.237321, 32.631737],
114
+    },
115
+    {
116
+      machineryId: 'm4',
117
+      name: '农机4',
118
+      typeId: 't3',
119
+      orgName: '合作社2',
120
+      lnglat: [112.002488, 32.563476],
121
+    },
122
+    {
123
+      machineryId: 'm5',
124
+      name: '农机5',
125
+      typeId: 't3',
126
+      orgName: '合作社3',
127
+      lnglat: [112.105485, 32.791195],
128
+    },
55 129
   ]);
56 130
 
57 131
   useEffect(() => {
@@ -95,7 +169,7 @@ export default (props) => {
95 169
               <StatisCard color="#F5CC5C" icon="icon3" value={168} title="总预约数(台)" />
96 170
               <StatisCard color="#C579FF" icon="icon4" value={1568} title="总服务数(台)" />
97 171
             </div>
98
-            <GeoMap machineTypeList={machineTypeList} />
172
+            <GeoMap machineTypeList={machineTypeList} orgList={orgList} machineList={machineList} />
99 173
           </div>
100 174
           <div className={Styles['grail-right']}>
101 175
             <div className="flex flex-column full-height">