Browse Source

仪表盘优化-增加国内地图显示

shimingxy 5 months ago
parent
commit
3ab9b80dfd

+ 1 - 0
maxkey-persistence/src/main/java/org/dromara/maxkey/persistence/mapper/ReportMapper.java

@@ -47,5 +47,6 @@ public  interface ReportMapper extends IJpaMapper<JpaEntity> {
 	
 	public List<Map<String,Object>> analysisApp(HashMap<String,Object> reportParameter );
 	
+	public List<Map<String,Object>> analysisProvince(HashMap<String,Object> reportParameter);
 	
 }

+ 1 - 0
maxkey-persistence/src/main/java/org/dromara/maxkey/persistence/service/ReportService.java

@@ -42,4 +42,5 @@ public interface ReportService  extends IJpaService<JpaEntity>{
 	
 	public List<Map<String,Object>> analysisApp(HashMap<String,Object> reportParameter);
 
+	public List<Map<String,Object>> analysisProvince(HashMap<String,Object> reportParameter);
 }

+ 24 - 0
maxkey-persistence/src/main/java/org/dromara/maxkey/persistence/service/impl/ReportServiceImpl.java

@@ -17,6 +17,7 @@
 
 package org.dromara.maxkey.persistence.service.impl;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -62,4 +63,27 @@ public class ReportServiceImpl  extends JpaServiceImpl<ReportMapper,JpaEntity> i
 		return getMapper().analysisApp(reportParameter);
 	}
 	
+	public List<Map<String,Object>> analysisProvince(HashMap<String,Object> reportParameter){
+		List<Map<String,Object>> maps = getMapper().analysisProvince(reportParameter);
+		if(null == maps) {
+			return new ArrayList<>();
+		}
+		for(Map<String,Object> map : maps) {
+			if(map.containsKey("reportstring")){
+				String name = map.get("reportstring").toString();
+				if (name.endsWith("省")
+						|| name.endsWith("市")
+						|| name.endsWith("特别行政区")
+						|| name.endsWith("自治区")) {
+					name = name.replace("省","")
+							.replace("市","")
+							.replace("特别行政区","")
+							.replace("自治区","");
+				}
+				map.put("name",name);
+			}
+		}
+		return maps;
+	}
+	
 }

+ 14 - 0
maxkey-persistence/src/main/resources/org/dromara/maxkey/persistence/mapper/xml/mysql/ReportMapper.xml

@@ -107,5 +107,19 @@
     	group by appname order by reportcount desc
     	limit 10
     </select>
+    
+    <!-- 30天各省份的访问统计 -->
+	<select id="analysisProvince" parameterType="java.util.HashMap" resultType="Map">
+		select
+			count(id) as reportcount,
+			coalesce(province,'Other') as reportstring
+		from mxk_history_login
+		where  instid   =   #{instId}
+		  and logintime >date_add(curdate(), interval - day(curdate()) -31 day)
+		  and province !=''
+		group by reportstring
+		order by reportcount desc
+			limit 1000
+	</select>
 
 </mapper>

+ 18 - 20
maxkey-web-frontend/maxkey-web-mgt-app/package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "maxkey",
-  "version": "3.5.0",
+  "version": "4.1.x",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "maxkey",
-      "version": "3.5.0",
+      "version": "4.1.x",
       "license": "Apache-2.0",
       "dependencies": {
         "@angular/animations": "~13.3.0",
@@ -29,6 +29,7 @@
         "ajv": "^8.10.0",
         "ajv-formats": "^2.1.1",
         "crypto-js": "^4.1.1",
+        "echarts": "^5.5.1",
         "monaco-editor": "^0.33.0",
         "ng-zorro-antd": "^13.1.1",
         "ngx-cookie-service": "^13.2.0",
@@ -8565,13 +8566,12 @@
       }
     },
     "node_modules/echarts": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.3.1.tgz",
-      "integrity": "sha512-nWdlbgX3OVY0hpqncSvp0gDt1FRSKWn7lsWEH+PHmfCuvE0QmSw17pczQvm8AvawnLEkmf1Cts7YwQJZNC0AEQ==",
-      "license": "Apache-2.0",
+      "version": "5.5.1",
+      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz",
+      "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==",
       "dependencies": {
         "tslib": "2.3.0",
-        "zrender": "5.3.1"
+        "zrender": "5.6.0"
       }
     },
     "node_modules/echarts/node_modules/tslib": {
@@ -22366,10 +22366,9 @@
       }
     },
     "node_modules/zrender": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.3.1.tgz",
-      "integrity": "sha512-7olqIjy0gWfznKr6vgfnGBk7y4UtdMvdwFmK92vVQsQeDPyzkHW1OlrLEKg6GHz1W5ePf0FeN1q2vkl/HFqhXw==",
-      "license": "BSD-3-Clause",
+      "version": "5.6.0",
+      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz",
+      "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==",
       "dependencies": {
         "tslib": "2.3.0"
       }
@@ -22377,8 +22376,7 @@
     "node_modules/zrender/node_modules/tslib": {
       "version": "2.3.0",
       "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
-      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
-      "license": "0BSD"
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
     }
   },
   "dependencies": {
@@ -28381,12 +28379,12 @@
       }
     },
     "echarts": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.3.1.tgz",
-      "integrity": "sha512-nWdlbgX3OVY0hpqncSvp0gDt1FRSKWn7lsWEH+PHmfCuvE0QmSw17pczQvm8AvawnLEkmf1Cts7YwQJZNC0AEQ==",
+      "version": "5.5.1",
+      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz",
+      "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==",
       "requires": {
         "tslib": "2.3.0",
-        "zrender": "5.3.1"
+        "zrender": "5.6.0"
       },
       "dependencies": {
         "tslib": {
@@ -38133,9 +38131,9 @@
       }
     },
     "zrender": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.3.1.tgz",
-      "integrity": "sha512-7olqIjy0gWfznKr6vgfnGBk7y4UtdMvdwFmK92vVQsQeDPyzkHW1OlrLEKg6GHz1W5ePf0FeN1q2vkl/HFqhXw==",
+      "version": "5.6.0",
+      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz",
+      "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==",
       "requires": {
         "tslib": "2.3.0"
       },

+ 1 - 0
maxkey-web-frontend/maxkey-web-mgt-app/package.json

@@ -61,6 +61,7 @@
     "ajv": "^8.10.0",
     "ajv-formats": "^2.1.1",
     "crypto-js": "^4.1.1",
+    "echarts": "^5.5.1",
     "monaco-editor": "^0.33.0",
     "ng-zorro-antd": "^13.1.1",
     "ngx-cookie-service": "^13.2.0",

+ 28 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/dashboard/home/home.component.html

@@ -109,6 +109,34 @@
       <g2-bar *ngIf="mouthData" height="275" [data]="mouthData"></g2-bar>
     </nz-card>
   </div>
+
+  <div nz-col nzXs="24" nzMd="24">
+    <nz-card [nzTitle]="monthProvinceAccessCount" [nzBordered]="false">
+      <ng-template #monthProvinceAccessCount> {{ 'mxk.home.monthProvinceAccessCount' | i18n }} </ng-template>
+      <div style="display: flex">
+        <!-- 地图-->
+        <div id="mapChart" style="width: 900px; height: 500px"></div>
+        <div>
+          <nz-table #basicTable [nzData]="top10ProvinceTableData" [nzFrontPagination]="false" style="width: 450px">
+            <thead>
+              <tr>
+                <th style="width: 20%; text-align: center">{{ 'mxk.home.number' | i18n }}</th>
+                <th style="width: 50%; text-align: center">{{ 'mxk.home.province' | i18n }}</th>
+                <th style="width: 30%; text-align: center">{{ 'mxk.home.accessPV' | i18n }}</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr *ngFor="let data of top10ProvinceTableData; let i = index">
+                <td style="text-align: center">{{ i + 1 }}</td>
+                <td style="text-align: center">{{ data.reportstring }}</td>
+                <td style="text-align: center">{{ data.reportcount }}</td>
+              </tr>
+            </tbody>
+          </nz-table>
+        </div>
+      </div>
+    </nz-card>
+  </div>
   <div nz-col nzXs="24" nzMd="12">
     <nz-card [nzTitle]="monthAppTitle" [nzBordered]="false">
       <ng-template #monthAppTitle> {{ 'mxk.home.monthAppCount' | i18n }} </ng-template>

+ 156 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/dashboard/home/home.component.ts

@@ -20,9 +20,12 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit,
 import type { Chart } from '@antv/g2';
 import { OnboardingService } from '@delon/abc/onboarding';
 import { format } from 'date-fns';
+// Features like Universal Transition and Label Layout
+import * as echarts from 'echarts';
 import { NzSafeAny } from 'ng-zorro-antd/core/types';
 
 import { AnalysisService } from '../../../service/analysis.service';
+import chinaMap from '../../../shared/map/json/china.json';
 
 @Component({
   selector: 'app-home',
@@ -48,6 +51,23 @@ export class HomeComponent implements OnInit {
 
   reportBrowser: any[] = [];
 
+  //地图数据
+  provinceMapData: any[] = [];
+
+  provinceTableData: any[] = [];
+
+  top10ProvinceTableData: any[] = [];
+
+  mapSplitList: any[] = [
+    { start: 400, end: 500 },
+    { start: 300, end: 400 },
+    { start: 200, end: 300 },
+    { start: 100, end: 200 },
+    { start: 0, end: 100 }
+  ];
+
+  mapColor: any[] = ['#5475f5', '#9feaa5', '#85daef', '#e6ac53', '#9fb5ea'];
+
   constructor(
     private analysisService: AnalysisService,
     private cdr: ChangeDetectorRef,
@@ -100,9 +120,145 @@ export class HomeComponent implements OnInit {
         });
       }
 
+      this.provinceTableData = res.data.reportProvince;
       this.reportApp = res.data.reportApp;
       this.reportBrowser = res.data.reportBrowser;
+      this.top10ProvinceTableData = [this.provinceTableData.length];
+      for (let i = 0; i < this.provinceTableData.length && i < 10; i += 1) {
+        this.top10ProvinceTableData[i] = this.provinceTableData[i];
+      }
+      //延迟加载地图,否则dom无法加载echarts地图
+      setTimeout(() => {
+        this.initCharts();
+      });
       this.cdr.detectChanges();
     });
   }
+
+  initCharts() {
+    let maxMapCount = 0;
+    for (let i = 0; i < this.provinceTableData.length; i++) {
+      this.provinceMapData.push({
+        value: this.provinceTableData[i].reportcount,
+        provinceName: this.provinceTableData[i].reportstring,
+        name: this.provinceTableData[i].name,
+        itemStyle: { color: this.mapColor.length - 1 }
+      });
+      if (maxMapCount < this.provinceMapData[i].reportcount) {
+        maxMapCount = this.provinceMapData[i].reportcount;
+      }
+    }
+    if (maxMapCount <= 100) {
+      //100以内
+      this.mapSplitList = [
+        { start: 80, end: 100 },
+        { start: 60, end: 80 },
+        { start: 40, end: 60 },
+        { start: 20, end: 40 },
+        { start: 0, end: 20 }
+      ];
+    } else if (maxMapCount <= 500) {
+      //500以内
+      this.mapSplitList = [
+        { start: 400, end: 500 },
+        { start: 300, end: 400 },
+        { start: 200, end: 300 },
+        { start: 100, end: 200 },
+        { start: 0, end: 100 }
+      ];
+    } else if (maxMapCount <= 1000) {
+      //1000以内
+      this.mapSplitList = [
+        { start: 800, end: 1000 },
+        { start: 600, end: 800 },
+        { start: 400, end: 600 },
+        { start: 200, end: 400 },
+        { start: 0, end: 200 }
+      ];
+    } else if (maxMapCount <= 5000) {
+      //5000以内
+      this.mapSplitList = [
+        { start: 4000, end: 5000 },
+        { start: 3000, end: 4000 },
+        { start: 2000, end: 3000 },
+        { start: 1000, end: 2000 },
+        { start: 0, end: 1000 }
+      ];
+    } else if (maxMapCount <= 10000) {
+      //10000以内
+      this.mapSplitList = [
+        { start: 8000, end: 10000 },
+        { start: 6000, end: 8000 },
+        { start: 4000, end: 6000 },
+        { start: 2000, end: 4000 },
+        { start: 0, end: 2000 }
+      ];
+    } else if (maxMapCount <= 50000) {
+      //50000以内
+      this.mapSplitList = [
+        { start: 40000, end: 50000 },
+        { start: 30000, end: 40000 },
+        { start: 20000, end: 30000 },
+        { start: 10000, end: 20000 },
+        { start: 0, end: 10000 }
+      ];
+    } else if (maxMapCount <= 100000) {
+      //100000以内
+      this.mapSplitList = [
+        { start: 80000, end: 100000 },
+        { start: 60000, end: 80000 },
+        { start: 40000, end: 60000 },
+        { start: 20000, end: 40000 },
+        { start: 0, end: 20000 }
+      ];
+    }
+    for (let i = 0; i < this.provinceMapData.length; i++) {
+      for (let si = 0; si < this.mapSplitList.length; si++) {
+        if (this.mapSplitList[si].start < this.provinceMapData[i].value && this.provinceMapData[i].value <= this.mapSplitList[si].end) {
+          this.provinceMapData[i].itemStyle.color = this.mapColor[si];
+          break;
+        }
+      }
+    }
+    console.log(this.provinceMapData);
+    const ec = echarts as any;
+
+    let mapChart = ec.init(document.getElementById('mapChart'));
+    //注册地图到echarts中  这里的 "china" 要与地图数据的option中的geo中的map对应
+    ec.registerMap('china', { geoJSON: chinaMap });
+    let optionMap = {
+      backgroundColor: '#FFFFFF',
+      tooltip: {
+        trigger: 'item'
+      },
+      //左侧小导航图标
+      visualMap: {
+        show: true,
+        x: 'left',
+        y: 'center',
+        splitList: this.mapSplitList,
+        color: this.mapColor
+      },
+      //配置属性
+      series: [
+        {
+          name: '数据',
+          type: 'map',
+          mapType: 'china',
+          roam: true,
+          label: {
+            normal: {
+              show: true //省份名称
+            },
+            emphasis: {
+              show: false
+            }
+          },
+          data: this.provinceMapData //数据
+        }
+      ]
+    };
+    mapChart.setOption(optionMap);
+    this.cdr.detectChanges();
+  }
 }

+ 2 - 0
maxkey-web-frontend/maxkey-web-mgt-app/tsconfig.json

@@ -15,6 +15,8 @@
     "experimentalDecorators": true,
     "moduleResolution": "node",
     "importHelpers": true,
+    "resolveJsonModule":true,      
+    "esModuleInterop": true,
     "target": "es2017",
     "module": "es2020",
     "lib": ["es2020", "dom"],

+ 2 - 0
maxkey-webs/maxkey-web-mgt/src/main/java/org/dromara/maxkey/web/contorller/DashboardController.java

@@ -56,6 +56,8 @@ public class DashboardController {
 		reportParameter.put("reportMonth", reportService.analysisMonth(reportParameter));
 		reportParameter.put("reportDayHour", reportService.analysisDayHour(reportParameter));
 		
+		reportParameter.put("reportProvince", reportService.analysisProvince(reportParameter));
+		
 		reportParameter.put("reportBrowser", reportService.analysisBrowser(reportParameter));
 		reportParameter.put("reportApp", reportService.analysisApp(reportParameter));
 		return new Message<HashMap<?,?>>(reportParameter);