|
|
|
@ -2,7 +2,7 @@
|
|
|
|
|
* @Author: donghao donghao@supervision.ltd
|
|
|
|
|
* @Date: 2024-05-10 10:47:45
|
|
|
|
|
* @LastEditors: donghao donghao@supervision.ltd
|
|
|
|
|
* @LastEditTime: 2024-05-22 11:14:05
|
|
|
|
|
* @LastEditTime: 2024-06-19 11:29:16
|
|
|
|
|
* @FilePath: \general-ai-platform-web\src\pages\Business\BusinessState\deviceSate.tsx
|
|
|
|
|
* @Description: 设备状态列表
|
|
|
|
|
* @交互说明
|
|
|
|
@ -13,10 +13,22 @@
|
|
|
|
|
import { CommButton, TextButton } from '@/components/Button';
|
|
|
|
|
import IsConfirmAction from '@/components/TableActionCard/isConfirmAction';
|
|
|
|
|
import { deviceStateEnums } from '@/enums/device';
|
|
|
|
|
import { getDeviceStateList } from '@/services/testApi/businessState';
|
|
|
|
|
import { getDictDeviceType } from '@/services/testApi/dict';
|
|
|
|
|
import { useBusinessInfo } from '@/hooks/useBusinessInfo';
|
|
|
|
|
import {
|
|
|
|
|
apiDeviceClassification,
|
|
|
|
|
apiDeviceStatusInfo,
|
|
|
|
|
apiDeviceStatusList,
|
|
|
|
|
} from '@/services/business/device';
|
|
|
|
|
import { apiEntityNodes } from '@/services/business/entity';
|
|
|
|
|
import { isSuccessApi } from '@/utils/forApi';
|
|
|
|
|
import { ProCard, ProForm, ProFormSelect, ProList } from '@ant-design/pro-components';
|
|
|
|
|
import { mathSumByNumberArr } from '@/utils/forMath';
|
|
|
|
|
import {
|
|
|
|
|
ProCard,
|
|
|
|
|
ProForm,
|
|
|
|
|
ProFormSelect,
|
|
|
|
|
ProFormTreeSelect,
|
|
|
|
|
ProList,
|
|
|
|
|
} from '@ant-design/pro-components';
|
|
|
|
|
import { FormattedMessage, useIntl } from '@umijs/max';
|
|
|
|
|
import { Tabs } from 'antd';
|
|
|
|
|
import { useEffect, useState } from 'react';
|
|
|
|
@ -30,6 +42,9 @@ import { ReactComponent as SearchIcon } from '/public/home/search_icon.svg';
|
|
|
|
|
const DeviceSate: React.FC = () => {
|
|
|
|
|
/**state */
|
|
|
|
|
const intl = useIntl();
|
|
|
|
|
const { getStoreBusinessInfo } = useBusinessInfo();
|
|
|
|
|
const [commInfo] = useState<Record<string, any>>({ ...getStoreBusinessInfo() }); // 通用信息
|
|
|
|
|
|
|
|
|
|
// 列表
|
|
|
|
|
const [serverList, setServerList] = useState<Record<string, any>[]>([]); // 列表数据
|
|
|
|
|
const [currentRow, setCurrentRow] = useState<Record<string, any>>();
|
|
|
|
@ -45,16 +60,70 @@ const DeviceSate: React.FC = () => {
|
|
|
|
|
const [querysData, setQuerysData] = useState<Record<string, any>>({}); // 列表查询参数
|
|
|
|
|
const [tabKey, setTabKey] = useState<string>(deviceStateEnums[0].key);
|
|
|
|
|
const [tabs, setTabs] = useState<DICTENUM.DICT_TAB_ITEM[]>([]);
|
|
|
|
|
const [deviceTreeList, setDeviceTreeList] = useState<Record<string, any>[]>([]);
|
|
|
|
|
|
|
|
|
|
// 组装进度展示信息
|
|
|
|
|
|
|
|
|
|
function toProgressListByItem(record) {
|
|
|
|
|
const { cpu, gpu, mem, storage } = record;
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
label: 'CPU',
|
|
|
|
|
percent: cpu / 100,
|
|
|
|
|
strokeColor: 'rgb(243,48,5)',
|
|
|
|
|
usedColors: ['#FFAB00', '#FF4409'],
|
|
|
|
|
freeColors: ['#477BFF', '#0048FE'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: '内存',
|
|
|
|
|
percent: mem / 100,
|
|
|
|
|
strokeColor: 'rgb(33,169,122)',
|
|
|
|
|
usedColors: ['#47A3FF', '#0D6EFF'],
|
|
|
|
|
freeColors: ['#00C45A ', '#4AE003'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: '存储',
|
|
|
|
|
percent: storage / 100,
|
|
|
|
|
strokeColor: 'rgb(33,169,122)',
|
|
|
|
|
usedColors: ['#FF8110', '#EB0404'],
|
|
|
|
|
freeColors: ['#4200FF', '#9520F0'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'GPU',
|
|
|
|
|
percent: gpu / 100,
|
|
|
|
|
strokeColor: 'rgb(250,173,20)',
|
|
|
|
|
usedColors: ['#AE47FF', '#F008AF'],
|
|
|
|
|
freeColors: ['#FF4D00', '#F2B721'],
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设备节点信息
|
|
|
|
|
async function loadDetail(record) {
|
|
|
|
|
const resp = await apiDeviceStatusInfo({ id: record?.id });
|
|
|
|
|
if (isSuccessApi(resp) && resp?.data) {
|
|
|
|
|
setCurrentRow({
|
|
|
|
|
...resp?.data,
|
|
|
|
|
id: record?.id,
|
|
|
|
|
progressData: toProgressListByItem(resp?.data),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将数据组装成reactDom
|
|
|
|
|
function toListDomByData(record) {
|
|
|
|
|
let startList = [...record];
|
|
|
|
|
startList = startList.map((item) => {
|
|
|
|
|
item.progressData = toProgressListByItem(item);
|
|
|
|
|
return item;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let finalList = startList.map((item) => ({
|
|
|
|
|
content: (
|
|
|
|
|
<DeviceStateCard
|
|
|
|
|
info={item}
|
|
|
|
|
fetchDetail={() => {
|
|
|
|
|
setCurrentRow(item);
|
|
|
|
|
loadDetail(item);
|
|
|
|
|
setDetailOpen(true);
|
|
|
|
|
}}
|
|
|
|
|
renderActions={[
|
|
|
|
@ -107,33 +176,38 @@ const DeviceSate: React.FC = () => {
|
|
|
|
|
|
|
|
|
|
// 企业列表数据api
|
|
|
|
|
async function fetchData() {
|
|
|
|
|
const resp = await getDeviceStateList({
|
|
|
|
|
const resp = await apiDeviceStatusList({
|
|
|
|
|
pageNo: currentPage,
|
|
|
|
|
pageSize: currentPageSize,
|
|
|
|
|
status: tabKey,
|
|
|
|
|
status: Number(tabKey),
|
|
|
|
|
entity_id: commInfo.id,
|
|
|
|
|
...querysData,
|
|
|
|
|
});
|
|
|
|
|
if (isSuccessApi(resp)) {
|
|
|
|
|
toListDomByData(resp.data.data);
|
|
|
|
|
const currCounts = { ...resp.data.status_count };
|
|
|
|
|
const currTotalCount = mathSumByNumberArr(Object.values(currCounts));
|
|
|
|
|
setTabs(() => {
|
|
|
|
|
const finalArr = [];
|
|
|
|
|
JSON.parse(JSON.stringify(deviceStateEnums)).forEach((item) => {
|
|
|
|
|
switch (item.key) {
|
|
|
|
|
case '1':
|
|
|
|
|
item.label = `${deviceStateEnums[1].label}(${resp.data.onlineCount})`;
|
|
|
|
|
case '1001':
|
|
|
|
|
item.label = `${deviceStateEnums[1].label}(${currCounts[deviceStateEnums[1].key]})`;
|
|
|
|
|
break;
|
|
|
|
|
case '2':
|
|
|
|
|
item.label = `${deviceStateEnums[2].label}(${resp.data.outlineCount})`;
|
|
|
|
|
case '1002':
|
|
|
|
|
item.label = `${deviceStateEnums[2].label}(${currCounts[deviceStateEnums[2].key]})`;
|
|
|
|
|
break;
|
|
|
|
|
case '3':
|
|
|
|
|
item.label = `${deviceStateEnums[3].label}(${resp.data.processCount})`;
|
|
|
|
|
case '1003':
|
|
|
|
|
item.label = `${deviceStateEnums[3].label}(${
|
|
|
|
|
currCounts[deviceStateEnums[3].key]
|
|
|
|
|
}})`;
|
|
|
|
|
break;
|
|
|
|
|
case '4':
|
|
|
|
|
item.label = `${deviceStateEnums[4].label}(${resp.data.errorCount})`;
|
|
|
|
|
case '1004':
|
|
|
|
|
item.label = `${deviceStateEnums[4].label}(${currCounts[deviceStateEnums[4].key]})`;
|
|
|
|
|
break;
|
|
|
|
|
case '0':
|
|
|
|
|
case '1000':
|
|
|
|
|
default:
|
|
|
|
|
item.label = `${deviceStateEnums[0].label}(${resp.data.count})`;
|
|
|
|
|
item.label = `${deviceStateEnums[0].label}(${currTotalCount})`;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
finalArr.push(item);
|
|
|
|
@ -142,13 +216,13 @@ const DeviceSate: React.FC = () => {
|
|
|
|
|
});
|
|
|
|
|
setTotal(() => {
|
|
|
|
|
switch (tabKey) {
|
|
|
|
|
case '1':
|
|
|
|
|
case '1001':
|
|
|
|
|
return resp.data.onlineCount;
|
|
|
|
|
case '2':
|
|
|
|
|
case '1002':
|
|
|
|
|
return resp.data.outlineCount;
|
|
|
|
|
case '3':
|
|
|
|
|
case '1003':
|
|
|
|
|
return resp.data.processCount;
|
|
|
|
|
case '4':
|
|
|
|
|
case '1004':
|
|
|
|
|
return resp.data.errorCount;
|
|
|
|
|
default:
|
|
|
|
|
return resp.data.count;
|
|
|
|
@ -156,7 +230,6 @@ const DeviceSate: React.FC = () => {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// TODO 切换时页码没有显示第一页
|
|
|
|
|
const changeTabMode = (key: string) => {
|
|
|
|
|
setTabKey(key);
|
|
|
|
|
setCurrentPage(1);
|
|
|
|
@ -167,11 +240,23 @@ const DeviceSate: React.FC = () => {
|
|
|
|
|
// setCurrentPage(1);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// 设备节点树
|
|
|
|
|
async function loadDeviceTree() {
|
|
|
|
|
const resp = await apiEntityNodes({ entity_id: commInfo.id });
|
|
|
|
|
if (isSuccessApi(resp)) {
|
|
|
|
|
setDeviceTreeList(resp?.data?.data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化加载 & 筛选查询
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
fetchData();
|
|
|
|
|
}, [tabKey, currentPageSize, currentPage, querysData]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
loadDeviceTree();
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="flex-1 bs_server_state_page bs_state_page gn_head_card">
|
|
|
|
|
<div className="gn_form gn_table_query_filter">
|
|
|
|
@ -211,10 +296,44 @@ const DeviceSate: React.FC = () => {
|
|
|
|
|
return true;
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{/* //TODO 缺失筛选条件设备组 树形选择*/}
|
|
|
|
|
<ProFormTreeSelect
|
|
|
|
|
width={300}
|
|
|
|
|
name="node_ids"
|
|
|
|
|
label={
|
|
|
|
|
<FormattedMessage
|
|
|
|
|
id="device_group_list.table.list.deviceNode"
|
|
|
|
|
defaultMessage="节点"
|
|
|
|
|
/>
|
|
|
|
|
}
|
|
|
|
|
placeholder={`${intl.formatMessage({
|
|
|
|
|
id: 'common.please_select',
|
|
|
|
|
defaultMessage: '$$$',
|
|
|
|
|
})}${intl.formatMessage({
|
|
|
|
|
id: 'device_group_list.table.list.deviceNode',
|
|
|
|
|
defaultMessage: '节点',
|
|
|
|
|
})}`}
|
|
|
|
|
// treeData={deviceTreeList}
|
|
|
|
|
// fieldNames= {{
|
|
|
|
|
// label: 'name',
|
|
|
|
|
// value: 'id',
|
|
|
|
|
// children: 'children',
|
|
|
|
|
// }}
|
|
|
|
|
|
|
|
|
|
fieldProps={{
|
|
|
|
|
multiple: true,
|
|
|
|
|
treeData: deviceTreeList,
|
|
|
|
|
style: { marginRight: 12 },
|
|
|
|
|
treeDefaultExpandAll: true,
|
|
|
|
|
fieldNames: {
|
|
|
|
|
label: 'name',
|
|
|
|
|
value: 'id',
|
|
|
|
|
children: 'children',
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<ProFormSelect
|
|
|
|
|
width={300}
|
|
|
|
|
name="deviceType"
|
|
|
|
|
name="classification_suid"
|
|
|
|
|
label={
|
|
|
|
|
<FormattedMessage
|
|
|
|
|
id="device_group_list.table.list.deviceType"
|
|
|
|
@ -231,7 +350,7 @@ const DeviceSate: React.FC = () => {
|
|
|
|
|
showSearch
|
|
|
|
|
debounceTime={500}
|
|
|
|
|
request={async () => {
|
|
|
|
|
const { data } = await getDictDeviceType();
|
|
|
|
|
const { data } = await apiDeviceClassification();
|
|
|
|
|
return data?.data?.map((v: Record<string, any>) => {
|
|
|
|
|
return { ...v, label: v.name, value: v.id };
|
|
|
|
|
});
|
|
|
|
@ -289,6 +408,7 @@ const DeviceSate: React.FC = () => {
|
|
|
|
|
<DetailDeviceState
|
|
|
|
|
detailOpen={detailOpen}
|
|
|
|
|
info={currentRow}
|
|
|
|
|
commInfo={commInfo}
|
|
|
|
|
closeModal={() => {
|
|
|
|
|
setDetailOpen(false);
|
|
|
|
|
}}
|
|
|
|
|