feat: 完善仪表盘访客地域分布区块内容
This commit is contained in:
parent
83b2e2a7c0
commit
dc1691f019
@ -17,6 +17,7 @@
|
|||||||
package top.charles7c.cnadmin.monitor.mapper;
|
package top.charles7c.cnadmin.monitor.mapper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import top.charles7c.cnadmin.common.base.BaseMapper;
|
import top.charles7c.cnadmin.common.base.BaseMapper;
|
||||||
import top.charles7c.cnadmin.monitor.model.entity.LogDO;
|
import top.charles7c.cnadmin.monitor.model.entity.LogDO;
|
||||||
@ -44,4 +45,11 @@ public interface LogMapper extends BaseMapper<LogDO> {
|
|||||||
* @return 仪表盘热门模块列表
|
* @return 仪表盘热门模块列表
|
||||||
*/
|
*/
|
||||||
List<DashboardPopularModuleVO> selectListDashboardPopularModule();
|
List<DashboardPopularModuleVO> selectListDashboardPopularModule();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询仪表盘访客地域分布信息
|
||||||
|
*
|
||||||
|
* @return 仪表盘访客地域分布信息
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectListDashboardGeoDistribution();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.charles7c.cnadmin.monitor.model.vo;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 仪表盘-访客地域分布信息
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2023/9/9 12:07
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "仪表盘-访客地域分布信息")
|
||||||
|
public class DashboardGeoDistributionVO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地点列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "地点列表", example = "[\"中国北京北京市\",\"中国广东省深圳市\"]")
|
||||||
|
private List<String> locations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地点 IP 统计信息
|
||||||
|
*/
|
||||||
|
@Schema(description = "地点 IP 统计信息",
|
||||||
|
example = "[{\"name\":\"中国北京北京市\",\"value\":1000},{\"name\":\"中国广东省深圳市\",\"value\": 500}]")
|
||||||
|
private List<Map<String, Object>> locationIpStatistics;
|
||||||
|
}
|
@ -32,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
|||||||
* @since 2023/9/9 9:52
|
* @since 2023/9/9 9:52
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
@Schema(description = "仪表盘-热门模块信息")
|
||||||
public class DashboardPopularModuleVO implements Serializable {
|
public class DashboardPopularModuleVO implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
@ -32,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
|||||||
* @since 2023/9/8 21:32
|
* @since 2023/9/8 21:32
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
@Schema(description = "仪表盘-总计信息")
|
||||||
public class DashboardTotalVO implements Serializable {
|
public class DashboardTotalVO implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
@ -18,6 +18,7 @@ package top.charles7c.cnadmin.monitor.service;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import top.charles7c.cnadmin.monitor.model.vo.DashboardGeoDistributionVO;
|
||||||
import top.charles7c.cnadmin.monitor.model.vo.DashboardPopularModuleVO;
|
import top.charles7c.cnadmin.monitor.model.vo.DashboardPopularModuleVO;
|
||||||
import top.charles7c.cnadmin.monitor.model.vo.DashboardTotalVO;
|
import top.charles7c.cnadmin.monitor.model.vo.DashboardTotalVO;
|
||||||
import top.charles7c.cnadmin.system.model.vo.DashboardAnnouncementVO;
|
import top.charles7c.cnadmin.system.model.vo.DashboardAnnouncementVO;
|
||||||
@ -44,6 +45,13 @@ public interface DashboardService {
|
|||||||
*/
|
*/
|
||||||
List<DashboardPopularModuleVO> listPopularModule();
|
List<DashboardPopularModuleVO> listPopularModule();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询访客地域分布信息
|
||||||
|
*
|
||||||
|
* @return 访客地域分布信息
|
||||||
|
*/
|
||||||
|
DashboardGeoDistributionVO getGeoDistribution();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询公告列表
|
* 查询公告列表
|
||||||
*
|
*
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package top.charles7c.cnadmin.monitor.service;
|
package top.charles7c.cnadmin.monitor.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import top.charles7c.cnadmin.common.model.query.PageQuery;
|
import top.charles7c.cnadmin.common.model.query.PageQuery;
|
||||||
import top.charles7c.cnadmin.common.model.vo.PageDataVO;
|
import top.charles7c.cnadmin.common.model.vo.PageDataVO;
|
||||||
@ -87,5 +88,12 @@ public interface LogService {
|
|||||||
*
|
*
|
||||||
* @return 仪表盘热门模块列表
|
* @return 仪表盘热门模块列表
|
||||||
*/
|
*/
|
||||||
List<DashboardPopularModuleVO> listPopularModule();
|
List<DashboardPopularModuleVO> listDashboardPopularModule();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询仪表盘访客地域分布信息
|
||||||
|
*
|
||||||
|
* @return 仪表盘访客地域分布信息
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> listDashboardGeoDistribution();
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,18 @@ package top.charles7c.cnadmin.monitor.service.impl;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
|
||||||
|
import top.charles7c.cnadmin.monitor.model.vo.DashboardGeoDistributionVO;
|
||||||
import top.charles7c.cnadmin.monitor.model.vo.DashboardPopularModuleVO;
|
import top.charles7c.cnadmin.monitor.model.vo.DashboardPopularModuleVO;
|
||||||
import top.charles7c.cnadmin.monitor.model.vo.DashboardTotalVO;
|
import top.charles7c.cnadmin.monitor.model.vo.DashboardTotalVO;
|
||||||
import top.charles7c.cnadmin.monitor.service.DashboardService;
|
import top.charles7c.cnadmin.monitor.service.DashboardService;
|
||||||
@ -61,7 +65,7 @@ public class DashboardServiceImpl implements DashboardService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DashboardPopularModuleVO> listPopularModule() {
|
public List<DashboardPopularModuleVO> listPopularModule() {
|
||||||
List<DashboardPopularModuleVO> popularModuleList = logService.listPopularModule();
|
List<DashboardPopularModuleVO> popularModuleList = logService.listDashboardPopularModule();
|
||||||
for (DashboardPopularModuleVO popularModule : popularModuleList) {
|
for (DashboardPopularModuleVO popularModule : popularModuleList) {
|
||||||
Long todayPvCount = popularModule.getTodayPvCount();
|
Long todayPvCount = popularModule.getTodayPvCount();
|
||||||
Long yesterdayPvCount = popularModule.getYesterdayPvCount();
|
Long yesterdayPvCount = popularModule.getYesterdayPvCount();
|
||||||
@ -73,6 +77,16 @@ public class DashboardServiceImpl implements DashboardService {
|
|||||||
return popularModuleList;
|
return popularModuleList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DashboardGeoDistributionVO getGeoDistribution() {
|
||||||
|
List<Map<String, Object>> locationIpStatistics = logService.listDashboardGeoDistribution();
|
||||||
|
DashboardGeoDistributionVO geoDistribution = new DashboardGeoDistributionVO();
|
||||||
|
geoDistribution.setLocationIpStatistics(locationIpStatistics);
|
||||||
|
geoDistribution.setLocations(
|
||||||
|
locationIpStatistics.stream().map(m -> Convert.toStr(m.get("name"))).collect(Collectors.toList()));
|
||||||
|
return geoDistribution;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DashboardAnnouncementVO> listAnnouncement() {
|
public List<DashboardAnnouncementVO> listAnnouncement() {
|
||||||
return announcementService.listDashboard();
|
return announcementService.listDashboard();
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package top.charles7c.cnadmin.monitor.service.impl;
|
package top.charles7c.cnadmin.monitor.service.impl;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -151,10 +152,15 @@ public class LogServiceImpl implements LogService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DashboardPopularModuleVO> listPopularModule() {
|
public List<DashboardPopularModuleVO> listDashboardPopularModule() {
|
||||||
return logMapper.selectListDashboardPopularModule();
|
return logMapper.selectListDashboardPopularModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> listDashboardGeoDistribution() {
|
||||||
|
return logMapper.selectListDashboardGeoDistribution();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 填充数据
|
* 填充数据
|
||||||
*
|
*
|
||||||
|
@ -22,4 +22,14 @@
|
|||||||
ORDER BY `pvCount` DESC
|
ORDER BY `pvCount` DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectListDashboardGeoDistribution" resultType="java.util.Map">
|
||||||
|
SELECT
|
||||||
|
`location` AS name,
|
||||||
|
COUNT(DISTINCT `client_ip`) AS value
|
||||||
|
FROM `sys_log`
|
||||||
|
GROUP BY `location`
|
||||||
|
ORDER BY COUNT(DISTINCT `client_ip`) DESC
|
||||||
|
LIMIT 10
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
@ -31,7 +31,7 @@ import top.charles7c.cnadmin.system.enums.AnnouncementTypeEnum;
|
|||||||
* @since 2023/8/20 10:55
|
* @since 2023/8/20 10:55
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "仪表盘公告信息")
|
@Schema(description = "仪表盘-公告信息")
|
||||||
public class DashboardAnnouncementVO implements Serializable {
|
public class DashboardAnnouncementVO implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
@ -16,6 +16,11 @@ export interface DashboardPopularModuleRecord {
|
|||||||
newPvFromYesterday: number;
|
newPvFromYesterday: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DashboardGeoDistributionRecord {
|
||||||
|
locations: string[];
|
||||||
|
locationIpStatistics: [];
|
||||||
|
}
|
||||||
|
|
||||||
export interface DashboardAnnouncementRecord {
|
export interface DashboardAnnouncementRecord {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
@ -32,6 +37,12 @@ export function listPopularModule() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getGeoDistribution() {
|
||||||
|
return axios.get<DashboardGeoDistributionRecord>(
|
||||||
|
`${BASE_URL}/geo/distribution`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function listAnnouncement() {
|
export function listAnnouncement() {
|
||||||
return axios.get<DashboardAnnouncementRecord[]>(`${BASE_URL}/announcement`);
|
return axios.get<DashboardAnnouncementRecord[]>(`${BASE_URL}/announcement`);
|
||||||
}
|
}
|
||||||
@ -44,14 +55,3 @@ export interface ContentDataRecord {
|
|||||||
export function queryContentData() {
|
export function queryContentData() {
|
||||||
return axios.get<ContentDataRecord[]>('/api/content-data');
|
return axios.get<ContentDataRecord[]>('/api/content-data');
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PopularRecord {
|
|
||||||
key: number;
|
|
||||||
clickNumber: string;
|
|
||||||
title: string;
|
|
||||||
increases: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function queryPopularList(params: { type: string }) {
|
|
||||||
return axios.get<TableData[]>('/api/popular/list', { params });
|
|
||||||
}
|
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-spin :loading="loading" style="width: 100%">
|
|
||||||
<a-card
|
|
||||||
class="general-card"
|
|
||||||
:header-style="{ paddingBottom: '0' }"
|
|
||||||
:body-style="{
|
|
||||||
padding: '20px',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<template #title>
|
|
||||||
{{ $t('workplace.categoriesPercent') }}
|
|
||||||
</template>
|
|
||||||
<Chart height="310px" :option="chartOption" />
|
|
||||||
</a-card>
|
|
||||||
</a-spin>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import useLoading from '@/hooks/loading';
|
|
||||||
import useChartOption from '@/hooks/chart-option';
|
|
||||||
|
|
||||||
const { loading } = useLoading();
|
|
||||||
const { chartOption } = useChartOption((isDark) => {
|
|
||||||
// echarts support https://echarts.apache.org/zh/theme-builder.html
|
|
||||||
// It's not used here
|
|
||||||
return {
|
|
||||||
legend: {
|
|
||||||
left: 'center',
|
|
||||||
data: ['纯文本', '图文类', '视频类'],
|
|
||||||
bottom: 0,
|
|
||||||
icon: 'circle',
|
|
||||||
itemWidth: 8,
|
|
||||||
textStyle: {
|
|
||||||
color: isDark ? 'rgba(255, 255, 255, 0.7)' : '#4E5969',
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
borderWidth: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
show: true,
|
|
||||||
trigger: 'item',
|
|
||||||
},
|
|
||||||
graphic: {
|
|
||||||
elements: [
|
|
||||||
{
|
|
||||||
type: 'text',
|
|
||||||
left: 'center',
|
|
||||||
top: '40%',
|
|
||||||
style: {
|
|
||||||
text: '内容量',
|
|
||||||
textAlign: 'center',
|
|
||||||
fill: isDark ? '#ffffffb3' : '#4E5969',
|
|
||||||
fontSize: 14,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'text',
|
|
||||||
left: 'center',
|
|
||||||
top: '50%',
|
|
||||||
style: {
|
|
||||||
text: '928,531',
|
|
||||||
textAlign: 'center',
|
|
||||||
fill: isDark ? '#ffffffb3' : '#1D2129',
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: 500,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
type: 'pie',
|
|
||||||
radius: ['50%', '70%'],
|
|
||||||
center: ['50%', '50%'],
|
|
||||||
label: {
|
|
||||||
formatter: '{d}%',
|
|
||||||
fontSize: 14,
|
|
||||||
color: isDark ? 'rgba(255, 255, 255, 0.7)' : '#4E5969',
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
borderColor: isDark ? '#232324' : '#fff',
|
|
||||||
borderWidth: 1,
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
value: [148564],
|
|
||||||
name: '纯文本',
|
|
||||||
itemStyle: {
|
|
||||||
color: isDark ? '#3D72F6' : '#249EFF',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: [334271],
|
|
||||||
name: '图文类',
|
|
||||||
itemStyle: {
|
|
||||||
color: isDark ? '#A079DC' : '#313CA9',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: [445694],
|
|
||||||
name: '视频类',
|
|
||||||
itemStyle: {
|
|
||||||
color: isDark ? '#6CAAF5' : '#21CCFF',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less"></style>
|
|
@ -3,8 +3,8 @@
|
|||||||
class="general-card"
|
class="general-card"
|
||||||
:title="$t('workplace.docs')"
|
:title="$t('workplace.docs')"
|
||||||
:header-style="{ paddingBottom: 0 }"
|
:header-style="{ paddingBottom: 0 }"
|
||||||
:body-style="{ paddingTop: 0 }"
|
:body-style="{ paddingTop: '10px', paddingBottom: '10px' }"
|
||||||
style="height: 166px"
|
style="height: 198px"
|
||||||
>
|
>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-link href="https://doc.charles7c.top" target="_blank" rel="noopener">{{
|
<a-link href="https://doc.charles7c.top" target="_blank" rel="noopener">{{
|
||||||
@ -48,6 +48,24 @@
|
|||||||
{{ $t('workplace.docs.changelog') }}
|
{{ $t('workplace.docs.changelog') }}
|
||||||
</a-link>
|
</a-link>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-link
|
||||||
|
href="https://blog.charles7c.top"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
{{ $t('workplace.docs.authorSite') }}👋
|
||||||
|
</a-link>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-link
|
||||||
|
href="https://doc.charles7c.top/require.html"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
{{ $t('workplace.docs.require') }}✨
|
||||||
|
</a-link>
|
||||||
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-card>
|
</a-card>
|
||||||
</template>
|
</template>
|
||||||
@ -58,3 +76,4 @@
|
|||||||
color: rgb(var(--gray-8));
|
color: rgb(var(--gray-8));
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<script setup lang="ts"></script>
|
@ -0,0 +1,90 @@
|
|||||||
|
<template>
|
||||||
|
<a-spin :loading="loading" style="width: 100%">
|
||||||
|
<a-card
|
||||||
|
class="general-card"
|
||||||
|
:header-style="{ paddingBottom: '0' }"
|
||||||
|
:body-style="{
|
||||||
|
padding: '0 20px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #title>
|
||||||
|
{{ $t('workplace.geoDistribution') }}
|
||||||
|
</template>
|
||||||
|
<Chart height="480px" :option="chartOption" />
|
||||||
|
</a-card>
|
||||||
|
</a-spin>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import useLoading from '@/hooks/loading';
|
||||||
|
import useChartOption from '@/hooks/chart-option';
|
||||||
|
import {
|
||||||
|
DashboardGeoDistributionRecord,
|
||||||
|
getGeoDistribution,
|
||||||
|
} from '@/api/common/dashboard';
|
||||||
|
|
||||||
|
const { loading, setLoading } = useLoading();
|
||||||
|
const statisticsData = ref<DashboardGeoDistributionRecord>({
|
||||||
|
locations: [],
|
||||||
|
locationIpStatistics: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询访客地域分布信息
|
||||||
|
*/
|
||||||
|
const getData = async () => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const { data } = await getGeoDistribution();
|
||||||
|
statisticsData.value = data;
|
||||||
|
} catch (err) {
|
||||||
|
// you can report use errorHandler or other
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
getData();
|
||||||
|
|
||||||
|
const { chartOption } = useChartOption((isDark) => {
|
||||||
|
// echarts support https://echarts.apache.org/zh/theme-builder.html
|
||||||
|
// It's not used here
|
||||||
|
return {
|
||||||
|
legend: {
|
||||||
|
left: 'center',
|
||||||
|
data: statisticsData.value.locations,
|
||||||
|
bottom: -5,
|
||||||
|
icon: 'circle',
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
show: true,
|
||||||
|
trigger: 'item',
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'pie',
|
||||||
|
radius: '70%',
|
||||||
|
label: {
|
||||||
|
formatter: '{d}%',
|
||||||
|
fontSize: 14,
|
||||||
|
color: isDark ? 'rgba(255, 255, 255, 0.7)' : '#4E5969',
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
borderColor: isDark ? '#232324' : '#fff',
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
data: statisticsData.value.locationIpStatistics,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.general-card {
|
||||||
|
min-height: 566px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -3,7 +3,7 @@
|
|||||||
<a-card
|
<a-card
|
||||||
class="general-card"
|
class="general-card"
|
||||||
:header-style="{ paddingBottom: '0' }"
|
:header-style="{ paddingBottom: '0' }"
|
||||||
:body-style="{ padding: '17px 20px 21px 20px' }"
|
:body-style="{ padding: '17px 20px 20px 20px' }"
|
||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
{{ $t('workplace.popularModule') }}
|
{{ $t('workplace.popularModule') }}
|
||||||
@ -13,7 +13,7 @@
|
|||||||
:data="dataList"
|
:data="dataList"
|
||||||
:pagination="false"
|
:pagination="false"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
:scroll="{ x: '100%', y: '310px' }"
|
:scroll="{ x: '100%', y: '484px' }"
|
||||||
>
|
>
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<a-table-column title="排名">
|
<a-table-column title="排名">
|
||||||
@ -89,7 +89,7 @@
|
|||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.general-card {
|
.general-card {
|
||||||
min-height: 395px;
|
min-height: 400px;
|
||||||
}
|
}
|
||||||
:deep(.arco-table-tr) {
|
:deep(.arco-table-tr) {
|
||||||
height: 44px;
|
height: 44px;
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
import DataPanel from './components/data-panel.vue';
|
import DataPanel from './components/data-panel.vue';
|
||||||
import ContentChart from './components/content-chart.vue';
|
import ContentChart from './components/content-chart.vue';
|
||||||
import PopularModule from './components/popular-module.vue';
|
import PopularModule from './components/popular-module.vue';
|
||||||
import CategoriesPercent from './components/categories-percent.vue';
|
import CategoriesPercent from './components/geo-distribution.vue';
|
||||||
import RecentlyVisited from './components/recently-visited.vue';
|
import RecentlyVisited from './components/recently-visited.vue';
|
||||||
import QuickOperation from './components/quick-operation.vue';
|
import QuickOperation from './components/quick-operation.vue';
|
||||||
import Announcement from './components/announcement.vue';
|
import Announcement from './components/announcement.vue';
|
||||||
|
@ -14,6 +14,8 @@ export default {
|
|||||||
'workplace.docs.userGuide': 'User Guide',
|
'workplace.docs.userGuide': 'User Guide',
|
||||||
'workplace.docs.faq': 'FAQ',
|
'workplace.docs.faq': 'FAQ',
|
||||||
'workplace.docs.changelog': 'Change Log',
|
'workplace.docs.changelog': 'Change Log',
|
||||||
|
'workplace.docs.authorSite': 'Author Site',
|
||||||
|
'workplace.docs.require': 'Require',
|
||||||
'workplace.announcement': 'Announcement',
|
'workplace.announcement': 'Announcement',
|
||||||
'workplace.recently.visited': 'Recently Visited',
|
'workplace.recently.visited': 'Recently Visited',
|
||||||
'workplace.record.nodata': 'No data',
|
'workplace.record.nodata': 'No data',
|
||||||
@ -23,8 +25,8 @@ export default {
|
|||||||
'workplace.loadMore': 'More',
|
'workplace.loadMore': 'More',
|
||||||
'workplace.viewMore': 'More',
|
'workplace.viewMore': 'More',
|
||||||
'workplace.contentData': 'Content Data',
|
'workplace.contentData': 'Content Data',
|
||||||
'workplace.popularModule': 'Popular Module',
|
'workplace.popularModule': 'Popular Module(Top10)',
|
||||||
'workplace.categoriesPercent': 'Categories Percent',
|
'workplace.geoDistribution': 'Geo Distribution(Top10)',
|
||||||
'workplace.unit.pecs': 'pecs',
|
'workplace.unit.pecs': 'pecs',
|
||||||
'workplace.unit.times': 'times',
|
'workplace.unit.times': 'times',
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,8 @@ export default {
|
|||||||
'workplace.docs.userGuide': '使用指南',
|
'workplace.docs.userGuide': '使用指南',
|
||||||
'workplace.docs.faq': '常见问题',
|
'workplace.docs.faq': '常见问题',
|
||||||
'workplace.docs.changelog': '更新日志',
|
'workplace.docs.changelog': '更新日志',
|
||||||
|
'workplace.docs.authorSite': '作者主页',
|
||||||
|
'workplace.docs.require': '需求墙',
|
||||||
'workplace.announcement': '公告',
|
'workplace.announcement': '公告',
|
||||||
'workplace.recently.visited': '最近访问',
|
'workplace.recently.visited': '最近访问',
|
||||||
'workplace.record.nodata': '暂无数据',
|
'workplace.record.nodata': '暂无数据',
|
||||||
@ -23,8 +25,8 @@ export default {
|
|||||||
'workplace.loadMore': '加载更多',
|
'workplace.loadMore': '加载更多',
|
||||||
'workplace.viewMore': '查看更多',
|
'workplace.viewMore': '查看更多',
|
||||||
'workplace.contentData': '内容数据',
|
'workplace.contentData': '内容数据',
|
||||||
'workplace.popularModule': '热门模块',
|
'workplace.popularModule': '热门模块(Top10)',
|
||||||
'workplace.categoriesPercent': '内容类型占比',
|
'workplace.geoDistribution': '访客地域分布(Top10)',
|
||||||
'workplace.unit.pecs': '个',
|
'workplace.unit.pecs': '个',
|
||||||
'workplace.unit.times': '次',
|
'workplace.unit.times': '次',
|
||||||
};
|
};
|
||||||
|
@ -30,6 +30,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
|
|
||||||
import top.charles7c.cnadmin.common.model.vo.R;
|
import top.charles7c.cnadmin.common.model.vo.R;
|
||||||
import top.charles7c.cnadmin.monitor.annotation.Log;
|
import top.charles7c.cnadmin.monitor.annotation.Log;
|
||||||
|
import top.charles7c.cnadmin.monitor.model.vo.DashboardGeoDistributionVO;
|
||||||
import top.charles7c.cnadmin.monitor.model.vo.DashboardPopularModuleVO;
|
import top.charles7c.cnadmin.monitor.model.vo.DashboardPopularModuleVO;
|
||||||
import top.charles7c.cnadmin.monitor.model.vo.DashboardTotalVO;
|
import top.charles7c.cnadmin.monitor.model.vo.DashboardTotalVO;
|
||||||
import top.charles7c.cnadmin.monitor.service.DashboardService;
|
import top.charles7c.cnadmin.monitor.service.DashboardService;
|
||||||
@ -63,6 +64,12 @@ public class DashboardController {
|
|||||||
return R.ok(dashboardService.listPopularModule());
|
return R.ok(dashboardService.listPopularModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询访客地域分布信息", description = "查询访客地域分布信息")
|
||||||
|
@GetMapping("/geo/distribution")
|
||||||
|
public R<DashboardGeoDistributionVO> getGeoDistribution() {
|
||||||
|
return R.ok(dashboardService.getGeoDistribution());
|
||||||
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询公告列表", description = "查询公告列表")
|
@Operation(summary = "查询公告列表", description = "查询公告列表")
|
||||||
@GetMapping("/announcement")
|
@GetMapping("/announcement")
|
||||||
public R<List<DashboardAnnouncementVO>> listAnnouncement() {
|
public R<List<DashboardAnnouncementVO>> listAnnouncement() {
|
||||||
|
Loading…
Reference in New Issue
Block a user