mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-10-27 06:57:12 +08:00
220 lines
5.5 KiB
Vue
220 lines
5.5 KiB
Vue
<template>
|
|
<a-spin :loading="loading" style="width: 100%">
|
|
<a-card
|
|
class="general-card"
|
|
:header-style="{ paddingBottom: 0 }"
|
|
:body-style="{
|
|
paddingTop: '20px',
|
|
}"
|
|
:title="$t('workplace.accessTrend')"
|
|
>
|
|
<template #extra>
|
|
<a-radio-group
|
|
v-model:model-value="dateRange"
|
|
type="button"
|
|
@change="handleDateRangeChange as any"
|
|
>
|
|
<a-radio :value="7">
|
|
{{ $t('workplace.accessTrend.dateRange7') }}
|
|
</a-radio>
|
|
<a-radio :value="30">
|
|
{{ $t('workplace.accessTrend.dateRange30') }}
|
|
</a-radio>
|
|
</a-radio-group>
|
|
</template>
|
|
<Chart height="289px" :option="chartOption" />
|
|
</a-card>
|
|
</a-spin>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref } from 'vue';
|
|
import useLoading from '@/hooks/loading';
|
|
import {
|
|
DashboardAccessTrendRecord,
|
|
listAccessTrend,
|
|
} from '@/api/common/dashboard';
|
|
import useChartOption from '@/hooks/chart-option';
|
|
import { ToolTipFormatterParams } from '@/types/echarts';
|
|
|
|
const tooltipItemsHtmlString = (items: ToolTipFormatterParams[]) => {
|
|
return items
|
|
.map(
|
|
(el) => `<div class="content-panel">
|
|
<p>
|
|
<span style="background-color: ${el.color}" class="tooltip-item-icon"></span>
|
|
<span>${el.seriesName}</span>
|
|
</p>
|
|
<span class="tooltip-value">
|
|
${el.value}
|
|
</span>
|
|
</div>`,
|
|
)
|
|
.join('');
|
|
};
|
|
const { loading, setLoading } = useLoading(true);
|
|
const dateRange = ref(30);
|
|
const xAxis = ref<string[]>([]);
|
|
const pvStatisticsData = ref<number[]>([]);
|
|
const ipStatisticsData = ref<number[]>([]);
|
|
const { chartOption } = useChartOption((isDark) => {
|
|
return {
|
|
grid: {
|
|
left: '38',
|
|
right: '0',
|
|
top: '10',
|
|
bottom: '50',
|
|
},
|
|
legend: {
|
|
bottom: -3,
|
|
icon: 'circle',
|
|
textStyle: {
|
|
color: '#4E5969',
|
|
},
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
offset: 2,
|
|
data: xAxis.value,
|
|
boundaryGap: false,
|
|
axisLabel: {
|
|
color: '#4E5969',
|
|
formatter(value: number, idx: number) {
|
|
if (idx === 0) return '';
|
|
if (idx === xAxis.value.length - 1) return '';
|
|
return `${value}`;
|
|
},
|
|
},
|
|
axisLine: {
|
|
show: false,
|
|
},
|
|
axisTick: {
|
|
show: false,
|
|
},
|
|
splitLine: {
|
|
show: true,
|
|
interval: (idx: number) => {
|
|
if (idx === 0) return false;
|
|
return idx !== xAxis.value.length - 1;
|
|
},
|
|
lineStyle: {
|
|
color: isDark ? '#3F3F3F' : '#E5E8EF',
|
|
},
|
|
},
|
|
axisPointer: {
|
|
show: true,
|
|
lineStyle: {
|
|
color: '#23ADFF',
|
|
width: 2,
|
|
},
|
|
},
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
axisLabel: {
|
|
formatter(value: any, idx: number) {
|
|
if (idx === 0) return value;
|
|
if (value >= 1000) {
|
|
return `${value / 1000}k`;
|
|
}
|
|
return `${value}`;
|
|
},
|
|
},
|
|
axisLine: {
|
|
show: false,
|
|
},
|
|
splitLine: {
|
|
lineStyle: {
|
|
type: 'dashed',
|
|
color: isDark ? '#3F3F3F' : '#E5E8EF',
|
|
},
|
|
},
|
|
},
|
|
tooltip: {
|
|
show: true,
|
|
trigger: 'axis',
|
|
formatter(params) {
|
|
const [firstElement] = params as ToolTipFormatterParams[];
|
|
return `<div>
|
|
<p class="tooltip-title">${firstElement.axisValueLabel}</p>
|
|
${tooltipItemsHtmlString(params as ToolTipFormatterParams[])}
|
|
</div>`;
|
|
},
|
|
className: 'echarts-tooltip-diy',
|
|
},
|
|
series: [
|
|
{
|
|
name: '浏览量(PV)',
|
|
data: pvStatisticsData.value,
|
|
type: 'line',
|
|
smooth: true,
|
|
showSymbol: false,
|
|
color: isDark ? '#3D72F6' : '#246EFF',
|
|
symbol: 'circle',
|
|
symbolSize: 10,
|
|
emphasis: {
|
|
focus: 'series',
|
|
itemStyle: {
|
|
borderWidth: 2,
|
|
borderColor: '#E0E3FF',
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: 'IP数',
|
|
data: ipStatisticsData.value,
|
|
type: 'line',
|
|
smooth: true,
|
|
showSymbol: false,
|
|
color: isDark ? '#A079DC' : '#00B2FF',
|
|
symbol: 'circle',
|
|
symbolSize: 10,
|
|
emphasis: {
|
|
focus: 'series',
|
|
itemStyle: {
|
|
borderWidth: 2,
|
|
borderColor: '#E2F2FF',
|
|
},
|
|
},
|
|
},
|
|
],
|
|
};
|
|
});
|
|
|
|
/**
|
|
* 查询趋势图信息
|
|
*
|
|
* @param days 日期数
|
|
*/
|
|
const getList = async (days: number) => {
|
|
setLoading(true);
|
|
try {
|
|
xAxis.value = [];
|
|
pvStatisticsData.value = [];
|
|
ipStatisticsData.value = [];
|
|
const { data: chartData } = await listAccessTrend(days);
|
|
chartData.forEach((el: DashboardAccessTrendRecord) => {
|
|
xAxis.value.unshift(el.date);
|
|
pvStatisticsData.value.unshift(el.pvCount);
|
|
ipStatisticsData.value.unshift(el.ipCount);
|
|
});
|
|
} catch (err) {
|
|
// you can report use errorHandler or other
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 切换日期范围
|
|
*
|
|
* @param days 日期数
|
|
*/
|
|
const handleDateRangeChange = (days: number) => {
|
|
getList(days);
|
|
};
|
|
getList(30);
|
|
</script>
|
|
|
|
<style scoped lang="less"></style>
|