Răsfoiți Sursa

Merge remote-tracking branch 'origin/master'

Gaosheng 2 zile în urmă
părinte
comite
c85599eb9e

+ 30 - 0
xinkeaboard-admin/src/pages/statistics/bigscreen/components/MapContainer.js

@@ -0,0 +1,30 @@
+import React from "react";
+import { connect } from "dva";
+import WorldMap from "./WorldMap";
+import styles from "../styles/common.less";
+
+const MapContainer = ({
+  data,
+  options,
+  current,
+  loading,
+  currentSite,
+  dispatch,
+}) => {
+  const parseData = (mapData) => {
+    return mapData.map((item) => ({
+      name: item.city,
+      value: [item.longitude ?? 116.4074, item.latitude ?? 39.9042, item.memberNum],
+    }));
+  };
+
+  return (
+    <div className={styles.common}>
+      <WorldMap data={parseData(data)} />
+    </div>
+  );
+};
+
+export default connect(({ bigscreen }) => ({
+  data: bigscreen.mapContainerData.data,
+}))(MapContainer);

+ 74 - 18
xinkeaboard-admin/src/pages/statistics/bigscreen/components/WorldMap.js

@@ -25,20 +25,64 @@ class WorldMap extends React.Component {
     window.removeEventListener("resize", this.resizeChart);
   }
 
+  componentDidUpdate() {
+    this.initChart();
+  }
+
   resizeChart = () => {
     if (this.chartInstance) {
       this.chartInstance.resize();
     }
   };
 
+  // 根据国家名获取中心经纬度
+  getGeoCenterByName(name) {
+    const feature = worldJson.features.find((f) => f.properties.name === name);
+    if (feature) {
+      // 计算多边形的中心点
+      const coords = feature.geometry.coordinates.flat(Infinity);
+      let lng = 0,
+        lat = 0;
+      for (let i = 0; i < coords.length; i += 2) {
+        lng += coords[i];
+        lat += coords[i + 1];
+      }
+      lng /= coords.length / 2;
+      lat /= coords.length / 2;
+      return [lng, lat];
+    }
+    return null;
+  }
+
   initChart() {
     if (!this.chartRef.current) return;
     this.chartInstance = echarts.init(this.chartRef.current);
-
+    console.log(this.props.data, "--sdsdsd");
+    // const seriesData = [
+    //   { name: "China", value: [116.4074, 39.9042, 100] },
+    //   { name: "United States", value: [-100.0, 40.0, 80] },
+    //   { name: "Brazil", value: [-47.9292, -15.7801, 60] },
+    //   { name: "Russia", value: [37.6173, 55.7558, 70] },
+    //   { name: "India", value: [77.1025, 28.7041, 90] },
+    // ];
+    // const seriesData = countries
+    //   ?.map((item) => {
+    //     const coord = this.getGeoCenterByName(item.name);
+    //     if (coord) {
+    //       return { name: item.name, value: [...coord, item.value] };
+    //     }
+    //     return null;
+    //   })
+    //   .filter(Boolean);
     const option = {
       tooltip: {
         formatter: (params) => {
-          return `${params.name}`;
+          return `${params.name} <br> ${params.value[2]}`;
+        },
+        textStyle: {
+          fontSize: 28, // 字体大小
+          // color: "#fff", // 字体颜色
+          fontWeight: "bold", // 可选加粗
         },
       },
       geo3D: {
@@ -48,10 +92,10 @@ class WorldMap extends React.Component {
 
         boxWidth: 200, // 宽度加大
         boxHeight: 20,
-        regionHeight: 2,
+        regionHeight: 1,
         viewControl: {
           distance: 120, // 相机拉远一点
-          alpha: 60,
+          alpha: 30,
           beta: 0,
         },
         shading: "lambert",
@@ -63,21 +107,36 @@ class WorldMap extends React.Component {
             backgroundColor: "rgba(0,0,0,0)",
           },
         },
+        // itemStyle: {
+        //   color: "#1d5e98",
+        //   opacity: 0.8,
+        //   borderWidth: 0.8,
+        //   borderColor: "#111",
+        // },
         itemStyle: {
-          color: "#1d5e98",
-          opacity: 0.8,
+          // 区域透明但微亮
+          color: "rgba(255,255,255,0.05)",
+          borderColor: "#66ccff", // 边界亮色
           borderWidth: 0.8,
-          borderColor: "#111",
         },
+
         emphasis: {
           itemStyle: {
-            color: "#2a333d",
-          },
-          label: {
-            show: false,
+            color: "rgba(255,255,255,0.1)",
+            borderColor: "#99ffff",
+            borderWidth: 1,
           },
         },
 
+        // emphasis: {
+        //   itemStyle: {
+        //     color: "#2a333d",
+        //   },
+        //   label: {
+        //     show: false,
+        //   },
+        // },
+
         light: {
           main: {
             intensity: 1.2,
@@ -100,13 +159,10 @@ class WorldMap extends React.Component {
           coordinateSystem: "geo3D",
           shading: "lambert",
           barSize: 1, // 柱子粗细
-          data: [
-            { name: "China", value: [116.4074, 39.9042, 100] },
-            { name: "United States", value: [-100.0, 40.0, 80] },
-            { name: "Brazil", value: [-47.9292, -15.7801, 60] },
-            { name: "Russia", value: [37.6173, 55.7558, 70] },
-            { name: "India", value: [77.1025, 28.7041, 90] },
-          ],
+          itemStyle: {
+            color: "#DE701C",
+          },
+          data: this.props.data,
         },
       ],
     };

+ 4 - 1
xinkeaboard-admin/src/pages/statistics/bigscreen/index.js

@@ -13,6 +13,7 @@ import AddProductTrend from "./components/addProductTrend";
 import SearchRankCloud from "./components/SearchRankCloud";
 import MemberLocation from "./components/MemberLocation";
 import StoreTraffic from "./components/StoreTraffic";
+import MapContainer from "./components/MapContainer"
 
 @connect(({ bigscreen }) => ({
   bigscreen,
@@ -255,7 +256,9 @@ class BigScreen extends React.Component {
               </PanelBlock>
             </div>
 
-            <div className={styles.mapContainer}></div>
+            <div className={styles.mapContainer}>
+              <MapContainer></MapContainer>
+            </div>
           </div>
         </div>
       </div>

+ 1 - 30
xinkeaboard-admin/src/pages/statistics/bigscreen/index.less

@@ -82,38 +82,9 @@
   .mapContainer {
     position: absolute;
     left: 540px;
-    top: 470px;
+    top: 180px;
     width: 2400px;
     height: 1176px;
-    border: 1px solid red;
     z-index: 0;
   }
-
-  // &Left,
-  // &Center,
-  // &Right {
-  //   display: flex;
-  //   flex-direction: column;
-  //   height: 100%;
-  // }
-
-  // &Left {
-  //   width: 25%;
-  // }
-
-  // &Center {
-  //   width: 50%;
-  // }
-
-  // &Right {
-  //   width: 25%;
-  // }
-}
-
-.mapContainer {
-  position: absolute;
-  width: 2336px;
-  height: 1080px;
-  border: 1px solid red;
-  z-index: 0;
 }

+ 1 - 0
xinkeaboard-admin/src/pages/statistics/bigscreen/styles/common.less

@@ -5,6 +5,7 @@
   display: flex;
   padding: 20px 10px 0 10px;
   flex-direction: column;
+  z-index: 2000;
 }
 
 .common_header {

+ 1 - 0
xinkeaboard-admin/src/pages/statistics/bigscreen/styles/overview.less

@@ -69,6 +69,7 @@
     width: 100%;
     height: 120px;
     margin-top: 20px;
+    z-index: 2000;
   }
 
   .overview_member_img {

+ 36 - 0
xinkeaboard-admin/src/pages/statistics/models/bigscreen.js

@@ -183,6 +183,10 @@ export default {
       ],
       current: "昨日",
     },
+    mapContainerData: {
+      loading: false,
+      data: [],
+    },
     updateTime: "",
   },
 
@@ -385,6 +389,24 @@ export default {
       });
     },
 
+    // 世界地图站点数据
+    *load_world_map({ payload }, { put, call, select }) {
+      yield put({
+        type: "setWorldMapData",
+        payload: { loading: true },
+      });
+      const response = yield call(
+        sldCommonService,
+        payload,
+        "get",
+        "v3/statistics/screen/analysis/memberDistribution"
+      );
+      yield put({
+        type: "setWorldMapData",
+        payload: { data: response.data, loading: false },
+      });
+    },
+
     // 初始化数据
     *load_data({ payload }, { put, call }) {
       // 更新时间
@@ -443,10 +465,24 @@ export default {
       yield put.resolve({
         type: "load_store_traffic",
       });
+
+      // 会员区域
+      yield put.resolve({
+        type: "load_world_map",
+      });
     },
   },
 
   reducers: {
+    setWorldMapData(state, { payload }) {
+      return {
+        ...state,
+        mapContainerData: {
+          ...state.mapContainerData,
+          ...payload,
+        },
+      };
+    },
     setStoreTrafficData(state, { payload }) {
       return {
         ...state,