包含多个会话的累积代码变更: - backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔 - admin-web: ETL 状态页、任务管理、调度配置、登录优化 - miniprogram: 看板页面、聊天集成、UI 组件、导航更新 - etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强 - tenant-admin: 项目初始化 - db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8) - packages/shared: 枚举和工具函数更新 - tools: 数据库工具、报表生成、健康检查 - docs: PRD/架构/部署/合约文档更新 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
159 lines
4.6 KiB
TypeScript
159 lines
4.6 KiB
TypeScript
/**
|
||
* 运维控制面板页面
|
||
*
|
||
* 功能:
|
||
* - 服务器系统资源概况(CPU / 内存 / 磁盘)
|
||
* - 各环境服务状态 + 启停重启按钮
|
||
* - 各环境 Git 状态 + pull / 同步依赖按钮
|
||
* - 各环境 .env 配置查看(敏感值脱敏)
|
||
*
|
||
* CHANGE 2026-07-25 | admin-web-restructure 8.1
|
||
* 拆分为 SystemResourceSection / ServiceStatusSection / GitStatusSection 三个子组件,
|
||
* 本页面改为组合子组件,功能不变。
|
||
*/
|
||
|
||
import React, { useEffect, useState, useCallback } from "react";
|
||
import { Modal, message, Spin, Typography } from "antd";
|
||
import { DesktopOutlined } from "@ant-design/icons";
|
||
import type { SystemInfo, ServiceStatus, GitInfo } from "../api/opsPanel";
|
||
import {
|
||
fetchSystemInfo,
|
||
fetchServicesStatus,
|
||
fetchGitInfo,
|
||
startService,
|
||
stopService,
|
||
restartService,
|
||
gitPull,
|
||
syncDeps,
|
||
} from "../api/opsPanel";
|
||
import {
|
||
SystemResourceSection,
|
||
ServiceStatusSection,
|
||
GitStatusSection,
|
||
} from "../components/ops";
|
||
|
||
const { Title } = Typography;
|
||
|
||
/* ------------------------------------------------------------------ */
|
||
/* 组件 */
|
||
/* ------------------------------------------------------------------ */
|
||
|
||
const OpsPanel: React.FC = () => {
|
||
const [system, setSystem] = useState<SystemInfo | null>(null);
|
||
const [services, setServices] = useState<ServiceStatus[]>([]);
|
||
const [gitInfos, setGitInfos] = useState<GitInfo[]>([]);
|
||
const [loading, setLoading] = useState(true);
|
||
const [actionLoading, setActionLoading] = useState<Record<string, boolean>>({});
|
||
|
||
// ---- 数据加载 ----
|
||
|
||
const loadAll = useCallback(async () => {
|
||
try {
|
||
const [sys, svc, git] = await Promise.all([
|
||
fetchSystemInfo(),
|
||
fetchServicesStatus(),
|
||
fetchGitInfo(),
|
||
]);
|
||
setSystem(sys);
|
||
setServices(svc);
|
||
setGitInfos(git);
|
||
} catch {
|
||
message.error("加载运维数据失败");
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
loadAll();
|
||
const timer = setInterval(loadAll, 15_000);
|
||
return () => clearInterval(timer);
|
||
}, [loadAll]);
|
||
|
||
// ---- 操作处理 ----
|
||
|
||
const withAction = async (key: string, fn: () => Promise<void>) => {
|
||
setActionLoading((prev) => ({ ...prev, [key]: true }));
|
||
try {
|
||
await fn();
|
||
} finally {
|
||
setActionLoading((prev) => ({ ...prev, [key]: false }));
|
||
}
|
||
};
|
||
|
||
const handleStart = (env: string) =>
|
||
withAction(`start-${env}`, async () => {
|
||
const r = await startService(env);
|
||
r.success ? message.success(r.message) : message.warning(r.message);
|
||
await loadAll();
|
||
});
|
||
|
||
const handleStop = (env: string) =>
|
||
withAction(`stop-${env}`, async () => {
|
||
const r = await stopService(env);
|
||
r.success ? message.success(r.message) : message.warning(r.message);
|
||
await loadAll();
|
||
});
|
||
|
||
const handleRestart = (env: string) =>
|
||
withAction(`restart-${env}`, async () => {
|
||
const r = await restartService(env);
|
||
r.success ? message.success(r.message) : message.warning(r.message);
|
||
await loadAll();
|
||
});
|
||
|
||
const handlePull = (env: string) =>
|
||
withAction(`pull-${env}`, async () => {
|
||
const r = await gitPull(env);
|
||
if (r.success) {
|
||
message.success("拉取成功");
|
||
Modal.info({ title: `Git Pull - ${env}`, content: <pre style={{ maxHeight: 300, overflow: "auto", fontSize: 12 }}>{r.output}</pre>, width: 600 });
|
||
} else {
|
||
message.error("拉取失败");
|
||
Modal.error({ title: `Git Pull 失败 - ${env}`, content: <pre style={{ maxHeight: 300, overflow: "auto", fontSize: 12 }}>{r.output}</pre>, width: 600 });
|
||
}
|
||
await loadAll();
|
||
});
|
||
|
||
const handleSyncDeps = (env: string) =>
|
||
withAction(`sync-${env}`, async () => {
|
||
const r = await syncDeps(env);
|
||
r.success ? message.success("依赖同步完成") : message.error(r.message);
|
||
});
|
||
|
||
// ---- 渲染 ----
|
||
|
||
if (loading) {
|
||
return <Spin size="large" style={{ display: "flex", justifyContent: "center", marginTop: 120 }} />;
|
||
}
|
||
|
||
return (
|
||
<div>
|
||
<Title level={4} style={{ marginBottom: 16 }}>
|
||
<DesktopOutlined style={{ marginRight: 8 }} />
|
||
运维控制面板
|
||
</Title>
|
||
|
||
{system && <SystemResourceSection system={system} />}
|
||
|
||
<ServiceStatusSection
|
||
services={services}
|
||
actionLoading={actionLoading}
|
||
onStart={handleStart}
|
||
onStop={handleStop}
|
||
onRestart={handleRestart}
|
||
/>
|
||
|
||
<GitStatusSection
|
||
gitInfos={gitInfos}
|
||
services={services}
|
||
actionLoading={actionLoading}
|
||
onPull={handlePull}
|
||
onSyncDeps={handleSyncDeps}
|
||
/>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default OpsPanel;
|