Commit 3a96054fcbe777886058d355d11ffbc4c6d16a21

Authored by fengtao
1 parent 90d831c0

perf: 优化接口调用历史折线图显示

1 -<script setup lang="ts">  
2 - import { Descriptions, Progress, Skeleton, Tooltip, DescriptionsItem } from 'ant-design-vue';  
3 -  
4 - defineProps({  
5 - seriesData: {  
6 - type: Array as PropType<Recordable[]>,  
7 - default: () => [],  
8 - },  
9 - });  
10 -</script>  
11 -<template>  
12 - <div class="m-16">  
13 - <Skeleton active :paragraph="{ rows: 10 }" :loading="!seriesData">  
14 - <Descriptions :column="1">  
15 - <template v-for="(item, index) in seriesData" :key="item.label">  
16 - <DescriptionsItem>  
17 - <span  
18 - class="mr-2 item-span"  
19 - :style="{  
20 - color:  
21 - index === 0  
22 - ? '#f0a16e'  
23 - : index === 1  
24 - ? '#868585'  
25 - : index === 2  
26 - ? '#e78739'  
27 - : '#4e84f5',  
28 - backgroundColor:  
29 - index === 0 ? '#FAD672' : index === 1 ? '#CBCAC9' : index === 2 ? '#F1B889' : '',  
30 - borderColor:  
31 - index === 0  
32 - ? '#fdee7d'  
33 - : index === 1  
34 - ? '#e6e6e5'  
35 - : index === 2  
36 - ? '#f8c296'  
37 - : '#0b55f1',  
38 - }"  
39 - >{{ index + 1 }}</span  
40 - >  
41 - <div class="flex justify-between" style="width: 100%">  
42 - <div class="label-span">  
43 - <Tooltip :title="item.label">  
44 - {{ item.label }}  
45 - </Tooltip>  
46 - </div>  
47 - <div class="flex w-7/10">  
48 - <Progress  
49 - :showInfo="false"  
50 - size="small"  
51 - style="width: 70%"  
52 - :percent="(item.value / seriesData[0].value) * 100"  
53 - :strokeWidth="12"  
54 - :strokeColor="  
55 - index === 0  
56 - ? '#ea5b42'  
57 - : index === 1  
58 - ? '#666'  
59 - : index === 2  
60 - ? '#e4751a'  
61 - : '#b5b6b6'  
62 - "  
63 - />  
64 - <span  
65 - class="ml-2"  
66 - :style="{ color: index === 0 ? '#EA5B42' : index === 2 ? '#E4751A' : '#666' }"  
67 - >  
68 - {{ item.value }}  
69 - </span>  
70 - </div>  
71 - </div>  
72 - </DescriptionsItem>  
73 - </template>  
74 - </Descriptions>  
75 - </Skeleton>  
76 - </div>  
77 -</template>  
78 -  
79 -<style scoped lang="less">  
80 - .item-span {  
81 - width: 1.4rem;  
82 - height: 1.25rem;  
83 - border: 1px solid;  
84 - color: #0b55f1;  
85 - border-radius: 50%;  
86 - display: flex;  
87 - align-items: center;  
88 - justify-content: center;  
89 - }  
90 -  
91 - .label-span {  
92 - width: 10rem;  
93 - white-space: nowrap;  
94 - text-overflow: ellipsis;  
95 - overflow: hidden;  
96 - word-break: break-all;  
97 - }  
98 -</style>  
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 }, 37 },
38 legend: { 38 legend: {
39 top: 'bottom', 39 top: 'bottom',
40 - padding: 5, 40 + type: 'scroll',
41 }, 41 },
42 title: [ 42 title: [
43 { 43 {
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 import { useECharts } from '/@/hooks/web/useECharts'; 3 import { useECharts } from '/@/hooks/web/useECharts';
4 import { useAppStore } from '/@/store/modules/app'; 4 import { useAppStore } from '/@/store/modules/app';
5 import { useI18n } from '/@/hooks/web/useI18n'; 5 import { useI18n } from '/@/hooks/web/useI18n';
  6 + import { Empty } from 'ant-design-vue';
6 7
7 const { t } = useI18n(); 8 const { t } = useI18n();
8 9
@@ -21,10 +22,11 @@ @@ -21,10 +22,11 @@
21 22
22 const timeRangeList = ref([ 23 const timeRangeList = ref([
23 { label: `1${t('home.index.timeUnit.hour')}`, value: 'hour', interval: 1000 * 60 * 5 }, 24 { label: `1${t('home.index.timeUnit.hour')}`, value: 'hour', interval: 1000 * 60 * 5 },
  25 + { label: `1${t('home.index.timeUnit.day')}`, value: 'day', interval: 1000 * 60 * 60 * 1 },
24 { 26 {
25 label: `7${t('home.index.timeUnit.day')}`, 27 label: `7${t('home.index.timeUnit.day')}`,
26 value: 'week', 28 value: 'week',
27 - interval: 1000 * 60 * 60 * 2, 29 + interval: 1000 * 60 * 60 * 1,
28 }, 30 },
29 { 31 {
30 label: `30${t('home.index.timeUnit.day')}`, 32 label: `30${t('home.index.timeUnit.day')}`,
@@ -95,13 +97,17 @@ @@ -95,13 +97,17 @@
95 }, 97 },
96 { 98 {
97 deep: true, 99 deep: true,
  100 + immediate: true,
98 } 101 }
99 ); 102 );
100 103
101 onMounted(() => { 104 onMounted(() => {
102 setOptions(getOptions()); 105 setOptions(getOptions());
103 //自适应 106 //自适应
104 - window.addEventListener('resize', () => resize()); 107 + window.addEventListener('resize', () => {
  108 + resize();
  109 + setOptions(getOptions());
  110 + });
105 }); 111 });
106 112
107 const handleTimeRangeChange = (e: any) => { 113 const handleTimeRangeChange = (e: any) => {
@@ -122,7 +128,10 @@ @@ -122,7 +128,10 @@
122 </template> 128 </template>
123 </a-radio-group> 129 </a-radio-group>
124 </template> 130 </template>
125 - <div ref="chartRef" class="w-full h-80"></div> 131 + <div v-show="seriesData.length" ref="chartRef" class="w-full h-80"></div>
  132 + <div v-show="!seriesData.length" class="w-full h-72 flex justify-center items-center"
  133 + ><Empty :image="Empty.PRESENTED_IMAGE_SIMPLE"
  134 + /></div>
126 </a-card> 135 </a-card>
127 </template> 136 </template>
128 137
@@ -76,15 +76,89 @@ @@ -76,15 +76,89 @@
76 ?.map((topItem) => topItem.value) 76 ?.map((topItem) => topItem.value)
77 ?.reduce((sum, curr) => sum + curr); 77 ?.reduce((sum, curr) => sum + curr);
78 // 相加总共 78 // 相加总共
79 - chartData.pieChartData.push({  
80 - name: '其他应用',  
81 - value: res.tops.length <= 5 ? 0 : otherApplicationCount,  
82 - }); 79 + if (res.tops && res.tops.length > 5) {
  80 + chartData.pieChartData.push({
  81 + name: '其他应用',
  82 + value: otherApplicationCount,
  83 + });
  84 + }
83 } 85 }
84 }; 86 };
85 87
  88 + //1小时->5分钟间隔 1天->2小时间隔 7天->1天间隔 30天->1天间隔
  89 + const timeFormat = (type, config) => {
  90 + let startT: any = null;
  91 + let endT: any = null;
  92 + let interval: any = null; //分割间隔
  93 + if (type == 'hour') {
  94 + interval = 5;
  95 + startT = moment().subtract(1, config.text);
  96 + endT = moment().format('HH:mm');
  97 + } else if (type == 'day') {
  98 + interval = 2;
  99 + startT = moment().subtract(1, config.text);
  100 + endT = moment().format('HH:mm');
  101 + } else if (type == 'week') {
  102 + interval = 1;
  103 + startT = moment().subtract(1, config.text);
  104 + endT = moment().format('HH:mm');
  105 + } else if (type == 'month') {
  106 + interval = 1;
  107 + startT = moment().subtract(1, config.text);
  108 + endT = moment().format('HH:mm');
  109 + }
  110 + let starTime = moment(startT, 'HH:mm');
  111 + let endTime = moment(endT, 'HH:mm');
  112 + let diff = endTime.diff(starTime, config.diffText);
  113 + let num = Math.ceil(diff / interval);
  114 + let times: any = [];
  115 + for (let i = 1; i <= num; i++) {
  116 + let timeFrom = starTime.clone().add((i - 1) * interval, config.timeText) as any;
  117 + times.push(timeFrom.format('YYYY-MM-DD HH:mm'));
  118 + }
  119 + return times;
  120 + };
  121 +
  122 + const configTime = [
  123 + {
  124 + name: 'hour',
  125 + value: {
  126 + text: 'hours',
  127 + diffText: 'minutes',
  128 + timeText: 'minutes',
  129 + },
  130 + },
  131 + {
  132 + name: 'day',
  133 + value: {
  134 + text: 'days',
  135 + diffText: 'hours',
  136 + timeText: 'hours',
  137 + },
  138 + },
  139 + {
  140 + name: 'week',
  141 + value: {
  142 + text: 'weeks',
  143 + diffText: 'days',
  144 + timeText: 'days',
  145 + },
  146 + },
  147 + {
  148 + name: 'month',
  149 + value: {
  150 + text: 'months',
  151 + diffText: 'days',
  152 + timeText: 'days',
  153 + },
  154 + },
  155 + ];
  156 + //代码保留
  157 +
86 // 接口调用历史 158 // 接口调用历史
87 const getClassify = async (type?: string) => { 159 const getClassify = async (type?: string) => {
  160 + const findValue = configTime.find((configItem) => configItem.name === type)?.value;
  161 + timeFormat(type, findValue);
88 const res = (await getApplicationRecordClassify(type)) as any as ClassifyItemType[]; 162 const res = (await getApplicationRecordClassify(type)) as any as ClassifyItemType[];
89 chartData.timeLineChartData = res?.map((classifyItem: ClassifyItemType) => ({ 163 chartData.timeLineChartData = res?.map((classifyItem: ClassifyItemType) => ({
90 type: 'line', 164 type: 'line',
@@ -125,15 +199,9 @@ @@ -125,15 +199,9 @@
125 </div> 199 </div>
126 <div> 200 <div>
127 <TimeLineChart 201 <TimeLineChart
128 - v-if="chartData.timeLineChartData.length"  
129 @emitTimeRange="handleReceiveTimeRange" 202 @emitTimeRange="handleReceiveTimeRange"
130 :seriesData="chartData.timeLineChartData" 203 :seriesData="chartData.timeLineChartData"
131 /> 204 />
132 - <a-card v-else :title="t('application.record.text.timeLineTitle')" class="w-full h-120">  
133 - <div class="w-full h-72 flex justify-center items-center"  
134 - ><Empty :image="Empty.PRESENTED_IMAGE_SIMPLE"  
135 - /></div>  
136 - </a-card>  
137 </div> 205 </div>
138 <div> 206 <div>
139 <a-card class="w-full h-140"> 207 <a-card class="w-full h-140">