chore: 演示站访问统计

This commit is contained in:
dap 2024-08-07 17:06:39 +08:00
parent 36a937191e
commit 20a57bfab4
9 changed files with 103732 additions and 0 deletions

View File

@ -0,0 +1,32 @@
import { requestClient } from '#/api/request';
export interface Temp {
name: string;
value: number;
}
export function visitList() {
return requestClient.get<Temp[]>('/monitor/logininfor/visitsMap');
}
export function deviceInfoList() {
return requestClient.get<Temp[]>('/monitor/logininfor/deviceInfoList');
}
export function browserInfoList() {
return requestClient.get<Temp[]>('/monitor/logininfor/browserInfoList');
}
export function ispInfoList() {
return requestClient.get<Temp[]>('/monitor/logininfor/ispInfoList');
}
export interface LoginLineResp {
date: string[];
fail: number[];
success: number[];
}
export function loginLine() {
return requestClient.get<LoginLineResp>('/monitor/logininfor/loginLine');
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { Tabs } from 'ant-design-vue';
import Browser from './pages/browser.vue';
import Device from './pages/device.vue';
import Isp from './pages/isp.vue';
import LoginLine from './pages/loginLine.vue';
import VisitMap from './pages/map.vue';
const TabPane = Tabs.TabPane;
const activeKey = ref<number>(1);
</script>
<template>
<div>
<Tabs v-model:activeKey="activeKey" class="h-full" tab-position="left">
<TabPane :key="1" tab="访问量数据"> <VisitMap /> </TabPane>
<TabPane :key="2" tab="使用设备"><Device /></TabPane>
<TabPane :key="3" tab="使用浏览器"><Browser /></TabPane>
<TabPane :key="4" tab="登录量"><LoginLine /></TabPane>
<TabPane :key="5" tab="运营商占比"><Isp /></TabPane>
</Tabs>
</div>
</template>

View File

@ -0,0 +1,58 @@
<script setup lang="ts">
import type { EChartsOption } from 'echarts';
// import * as echarts from 'echarts';
import { onMounted, ref } from 'vue';
import { EchartsUI, type EchartsUIType, useEcharts } from '@vben/chart-ui';
import { browserInfoList } from '../api';
defineOptions({ name: 'Browser' });
const browserRef = ref<EchartsUIType>();
const { renderEcharts } = useEcharts(browserRef);
onMounted(async () => {
const data = await browserInfoList();
const options: EChartsOption = {
legend: {
left: 'left',
orient: 'vertical',
},
series: [
{
data,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)',
shadowOffsetX: 0,
},
},
//
label: {
formatter: '{b}: {c} - ({d}%)', // (b:name, c:value, d:)
show: true,
},
radius: '50%',
type: 'pie',
},
],
title: {
left: 'center',
text: '使用浏览器占比',
},
tooltip: {
trigger: 'item',
},
};
renderEcharts(options);
});
</script>
<template>
<EchartsUI ref="browserRef" height="720px" width="100%" />
</template>
<style scoped></style>

View File

@ -0,0 +1,58 @@
<script setup lang="ts">
import type { EChartsOption } from 'echarts';
// import * as echarts from 'echarts';
import { onMounted, ref } from 'vue';
import { EchartsUI, type EchartsUIType, useEcharts } from '@vben/chart-ui';
import { deviceInfoList } from '../api';
defineOptions({ name: 'Device' });
const deviceRef = ref<EchartsUIType>();
const { renderEcharts } = useEcharts(deviceRef);
onMounted(async () => {
const data = await deviceInfoList();
const options: EChartsOption = {
legend: {
left: 'left',
orient: 'vertical',
},
series: [
{
data,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)',
shadowOffsetX: 0,
},
},
//
label: {
formatter: '{b}: {c} - ({d}%)', // (b:name, c:value, d:)
show: true,
},
radius: '50%',
type: 'pie',
},
],
title: {
left: 'center',
text: '使用设备占比',
},
tooltip: {
trigger: 'item',
},
};
renderEcharts(options);
});
</script>
<template>
<EchartsUI ref="deviceRef" height="720px" width="100%" />
</template>
<style scoped></style>

View File

@ -0,0 +1,58 @@
<script setup lang="ts">
import type { EChartsOption } from 'echarts';
// import * as echarts from 'echarts';
import { onMounted, ref } from 'vue';
import { EchartsUI, type EchartsUIType, useEcharts } from '@vben/chart-ui';
import { ispInfoList } from '../api';
defineOptions({ name: 'Isp' });
const ispRef = ref<EchartsUIType>();
const { renderEcharts } = useEcharts(ispRef);
onMounted(async () => {
const data = await ispInfoList();
const options: EChartsOption = {
legend: {
left: 'left',
orient: 'vertical',
},
series: [
{
data,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)',
shadowOffsetX: 0,
},
},
//
label: {
formatter: '{b}: {c} - ({d}%)', // (b:name, c:value, d:)
show: true,
},
radius: '50%',
type: 'pie',
},
],
title: {
left: 'center',
text: '网络运营商占比',
},
tooltip: {
trigger: 'item',
},
};
renderEcharts(options);
});
</script>
<template>
<EchartsUI ref="ispRef" height="720px" width="100%" />
</template>
<style scoped></style>

View File

@ -0,0 +1,79 @@
<script setup lang="ts">
import type { EChartsOption } from 'echarts';
// import * as echarts from 'echarts';
import { onMounted, ref } from 'vue';
import { EchartsUI, type EchartsUIType, useEcharts } from '@vben/chart-ui';
import { loginLine } from '../api';
defineOptions({ name: 'LoginLine' });
const loginLineRef = ref<EchartsUIType>();
const { renderEcharts } = useEcharts(loginLineRef);
onMounted(async () => {
const data = await loginLine();
console.log(data);
const options: EChartsOption = {
legend: {},
series: [
{
data: data.success,
itemStyle: {
color: '#3399CC',
},
lineStyle: {
color: '#3399CC',
},
name: '登录成功',
type: 'line',
},
{
data: data.fail,
itemStyle: {
color: '#CC6633',
},
lineStyle: {
color: '#CC6633',
},
name: '登录失败',
type: 'line',
},
],
title: {
text: '近一月登录量统计',
},
toolbox: {
feature: {
dataView: { readOnly: true },
dataZoom: {
yAxisIndex: 'none',
},
magicType: { type: ['line', 'bar'] },
saveAsImage: {},
},
show: true,
},
tooltip: {
trigger: 'axis',
},
xAxis: {
boundaryGap: false,
data: data.date,
type: 'category',
},
yAxis: {
type: 'value',
},
};
renderEcharts(options);
});
</script>
<template>
<EchartsUI ref="loginLineRef" height="720px" width="100%" />
</template>
<style scoped></style>

View File

@ -0,0 +1,107 @@
<script setup lang="ts">
import type { EChartsOption } from 'echarts';
// import * as echarts from 'echarts';
import { onMounted, ref } from 'vue';
import { EchartsUI, type EchartsUIType, useEcharts } from '@vben/chart-ui';
import * as echarts from 'echarts/core';
import { type Temp, visitList } from '../api';
import * as chinaMap from '../china.json';
defineOptions({ name: 'VisitMap' });
const mapRef = ref<EchartsUIType>();
const { renderEcharts } = useEcharts(mapRef);
function transformData(data: Temp[]) {
const nameList: string[] = chinaMap.features.map(
(item) => item.properties.name,
);
// eslint-disable-next-line unicorn/prefer-set-has
const dataNameList: string[] = data.map((item) => item.name);
//
const diff = nameList.filter(
(item) => !dataNameList.includes(item) && item.trim() !== '',
);
diff.forEach((name) => {
data.push({
name,
value: 0,
});
});
}
onMounted(async () => {
echarts.registerMap('china', chinaMap as any);
const data = await visitList();
transformData(data);
const max = Math.max.apply(
null,
data.map((item) => item.value),
);
const options: EChartsOption = {
series: [
{
data,
emphasis: {
label: {
show: true,
},
},
label: {
// formatter: '{b}\n{c}',
formatter: '{c}',
position: 'inside',
show: true,
},
map: 'china',
roam: true,
//
top: 200,
type: 'map',
zoom: 1.5,
},
],
title: {
left: 'right',
text: '用户访问量数据',
},
toolbox: {
feature: {
dataView: { readOnly: true },
saveAsImage: {},
},
// orient: 'vertical',
left: 'left',
show: true,
top: 'top',
},
tooltip: {
formatter: '{b}<br/>{c}',
showDelay: 0,
transitionDuration: 0.2,
trigger: 'item',
},
visualMap: {
calculable: true,
inRange: {
color: ['#ffffff', '#00FF66', '#00CCFF', '#CC6600'],
},
left: 'left',
max,
min: 0,
text: ['最高', '最低'],
},
};
renderEcharts(options);
});
</script>
<template>
<EchartsUI ref="mapRef" height="720px" width="100%" />
</template>
<style scoped></style>

View File

@ -16,6 +16,7 @@ import {
BarChart,
GaugeChart,
LineChart,
MapChart,
PieChart,
RadarChart,
} from 'echarts/charts';
@ -29,6 +30,7 @@ import {
TooltipComponent,
// 内置数据转换器组件 (filter, sort)
TransformComponent,
VisualMapComponent,
} from 'echarts/components';
import * as echarts from 'echarts/core';
import { LabelLayout, UniversalTransition } from 'echarts/features';
@ -61,6 +63,8 @@ echarts.use([
LegendComponent,
ToolboxComponent,
GaugeChart,
VisualMapComponent,
MapChart,
]);
export default echarts;