mirror of
https://github.com/didi/KnowStreaming.git
synced 2026-01-05 21:12:13 +08:00
初始化3.0.0版本
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
// @ts-nocheck
|
||||
|
||||
import { notification, Utils } from 'knowdesign';
|
||||
const { EventBus } = Utils;
|
||||
export const licenseEventBus = new EventBus();
|
||||
|
||||
export const goLogin = () => {
|
||||
if (!window.location.pathname.includes('login')) {
|
||||
// notification.error({ message: '当前未登录,将自动跳转到登录页' });
|
||||
window.history.replaceState({}, '', `/login?redirect=${window.location.href.slice(window.location.origin.length)}`);
|
||||
}
|
||||
};
|
||||
|
||||
const serviceInstance = Utils.service;
|
||||
|
||||
// 清除 axios 实例默认的响应拦截
|
||||
serviceInstance.interceptors.response.handlers = [];
|
||||
|
||||
// 请求拦截
|
||||
serviceInstance.interceptors.request.use(
|
||||
(config: any) => {
|
||||
const user = Utils.getCookie('X-SSO-USER');
|
||||
const id = Utils.getCookie('X-SSO-USER-ID');
|
||||
if ((!user || !id) && !window.location.pathname.toLowerCase().startsWith('/login')) {
|
||||
goLogin();
|
||||
} else {
|
||||
config.headers['X-SSO-USER'] = user; // 请求携带token
|
||||
config.headers['X-SSO-USER-ID'] = id;
|
||||
return config;
|
||||
}
|
||||
},
|
||||
(err: any) => {
|
||||
return err;
|
||||
}
|
||||
);
|
||||
|
||||
// 响应拦截
|
||||
serviceInstance.interceptors.response.use(
|
||||
(config: any) => {
|
||||
const res: { code: number; message: string; data: any } = config.data;
|
||||
if (res.code !== 0 && res.code !== 200) {
|
||||
const desc = res.message;
|
||||
// TODO: ---
|
||||
if (res.code === 1000000000 || res.code === 1000000001 || res.code === 1000000002) {
|
||||
licenseEventBus.emit('licenseError', desc);
|
||||
} else {
|
||||
notification.error({
|
||||
message: desc,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
throw res;
|
||||
}
|
||||
return res;
|
||||
},
|
||||
(err: any) => {
|
||||
const config = err.config;
|
||||
if (!config || !config.retryTimes) return dealResponse(err, config.customNotification);
|
||||
const { __retryCount = 0, retryDelay = 300, retryTimes } = config;
|
||||
config.__retryCount = __retryCount;
|
||||
if (__retryCount >= retryTimes) {
|
||||
return dealResponse(err);
|
||||
}
|
||||
config.__retryCount++;
|
||||
const delay = new Promise<void>((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, retryDelay);
|
||||
});
|
||||
// 重新发起请求
|
||||
return delay.then(function () {
|
||||
return serviceInstance(config);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const dealResponse = (error: any) => {
|
||||
if (error?.response) {
|
||||
switch (error.response.status) {
|
||||
case 401:
|
||||
goLogin();
|
||||
break;
|
||||
case 403:
|
||||
location.href = '/403';
|
||||
break;
|
||||
case 405:
|
||||
notification.error({
|
||||
message: '错误',
|
||||
duration: 3,
|
||||
description: `${error.response.data.message || '请求方式错误'}`,
|
||||
});
|
||||
break;
|
||||
case 500:
|
||||
notification.error({
|
||||
message: '错误',
|
||||
duration: 3,
|
||||
description: '服务错误,请重试!',
|
||||
});
|
||||
break;
|
||||
case 502:
|
||||
notification.error({
|
||||
message: '错误',
|
||||
duration: 3,
|
||||
description: '网络错误,请重试!',
|
||||
});
|
||||
break;
|
||||
default:
|
||||
notification.error({
|
||||
message: '连接出错',
|
||||
duration: 3,
|
||||
description: `${error.response.status}`,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
notification.error({
|
||||
description: '请重试或检查服务',
|
||||
message: '连接超时! ',
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
return Promise.reject(error);
|
||||
};
|
||||
@@ -0,0 +1,213 @@
|
||||
import moment from 'moment';
|
||||
|
||||
export const UNIT_MAP = {
|
||||
TB: Math.pow(1024, 4),
|
||||
GB: Math.pow(1024, 3),
|
||||
MB: Math.pow(1024, 2),
|
||||
KB: 1024,
|
||||
};
|
||||
|
||||
export const DATA_NUMBER_MAP = {
|
||||
十亿: Math.pow(1000, 3),
|
||||
百万: Math.pow(1000, 2),
|
||||
千: 1000,
|
||||
};
|
||||
|
||||
export const getUnit = (value: number) => Object.entries(UNIT_MAP).find(([, size]) => value / size >= 1) || ['Byte', 1];
|
||||
|
||||
export const getDataNumberUnit = (value: number) => Object.entries(DATA_NUMBER_MAP).find(([, size]) => value / size >= 1) || ['', 1];
|
||||
|
||||
// 图表 tooltip 基础展示样式
|
||||
const tooltipFormatter = (date: any, arr: any, tooltip: any) => {
|
||||
// 从大到小排序
|
||||
// arr = arr.sort((a: any, b: any) => b.value - a.value);
|
||||
const str = arr
|
||||
.map(
|
||||
(item: any) => `<div style="margin: 3px 0;">
|
||||
<div style="display:flex;align-items:center;">
|
||||
<div style="margin-right:4px;width:8px;height:2px;background-color:${item.color};"></div>
|
||||
<div style="flex:1;display:flex;justify-content:space-between;align-items:center;overflow: hidden;">
|
||||
<span style="font-size:12px;color:#74788D;pointer-events:auto;margin-left:2px;line-height: 18px;font-family: HelveticaNeue;overflow: hidden; text-overflow: ellipsis; white-space: no-wrap;">
|
||||
${item.seriesName}
|
||||
</span>
|
||||
<span style="font-size:12px;color:#212529;line-height:18px;font-family:HelveticaNeue-Medium; padding-left: 6px;">
|
||||
${parseFloat(Number(item.value[1]).toFixed(3))}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
)
|
||||
.join('');
|
||||
|
||||
return `<div style="margin: 0px 0 0; position: relative; z-index: 99;width: ${
|
||||
tooltip.customWidth ? tooltip.customWidth + 'px' : 'fit-content'
|
||||
};">
|
||||
<div style="padding: 8px 0;height: 100%;">
|
||||
<div style="font-size:12px;padding: 0 12px;color:#212529;line-height:20px;font-family: HelveticaNeue;">
|
||||
${date}
|
||||
</div>
|
||||
<div style="${
|
||||
tooltip.legendContextMaxHeight ? 'max-height: ' + tooltip.legendContextMaxHeight + 'px' : ''
|
||||
}; margin: 4px 0 0 0;overflow-y:auto;padding: 0 12px;">
|
||||
${str}
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
};
|
||||
|
||||
// 折线图基础主题配置,返回 echarts 配置项。详见 https://echarts.apache.org/zh/option.html
|
||||
export const getBasicChartConfig = (props: any = {}) => {
|
||||
const { title = {}, grid = {}, legend = {}, xAxis = {}, yAxis = {}, tooltip = {}, ...restConfig } = props;
|
||||
return {
|
||||
title: {
|
||||
show: true,
|
||||
text: '示例标题',
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
fontFamily: 'HelveticaNeue-Medium',
|
||||
color: '#212529',
|
||||
letterSpacing: 0.5,
|
||||
lineHeight: 16,
|
||||
rich: {
|
||||
unit: {
|
||||
fontSize: 12,
|
||||
fontFamily: 'HelveticaNeue-Medium',
|
||||
color: '#495057',
|
||||
lineHeight: 16,
|
||||
},
|
||||
},
|
||||
},
|
||||
top: 12,
|
||||
left: 16,
|
||||
zlevel: 1,
|
||||
...title,
|
||||
},
|
||||
// 图表整体布局
|
||||
grid: {
|
||||
zlevel: 0,
|
||||
top: 60,
|
||||
left: 22,
|
||||
right: 16,
|
||||
bottom: 40,
|
||||
containLabel: true,
|
||||
...grid,
|
||||
},
|
||||
// 图例配置
|
||||
legend: {
|
||||
zlevel: 1,
|
||||
type: 'scroll',
|
||||
orient: 'horizontal',
|
||||
left: 20,
|
||||
top: 'auto',
|
||||
bottom: 12,
|
||||
icon: 'rect',
|
||||
itemHeight: 2,
|
||||
itemWidth: 8,
|
||||
itemGap: 8,
|
||||
textStyle: {
|
||||
width: 85,
|
||||
overflow: 'truncate',
|
||||
ellipsis: '...',
|
||||
fontSize: 11,
|
||||
lineHeight: 12,
|
||||
color: '#74788D',
|
||||
},
|
||||
pageIcons: {
|
||||
horizontal: [
|
||||
'path://M474.496 512l151.616 151.616a9.6 9.6 0 0 1 0 13.568l-31.68 31.68a9.6 9.6 0 0 1-13.568 0l-190.08-190.08a9.6 9.6 0 0 1 0-13.568l190.08-190.08a9.6 9.6 0 0 1 13.568 0l31.68 31.68a9.6 9.6 0 0 1 0 13.568L474.496 512z',
|
||||
'path://M549.504 512L397.888 360.384a9.6 9.6 0 0 1 0-13.568l31.68-31.68a9.6 9.6 0 0 1 13.568 0l190.08 190.08a9.6 9.6 0 0 1 0 13.568l-190.08 190.08a9.6 9.6 0 0 1-13.568 0l-31.68-31.68a9.6 9.6 0 0 1 0-13.568L549.504 512z',
|
||||
],
|
||||
},
|
||||
pageIconColor: '#495057',
|
||||
pageIconInactiveColor: '#ADB5BC',
|
||||
pageIconSize: 6,
|
||||
...legend,
|
||||
},
|
||||
// 横坐标配置
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: true,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#c5c5c5',
|
||||
width: 1,
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
formatter: (value: number) => {
|
||||
value = Number(value);
|
||||
return [`{date|${moment(value).format('MM-DD')}}`, `{time|${moment(value).format('HH:mm')}}`].join('\n');
|
||||
},
|
||||
padding: 0,
|
||||
rich: {
|
||||
date: {
|
||||
color: '#495057',
|
||||
fontSize: 11,
|
||||
lineHeight: 18,
|
||||
fontFamily: 'HelveticaNeue',
|
||||
},
|
||||
time: {
|
||||
color: '#ADB5BC',
|
||||
fontSize: 11,
|
||||
lineHeight: 11,
|
||||
fontFamily: 'HelveticaNeue',
|
||||
},
|
||||
},
|
||||
},
|
||||
...xAxis,
|
||||
},
|
||||
// 纵坐标配置
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
interval: 0,
|
||||
hideOverlap: false,
|
||||
color: '#495057',
|
||||
fontSize: 12,
|
||||
lineHeight: 20,
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
type: 'dashed',
|
||||
color: ['#E4E7ED'],
|
||||
},
|
||||
},
|
||||
...yAxis,
|
||||
},
|
||||
// 提示框浮层配置
|
||||
tooltip: {
|
||||
position: function (pos: any, params: any, el: any, elRect: any, size: any) {
|
||||
const tooltipWidth = el.offsetWidth || 120;
|
||||
const result =
|
||||
tooltipWidth + pos[0] < size.viewSize[0]
|
||||
? {
|
||||
top: 40,
|
||||
left: pos[0] + 30,
|
||||
}
|
||||
: {
|
||||
top: 40,
|
||||
left: pos[0] - tooltipWidth - 30,
|
||||
};
|
||||
return result;
|
||||
},
|
||||
formatter: function (params: any) {
|
||||
let res = '';
|
||||
if (params != null && params.length > 0) {
|
||||
// 传入tooltip是为了便于拿到外部传入的控制这个自定义浮层的样式
|
||||
// 例如tooltip里写customWidth: 200,则tooltipFormatter里可以取出这个宽度使用
|
||||
res += tooltipFormatter(moment(Number(params[0].axisValue)).format('YYYY-MM-DD HH:mm'), params, tooltip);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
extraCssText:
|
||||
'padding: 0;box-shadow: 0 -2px 4px 0 rgba(0,0,0,0.02), 0 2px 6px 6px rgba(0,0,0,0.02), 0 2px 6px 0 rgba(0,0,0,0.06);border-radius: 8px;',
|
||||
axisPointer: {
|
||||
type: 'line',
|
||||
},
|
||||
...tooltip,
|
||||
},
|
||||
...restConfig,
|
||||
};
|
||||
};
|
||||
139
km-console/packages/layout-clusters-fe/src/constants/common.ts
Executable file
139
km-console/packages/layout-clusters-fe/src/constants/common.ts
Executable file
@@ -0,0 +1,139 @@
|
||||
export const defaultPagination = {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
};
|
||||
|
||||
export const defaultPaginationConfig = {
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ['10', '20', '50', '100', '200', '500'],
|
||||
showTotal: (total: number) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
export const cellStyle = {
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap' as any,
|
||||
textOverflow: 'ellipsis',
|
||||
cursor: 'pointer',
|
||||
maxWidth: 150,
|
||||
};
|
||||
|
||||
export const systemCipherKey = 'Szjx2022@666666$';
|
||||
|
||||
export const oneDayMillims = 24 * 60 * 60 * 1000;
|
||||
|
||||
export const classNamePrefix = 'bdp';
|
||||
|
||||
export const timeFormat = 'YYYY-MM-DD HH:mm:ss';
|
||||
|
||||
export const dateFormat = 'YYYY-MM-DD';
|
||||
|
||||
export const SMALL_DRAWER_WIDTH = 480;
|
||||
export const MIDDLE_DRAWER_WIDTH = 728;
|
||||
export const LARGE_DRAWER_WIDTH = 1080;
|
||||
|
||||
// 小间隔(1 分钟)图表点的最大请求时间范围,单位: ms
|
||||
export const MAX_TIME_RANGE_WITH_SMALL_POINT_INTERVAL = 6 * 60 * 60 * 1000;
|
||||
|
||||
export const primaryColor = '#556EE6';
|
||||
|
||||
export const numberToFixed = (value: number, num = 2) => {
|
||||
if (value === null || isNaN(value)) return '-';
|
||||
value = Number(value);
|
||||
return Number.isInteger(value) ? value : value.toFixed(num);
|
||||
};
|
||||
|
||||
const K = 1024;
|
||||
const M = 1024 * K;
|
||||
const G = 1024 * M;
|
||||
const T = 1024 * G;
|
||||
|
||||
export const getSizeAndUnit: any = (value: any, unitSuffix?: any, num = 2) => {
|
||||
if (value === null || value === undefined || isNaN(+value)) {
|
||||
return { value: null, unit: '', valueWithUnit: '-' };
|
||||
}
|
||||
|
||||
if (value <= K) {
|
||||
return { value: numberToFixed(value, num), unit: '' + unitSuffix, valueWithUnit: numberToFixed(value) + '' + unitSuffix };
|
||||
}
|
||||
if (value > K && value < M) {
|
||||
return { value: numberToFixed(value / K, num), unit: 'K' + unitSuffix, valueWithUnit: numberToFixed(value / K) + 'K' + unitSuffix };
|
||||
}
|
||||
if (value >= M && value < G) {
|
||||
return { value: numberToFixed(value / M, num), unit: 'M' + unitSuffix, valueWithUnit: numberToFixed(value / M) + 'M' + unitSuffix };
|
||||
}
|
||||
if (value >= G && value < T) {
|
||||
return { value: numberToFixed(value / G, num), unit: 'G' + unitSuffix, valueWithUnit: numberToFixed(value / G) + 'G' + unitSuffix };
|
||||
}
|
||||
if (value >= T) {
|
||||
return { value: numberToFixed(value / T, num), unit: 'T' + unitSuffix, valueWithUnit: numberToFixed(value / T) + 'T' + unitSuffix };
|
||||
}
|
||||
return '-';
|
||||
};
|
||||
|
||||
export const orderTypeMap: any = {
|
||||
ascend: 'asc',
|
||||
descend: 'desc',
|
||||
};
|
||||
|
||||
export const dealTableRequestParams = ({ searchKeywords, pageNo, pageSize, sorter, filters, isPhyId = undefined }: any) => {
|
||||
const _params = {
|
||||
searchKeywords,
|
||||
pageNo,
|
||||
pageSize,
|
||||
isPhyId,
|
||||
};
|
||||
if (sorter && sorter.field && sorter.order) {
|
||||
Object.assign(_params, {
|
||||
sortField: sorter.field,
|
||||
sortType: orderTypeMap[sorter.order],
|
||||
});
|
||||
}
|
||||
if (filters) {
|
||||
const filterDTOList = [];
|
||||
for (const key of Object.keys(filters)) {
|
||||
if (filters[key]) {
|
||||
filterDTOList.push({
|
||||
fieldName: key,
|
||||
fieldValueList: filters[key],
|
||||
});
|
||||
}
|
||||
}
|
||||
Object.assign(_params, {
|
||||
filterDTOList,
|
||||
});
|
||||
}
|
||||
|
||||
return _params;
|
||||
};
|
||||
|
||||
// url hash Parse
|
||||
export const hashDataParse = (hash: string) => {
|
||||
const newHashData: any = {};
|
||||
hash
|
||||
.slice(1)
|
||||
.split('&')
|
||||
.forEach((str: string) => {
|
||||
const hashStr = str.split('=');
|
||||
newHashData[hashStr[0]] = hashStr[1];
|
||||
});
|
||||
|
||||
return newHashData;
|
||||
};
|
||||
|
||||
const BUSINESS_VERSION = process.env.BUSINESS_VERSION;
|
||||
|
||||
export const getLicenseInfo = (cbk: (msg: string) => void) => {
|
||||
if (BUSINESS_VERSION) {
|
||||
const info = (window as any).code;
|
||||
if (!info) {
|
||||
setTimeout(() => getLicenseInfo(cbk), 1000);
|
||||
} else {
|
||||
const res = info() || {};
|
||||
if (res.code !== 0) {
|
||||
cbk(res.msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
145
km-console/packages/layout-clusters-fe/src/constants/menu.ts
Executable file
145
km-console/packages/layout-clusters-fe/src/constants/menu.ts
Executable file
@@ -0,0 +1,145 @@
|
||||
import { ClustersPermissionMap } from '@src/pages/CommonConfig';
|
||||
|
||||
const pkgJson = require('../../package');
|
||||
export const systemKey = pkgJson.ident;
|
||||
|
||||
export const leftMenus = (clusterId?: string) => ({
|
||||
name: `${systemKey}`,
|
||||
icon: 'icon-jiqun',
|
||||
path: `cluster/${clusterId}`,
|
||||
children: [
|
||||
{
|
||||
name: 'cluster',
|
||||
path: 'cluster',
|
||||
icon: 'icon-Cluster',
|
||||
children: [
|
||||
{
|
||||
name: 'overview',
|
||||
path: '',
|
||||
icon: '#icon-luoji',
|
||||
},
|
||||
process.env.BUSINESS_VERSION
|
||||
? {
|
||||
name: 'balance',
|
||||
path: 'balance',
|
||||
icon: '#icon-luoji',
|
||||
}
|
||||
: undefined,
|
||||
].filter((m) => m),
|
||||
},
|
||||
{
|
||||
name: 'broker',
|
||||
path: 'broker',
|
||||
icon: 'icon-Brokers',
|
||||
children: [
|
||||
{
|
||||
name: 'dashbord',
|
||||
path: '',
|
||||
icon: '#icon-luoji',
|
||||
},
|
||||
{
|
||||
name: 'list',
|
||||
path: 'list',
|
||||
icon: '#icon-jiqun1',
|
||||
},
|
||||
{
|
||||
name: 'controller-changelog',
|
||||
path: 'controller-changelog',
|
||||
icon: '#icon-jiqun1',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'topic',
|
||||
path: 'topic',
|
||||
icon: 'icon-Topics',
|
||||
children: [
|
||||
{
|
||||
name: 'dashbord',
|
||||
path: '',
|
||||
icon: 'icon-luoji',
|
||||
},
|
||||
{
|
||||
name: 'list',
|
||||
path: 'list',
|
||||
icon: 'icon-luoji',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'consumer-group',
|
||||
path: 'consumers',
|
||||
icon: 'icon-ConsumerGroups',
|
||||
// children: [
|
||||
// {
|
||||
// name: 'operating-state',
|
||||
// path: 'operating-state/list',
|
||||
// icon: '#icon-luoji',
|
||||
// },
|
||||
// {
|
||||
// name: 'group-list',
|
||||
// path: 'group-list',
|
||||
// icon: '#icon-luoji',
|
||||
// },
|
||||
// ],
|
||||
},
|
||||
process.env.BUSINESS_VERSION
|
||||
? {
|
||||
name: 'produce-consume',
|
||||
path: 'testing',
|
||||
icon: 'icon-a-ProduceConsume',
|
||||
permissionPoint: [ClustersPermissionMap.TEST_CONSUMER, ClustersPermissionMap.TEST_PRODUCER],
|
||||
children: [
|
||||
{
|
||||
name: 'producer',
|
||||
path: 'producer',
|
||||
icon: 'icon-luoji',
|
||||
permissionPoint: ClustersPermissionMap.TEST_PRODUCER,
|
||||
},
|
||||
{
|
||||
name: 'consumer',
|
||||
path: 'consumer',
|
||||
icon: 'icon-luoji',
|
||||
permissionPoints: ClustersPermissionMap.TEST_CONSUMER,
|
||||
},
|
||||
],
|
||||
}
|
||||
: undefined,
|
||||
{
|
||||
name: 'security',
|
||||
path: 'security',
|
||||
icon: 'icon-ACLs',
|
||||
children: [
|
||||
{
|
||||
name: 'acls',
|
||||
path: 'acls',
|
||||
icon: 'icon-luoji',
|
||||
},
|
||||
{
|
||||
name: 'users',
|
||||
path: 'users',
|
||||
icon: 'icon-luoji',
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// name: 'acls',
|
||||
// path: 'acls',
|
||||
// icon: 'icon-wodegongzuotai',
|
||||
// },
|
||||
{
|
||||
name: 'jobs',
|
||||
path: 'jobs',
|
||||
icon: 'icon-Jobs',
|
||||
},
|
||||
].filter((m) => m),
|
||||
});
|
||||
|
||||
// key值需要与locale zh 中key值一致
|
||||
export const permissionPoints = {
|
||||
[`menu.${systemKey}.home`]: true,
|
||||
};
|
||||
|
||||
export const ROUTER_CACHE_KEYS = {
|
||||
home: `menu.${systemKey}.home`,
|
||||
};
|
||||
Reference in New Issue
Block a user