refactor: 优化代码结构和类型定义
feat(types): 添加express.d.ts类型引用 style: 格式化express.d.ts中的接口定义 refactor: 移除未使用的AntFC类型导入 chore: 删除自动生成的.umi-production文件 feat: 添加店铺管理相关表和初始化脚本 docs: 更新安全规则和交互指南文档 refactor: 统一使用FC类型替代React.FC perf: 优化图表组件导入方式 style: 添加.prettierrc配置文件 refactor: 调整组件导入顺序和结构 feat: 添加平台库存管理路由 fix: 修复订单同步时的库存检查逻辑 docs: 更新RBAC设计和租户管理文档 refactor: 优化部门控制器代码
This commit is contained in:
553
dashboard/src/pages/Monitoring/SystemStatus.tsx
Normal file
553
dashboard/src/pages/Monitoring/SystemStatus.tsx
Normal file
@@ -0,0 +1,553 @@
|
||||
/**
|
||||
* [FE-MON004] 系统状态监控页面
|
||||
* @description 展示系统健康状态、服务状态、性能指标、告警信息
|
||||
* @version 1.0
|
||||
*/
|
||||
import { useState, useEffect, useCallback, FC } from '@/imports';
|
||||
import {
|
||||
Card,
|
||||
Row,
|
||||
Col,
|
||||
Statistic,
|
||||
Table,
|
||||
Tag,
|
||||
Alert,
|
||||
Progress,
|
||||
Badge,
|
||||
Button,
|
||||
Space,
|
||||
Typography,
|
||||
Tooltip,
|
||||
Spin,
|
||||
Descriptions,
|
||||
Timeline,
|
||||
Tabs,
|
||||
} from 'antd';
|
||||
import {
|
||||
CheckCircleOutlined,
|
||||
CloseCircleOutlined,
|
||||
WarningOutlined,
|
||||
SyncOutlined,
|
||||
ReloadOutlined,
|
||||
ServerOutlined,
|
||||
DatabaseOutlined,
|
||||
CloudServerOutlined,
|
||||
AlertOutlined,
|
||||
DashboardOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import {
|
||||
systemStatusDataSource,
|
||||
MonitoringDashboardData,
|
||||
ServiceStatus,
|
||||
AlertInfo,
|
||||
PerformanceDataPoint,
|
||||
} from '@/services/systemStatusDataSource';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
const SystemMonitoringPage: FC = () => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [data, setData] = useState<MonitoringDashboardData | null>(null);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [autoRefresh, setAutoRefresh] = useState(true);
|
||||
|
||||
const loadData = useCallback(async () => {
|
||||
try {
|
||||
const result = await systemStatusDataSource.getDashboardData();
|
||||
setData(result);
|
||||
} catch (error) {
|
||||
console.error('Failed to load monitoring data:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
setRefreshing(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
|
||||
let unsubscribe: (() => void) | null = null;
|
||||
|
||||
if (autoRefresh) {
|
||||
unsubscribe = systemStatusDataSource.subscribeToUpdates((newData) => {
|
||||
setData(newData);
|
||||
});
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (unsubscribe) {
|
||||
unsubscribe();
|
||||
}
|
||||
};
|
||||
}, [loadData, autoRefresh]);
|
||||
|
||||
const handleRefresh = () => {
|
||||
setRefreshing(true);
|
||||
loadData();
|
||||
};
|
||||
|
||||
const handleAcknowledgeAlert = async (alertId: string) => {
|
||||
await systemStatusDataSource.acknowledgeAlert(alertId);
|
||||
loadData();
|
||||
};
|
||||
|
||||
const handleRestartService = async (serviceId: string) => {
|
||||
try {
|
||||
const result = await systemStatusDataSource.restartService(serviceId);
|
||||
if (result.success) {
|
||||
loadData();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to restart service:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusBadge = (status: string) => {
|
||||
switch (status) {
|
||||
case 'healthy':
|
||||
case 'up':
|
||||
case 'running':
|
||||
return <Badge status="success" text="正常" />;
|
||||
case 'degraded':
|
||||
return <Badge status="warning" text="降级" />;
|
||||
case 'unhealthy':
|
||||
case 'down':
|
||||
case 'error':
|
||||
return <Badge status="error" text="异常" />;
|
||||
case 'stopped':
|
||||
return <Badge status="default" text="停止" />;
|
||||
case 'pending':
|
||||
return <Badge status="processing" text="启动中" />;
|
||||
default:
|
||||
return <Badge status="default" text={status} />;
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusIcon = (status: string) => {
|
||||
switch (status) {
|
||||
case 'healthy':
|
||||
case 'up':
|
||||
case 'running':
|
||||
return <CheckCircleOutlined style={{ color: '#52c41a', fontSize: 24 }} />;
|
||||
case 'degraded':
|
||||
return <WarningOutlined style={{ color: '#faad14', fontSize: 24 }} />;
|
||||
case 'unhealthy':
|
||||
case 'down':
|
||||
case 'error':
|
||||
return <CloseCircleOutlined style={{ color: '#ff4d4f', fontSize: 24 }} />;
|
||||
default:
|
||||
return <SyncOutlined spin style={{ color: '#1890ff', fontSize: 24 }} />;
|
||||
}
|
||||
};
|
||||
|
||||
const serviceColumns: ColumnsType<ServiceStatus> = [
|
||||
{
|
||||
title: '服务名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
render: (name: string, record) => (
|
||||
<Space>
|
||||
<CloudServerOutlined />
|
||||
<span>{name}</span>
|
||||
{record.version && <Tag color="blue">v{record.version}</Tag>}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
width: 120,
|
||||
render: (status: string) => getStatusBadge(status),
|
||||
},
|
||||
{
|
||||
title: '运行时间',
|
||||
dataIndex: 'uptime',
|
||||
key: 'uptime',
|
||||
width: 120,
|
||||
render: (uptime: number) => formatUptime(uptime),
|
||||
},
|
||||
{
|
||||
title: 'CPU',
|
||||
dataIndex: 'cpu',
|
||||
key: 'cpu',
|
||||
width: 120,
|
||||
render: (cpu: number) => (
|
||||
<Progress
|
||||
percent={Math.round(cpu)}
|
||||
size="small"
|
||||
status={cpu > 80 ? 'exception' : 'normal'}
|
||||
format={(percent) => `${percent}%`}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '内存',
|
||||
dataIndex: 'memory',
|
||||
key: 'memory',
|
||||
width: 120,
|
||||
render: (memory: number) => (
|
||||
<Progress
|
||||
percent={Math.round(memory)}
|
||||
size="small"
|
||||
status={memory > 80 ? 'exception' : 'normal'}
|
||||
format={(percent) => `${percent}%`}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '最后心跳',
|
||||
dataIndex: 'lastHeartbeat',
|
||||
key: 'lastHeartbeat',
|
||||
width: 180,
|
||||
render: (time: string) => new Date(time).toLocaleString(),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 100,
|
||||
render: (_: unknown, record: ServiceStatus) => (
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => handleRestartService(record.id)}
|
||||
disabled={record.status !== 'running'}
|
||||
>
|
||||
重启
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const alertColumns: ColumnsType<AlertInfo> = [
|
||||
{
|
||||
title: '类型',
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
width: 80,
|
||||
render: (type: string) => {
|
||||
const colors: Record<string, string> = {
|
||||
error: 'red',
|
||||
warning: 'orange',
|
||||
info: 'blue',
|
||||
};
|
||||
const icons: Record<string, React.ReactNode> = {
|
||||
error: <CloseCircleOutlined />,
|
||||
warning: <WarningOutlined />,
|
||||
info: <AlertOutlined />,
|
||||
};
|
||||
return (
|
||||
<Tag color={colors[type]} icon={icons[type]}>
|
||||
{type.toUpperCase()}
|
||||
</Tag>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '消息',
|
||||
dataIndex: 'message',
|
||||
key: 'message',
|
||||
},
|
||||
{
|
||||
title: '来源',
|
||||
dataIndex: 'source',
|
||||
key: 'source',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'timestamp',
|
||||
key: 'timestamp',
|
||||
width: 180,
|
||||
render: (time: string) => new Date(time).toLocaleString(),
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'acknowledged',
|
||||
key: 'acknowledged',
|
||||
width: 100,
|
||||
render: (acknowledged: boolean) => (
|
||||
<Tag color={acknowledged ? 'green' : 'orange'}>
|
||||
{acknowledged ? '已确认' : '待处理'}
|
||||
</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 80,
|
||||
render: (_: unknown, record: AlertInfo) => (
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => handleAcknowledgeAlert(record.id)}
|
||||
disabled={record.acknowledged}
|
||||
>
|
||||
确认
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div style={{ textAlign: 'center', padding: '100px 0' }}>
|
||||
<Spin size="large" tip="加载系统状态..." />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return (
|
||||
<Alert
|
||||
message="无法加载系统状态"
|
||||
description="请检查后端服务是否正常运行"
|
||||
type="error"
|
||||
showIcon
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={24}>
|
||||
<Card>
|
||||
<Row justify="space-between" align="middle">
|
||||
<Col>
|
||||
<Space>
|
||||
<DashboardOutlined style={{ fontSize: 24 }} />
|
||||
<Title level={4} style={{ margin: 0 }}>系统状态监控</Title>
|
||||
</Space>
|
||||
</Col>
|
||||
<Col>
|
||||
<Space>
|
||||
<Button
|
||||
icon={<SyncOutlined spin={refreshing} />}
|
||||
onClick={handleRefresh}
|
||||
loading={refreshing}
|
||||
>
|
||||
刷新
|
||||
</Button>
|
||||
<Button
|
||||
type={autoRefresh ? 'primary' : 'default'}
|
||||
icon={<ReloadOutlined />}
|
||||
onClick={() => setAutoRefresh(!autoRefresh)}
|
||||
>
|
||||
{autoRefresh ? '停止自动刷新' : '开启自动刷新'}
|
||||
</Button>
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||
<Col span={6}>
|
||||
<Card>
|
||||
<Statistic
|
||||
title="系统状态"
|
||||
value={data.health.status === 'healthy' ? '正常' : data.health.status === 'degraded' ? '降级' : '异常'}
|
||||
prefix={getStatusIcon(data.health.status)}
|
||||
valueStyle={{
|
||||
color: data.health.status === 'healthy' ? '#52c41a' :
|
||||
data.health.status === 'degraded' ? '#faad14' : '#ff4d4f'
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card>
|
||||
<Statistic
|
||||
title="CPU 使用率"
|
||||
value={Math.round(data.health.metrics.cpu)}
|
||||
suffix="%"
|
||||
prefix={<ServerOutlined />}
|
||||
valueStyle={{
|
||||
color: data.health.metrics.cpu > 80 ? '#ff4d4f' :
|
||||
data.health.metrics.cpu > 60 ? '#faad14' : '#52c41a'
|
||||
}}
|
||||
/>
|
||||
<Progress
|
||||
percent={Math.round(data.health.metrics.cpu)}
|
||||
showInfo={false}
|
||||
status={data.health.metrics.cpu > 80 ? 'exception' : 'normal'}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card>
|
||||
<Statistic
|
||||
title="内存使用率"
|
||||
value={Math.round(data.health.metrics.memory)}
|
||||
suffix="%"
|
||||
prefix={<DatabaseOutlined />}
|
||||
valueStyle={{
|
||||
color: data.health.metrics.memory > 80 ? '#ff4d4f' :
|
||||
data.health.metrics.memory > 60 ? '#faad14' : '#52c41a'
|
||||
}}
|
||||
/>
|
||||
<Progress
|
||||
percent={Math.round(data.health.metrics.memory)}
|
||||
showInfo={false}
|
||||
status={data.health.metrics.memory > 80 ? 'exception' : 'normal'}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card>
|
||||
<Statistic
|
||||
title="活跃连接"
|
||||
value={data.activeConnections}
|
||||
prefix={<CloudServerOutlined />}
|
||||
/>
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<Text type="secondary">队列大小: {data.queueSize}</Text>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||
<Col span={6}>
|
||||
<Card>
|
||||
<Statistic
|
||||
title="请求速率"
|
||||
value={Math.round(data.health.metrics.requestRate)}
|
||||
suffix="req/s"
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card>
|
||||
<Statistic
|
||||
title="平均响应时间"
|
||||
value={Math.round(data.health.metrics.avgResponseTime)}
|
||||
suffix="ms"
|
||||
valueStyle={{
|
||||
color: data.health.metrics.avgResponseTime > 500 ? '#ff4d4f' :
|
||||
data.health.metrics.avgResponseTime > 200 ? '#faad14' : '#52c41a'
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card>
|
||||
<Statistic
|
||||
title="错误率"
|
||||
value={data.health.metrics.errorRate.toFixed(2)}
|
||||
suffix="%"
|
||||
valueStyle={{
|
||||
color: data.health.metrics.errorRate > 5 ? '#ff4d4f' :
|
||||
data.health.metrics.errorRate > 1 ? '#faad14' : '#52c41a'
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card>
|
||||
<Statistic
|
||||
title="缓存命中率"
|
||||
value={(data.cacheHitRate * 100).toFixed(1)}
|
||||
suffix="%"
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||
<Col span={24}>
|
||||
<Card title="组件状态">
|
||||
<Row gutter={[16, 16]}>
|
||||
{Object.entries(data.health.components).map(([name, component]) => (
|
||||
<Col span={4} key={name}>
|
||||
<Tooltip title={`响应时间: ${component.responseTime}ms`}>
|
||||
<Card size="small">
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
{getStatusIcon(component.status)}
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<Text strong>{name.toUpperCase()}</Text>
|
||||
</div>
|
||||
<div style={{ marginTop: 4 }}>
|
||||
{getStatusBadge(component.status)}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||
<Col span={24}>
|
||||
<Card title="服务状态">
|
||||
<Table
|
||||
columns={serviceColumns}
|
||||
dataSource={data.services}
|
||||
rowKey="id"
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||
<Col span={24}>
|
||||
<Card title="告警信息">
|
||||
<Table
|
||||
columns={alertColumns}
|
||||
dataSource={data.alerts}
|
||||
rowKey="id"
|
||||
pagination={{ pageSize: 5 }}
|
||||
size="small"
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||
<Col span={24}>
|
||||
<Card title="系统信息">
|
||||
<Descriptions column={4}>
|
||||
<Descriptions.Item label="系统运行时间">
|
||||
{formatUptime(data.health.metrics.uptime)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="磁盘使用率">
|
||||
{Math.round(data.health.metrics.disk)}%
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="最后更新">
|
||||
{new Date(data.health.timestamp).toLocaleString()}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="数据刷新">
|
||||
{autoRefresh ? '自动 (5秒)' : '手动'}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function formatUptime(seconds: number): string {
|
||||
const days = Math.floor(seconds / 86400);
|
||||
const hours = Math.floor((seconds % 86400) / 3600);
|
||||
const mins = Math.floor((seconds % 3600) / 60);
|
||||
|
||||
if (days > 0) {
|
||||
return `${days}天 ${hours}小时`;
|
||||
}
|
||||
if (hours > 0) {
|
||||
return `${hours}小时 ${mins}分钟`;
|
||||
}
|
||||
return `${mins}分钟`;
|
||||
}
|
||||
|
||||
export default SystemMonitoringPage;
|
||||
@@ -1,172 +1,5 @@
|
||||
import {
|
||||
useState,
|
||||
useEffect,
|
||||
Card,
|
||||
Table,
|
||||
Button,
|
||||
Space,
|
||||
Input,
|
||||
message,
|
||||
Tag,
|
||||
Modal,
|
||||
Form,
|
||||
Select,
|
||||
DatePicker,
|
||||
Row,
|
||||
Col,
|
||||
Statistic,
|
||||
ReloadOutlined,
|
||||
PlusOutlined,
|
||||
SearchOutlined,
|
||||
Option,
|
||||
RangePicker,
|
||||
FC,
|
||||
} from '@/imports';
|
||||
import { MonitoringDataSource } from '@/services/monitoringDataSource';
|
||||
import type { MonitoringItem } from '@/services/monitoringDataSource';
|
||||
|
||||
const MonitoringPage: FC = () => {
|
||||
const [data, setData] = useState<MonitoringItem[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [searchText, setSearchText] = useState('');
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const [form] = Form.useForm();
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const loadData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const result = await MonitoringDataSource.list();
|
||||
setData(result);
|
||||
} catch (error: unknown) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
message.error(`加载失败: ${errorMessage}`);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCreate = async (values: any) => {
|
||||
try {
|
||||
await MonitoringDataSource.create(values);
|
||||
message.success('创建成功');
|
||||
setModalVisible(false);
|
||||
form.resetFields();
|
||||
loadData();
|
||||
} catch (error: unknown) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
message.error(`创建失败: ${errorMessage}`);
|
||||
}
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
render: (status: string) => {
|
||||
const color = status === 'ACTIVE' ? 'green' : status === 'INACTIVE' ? 'red' : 'default';
|
||||
return <Tag color={color}>{status}</Tag>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createdAt',
|
||||
key: 'createdAt',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 150,
|
||||
render: (_: any, record: MonitoringItem) => (
|
||||
<Space>
|
||||
<Button type="link" size="small">查看</Button>
|
||||
<Button type="link" size="small">编辑</Button>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card>
|
||||
<Row gutter={16} style={{ marginBottom: 16 }}>
|
||||
<Col span={6}>
|
||||
<Statistic title="总数" value={data.length} />
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Statistic
|
||||
title="活跃"
|
||||
value={data.filter(item => item.status === 'ACTIVE').length}
|
||||
valueStyle={{ color: '#3f8600' }}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
<Space>
|
||||
<Input
|
||||
placeholder="搜索..."
|
||||
prefix={<SearchOutlined />}
|
||||
value={searchText}
|
||||
onChange={(e) => setSearchText(e.target.value)}
|
||||
style={{ width: 200 }}
|
||||
/>
|
||||
<Button type="primary" icon={<PlusOutlined />} onClick={() => setModalVisible(true)}>
|
||||
新建
|
||||
</Button>
|
||||
<Button icon={<ReloadOutlined />} onClick={loadData}>
|
||||
刷新
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={data.filter(item =>
|
||||
item.name?.toLowerCase().includes(searchText.toLowerCase())
|
||||
)}
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
pagination={{ pageSize: 20 }}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
<Modal
|
||||
title="新建"
|
||||
open={modalVisible}
|
||||
onCancel={() => setModalVisible(false)}
|
||||
onOk={() => form.submit()}
|
||||
>
|
||||
<Form form={form} layout="vertical" onFinish={handleCreate}>
|
||||
<Form.Item name="name" label="名称" rules={[{ required: true }]}>
|
||||
<Input placeholder="请输入名称" />
|
||||
</Form.Item>
|
||||
<Form.Item name="status" label="状态" rules={[{ required: true }]}>
|
||||
<Select placeholder="请选择状态">
|
||||
<Option value="ACTIVE">活跃</Option>
|
||||
<Option value="INACTIVE">非活跃</Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MonitoringPage;
|
||||
/**
|
||||
* 监控模块入口
|
||||
* @description 包含监控配置和系统状态监控页面
|
||||
*/
|
||||
export { default as SystemStatus } from './SystemStatus';
|
||||
|
||||
Reference in New Issue
Block a user