diff --git a/frontend/src/pages/Dashboard/index.tsx b/frontend/src/pages/Dashboard/index.tsx
index 044bf441..ee1dec2e 100644
--- a/frontend/src/pages/Dashboard/index.tsx
+++ b/frontend/src/pages/Dashboard/index.tsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useState, useEffect } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Progress } from "@/components/ui/progress";
@@ -20,90 +20,195 @@ import {
ChevronRight,
CheckCircle,
AlertTriangle,
- XCircle
+ XCircle,
+ Loader2,
+ ServerCrash,
+ Server
} from "lucide-react";
+import { getEnvironmentList } from '@/pages/Deploy/Environment/List/service';
+import { getDevelopmentLanguages } from '@/pages/Deploy/Application/List/service';
+import { getDeploymentConfigPage } from '@/pages/Deploy/Deployment/List/service';
+import type { Environment } from '@/pages/Deploy/Environment/List/types';
+import type { DevelopmentLanguageType } from '@/pages/Deploy/Application/List/types';
+import type { DeploymentConfig, DeploymentConfigQueryParams } from '@/pages/Deploy/Deployment/List/types';
+import type { Page } from '@/types/base';
-// Mock环境数据
-const environments = [
- {
- id: "dev",
- name: "开发环境",
- projectCount: 10,
- status: "success",
- lastDeployment: "10分钟前",
- cpu: 60,
- memory: 70,
- storage: 50
- },
- {
- id: "test",
- name: "测试环境",
- projectCount: 8,
- status: "warning",
- lastDeployment: "1小时前",
- cpu: 80,
- memory: 75,
- storage: 60
- },
- {
- id: "staging",
- name: "预发环境",
- projectCount: 5,
- status: "success",
- lastDeployment: "2小时前",
- cpu: 40,
- memory: 50,
- storage: 30
- },
- {
- id: "prod",
- name: "生产环境",
- projectCount: 12,
- status: "error",
- lastDeployment: "1天前",
- cpu: 90,
- memory: 85,
- storage: 70
- }
-];
+type EnvironmentStatus = 'success' | 'warning' | 'error';
-// Mock项目数据
-const projects = [
- {
- id: 1,
- name: "用户中心",
- code: "user-center",
- type: "微服务",
- version: "v2.3.1",
- status: "活跃",
- buildStatus: "success",
- lastDeployment: "30分钟前"
- },
- {
- id: 2,
- name: "订单系统",
- code: "order-system",
- type: "后端服务",
- version: "v1.7.0",
- status: "活跃",
- buildStatus: "error",
- lastDeployment: "2小时前"
- },
- {
- id: 3,
- name: "前端门户",
- code: "frontend-portal",
- type: "前端应用",
- version: "v3.1.2",
- status: "活跃",
- buildStatus: "running",
- lastDeployment: "1天前"
- }
-];
+// 扩展环境类型,添加监控数据
+interface EnhancedEnvironment extends Environment {
+ projectCount: number;
+ status: EnvironmentStatus;
+ lastDeployment: string;
+ cpu: number;
+ memory: number;
+ storage: number;
+}
+
+const EmptyState: React.FC<{ title: string; description: string; icon: React.ReactNode }> = ({
+ title,
+ description,
+ icon
+}) => (
+
+
+ {icon}
+
+
{title}
+
{description}
+
+);
+
+const LoadingState = () => (
+
+);
const Dashboard: React.FC = () => {
const [projectType, setProjectType] = useState("");
const [status, setStatus] = useState("");
+ const [environments, setEnvironments] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [languages, setLanguages] = useState([]);
+ const [deployConfigs, setDeployConfigs] = useState([]);
+ const [searchText, setSearchText] = useState("");
+ const [currentEnvId, setCurrentEnvId] = useState();
+
+ // 获取环境和语言数据
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ setLoading(true);
+ const [envResponse, langResponse] = await Promise.all([
+ getEnvironmentList(),
+ getDevelopmentLanguages()
+ ]);
+
+ if (envResponse) {
+ const enrichedEnvironments = envResponse.map(env => {
+ const randomStatus: EnvironmentStatus = Math.random() > 0.7 ? 'warning' : 'success';
+ return {
+ ...env,
+ projectCount: 0, // 初始化为0,后续更新
+ status: randomStatus,
+ lastDeployment: '暂无部署',
+ cpu: Math.floor(Math.random() * 40) + 40,
+ memory: Math.floor(Math.random() * 30) + 50,
+ storage: Math.floor(Math.random() * 40) + 30,
+ };
+ });
+ setEnvironments(enrichedEnvironments);
+ if (enrichedEnvironments.length > 0) {
+ setCurrentEnvId(enrichedEnvironments[0].id);
+ }
+ }
+
+ if (langResponse) {
+ setLanguages(langResponse);
+ }
+ } catch (error) {
+ console.error('Failed to fetch data:', error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchData();
+ }, []);
+
+ // 获取部署配置数据
+ useEffect(() => {
+ const fetchDeployConfigs = async () => {
+ if (!currentEnvId) return;
+
+ try {
+ const queryParams: DeploymentConfigQueryParams = {
+ pageSize: 100,
+ pageNum: 1,
+ environmentId: currentEnvId,
+ workflowDefinitionId: 0
+ };
+
+ const response = await getDeploymentConfigPage(queryParams);
+
+ if (response) {
+ setDeployConfigs(response.content);
+ // 更新环境的项目数量
+ setEnvironments(prevEnvs =>
+ prevEnvs.map(env =>
+ env.id === currentEnvId
+ ? { ...env, projectCount: response.totalElements }
+ : env
+ )
+ );
+ }
+ } catch (error) {
+ console.error('Failed to fetch deployment configs:', error);
+ }
+ };
+
+ fetchDeployConfigs();
+ }, [currentEnvId]);
+
+ const handleSearch = async () => {
+ if (!currentEnvId) return;
+
+ try {
+ const queryParams: DeploymentConfigQueryParams = {
+ pageSize: 100,
+ pageNum: 1,
+ environmentId: currentEnvId,
+ workflowDefinitionId: 0,
+ enabled: status === 'active' ? true : status === 'paused' ? false : undefined
+ };
+
+ const response = await getDeploymentConfigPage(queryParams);
+
+ if (response) {
+ // 在前端过滤开发语言
+ const filteredConfigs = response.content.filter(config => {
+ if (projectType && config.languageType !== projectType) {
+ return false;
+ }
+ return true;
+ });
+ setDeployConfigs(filteredConfigs);
+ }
+ } catch (error) {
+ console.error('Failed to search deployment configs:', error);
+ }
+ };
+
+ const handleReset = () => {
+ setSearchText("");
+ setProjectType("");
+ setStatus("");
+ if (currentEnvId) {
+ const queryParams: DeploymentConfigQueryParams = {
+ pageSize: 100,
+ pageNum: 1,
+ environmentId: currentEnvId,
+ workflowDefinitionId: 0
+ };
+
+ getDeploymentConfigPage(queryParams).then(response => {
+ if (response) {
+ setDeployConfigs(response.content);
+ }
+ });
+ }
+ };
+
+ const handleTabChange = (envCode: string) => {
+ const env = environments.find(e => e.envCode === envCode);
+ if (env) {
+ setCurrentEnvId(env.id);
+ }
+ };
const getStatusIcon = (status: string) => {
switch (status) {
@@ -118,13 +223,11 @@ const Dashboard: React.FC = () => {
}
};
- const getBuildStatusBadge = (status: string) => {
- const statusConfig = {
- success: { className: "bg-green-100 text-green-800", text: "成功" },
- error: { className: "bg-red-100 text-red-800", text: "失败" },
- running: { className: "bg-blue-100 text-blue-800", text: "进行中" }
- };
- const config = statusConfig[status as keyof typeof statusConfig] || statusConfig.running;
+ const getBuildStatusBadge = (enabled: boolean) => {
+ const config = enabled
+ ? { className: "bg-green-100 text-green-800", text: "活跃" }
+ : { className: "bg-red-100 text-red-800", text: "暂停" };
+
return (
{config.text}
@@ -132,149 +235,194 @@ const Dashboard: React.FC = () => {
);
};
+ if (loading) {
+ return ;
+ }
+
+ const hasEnvironments = environments.length > 0;
+ const hasProjects = deployConfigs.length > 0;
+
return (
部署环境概览
-
- {environments.map((env) => (
-
-
- {env.name}
- {getStatusIcon(env.status)}
-
-
- {env.projectCount}
- 个项目
-
-
-
- 最近部署: {env.lastDeployment}
-
-
-
-
CPU
-
{env.cpu}%
+
+ {!hasEnvironments ? (
+
+
+ }
+ title="暂无环境数据"
+ description="当前系统中还没有配置任何环境。请先添加部署环境,然后开始使用部署功能。"
+ />
+
+
+ ) : (
+ <>
+
+ {environments.map((env) => (
+
+
+ {env.envName}
+ {getStatusIcon(env.status)}
+
+
+ {env.projectCount}
+ 个项目
+
+
+
+ 最近部署: {env.lastDeployment}
+
+
+
+ CPU
+ {env.cpu}%
+
+
+
+
+
+ 内存
+ {env.memory}%
+
+
+
+
+
+ 存储
+ {env.storage}%
+
+
+
-
-
-
-
- 内存
- {env.memory}%
-
-
-
-
-
- 存储
- {env.storage}%
-
-
-
-
-
-
- ))}
-
-
-
-
-
-
- {environments.map((env) => (
-
- {env.name}
-
- ))}
-
+
+
+ ))}
- {environments.map((env) => (
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ {environments.map((env) => (
+
+ {env.envName}
+
+ ))}
+
-
- {projects.map((project) => (
-
-
-
-
-
{project.name}
-
{project.code}
-
- {getBuildStatusBadge(project.buildStatus)}
-
-
-
-
-
版本
-
{project.version}
-
-
-
状态
-
{project.status}
-
-
-
最近部署
-
{project.lastDeployment}
-
-
-
-
+
+
+ {!hasProjects ? (
+
+
+ }
+ title="暂无项目数据"
+ description="当前环境中还没有配置任何项目。请先创建项目,然后开始部署。"
+ />
+
+
+ ) : (
+
+ {deployConfigs.map((config) => (
+
+
+
+
+
{config.application.appName}
+
{config.application.appCode}
+
+ {getBuildStatusBadge(config.enabled)}
+
+
+
+
构建类型
+
{config.buildType}
+
+
+
开发语言
+
{config.languageType}
+
+
+
工作流
+
{config.publishedWorkflowDefinition?.name || '未配置'}
+
+
+
最近更新
+
{new Date(config.updateTime).toLocaleString()}
+
+
+
+
+
+ 编辑
+
+
+
+ 详情
+
+
+
+
+ ))}
+
+ )}
+
+ ))}
+
+
+ >
+ )}
);
};
diff --git a/frontend/src/pages/Deploy/Application/List/service.ts b/frontend/src/pages/Deploy/Application/List/service.ts
index 04183e71..834fde12 100644
--- a/frontend/src/pages/Deploy/Application/List/service.ts
+++ b/frontend/src/pages/Deploy/Application/List/service.ts
@@ -1,6 +1,7 @@
import request from '@/utils/request';
import type { CreateApplicationRequest, UpdateApplicationRequest, Application, ApplicationQuery } from './types';
import type { Page } from '@/types/base';
+import {DevelopmentLanguageType} from "./types";
const BASE_URL = '/api/v1/applications';
@@ -31,3 +32,6 @@ export const getApplicationList = () =>
// 条件查询应用列表
export const getApplicationListByCondition = (params?: ApplicationQuery) =>
request.get(`${BASE_URL}/list`, { params });
+
+export const getDevelopmentLanguages = () =>
+ request.get(`${BASE_URL}/development-languages`);
diff --git a/frontend/src/pages/Deploy/Application/List/types.ts b/frontend/src/pages/Deploy/Application/List/types.ts
index e3b66e24..84075af7 100644
--- a/frontend/src/pages/Deploy/Application/List/types.ts
+++ b/frontend/src/pages/Deploy/Application/List/types.ts
@@ -40,4 +40,10 @@ export interface ApplicationQuery extends BaseQuery {
appCode?: string;
appName?: string;
enabled?: boolean;
+ language?: string;
+}
+
+export interface DevelopmentLanguageType {
+ code: string;
+ name: string;
}