初始化3.0.0版本

This commit is contained in:
zengqiao
2022-08-18 17:04:05 +08:00
parent 462303fca0
commit 51832385b1
2446 changed files with 93177 additions and 127211 deletions

View File

@@ -0,0 +1,433 @@
import React, { useState, useEffect, useRef } from 'react';
import { Select, Form, Utils, AppContainer, Input, Button, ProTable, Badge, Tag, SearchInput } from 'knowdesign';
import BalanceDrawer from './BalanceDrawer';
import HistoryDrawer from './HistoryDrawer';
import DBreadcrumb from 'knowdesign/lib/extend/d-breadcrumb';
import { getSizeAndUnit } from '../../constants/common';
import api from '../../api';
import './index.less';
import LoadRebalanceCardBar from '@src/components/CardBar/LoadRebalanceCardBar';
import { BalanceFilter } from './BalanceFilter';
const Balance_Status_OPTIONS = [
{
label: '全部',
value: null,
},
{
label: '已均衡',
value: 0,
},
{
label: '未均衡',
value: 2,
},
];
const balanceStatus: any = {
0: '已均衡',
2: '未均衡',
};
const filterNorms: any = {
['disk']: 'Disk',
['bytesIn']: 'Byte In',
['bytesOut']: 'Byte Out',
};
export const defaultPagination = {
current: 1,
pageSize: 10,
position: 'bottomRight',
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
};
const LoadBalance: React.FC = (props: any) => {
const [global] = AppContainer.useGlobalValue();
const [form] = Form.useForm();
const [pagination, setPagination] = useState<any>(defaultPagination);
const [loading, setLoading] = useState<boolean>(true);
const [data, setData] = useState([]);
const [visible, setVisible] = useState<boolean>(false);
const [isCycle, setIsCycle] = useState<boolean>(false);
const [planVisible, setPlanVisible] = useState<boolean>(false);
const [circleFormData, setCircleFormData] = useState(null);
const [trigger, setTrigger] = useState(false);
const [filterList, setFilterList] = useState<any>(null);
const [balanceList, setBalanceList] = useState<string>(null);
const [searchKeywords, setSearchKeywords] = useState<string>('');
const [searchValue, setSearchValue] = useState<string>('');
const columns = () => [
{
title: 'Broker ID',
dataIndex: 'brokerId',
key: 'brokerId',
fixed: 'left',
width: 140,
},
{
title: 'Host',
dataIndex: 'host',
key: 'host',
width: 140,
},
{
title: 'Leader',
dataIndex: 'leader',
key: 'leader',
width: 100,
},
{
title: 'Replicas',
dataIndex: 'replicas',
key: 'replicas',
width: 100,
},
// {
// title: 'CPU',
// children: [
// {
// title: '规格',
// dataIndex: 'cpu_spec',
// key: 'cpu_spec',
// render: (text: any, row: any) => {
// return text !== null ? `${text}` : '-';
// },
// },
// {
// title: 'AVG',
// dataIndex: 'cpu_avg',
// key: 'cpu_avg',
// render: (text: any, row: any) => {
// return text !== null ? `${text} (${(row.cpu_avg * 100 / row.cpu_spec).toFixed(2)}%)` : '-';
// },
// },
// {
// title: '是否均衡',
// dataIndex: 'cpu_status',
// key: 'cpu_status',
// render: (text: any, row: any) => {
// // 0:已均衡非0:未均衡
// return text !== null ? (text === 0 ? (
// <span className="isbalance">
// <span className="dot"></span>已均衡
// </span>
// ) : (
// <span className="noBalance">
// <span className="dot"></span>未均衡
// </span>
// )) : '-';
// },
// },
// ],
// },
{
title: 'Disk规格',
dataIndex: 'disk_spec',
key: 'disk_spec',
width: '150px',
render: (text: any, row: any) => {
return text !== null ? `${text}GB` : '-';
},
},
{
title: 'Disk AVG',
dataIndex: 'disk_avg',
key: 'disk_avg',
width: '200px',
render: (text: any, row: any) => {
return text !== null ? (
<span>
<Badge status={row?.disk_status === 0 ? 'success' : 'error'} />
{`${getSizeAndUnit(text, 'B').valueWithUnit} (${((row.disk_avg * 100) / Utils.transGBToB(row.disk_spec)).toFixed(2)}%)`}
</span>
) : (
'-'
);
},
},
{
title: 'BytesIn规格',
dataIndex: 'bytesIn_spec',
key: 'bytesIn_spec',
width: '150px',
render: (text: any, row: any) => {
return text !== null ? `${text}MB/s` : '-';
},
},
{
title: 'BytesIn AVG',
dataIndex: 'bytesIn_avg',
key: 'bytesIn_avg',
width: '200px',
render: (text: any, row: any) => {
return text !== null ? (
<span>
<Badge status={row?.bytesIn_status === 0 ? 'success' : 'error'} />
{`${getSizeAndUnit(text, 'B/s').valueWithUnit} (${((row.bytesIn_avg * 100) / (row.bytesIn_spec * 1024 * 1024)).toFixed(2)}%)`}
</span>
) : (
'-'
);
},
},
{
title: 'BytesOut规格',
dataIndex: 'bytesOut_spec',
key: 'bytesOut_spec',
width: '150px',
render: (text: any, row: any) => {
return text !== null ? `${text}MB/s` : '-';
},
},
{
title: 'BytesOut AVG',
dataIndex: 'bytesOut_avg',
key: 'bytesOut_avg',
width: '200px',
// eslint-disable-next-line react/display-name
render: (text: any, row: any) => {
return text !== null ? (
<span>
<Badge status={row?.bytesOut_status === 0 ? 'success' : 'error'} />
{`${getSizeAndUnit(text, 'B/s').valueWithUnit} (${((row.bytesOut_avg * 100) / (row.bytesOut_spec * 1024 * 1024)).toFixed(2)}%)`}
</span>
) : (
'-'
);
},
},
];
useEffect(() => {
getList();
}, []);
const onTableChange = (curPagination: any) => {
setPagination({
...curPagination,
});
getList({ pageNo: curPagination.current, pageSize: curPagination.pageSize });
};
const resetList = () => {
setPagination({
...pagination,
pageNo: 1,
});
getList();
};
const hostSearch = (e: any) => {
setFilterList([]);
setPagination({
...pagination,
pageNo: 1,
});
setSearchKeywords(e);
getList({ searchKeywords: e, stateParam: balanceList });
};
const getList = (query = {}) => {
const formData = form.getFieldsValue();
const queryParams = {
pageNo: pagination.current,
pageSize: pagination.pageSize,
...formData,
...query,
};
setLoading(true);
Utils.request(api.getBalanceList(global?.clusterInfo?.id), {
method: 'POST',
data: queryParams,
}).then(
(res: any) => {
const { pageNo, pageSize, pages, total } = res.pagination;
setPagination({
...pagination,
current: pageNo,
pageSize,
total,
});
const dataDe = res?.bizData || [];
const dataHandle = dataDe.map((item: any) => {
return {
...item,
cpu_spec: item?.sub?.cpu?.spec,
cpu_avg: item?.sub?.cpu?.avg,
cpu_status: item?.sub?.cpu?.status,
disk_spec: item?.sub?.disk?.spec,
disk_avg: item?.sub?.disk?.avg,
disk_status: item?.sub?.disk?.status,
bytesIn_spec: item?.sub?.bytesIn?.spec,
bytesIn_avg: item?.sub?.bytesIn?.avg,
bytesIn_status: item?.sub?.bytesIn?.status,
bytesOut_spec: item?.sub?.bytesOut?.spec,
bytesOut_avg: item?.sub?.bytesOut?.avg,
bytesOut_status: item?.sub?.bytesOut?.status,
};
});
setData(dataHandle);
setLoading(false);
},
() => setLoading(false)
);
};
const drawerClose = (sure?: boolean) => {
if (sure) {
setTrigger(!trigger);
}
setVisible(false);
};
const balanceClick = (val: boolean = false) => {
if (val) {
Utils.request(api.getBalanceForm(global?.clusterInfo?.id), {
method: 'GET',
})
.then((res: any) => {
const dataDe = res || {};
setCircleFormData(dataDe);
})
.catch(() => {
setCircleFormData(null);
});
} else {
setCircleFormData(null);
}
setIsCycle(val);
setVisible(true);
};
const getNorms = (stateParamArr: any) => {
const stateParam: any = {};
stateParamArr.forEach((item: any) => {
stateParam[item.firstLevel] = item.secondLevel;
});
setFilterList(stateParamArr);
setPagination({
...pagination,
pageNo: 1,
});
setBalanceList(stateParam);
getList({ searchKeywords, stateParam });
};
const filterNormsClose = (rowId: any) => {
const newFilterList = filterList.filter((item: any) => item.id !== rowId);
getNorms(newFilterList);
};
return (
<>
<div className="breadcrumb" style={{ marginBottom: '10px' }}>
<DBreadcrumb
breadcrumbs={[
{ label: '多集群管理', aHref: '/' },
{ label: global?.clusterInfo?.name, aHref: `/cluster/${global?.clusterInfo?.id}` },
{ label: 'Load Rebalance', aHref: `` },
]}
/>
</div>
<div style={{ margin: '12px 0' }}>
<LoadRebalanceCardBar trigger={trigger} genData={resetList} filterList={filterList} />
</div>
<div className="load-rebalance-container">
<div className="balance-main clustom-table-content">
<div className="header-con">
{/* <Form form={form} layout="inline" onFinish={resetList}>
<Form.Item name="status">
<Select className="grid-select" placeholder="请选择状态" style={{ width: '180px' }} options={Balance_Status_OPTIONS} />
</Form.Item>
<Form.Item name="searchKeywords">
<Input placeholder="请输入Host" style={{ width: '180px' }} />
</Form.Item>
<Form.Item>
<Button type="primary" ghost htmlType="submit">
查询
</Button>
</Form.Item>
</Form> */}
<BalanceFilter title="负载均衡列表筛选" data={[]} getNorms={getNorms} filterList={filterList} />
<div className="float-r">
<SearchInput
onSearch={hostSearch}
attrs={{
value: searchValue,
onChange: setSearchValue,
placeholder: '请输入 Host',
style: { width: '210px' },
maxLength: 128,
}}
/>
<Button type="primary" ghost onClick={() => setPlanVisible(true)}>
</Button>
<Button type="primary" ghost onClick={() => balanceClick(true)}>
</Button>
<Button type="primary" onClick={() => balanceClick(false)}>
</Button>
</div>
</div>
{filterList && filterList.length > 0 && (
<div style={{ marginBottom: '12px' }}>
<span style={{ marginRight: '6px' }}>:{pagination?.total || 0}</span>
{filterList.map((item: any) => {
return (
<Tag
style={{ padding: '6px 10px', backgroundColor: 'rgba(33,37,41,0.08)', color: '#495057', borderRadius: '6px' }}
key={item.id}
closable
onClose={() => filterNormsClose(item.id)}
>
<span>{filterNorms[item.firstLevel]}:</span>
<span>{balanceStatus[item.secondLevel]}</span>
</Tag>
);
})}
</div>
)}
<ProTable
tableProps={{
showHeader: false,
loading,
rowKey: 'brokerId',
dataSource: data,
paginationProps: pagination,
columns: columns() as any,
lineFillColor: true,
attrs: {
onChange: onTableChange,
// bordered: false,
// className: 'remove-last-border',
scroll: { x: 'max-content', y: 'calc(100vh - 440px)' },
},
}}
/>
</div>
<BalanceDrawer visible={visible} isCycle={isCycle} onClose={drawerClose} formData={circleFormData} genData={getList} />
{planVisible && (
<HistoryDrawer
visible={planVisible}
onClose={() => {
setPlanVisible(false);
}}
/>
)}
</div>
</>
);
};
export default LoadBalance;