feat: 资源管理设备状态静态完成,fabric监控信息展示初始化

develop
zhoux 1 year ago
parent 694c5bdd69
commit f7402f5822

@ -185,6 +185,11 @@ export default [
'path': '/resource/model-version-list',
'component': 'Resource/ModelVersionList',
'access': 'canReadMenu'
},{
'name': 'resource-device-status', // 2
'path': '/resource/resource-device-status',
'component': 'Resource/ResourceDeviceStatus',
'access': 'canReadMenu'
}]
},
{
@ -259,4 +264,14 @@ export default [
layout: false,
component: './404',
},
{
name: 'fabricView',
path: '/fabricView',
routes: [{
'name': 'fabricView-room',
'path': '/fabricView/room',
'component': 'FabricView/Room',
'access': 'canReadMenu'
}]
},
];

@ -1,30 +1,72 @@
export const deviceStatusEnums: Record<string, any> = {
allStatus: {
miniName: '全部',
value: '0',
color: '',
},
onlineStatus: {
miniName: '在线',
value: '1',
color: 'success',
},
outlineStatus: {
miniName: '离线',
value: '2',
color: 'default',
},
processingStatus: {
miniName: '运行中',
value: '3',
color: 'warning',
},
errorStatus: {
miniName: '故障',
value: '4',
color: 'error',
},
};
export const deviceStatusEnums : Record<string,any> = {
'allStatus': {
miniName: '全部',
value: '0',
color: ''
},
'onlineStatus': {
miniName: '在线',
value: '1',
color: 'success'
},
'outlineStatus': {
miniName: '离线',
value: '2',
color: 'default'
},
'processingStatus': {
miniName: '运行中',
value: '3',
color: 'warning'
},
'errorStatus': {
miniName: '故障',
value: '4',
color: 'error'
}
}
export const resourceDeviceStatusEnums: Record<string, any> = {
allStatus: {
miniName: '全部异常',
value: '0',
color: '',
renderType: '',
},
storageWarn: {
miniName: '存储告警',
value: '1',
color: 'error',
renderType: 'progress',
},
GPUWarn: {
miniName: 'GPU告警',
value: '2',
color: 'success',
renderType: 'progress',
},
memoryWarn: {
miniName: '内存告警',
value: '3',
color: 'success',
renderType: 'progress',
},
errorStatus: {
miniName: 'CPU告警',
value: '4',
color: 'warning',
renderType: 'progress',
},
codeError: {
miniName: '代码出错',
value: '5',
color: 'error',
renderType: 'dot',
},
serveTimeOut: {
miniName: '服务器超时',
value: '6',
color: 'error',
renderType: 'dot',
},
};

@ -116,6 +116,8 @@ a.ant-dropdown-trigger {
.ant-menu-light .ant-menu-item-selected,
.ant-menu-light > .ant-menu .ant-menu-item-selected {
background-color: #e8effb;
border-left: 3px solid #155BD4;
border-radius: 0;
}
.ant-select-dropdown .ant-select-item-option-active:not(.ant-select-item-option-disabled) {
background-color: #e8effb;
@ -131,6 +133,9 @@ a.ant-dropdown-trigger {
.ant-steps .ant-steps-item-active > .ant-steps-item-container > .ant-steps-item-content > .ant-steps-item-description {
color: #155BD4;
}
.ant-layout-sider-children {
background-color: white;
}
.ant-btn-link.ant-btn-dangerous,
.ant-btn-default.ant-btn-dangerous {
color: #E80D0D;
@ -174,7 +179,7 @@ a.ant-dropdown-trigger {
border-radius: 8px;
}
.ant-pro-list .ant-pro-table-list-toolbar-left {
flex: 0.8;
flex: 1;
}
.ant-popover .ant-popover-content {
min-width: 200px;
@ -295,7 +300,7 @@ a.ant-dropdown-trigger {
}
.gn .proListActionBox .ant-btn.ant-btn-sm {
padding: 0;
font-size: 12px;
font-size: 14px;
}
.gn.fw7 {
font-weight: 700;

@ -142,6 +142,8 @@ a.ant-dropdown-trigger{
.ant-menu-light .ant-menu-item-selected, .ant-menu-light>.ant-menu .ant-menu-item-selected {
background-color: #e8effb;
border-left: 3px solid #155BD4;
border-radius: 0;
}
.ant-select-dropdown .ant-select-item-option-active:not(.ant-select-item-option-disabled) {
@ -163,6 +165,9 @@ a.ant-dropdown-trigger{
}
}
.ant-layout-sider-children{
background-color: white;
}
.ant-btn-link.ant-btn-dangerous, .ant-btn-default.ant-btn-dangerous {
color: #E80D0D;
@ -226,7 +231,7 @@ a.ant-dropdown-trigger{
}
.ant-pro-table-list-toolbar-left{
flex: 0.8
flex: 1
}
}
@ -363,7 +368,7 @@ a.ant-dropdown-trigger{
.proListActionBox{
.ant-btn.ant-btn-sm{
padding: 0;
font-size: 12px;
font-size: 14px;
}
}

@ -1,11 +1,3 @@
/*
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-12-08 10:11:54
* @LastEditors: zhoux zhouxia@supervision.ltd
* @LastEditTime: 2023-12-11 17:15:39
* @FilePath: \general-ai-platform-web\src\pages\DCSDevice\DeviceStatus\index.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import TableActionCard from '@/components/TableActionCard';
import IsConfirmAction from '@/components/TableActionCard/isConfirmAction';
import { deviceStatusEnums } from '@/enums/status';
@ -19,9 +11,9 @@ import DeviceStatusCard from './components/DeviceStatusCard';
/**
* @
* 1
* 2UI
* 3
* 1
* 2
* 3
*/
const tabOptions: Record<string, any> = {
allStatus: 90,
@ -76,24 +68,34 @@ const DeviceStatus: React.FC = () => {
}
return {
content: (
<ProCard className="gn"
style={{ backgroundColor: '#FAFAFA', margin: 0, padding: 0 }} bodyStyle={{ margin: 0, padding: 0 }}>
<ProCard
className="gn"
style={{ backgroundColor: '#FAFAFA', margin: 0, padding: 0 }}
bodyStyle={{ margin: 0, padding: 0 }}
>
<div
style={{
display: 'flex',
alignItems: 'center',
padding: 12,
justifyContent: 'space-between',
borderBottom: '1px solid rgba(224, 224, 224, 1)'
borderBottom: '1px solid rgba(224, 224, 224, 1)',
}}
>
<div style={{
display: 'flex',
alignItems: 'center',
maxWidth: '60%'
}}>
<div
style={{
display: 'flex',
alignItems: 'center',
maxWidth: '60%',
}}
>
<Tag color={currColor}>{record.status}</Tag>
<p className='gn single_line text_1 fw7' style={{maxWidth: '80%', padding: 0, margin: 0}}>{index + 1}</p>
<p
className="gn single_line text_1 fw7"
style={{ maxWidth: '80%', padding: 0, margin: 0 }}
>
{index + 1}
</p>
</div>
<TableActionCard
key="TableActionCardRef"
@ -137,8 +139,6 @@ const DeviceStatus: React.FC = () => {
onClick={() => {
handleDetailModal();
setCurrentRow(record);
// doToDetail(record);
// setShowDetail(true);
}}
>
<FormattedMessage id="pages.searchTable.detail" defaultMessage="Update" />
@ -154,13 +154,6 @@ const DeviceStatus: React.FC = () => {
};
});
const columns: ProColumns<Record<string, any>>[] = [
{
title: '123',
dataIndex: 'status',
// hideInSearch: true,
},
];
return (
<PageContainer>
<ProList<any>
@ -190,7 +183,7 @@ const DeviceStatus: React.FC = () => {
{Object.keys(deviceStatusEnums).includes(item)
? deviceStatusEnums[item].miniName
: ''}
{tabOptions[item]}
{"("+tabOptions[item]+ ')'}
</Button>
);
})}
@ -201,8 +194,8 @@ const DeviceStatus: React.FC = () => {
bodyStyle: {
background: 'white',
padding: '8px 16px 16px',
borderRadius: 8
}
borderRadius: 8,
},
}}
pagination={{
...proTablePaginationOptions,
@ -211,9 +204,10 @@ const DeviceStatus: React.FC = () => {
}}
showActions="hover"
rowSelection={false}
grid={{ gutter: 16, xs: 1, md: 2, lg: 3, xl: 4, xxl: 4 }}
grid={{ gutter: 16, xs: 1, md: 2, lg: 2, xl: 3, xxl: 4 }}
metas={{
type: {
// 不展示在筛选项
hideInSearch: true,
},
content: {

@ -0,0 +1,167 @@
/*
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-11-01 13:56:33
* @LastEditors: zhoux zhouxia@supervision.ltd
* @LastEditTime: 2023-12-15 16:58:50
* @FilePath: \general-ai-platform-web\src\pages\Resource\ModelCategoryList\components\ColumnDrawer.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { CloseOutlined } from '@ant-design/icons';
import { ProColumns, ProDescriptions, ProDescriptionsItemProps } from '@ant-design/pro-components';
import React, { useEffect, useState } from 'react';
export type ColumnDrawProps = {
handleDrawer: (id?: any) => void;
isShowDetail: boolean;
columns: ProColumns<API.ModelCategory>[];
currentRow: Record<string, any>;
clipPathData: Record<string, any>;
};
const ColumnDrawer: React.FC<ColumnDrawProps> = (props) => {
const [positionStyle, setPositionStyle] = useState<React.CSSProperties>({});
// 生成模型详情卡片位置
function initPointPosition() {
type Point = { x: number; y: number };
type Position = 'left' | 'right' | 'top' | 'bottom';
let currPositionStyle: React.CSSProperties = {};
const modelInfoPosition: Position[] = ['right'];
const maxX = props.clipPathData?.width; // 画布宽度
const maxY = props.clipPathData?.height; // 画布高度
const x = props.currentRow.baseInfo?.left; // 模型x轴位置
const y = props.currentRow.baseInfo?.top; // 模型y轴位置
const modelWidth: number = 120; // 模型自身宽度
const modelHeight: number = 54; // 模型自身高度
const modelInfoWidth: number = 400; // 模型信息卡片宽度
const modelInfoHeight: number = 240; // 模型信息卡片高度
// if (x < 0 || x > maxX || y < 0 || y > maxY) {
// // 模型超过范围
// }
if (x > maxX / 2) {
modelInfoPosition.push('left');
// if (x < maxX / 2) {
// modelInfoPosition.push('left');
// } else {
// modelInfoPosition.push('right');
// }
} else {
modelInfoPosition.push('right');
// if (y < maxY / 2) {
// modelInfoPosition.push('top');
// } else {
// modelInfoPosition.push('bottom');
// }
}
console.log(props.currentRow, 'currentRow');
if (modelInfoPosition.includes('left')) {
let topValue = y - modelInfoHeight / 2 + modelHeight / 2
if(topValue> maxY - modelInfoHeight){
topValue = maxY - modelInfoHeight
}
if(topValue<0){
topValue = 0
}
currPositionStyle = {
top: topValue,
left: x - modelInfoWidth - 10,
};
} else {
let topValue = y - modelInfoHeight / 2 + modelHeight / 2
if(topValue> maxY - modelInfoHeight){
topValue = maxY - modelInfoHeight
}
if(topValue<0){
topValue = 0
}
currPositionStyle = {
top: topValue,
left: x + modelWidth + 10,
};
}
setPositionStyle(currPositionStyle);
}
useEffect(() => {
if (props.currentRow) {
initPointPosition();
}
}, [props.currentRow, props.clipPathData]);
return props.isShowDetail ? (
<div
style={{
position: 'absolute',
background: '#fff',
borderRadius: 4,
width: 400,
boxShadow: '0px 8px 12px rgba(0, 0, 0, 0.25)',
border: '1px solid #eee',
...positionStyle,
}}
>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
padding: '16px 24px',
borderBottom: '1px solid #eee',
color: '#1E1E1E',
fontSize: 20,
fontWeight: 700,
marginBottom: 16,
}}
>
<span></span>
<CloseOutlined onClick={() => props.handleDrawer()} />
</div>
<ProDescriptions
style={{
padding: '0 24px',
}}
column={2}
dataSource={props.currentRow || {}}
columns={props.columns as ProDescriptionsItemProps<API.ModelCategory>[]}
></ProDescriptions>
</div>
) : (
<></>
);
// <Modal
// title="设备信息"
// mask={false}
// open={props.isShowDetail}
// width={500}
// footer={null}
// onCancel={() => props.handleDrawer()}
// >
// </Modal>
// <Drawer
// width={500}
// open={props.isShowDetail}
// onClose={() => {
// props.handleDrawer();
// }}
// closable={true}
// >
// {props.currentRow?.id && (
// <ProDescriptions<API.ModelCategory>
// style={{
// // paddingLeft: 4,
// // paddingRight: 4
// }}
// column={2}
// title={props.currentRow?.id}
// request={async () => ({
// data: props.currentRow || {},
// })}
// params={{
// id: props.currentRow?.id,
// }}
// columns={props.columns as ProDescriptionsItemProps<API.ModelCategory>[]}
// />
// )}
// </Drawer>
};
export { ColumnDrawer };

@ -0,0 +1,204 @@
/*
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-12-12 10:57:54
* @LastEditors: zhoux zhouxia@supervision.ltd
* @LastEditTime: 2023-12-15 17:06:36
* @FilePath: \general-ai-platform-web\src\pages\FabricView\Room\index.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
// import { useUuid } from '@/hooks/useUuid';
import { currJson } from '@/testData/fabricRoomList';
import { bgImageData } from '@/testData/fabricRoomSvg';
import { ProCard } from '@ant-design/pro-components';
import { useIntl } from '@umijs/max';
import { Button } from 'antd';
import { fabric } from 'fabric';
import React, { useEffect, useRef, useState } from 'react';
import { ColumnDrawer } from './components/ColumnDrawer';
export const ModelCategoryColumns = [
{
title: '设备ID',
dataIndex: 'id',
},
{
title: '设备名称',
dataIndex: 'deviceName',
},
{
title: '设备代码',
dataIndex: 'deviceCode',
},
{
title: '设备位置',
dataIndex: 'deviceLocation',
},
{
title: '设备代码',
dataIndex: 'deviceCode',
},
{
title: '设备名称',
dataIndex: 'deviceName',
},
{
title: '设备代码',
dataIndex: 'deviceCode',
},
{
title: '设备名称',
dataIndex: 'deviceName',
},
];
const FabricViewRoom: React.FC = () => {
const intl = useIntl();
const canvasRef = useRef(null);
const itemsRef = useRef(null);
const [cvs, setCanvas] = useState(null);
const [descriptors, setDescriptors] = useState<Record<string, any>>({});
const [category_fk_id_open, set_category_fk_id_open] = useState(false);
const [currentModelUserProperty, setCurrentModelUserProperty] = useState<Record<string, any>>({});
const [changeId, setChangeId] = useState<string[]>([]);
const [currentTargetObject, setCurrentTargetObject] = useState<any>(null);
const [clipPathData, setClipPathData] = useState({
width: 1200, // 宽
height: 900, // 高
});
const [jsonData, setJsonData] = useState<Record<string, any>>({});
/*test */
// const { fetchUuid } = useUuid();
function changeModelStatus() {
setChangeId(['2', '3']);
}
const handle_category_fk_id = () => {
if (category_fk_id_open) {
set_category_fk_id_open(false);
}
};
function closeSelectedModel(targetCvs?: any) {
let finalCvs = cvs;
if (targetCvs) {
finalCvs = targetCvs;
}
finalCvs.getObjects().forEach((item) => {
// if (changeId.includes(item?.userProperty?.id)) {
const groupObject = item;
// 选中组合对象
// canvasObject.setActiveObject(groupObject); // 可以改变 selectable 值
finalCvs.requestRenderAll();
// 获取组合对象中的子对象
const objectsInGroup = groupObject.getObjects();
groupObject.item(0).item(1).set({
fill: '#DCDCDC',
});
groupObject.item(1).set({
fill: 'rgb(0,0,0)',
})
finalCvs.renderAll();
// 遍历子对象找到要修改的子对象
// }
});
}
// 初始化加载画布&渲染模型
useEffect(() => {
const canvasObject = new fabric.Canvas(canvasRef.current);
canvasObject.setBackgroundImage(bgImageData.src, canvasObject.renderAll.bind(canvasObject), {
width: clipPathData.width,
height: clipPathData.height,
originX: 'left',
originY: 'top',
});
canvasObject.loadFromJSON(JSON.stringify(currJson), () => {
canvasObject.renderAll();
// const groupObjectList = canvasObject.getObjects()
// const groupObject = canvasObject.getObjects()[0];
// 选中组合对象
// console.log(groupObject, 'groupObject', canvasObject.getObjects());
// 注册事件监听器
canvasObject.on('mouse:down', (event) => {
// 获取事件的目标对象
const targetObject = event.target;
// set_category_fk_id_open(false);
// 检查目标对象是否为组合对象
if (targetObject && targetObject?.userProperty) {
// canvasObject.setActiveObject(targetObject);
setChangeId([targetObject?.userProperty?.id]);
// console.log('mouse:up:', targetObject);
setCurrentModelUserProperty(targetObject.userProperty);
set_category_fk_id_open(true);
}
// 检查目标对象是否为组合对象
if (targetObject) {
setCurrentTargetObject(targetObject);
closeSelectedModel(canvasObject);
// console.log('mouse:down:', );
targetObject.item(0).item(1).set({
fill: 'blue',
});
targetObject.item(1).set({
fill: 'blue',
})
}
canvasObject.renderAll();
});
});
setCanvas(canvasObject);
return () => {
canvasObject.dispose();
};
}, []);
useEffect(() => {
// TODO_3 需要加个loading效果
// import('./Descriptors.json').then((descriptors) => {
// setDescriptors(descriptors);
// });
// console.log(fetchUuid(), 'fetchUuid');
if (changeId && changeId.length && !category_fk_id_open) {
closeSelectedModel();
}
}, [changeId, category_fk_id_open]);
return (
<ProCard
gutter={24}
extra={
<>
<Button type="primary" onClick={changeModelStatus}>
</Button>
</>
}
>
{/* <ProCard colSpan={4}>
<ImageMapItems ref={itemsRef} canvasRef={canvasRef} descriptors={descriptors} />
</ProCard> */}
<ProCard colSpan={24} style={{ padding: 0, margin: 0 }} bodyStyle={{ padding: 0, margin: 0 }}>
<canvas ref={canvasRef} {...clipPathData} style={{ border: '1px dashed #eee' }}></canvas>
<ColumnDrawer
handleDrawer={handle_category_fk_id}
isShowDetail={category_fk_id_open}
columns={ModelCategoryColumns}
currentRow={currentModelUserProperty}
clipPathData={clipPathData}
/>
</ProCard>
</ProCard>
// 属性预览
);
};
export default FabricViewRoom;

@ -0,0 +1,158 @@
/*
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-11-06 16:12:17
* @LastEditors: zhoux zhouxia@supervision.ltd
* @LastEditTime: 2023-12-15 14:00:33
* @FilePath: \general-ai-platform-web\src\pages\Setting\components\ProjectCardList.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React from 'react';
import { Progress } from 'antd';
// import { postModelVersionGetModelVersionListByIds } from '@/services/resource/ModelVersion';
// const [tabs, setTabs] = useState([]);
// const [projectData, setProjectData] = useState<any>({});
// const [tab, setTab] = useState('');
// const [modelVersionData, setModelVersionData] = useState<any[]>([]);
/**styles */
const listItemStyle = {
display: 'flex',
fontSize: 14,
color: '#333333',
width: '100%',
alignItems: 'center',
padding: '4px 0 0',
};
const listItemLabelStyle = {
display: 'flex',
alignItems: 'center',
fontSize: 12,
color: '#666666',
minWidth: 53
};
const listItemTextStyle = {
fontSize: 14,
margin: 0,
};
// 卡片
export type UpdateProjectProps = {
info: Record<string, any>;
// reload: any;
};
type DeviceItemProgress = {
label: string;
percent: number;
};
// 进度条
// TODO 进度条的边框圆角调整为矩形
const DeviceItemProgress: React.FC<DeviceItemProgress> = (props) => {
let strokeColor = 'rgb(243,48,5)';
switch (props.label) {
case '存储告警':
strokeColor = 'rgb(243,48,5)';
break;
case 'GPU告警':
case '内存告警':
strokeColor = 'rgb(33,169,122)';
break;
case 'CPU告警':
strokeColor = 'rgb(250,173,20)';
break;
}
return (
<div style={{ width: '100%', display: 'flex' }} className="rectProgress_box">
<span style={listItemLabelStyle}>{props.label}</span>
<Progress
style={{ padding: 0, margin: 0, borderRadius: 0 }}
size={['100%', 10]}
percent={props.percent * 100}
strokeColor={strokeColor}
showInfo={false}
/>
</div>
);
};
const DeviceStatusCard: React.FC<UpdateProjectProps> = ({
info,
}: {
info: Record<string, any>;
}) => {
return (
<div
style={{
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'left',
paddingLeft: 8,
paddingRight: 8,
}}
>
{/* <div style={{ display: 'flex', alignItems: 'center', paddingBottom: 10 }}>
<span style={{ fontWeight: 700, fontSize: 14, paddingRight: 10 }}></span>
<Tag color="#44AEF5"></Tag>
</div> */}
<ul
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
fontSize: 12,
color: '#E80D0D',
padding: '8px 0 0',
lineHeight: '18px',
margin: 0,
}}
>
<li>
<span
style={{
display: 'inline-block',
width: 8,
height: 8,
borderRadius: '50%',
backgroundColor: '#E80D0D',
}}
></span>
<span style={{ paddingLeft: 8 }}></span>
</li>
<li>
<span
style={{
display: 'inline-block',
width: 8,
height: 8,
borderRadius: '50%',
backgroundColor: '#E80D0D',
}}
></span>
<span style={{ paddingLeft: 8 }}></span>
</li>
</ul>
<ul style={{ width: '100%', marginBottom: 8 }}>
<li style={listItemStyle}>
<DeviceItemProgress label="存储告警" percent={0.79}></DeviceItemProgress>
</li>
<li style={listItemStyle}>
<DeviceItemProgress label="GPU告警" percent={0.18}></DeviceItemProgress>
</li>
<li style={listItemStyle}>
<DeviceItemProgress label="内存告警" percent={0.16}></DeviceItemProgress>
</li>
<li style={listItemStyle}>
<DeviceItemProgress label="CPU告警" percent={0.58}></DeviceItemProgress>
</li>
</ul>
</div>
);
};
export default DeviceStatusCard;

@ -0,0 +1,181 @@
import TableActionCard from '@/components/TableActionCard';
import IsConfirmAction from '@/components/TableActionCard/isConfirmAction';
import { resourceDeviceStatusEnums } from '@/enums/status';
import { PageContainer, ProCard, ProColumns, ProList } from '@ant-design/pro-components';
import { FormattedMessage } from '@umijs/max';
import { Button, Tag } from 'antd';
import React, { useState } from 'react';
import { proTableCommonOptions, proTablePaginationOptions } from '../../../../config/defaultTable';
import DeviceStatusCard from './components/DeviceStatusCard';
/**
* @
* 1
* 2
* 3
*/
const tabOptions: Record<string, any> = {
allStatus: 90,
storageWarn: 20,
GPUWarn: 20,
memoryWarn: 10,
errorStatus: 20,
codeError: 10,
serveTimeOut: 20,
};
const ResourceDeviceStatus: React.FC = () => {
const [detailModalOpen, setDetailModalOpen] = useState<boolean>(false);
const [currentRow, setCurrentRow] = useState<Record<string, any>>({});
// 动态设置每页数量
const [currentPageSize, setCurrentPageSize] = useState<number>(15);
const [activeTabIndex, setActiveTabIndex] = useState<number>(0);
const dataTestList = [
{ status: '存储告警' },
{ status: 'GPU告警' },
{ status: '内存告警' },
{ status: 'CPU告警' },
{ status: '代码出错' },
{ status: '服务器超时' },
{ status: '存储告警' },
{ status: '代码出错' },
{ status: '存储告警' },
{ status: 'GPU告警' },
{ status: '内存告警' },
{ status: 'CPU告警' },
{ status: '代码出错' },
{ status: '服务器超时' },
{ status: '存储告警' },
{ status: '代码出错' },
].map((record, index) => {
return {
content: (
<ProCard
className="gn"
style={{ backgroundColor: '#fafafa', margin: 0, padding: 0 }}
bodyStyle={{ margin: 0, padding: 0 }}
>
<div
style={{
display: 'flex',
alignItems: 'center',
backgroundColor: 'rgba(21, 77, 221, 0.10)',
padding: 12,
justifyContent: 'space-between',
borderBottom: '1px solid rgba(224, 224, 224, 1)',
}}
>
<p
className="gn single_line text_1 fw7"
style={{ maxWidth: 'calc(100% - 12px)', padding: 0, margin: 0 }}
>
{index + 1}
</p>
</div>
<DeviceStatusCard info={record}></DeviceStatusCard>{' '}
</ProCard>
),
};
});
return (
<PageContainer>
<ProList<any>
className="gn"
ghost={true}
itemCardProps={{
ghost: true,
bodyStyle: { padding: 0, margin: 0 },
}}
headerTitle={
<>
<ProCard style={{padding: 0, margin: 0}} bodyStyle={{padding: 0, margin: 0}}>
{Object.keys(tabOptions).map((item, index) => {
// eslint-disable-next-line react/jsx-key
return (
<Button
style={{ marginRight: 12, marginTop: 8 }}
type={activeTabIndex === index ? 'primary' : 'default'}
key={index}
onClick={() => {
setActiveTabIndex(index);
}}
>
{Object.keys(resourceDeviceStatusEnums).includes(item)
? resourceDeviceStatusEnums[item].miniName
: ''}
{"("+tabOptions[item]+ ')'}
</Button>
);
})}
</ProCard>
</>
}
cardProps={{
bodyStyle: {
background: 'white',
padding: '0px 16px 16px',
borderRadius: 8,
},
}}
pagination={{
...proTablePaginationOptions,
pageSize: currentPageSize,
onChange: (page, pageSize) => setCurrentPageSize(pageSize),
}}
showActions="hover"
rowSelection={false}
grid={{ gutter: 16, xs: 1, md: 3, lg: 4, xl: 5, xxl: 7 }}
metas={{
type: {
},
content: {
},
actions: {
cardActionProps: 'extra',
}
}}
request={async (params = {}, sort) => {
const { current, ...rest } = params;
const reqParams = {
page: current,
desc: false,
orderKey: '',
...rest,
};
if (sort && Object.keys(sort).length) {
reqParams.orderKey = Object.keys(sort)[0];
let sort_select = sort[reqParams.orderKey];
reqParams.desc = sort_select === 'descend';
}
// TODO 联调查询设备状态接口
// let resps = await postDeviceGroupGetDeviceGroupList({ ...reqParams });
let resp = {
success: true,
data: {
list: dataTestList,
total: 16,
page: 1,
pageSize: 16,
},
};
return {
data: resp.data.list,
success: resp.success,
total: resp.data.total,
current: resp.data.page,
pageSize: resp.data.pageSize,
};
}}
/>
</PageContainer>
);
};
export default ResourceDeviceStatus;

File diff suppressed because it is too large Load Diff

@ -0,0 +1,147 @@
/*
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-12-12 15:41:56
* @LastEditors: zhoux zhouxia@supervision.ltd
* @LastEditTime: 2023-12-15 17:22:03
* @FilePath: \general-ai-platform-web\src\testData\fabricRoomList.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { fetchWatchGroupObjects } from './fabricWatchIcons';
// 模型状态 在线 离线 告警 故障
const startData: Record<string, any> = {
modelsList: [
{
deviceType: '1', // 模型类型 1 设备1 2 设备2
id: '1001', // 模型id
status: 'watchOnline', //
deviceName: '监控设备1', // 模型名称
deviceCode: 'code1002',
deviceLocation: '客厅',
deviceParams: '设备参数',
deviceCategory: '控制器',
diviceGroup: '组1',
baseInfo: {
left: 527.0215, // 相对x
top: 24.5797, // 相对y
},
},
{
deviceType: '1', // 模型类型 1 设备1 2 设备2
id: '1002', // 模型id
status: 'watchError', // 模型状态 在线 离线 告警 故障
deviceName: '监控设备2', // 模型名称
deviceCode: 'code1001',
deviceLocation: '客厅',
deviceParams: '设备参数',
deviceCategory: '控制器',
diviceGroup: '组1',
baseInfo: {
left: 397.0215, // 相对x
top: 444.5797, // 相对y
},
},
{
deviceType: '1', // 模型类型 1 设备1 2 设备2
id: '1003', // 模型id
status: 'watchOutline', // 模型状态 在线 离线 告警 故障
deviceName: '监控设备2', // 模型名称
deviceCode: 'code1001',
deviceLocation: '客厅',
deviceParams: '设备参数',
deviceCategory: '控制器',
diviceGroup: '组1',
baseInfo: {
left: 397.0215, // 相对x
top: 144.5797, // 相对y
},
},
{
deviceType: '1', // 模型类型 1 设备1 2 设备2
id: '1004', // 模型id
status: 'watchOutline', // 模型状态 在线 离线 告警 故障
deviceName: '监控设备2', // 模型名称
deviceCode: 'code1001',
deviceLocation: '客厅',
deviceParams: '设备参数',
deviceCategory: '控制器',
diviceGroup: '组1',
baseInfo: {
left: 297.0215, // 相对x
top: 644.5797, // 相对y
},
},
{
deviceType: '1', // 模型类型 1 设备1 2 设备2
id: '1005', // 模型id
status: 'watchWarn', // 模型状态 在线 离线 告警 故障
deviceName: '监控设备2', // 模型名称
deviceCode: 'code1001',
deviceLocation: '客厅',
deviceParams: '设备参数',
deviceCategory: '控制器',
diviceGroup: '组1',
baseInfo: {
left: 797.0215, // 相对x
top: 844.5797, // 相对y
},
},
],
};
const fabricRoomListData: Record<string, any>[] = [];
startData.modelsList.forEach((item: Record<string, any>) => {
const { baseInfo, ...restInfo } = item;
fabricRoomListData.push(
JSON.parse(
JSON.stringify({
...fetchWatchGroupObjects(item),
...baseInfo,
userProperty: item,
selectable: false,
}),
),
);
});
export const currJson = {
version: '5.3.0',
objects: fabricRoomListData,
clipPath: {
type: 'rect',
version: '5.3.0',
originX: 'left',
originY: 'top',
left: 0,
top: 0,
width: 1200,
height: 900,
fill: 'rgba(255,255,255,1)',
stroke: null,
strokeWidth: 0,
strokeDashArray: null,
strokeLineCap: 'butt',
strokeDashOffset: 0,
strokeLineJoin: 'miter',
strokeUniform: false,
strokeMiterLimit: 4,
scaleX: 1,
scaleY: 1,
angle: 0,
flipX: false,
flipY: false,
opacity: 1,
shadow: null,
visible: true,
backgroundColor: '',
fillRule: 'nonzero',
paintFirst: 'fill',
globalCompositeOperation: 'source-over',
skewX: 0,
skewY: 0,
rx: 0,
ry: 0,
selectable: false,
hasControls: true,
},
};

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save