Commit 04060e06 authored by liwei's avatar liwei

新建了API监控页面

parent 05482702
...@@ -11,27 +11,27 @@ export const columns1: BasicColumn[] = [ ...@@ -11,27 +11,27 @@ export const columns1: BasicColumn[] = [
{ {
title: 'gateway', title: 'gateway',
dataIndex: 'gateway', dataIndex: 'gateway',
width: 150, width: 100,
}, },
{ {
title: 'executor', title: 'executor',
dataIndex: 'executor', dataIndex: 'executor',
width: 150, width: 100,
}, },
{ {
title: '调用者', title: '调用者',
dataIndex: 'caller', dataIndex: 'caller',
width: 150, width: 100,
}, },
{ {
title: '开始时间', title: '开始时间',
dataIndex: 'startTime', dataIndex: 'startTime',
width: 150, width: 100,
}, },
{ {
title: '已耗时', title: '已耗时',
dataIndex: 'consume', dataIndex: 'consume',
width: 150, width: 100,
}, },
]; ];
export const searchFormSchema: FormSchema[] = [ export const searchFormSchema: FormSchema[] = [
......
<template> <template>
<Card :loading="loading"> <Card :loading="loading">
333 <div style="display: flex">
<div ref="chartRef1" style="width: 80%; height: 400px"></div>
<div ref="chartRef2" style="width: 20%;height: 400px"></div>
</div>
</Card> </Card>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; import {onMounted, ref} from 'vue';
import { Tag, Card,Select } from 'ant-design-vue'; import { Tag, Card,Select } from 'ant-design-vue';
import { BasicTable, useTable, TableAction } from '@/components/Table'; import { BasicTable, useTable, TableAction } from '@/components/Table';
import {} from "./ApiMonitor.data";
import {} from "./ApiMonitorData";
import Icon from '@/components/Icon/Icon.vue'; import Icon from '@/components/Icon/Icon.vue';
import {useECharts} from "@/hooks/web/useECharts";
const chartRef1 = ref<HTMLDivElement | null>(null);
const { setOptions: setOptions1 } = useECharts(chartRef1 as Ref<HTMLDivElement>);
const chartRef2 = ref<HTMLDivElement | null>(null);
const { setOptions: setOptions2 } = useECharts(chartRef2 as Ref<HTMLDivElement>);
function getEchartsData1() {
setOptions1({
title: {
text: '业务错误码趋势统计',
left: 'left', // 将标题放在左侧
top: '10', // 距离顶部10px
textStyle: {
color: '#333', // 标题文字颜色
fontSize: 16, // 标题字体大小
fontWeight: 'bold' // 标题字体加粗
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
width: 1,
color: '#019680',
},
},
},
legend: {
orient: 'vertical', // 垂直方向
right: '2%', // 图例放置在右侧
top: 'center', // 图例垂直居中
itemWidth: 15, // 图例标记宽度
itemHeight: 15, // 图例标记高度
textStyle: {
color: '#333', // 图例文字颜色
fontSize: 12, // 图例文字大小
},
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [...new Array(8)].map((_item, index) => `10/0${index + 1}`),
splitLine: {
show: true,
lineStyle: {
width: 1,
type: 'solid',
color: 'rgba(226,226,226,0.5)',
},
},
axisTick: {
show: false,
},
},
yAxis: [
{
type: 'value',
max: 5000, // 设置最大值以适应所有数据
splitNumber: 6, // 分割线数量
axisTick: {
show: false,
},
splitArea: {
show: true,
areaStyle: {
color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'],
},
},
},
],
grid: {
left: '1%',
right: '35%', // 给图例留出空间
top: '70px',
bottom: '5%',
containLabel: true,
},
series: [
{ name: '62101(服务参数解析异常)', data: [450, 675, 450, 1125, 1800, 1575, 1800, 2025], type: 'line', itemStyle: { color: 'rgb(90, 143, 240)' } }, // 番茄红
{ name: '62102(缺少必要的服务参数)', data: [675, 900, 675, 1350, 2025, 1800, 2025, 2250], type: 'line', itemStyle: { color: 'rgb(153, 205, 255)' } }, // 金黄色
{ name: '62201(数据库异常,无法获取JDBC连接)', data: [900, 1125, 900, 1575, 2250, 2025, 2250, 2475], type: 'line', itemStyle: { color: 'rgb(250, 225, 200)' } }, // 柠檬绿
{ name: '62202(数据库异常,没有劝返访问)', data: [1125, 1350, 1125, 1800, 2475, 2250, 2475, 2700], type: 'line', itemStyle: { color: 'rgb(237, 200, 109)' } }, // 青色
{ name: '62301(查询异常,不存在的数据列)', data: [1350, 1575, 1350, 2025, 2700, 2475, 2700, 2925], type: 'line', itemStyle: { color: 'rgb(136, 231, 226)' } }, // 蓝色
{ name: '62302(查询异常,不存在的数据列)', data: [1575, 1800, 1575, 2250, 2925, 2700, 2925, 3150], type: 'line', itemStyle: { color: 'rgb(170, 233, 240)' } }, // 蓝紫色
{ name: '62303(查询异常,无法解析SQL)', data: [1800, 2025, 1800, 2475, 3150, 2925, 3150, 3375], type: 'line', itemStyle: { color: 'rgb(246, 185, 148)' } }, // 紫罗兰
{ name: '62401(服务异常,没有对应服务)', data: [2025, 2250, 2025, 2700, 3375, 3150, 3375, 3600], type: 'line', itemStyle: { color: 'rgb(156, 140, 249)' } }, // 深粉红色
{ name: '62501(SQL拼接异常)', data: [2250, 2475, 2250, 2925, 3600, 3375, 3600, 3825], type: 'line', itemStyle: { color: 'rgb(227, 129, 129)' } }, // 橙红色
{ name: '62601(服务实现版本查询异常)', data: [2475, 2700, 2475, 3150, 3825, 3600, 3825, 4050], type: 'line', itemStyle: { color: 'rgb(174, 182, 192)' } }, // 巧克力色
],
});
}
function getEchartsData2() {
setOptions2({
title: {
text: '业务错误码分布统计',
left: 'left', // 标题居中
top: '5%', // 距离图表顶部5%
textStyle: {
fontSize: 15, // 标题字体大小
fontWeight: 'bold' // 加粗
}
},
tooltip: {
trigger: 'item',
},
series: [
{
color: ['rgb(255, 210, 163)', 'rgb(142, 228, 237)', 'rgb(113, 213, 166)', 'rgb(248, 161, 59)', 'rgb(224, 97, 97)', 'rgb(93, 177, 255)', 'rgb(53, 119, 241)', 'rgb(138, 146, 160)', 'rgb(224, 180, 18)', 'rgb(130, 106, 249)'],
name: '访问来源',
type: 'pie',
radius: ['70%', '100%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 5,
borderColor: '#fff',
borderWidth: 2,
},
label: {
show: true,
position: 'center',
formatter: function (params) {
return '总数: ' + 957;
},
textStyle: {
fontSize: 16,
fontWeight: 'bold'
}
},
emphasis: {
label: {
show: true,
fontSize: '12',
fontWeight: 'bold',
},
},
labelLine: {
show: false,
},
data: [
{ value: 110, name: '62101' },
{ value: 120, name: '62102' },
{ value: 130, name: '62201' },
{ value: 50, name: '62202' },
{ value: 50, name: '62301' },
{ value: 50, name: '62302' },
{ value: 80, name: '62303' },
{ value: 100, name: '62401' },
{ value: 120, name: '62501' },
{ value: 150, name: '62601' },
],
animationType: 'scale',
animationEasing: 'exponentialInOut',
animationDelay: function () {
return Math.random() * 100;
},
},
],
});
}
onMounted(() => {
getEchartsData1()
getEchartsData2()
})
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
......
<template> <template>
<BasicTable @register="registerPartitionTable"> <div class="charts-container">
<template #bodyCell="{ column }"> <div class="header">
<template v-if="column.key === 'action'"> <span>响应时长统计</span>
<TableAction </div>
:actions="[ <div class="charts">
{ <div id="chart3" class="chart"></div>
label: '查看日志', <div id="chart4" class="chart"></div>
}, </div>
]" </div>
/>
</template>
</template>
</BasicTable>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { BasicTable, TableAction, useTable } from '@/components/Table'; import { onMounted } from 'vue';
import { partitionColumns } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitor.data'; import * as echarts from 'echarts';
import { partitionData } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitorData'; import { fieldChangeData } from '@/views/metadata/metadataData';
import {
const [registerPartitionTable] = useTable({ responseData,
title: '调用失败记录', second1Data,
dataSource: partitionData, second2Data,
columns: partitionColumns, second3Data,
showIndexColumn: false, second4Data,
pagination: true, totalApiData,
actionColumn: { totalApiFailedData,
width: 120, totalApiSucessData,
title: '操作', } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitorData';
dataIndex: 'action',
fixed: 'right', function parseValue(value) {
}, return parseFloat(value); // This will convert '3.5ms' to 3.5
scroll: { y: 300 }, }
});
onMounted(() => {
{
// 获取图表容器
const chart3Container = document.getElementById('chart3');
const chart4Container = document.getElementById('chart4');
// 初始化图表实例
const chart3Instance = echarts.init(chart3Container);
const chart4Instance = echarts.init(chart4Container);
// 设置图表选项
chart3Instance.setOption({
title: {
text: '平均响应时长',
},
tooltip: {
formatter: function (params) {
return `${params.name}: ${params.value} ms`;
},
},
xAxis: {
data: responseData.map((item) => item.date),
boundaryGap: false, // 数据点与标签对齐
},
yAxis: {
min: 0, // 设置 Y 轴的最小值
max: 6, // 设置 Y 轴的最大值为 6
splitNumber: 7,
axisLabel: {
formatter: '{value} ms', // 在 Y 轴标签上添加 "ms"
},
},
series: [
{
name: '数据表变更',
type: 'line',
color: '#48bdf3',
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#48bdf3', // 渐变起始颜色
},
{
offset: 1,
color: '#ffffff', // 渐变结束颜色
},
],
global: false, // 缺省为 false
},
},
data: responseData.map((item) => parseValue(item.value)), // Convert to number
},
],
});
chart4Instance.setOption({
title: {
text: '响应时长大于X秒的请求量',
},
tooltip: {
trigger: 'axis', // 使用坐标轴触发提示框,默认为 true
},
legend: {
// 显示图例
data: ['< 1秒', '1 ~ 30秒', '11 ~ 60秒', '> 60秒'],
orient: 'horizontal',
left: '5%',
top: '8%',
},
xAxis: {
type: 'category', // 类目轴
data: totalApiData.map((item) => item.date),
boundaryGap: true, // 柱状图默认是 true,即柱子有间距
axisLabel: {
rotate: 45, // 如果日期较长可以旋转标签以避免重叠
},
},
yAxis: {
type: 'value', // 数值轴
min: 0, // 设置 Y 轴的最小值
max: 600,
splitNumber: 7, // 分割段数,可以根据需要调整
},
barWidth: 20,
series: [
{
name: '> 60秒',
type: 'bar',
stack: 'total', // 设置相同的 stack 值以合并柱状图
color: '#36e385',
data: second1Data.map((item) => item.value),
},
{
name: '11 ~ 60秒',
type: 'bar',
stack: 'total', // 设置相同的 stack 值以合并柱状图
color: '#135adc',
data: second2Data.map((item) => item.value),
},
{
name: '1 ~ 30秒',
type: 'bar',
stack: 'total', // 设置相同的 stack 值以合并柱状图
color: '#7dc6ed',
data: second3Data.map((item) => item.value),
},
{
name: '< 1秒',
type: 'bar',
stack: 'total', // 设置相同的 stack 值以合并柱状图
color: '#da9bfd',
data: second4Data.map((item) => item.value),
},
],
});
}
});
</script> </script>
<style lang="less" scoped></style> <style lang="less" scoped>
.charts-container {
background-color: white; /* 设置容器背景为白色 */
padding: 20px; /* 给容器添加内边距 */
border-radius: 10px; /* 可选:给容器添加圆角 */
width: 100%; /* 确保容器宽度适应父级元素 */
}
.header {
font-size: 20px;
margin-bottom: 20px;
text-align: left;
color: #333;
}
.charts {
display: flex;
justify-content: space-between;
gap: 20px;
}
.chart {
width: calc(50% - 10px); /* 确保两个图表并排显示 */
height: 400px;
background-color: transparent; /* 使图表的背景透明 */
}
</style>
<template>
<BasicTable @register="registerPartitionTable">
<template #bodyCell="{ column }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
label: '查看日志',
},
]"
/>
</template>
</template>
</BasicTable>
</template>
<script lang="ts" setup>
import { BasicTable, TableAction, useTable } from '@/components/Table';
import { partitionColumns } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitor.data';
import { partitionData } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitorData';
const [registerPartitionTable] = useTable({
title: '调用失败记录',
dataSource: partitionData,
columns: partitionColumns,
showIndexColumn: false,
pagination: true,
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
fixed: 'right',
},
scroll: { y: 300 },
});
</script>
<style lang="less" scoped></style>
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<RightContent4 class="!my-4 w-full" :loading="loading" /> <RightContent4 class="!my-4 w-full" :loading="loading" />
<RightContent5 class="!my-4 w-full" :loading="loading" /> <RightContent5 class="!my-4 w-full" :loading="loading" />
<RightContent6 class="!my-4 w-full" :loading="loading" /> <RightContent6 class="!my-4 w-full" :loading="loading" />
<RightContent7 class="!my-4 w-full" :loading="loading" />
</div> </div>
</PageWrapper> </PageWrapper>
</template> </template>
...@@ -27,7 +28,7 @@ ...@@ -27,7 +28,7 @@
import RightContent4 from './RightContent4.vue'; import RightContent4 from './RightContent4.vue';
import RightContent5 from './RightContent5.vue'; import RightContent5 from './RightContent5.vue';
import RightContent6 from './RightContent6.vue'; import RightContent6 from './RightContent6.vue';
import RightContent7 from './RightContent7.vue';
defineOptions({ name: 'AccountManagement' }); defineOptions({ name: 'AccountManagement' });
const { createMessage, createConfirm } = useMessage(); const { createMessage, createConfirm } = useMessage();
const route = useRoute(); const route = useRoute();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment