Commit 21272514 authored by liwei's avatar liwei

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/router/routes/index.ts
parents 5447f8c7 c6cf560c
...@@ -751,6 +751,15 @@ export const serviceDevelopmentRoute: AppRouteRecordRaw = { ...@@ -751,6 +751,15 @@ export const serviceDevelopmentRoute: AppRouteRecordRaw = {
icon: '', icon: '',
}, },
}, },
{
path: 'serviceMonitor/useLog',
name: 'useLog',
component: () => import('@/views/dataService/serviceMonitor/logMangae.vue'),
meta: {
title: '日志管理',
icon: '',
},
},
{ {
path: 'serviceDevelopment/apiDetail', path: 'serviceDevelopment/apiDetail',
name: 'apiDetail', name: 'apiDetail',
......
<template>
<PageWrapper>
</PageWrapper>
</template>
<script lang="ts" setup>
import PageWrapper from "@/components/Page/src/PageWrapper.vue";
</script>
<style scoped>
</style>
<template>
<div class="m-4 mr-0 overflow-hidden bg-white">
<BasicTree
ref="treeRef"
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:defaultExpandAll="true"
:fieldNames="{ key: 'key', title: 'title' }"
:treeData="TreeData"
@select="handleSelect"
/>
</div>
</template>
<script lang="ts" setup>
import { nextTick, onMounted, ref, unref } from 'vue';
import { BasicTree, TreeActionType, TreeItem } from '@/components/Tree';
import { Nullable } from '@vben/types';
import { TreeData } from './monitorData';
defineOptions({ name: 'DeptTree' });
const emit = defineEmits(['select']);
const treeRef = ref<Nullable<TreeActionType>>(null);
function handleSelect(keys) {
emit('select', keys[0]);
}
</script>
<template>
<PageWrapper title="供电单位用电量" contentFullHeight fixedHeight >
<template #extra>
<a-button type="primary" @click="handleLog">调用日志</a-button>
</template>
<template #footer>
<div style="display: flex">
<ModelTree class="w-1/4 xl:w-1/5" @select="handleSelect" />
<div class="w-3/4 xl:w-4/5">
<div style="display: flex; flex-direction: column">
<BasicTable @register="registerTable" :searchInfo="searchInfo" :rowSelection="rowSelection">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon: 'ant-design:stop-outlined',
onClick: handleEdit.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
<div>
<div style="margin-left: 20px; font-weight: bold; font-size: 16px">流量统计</div>
<div style="display: flex">
<div class="w-1/3" style="margin-left: 20px">
<div style="border-left: 3px solid #1396e9; margin-top: 20px; font-size: 15px"
>实时总流量</div
>
<div style="margin-top: 10px; width: 100%; height: 100%; text-align: center">
<img src="../../../assets/images/serviceMinotor.png" style="width: 68%" />
<div style="font-size: 18px">SLB</div>
<div
><span style="font-size: 23px; font-weight: bold">{{ APIRate }}</span
><span style="font-size: 18px; margin-left: 5px">MB/S</span></div
>
</div>
</div>
<div class="w-2/3">
<div style="border-left: 3px solid #1396e9; font-size: 15px; margin-top: 20px"
>流量统计</div
>
<div id="echarts2" style="width: 100%; height: 300px"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
</PageWrapper>
</template>
<script lang="ts" setup>
import { reactive, onMounted, ref } from 'vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { PageWrapper } from '@/components/Page';
import { useMessage } from '@/hooks/web/useMessage';
import { useModal } from '@/components/Modal';
import { columns, searchFormSchema } from './monitor.data';
import { tableList } from './monitorData';
import { router } from '@/router';
import { useRoute, onBeforeRouteLeave } from 'vue-router';
import { Alert } from 'ant-design-vue';
import * as echarts from 'echarts';
import ModelTree from './ModelTree.vue';
type EChartsOption = echarts.EChartsOption;
defineOptions({ name: 'SafetyLevelManage' });
const { createMessage, createConfirm } = useMessage();
const route = useRoute();
const [registerModal, { openModal }] = useModal();
const [registerImport, { openModal: openImportModal }] = useModal();
const searchInfo = reactive<Recordable>({});
const APIRate = ref('375');
const [
registerTable,
{ reload, updateTableDataRecord, getSearchInfo, getForm, getRowSelection },
] = useTable({
title: '执行中请求',
scroll: { y: 500 },
titleHelpMessage: '执行中请求',
api: async (params) => {
const response = {
pageNu: '1',
pageSize: '10',
pages: '1',
total: tableList.length,
code: '',
message: '',
data: tableList,
};
return { ...response };
},
rowKey: 'businessId',
rowSelection: false,
showIndexColumn: false,
columns,
formConfig: {
labelWidth: 100,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
resetFunc: () => {
searchInfo.deptId = '';
},
},
useSearchForm: true,
showTableSetting: false,
bordered: true,
handleSearchInfoFn(info) {
console.log('handleSearchInfoFn', info);
return info;
},
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
},
});
function handleImport() {
openImportModal(true, {});
}
function handleLog() {
router.push({
path: '/dataService/serviceMonitor/useLog',
});
}
function handleDeleteIds() {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '确认批量删除选中数据吗?',
onOk() {
createMessage.success('批量删除成功!');
},
});
}
/** 部门树的select*/
function handleSelect(key) {
if (key !== null && key !== undefined) {
modelLevel.value = key.split('-').length - 1;
} else {
modelLevel.value = 0;
}
if (modelLevel.value > 1) {
const regex = new RegExp(key, 'i');
const data = tableList.value.filter(
(item) => item.type === 'model' && regex.test(item.themeId),
);
setTableData(data);
} else {
const regex = new RegExp(key, 'i');
const data = tableData.value.filter(
(item) => item.type === 'theme' && regex.test(item.themeId),
);
setTableData(data);
}
}
/** 新增按钮*/
function handleCreate() {
openModal(true, {
isUpdate: false,
});
}
/** 编辑按钮*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
});
}
/** 重置密码弹窗确定按钮*/
/** 删除按钮*/
function handleDelete(record: Recordable) {
const rowSelection = getRowSelection().selectedRowKeys;
console.log('11111111111', rowSelection);
createMessage.success('删除成功!');
reload();
}
/** 新增/编辑成功*/
function handleSuccess({ isUpdate, values }) {
if (isUpdate) {
// 演示不刷新表格直接更新内部数据。
// 注意:updateTableDataRecord要求表格的rowKey属性为string并且存在于每一行的record的keys中
const result = updateTableDataRecord(values.id, values);
console.log(result);
reload();
} else {
reload();
}
}
function getEcharts2() {
const chartDom = document.getElementById('echarts2')!;
const myChart = echarts.init(chartDom);
let option: EChartsOption;
option = {
grid: {
left: '5%',
right: '5%',
top: '10%',
bottom: '7%',
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['10/01', '10/02', '10/03', '10/04', '10/05', '10/06', '10/07'],
},
yAxis: {
type: 'value',
min: 0,
max: 2500000,
interval: 500000,
axisLabel: {
formatter: function (value, index) {
var value;
if (value >= 1000 && value < 1000000) {
value = value / 1000 + 'k';
} else if (value >= 1000000) {
value = value / 1000000 + 'Mil';
} else if (value < 1000) {
value = value;
}
return value;
},
},
},
series: [
{
data: [1500000, 2000000, 1700000, 2300000, 1100000, 2300000, 1700000],
type: 'line',
areaStyle: {},
},
],
};
option && myChart.setOption(option);
}
onMounted(() => {
getEcharts2();
});
</script>
<template>
<PageWrapper title="调用日志管理" contentFullHeight fixedHeight contentClass="flex">
<template #footer>
<BasicTable @register="registerTable" :searchInfo="searchInfo" :rowSelection="rowSelection">
<template #toolbar>
<a-button type="link" :disabled="getRowSelection().selectedRowKeys <= 0"
>下载日志</a-button
>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
label: '查看日志',
disabled: record.isAPI,
onClick: handleView.bind(null, record),
},
{
label: '下载日志',
disabled: record.isAPI,
onClick: handleDownLoad.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
</template>
</PageWrapper>
</template>
<script lang="ts" setup>
import { reactive, onMounted, ref } from 'vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { PageWrapper } from '@/components/Page';
import { useMessage } from '@/hooks/web/useMessage';
import { useModal } from '@/components/Modal';
import { logColumns, logSearchFormSchema } from './monitor.data';
import { logTableList } from './monitorData';
import { useRoute, onBeforeRouteLeave } from 'vue-router';
import { Alert } from 'ant-design-vue';
import * as echarts from 'echarts';
type EChartsOption = echarts.EChartsOption;
defineOptions({ name: 'SafetyLevelManage' });
const { createMessage, createConfirm } = useMessage();
const route = useRoute();
const [registerModal, { openModal }] = useModal();
const [registerImport, { openModal: openImportModal }] = useModal();
const searchInfo = reactive<Recordable>({});
const APIRate = ref('375');
const [
registerTable,
{ reload, updateTableDataRecord, getSearchInfo, getForm, getRowSelection },
] = useTable({
scroll: { y: 500 },
titleHelpMessage: '执行中请求',
api: async (params) => {
const response = {
pageNu: '1',
pageSize: '10',
pages: '1',
total: logTableList.length,
code: '',
message: '',
data: logTableList,
};
return { ...response };
},
rowKey: 'businessId',
rowSelection: true,
showIndexColumn: false,
columns: logColumns,
formConfig: {
labelWidth: 60,
schemas: logSearchFormSchema,
autoSubmitOnEnter: true,
resetFunc: () => {
searchInfo.deptId = '';
},
},
useSearchForm: true,
showTableSetting: false,
bordered: true,
handleSearchInfoFn(info) {
console.log('handleSearchInfoFn', info);
return info;
},
actionColumn: {
width: 150,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
},
});
function handleDownLoad() {}
function handleView() {}
function handleDeleteIds() {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '确认批量删除选中数据吗?',
onOk() {
createMessage.success('批量删除成功!');
},
});
}
/** 重置密码弹窗确定按钮*/
/** 删除按钮*/
function handleDelete(record: Recordable) {
const rowSelection = getRowSelection().selectedRowKeys;
console.log('11111111111', rowSelection);
createMessage.success('删除成功!');
reload();
}
/** 新增/编辑成功*/
function handleSuccess({ isUpdate, values }) {
if (isUpdate) {
// 演示不刷新表格直接更新内部数据。
// 注意:updateTableDataRecord要求表格的rowKey属性为string并且存在于每一行的record的keys中
const result = updateTableDataRecord(values.id, values);
console.log(result);
reload();
} else {
reload();
}
}
onMounted(() => {});
</script>
import { FormSchema } from '@/components/Form';
import { BasicColumn } from '@/components/Table';
import moment from "moment";
export const searchFormSchema: FormSchema[] = [
{
field: 'APIName',
label: '调用方',
component: 'Select',
colProps: { span: 4 },
componentProps: {
options: [
{ value: 'admin', label: 'admin' },
{ value: '个人', label: '个人' },
{ value: 'user', label: 'user' },
],
defaultValue: 'admin',
},
},
{
field: 'callTime',
label: '调用时间',
component: 'RangePicker',
colProps: { span: 4 },
defaultValue: [moment().subtract(7, 'days').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')],
componentProps: {
},
},
{
field: 'callUseTime',
label: '调用有效期',
component: 'DatePicker',
colProps: { span: 4 },
},
];
export const logSearchFormSchema: FormSchema[] = [
{
field: 'callTime',
label: '调用时间',
component: 'RangePicker',
colProps: { span: 4 },
// defaultValue: [moment().subtract(7, 'days').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')],
},
];
export const columns: BasicColumn[] = [
{
title: 'gateway',
dataIndex: 'gateway',
width: 120,
},
{
title: 'executor',
dataIndex: 'executor',
width: 120,
},
{
title: '数据源',
dataIndex: 'dataSource',
width: 120,
},
{
title: '调用方',
dataIndex: 'useBy',
width: 140,
},
{
title: '开始时间',
dataIndex: 'startTime',
width: 140,
},
{
title: '已耗时',
dataIndex: 'consumeTime',
width: 180,
},
];
export const logColumns: BasicColumn[] = [
{
title: '路由名称',
dataIndex: 'routerName',
width: 120,
},
{
title: 'IP',
dataIndex: 'ipName',
width: 120,
},
{
title: '调用时间',
dataIndex: 'useTime',
width: 120,
},
{
title: '调用状态',
dataIndex: 'useStatus',
width: 140,
},
{
title: '调用时长',
dataIndex: 'useTimeLength',
width: 140,
},
{
title: 'Http错误码',
dataIndex: 'herrorNum',
width: 180,
},
{
title: '业务错误码',
dataIndex: 'taskErrorNum',
width: 180,
},
{
title: '调用方',
dataIndex: 'useBy',
width: 180,
},
];
export const tableList: any[] = [
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021-02-21 15:55:16',
consumeTime: '2s',
themeId: '1-1-1',
},
{
gateway: '168.19.18.19',
businessId: 309,
executor: '19.10.189.10',
dataSource: 'dataset_meta',
useBy: '李丽',
startTime: '2021-02-21 15:55:16',
consumeTime: '3s',
themeId: '1-1-1',
},
{
gateway: '179.18.100.18',
businessId: 309,
executor: '190.187.10.10',
dataSource: 'inceptor数据源',
useBy: '崔大山',
startTime: '2021-02-21 15:55:16',
consumeTime: '15',
themeId: '1-1-2',
},
{
gateway: '172.190.187.178',
businessId: 309,
executor: '183.180.190.190',
dataSource: 'postgres',
useBy: '张小北',
startTime: '20210221 15:55:16',
consumeTime: '4s',
themeId: '1-1-2',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
{
gateway: '172.179.90.19',
businessId: 309,
executor: '156.190.189.10',
dataSource: 'mysql',
useBy: '张三',
startTime: '2021022115:55:16',
consumeTime: '2s',
},
];
export const logTableList = [
{
routerName: 'employee',
businessId: 309,
isAPI: true,
ipName: '172.22.204.228',
useTime: '2023/01/12 16:40:35',
useStatus: '成功',
useTimeLength: '663.0 ms',
herrorNum: '-',
taskErrorNum: '-',
useBy: 'apiuser',
},
{
routerName: 'employee',
businessId: 310,
isAPI: false,
ipName: '172.22.204.228',
useTime: '2023/01/12 16:40:35',
useStatus: '成功',
useTimeLength: '663.0 ms',
herrorNum: '-',
taskErrorNum: '-',
useBy: 'apiuser',
},
];
export const TreeData = [
{
key: '1',
title: 'API监控',
level: '0',
children: [
{
key: '1-1',
title: '三方API-ip-urlpath',
level: '1',
children: [
{ key: '1-1-1', title: 'test01_1', level: '2' },
{ key: '1-1-2', title: 'test', level: '2' },
],
},
{
key: '1-2',
title: '三方托管',
level: '1',
children: [
{ key: '1-2-1', title: 'test01_2', level: '2' },
{ key: '1-2-2', title: 'test01', level: '2' },
],
},
{
key: '1-3',
title: '三方API',
level: '1',
children: [
{ key: '1-3-1', title: 'test01_3', level: '2' },
{ key: '1-3-2', title: 'TEST', level: '2' },
],
},
],
},
{
key: '2',
title: 'admin-个人工作区',
level: '0',
children: [
{
key: '2-1',
title: '三方API-ip-urlpath',
level: '2',
children: [
{ key: '2-1-1', title: 'test01_1', level: '2' },
{ key: '2-1-2', title: 'test', level: '2' },
],
},
{
key: '2-2',
title: '三方托管',
level: '2',
children: [
{ key: '2-2-1', title: 'test01_2', level: '2' },
{ key: '2-2-2', title: 'test01', level: '2' },
],
},
{
key: '2-3',
title: '三方API',
level: '2',
children: [
{ key: '2-3-1', title: 'test01_3', level: '2' },
{ key: '2-3-2', title: 'TEST', level: '2' },
],
},
],
},
{
key: '3',
title: '共享工作区',
level: '3',
children: [
{
key: '3-1',
title: '三方API-ip-urlpath',
level: '3',
children: [
{ key: '3-1-1', title: 'test01_1', level: '2' },
{ key: '3-1-2', title: 'test', level: '2' },
],
},
{
key: '3-2',
title: '三方托管',
level: '3',
children: [
{ key: '3-2-1', title: 'test01_2', level: '2' },
{ key: '3-2-2', title: 'test01', level: '2' },
],
},
{
key: '3-3',
title: '三方API',
level: '3',
children: [
{ key: '3-3-1', title: 'test01_3', level: '2' },
{ key: '3-3-2', title: 'TEST', level: '2' },
],
},
],
},
];
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