1
This commit is contained in:
parent
b9d559a683
commit
7ad20a0cbd
@ -117,18 +117,6 @@ const EnvironmentModal: React.FC<EnvironmentModalProps> = ({
|
|||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
name="deployType"
|
|
||||||
label="部署方式"
|
|
||||||
rules={[{required: true, message: '请选择部署方式'}]}
|
|
||||||
>
|
|
||||||
<Select
|
|
||||||
placeholder="请选择部署方式"
|
|
||||||
options={deployTypeOptions}
|
|
||||||
style={{width: '100%'}}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="envDesc"
|
name="envDesc"
|
||||||
label="环境描述"
|
label="环境描述"
|
||||||
|
|||||||
@ -31,26 +31,6 @@ const buildTypeMap = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const deployTypeMap = {
|
|
||||||
[DeployTypeEnum.K8S]: {
|
|
||||||
label: 'Kubernetes集群部署',
|
|
||||||
color: '#1890ff',
|
|
||||||
icon: <CloudServerOutlined/>,
|
|
||||||
description: '部署到Kubernetes容器编排平台'
|
|
||||||
},
|
|
||||||
[DeployTypeEnum.DOCKER]: {
|
|
||||||
label: 'Docker容器部署',
|
|
||||||
color: '#13c2c2',
|
|
||||||
icon: <RocketOutlined/>,
|
|
||||||
description: '部署为Docker独立容器'
|
|
||||||
},
|
|
||||||
[DeployTypeEnum.VM]: {
|
|
||||||
label: '虚拟机部署',
|
|
||||||
color: '#faad14',
|
|
||||||
icon: <SettingOutlined/>,
|
|
||||||
description: '部署到传统虚拟机环境'
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const EnvironmentList: React.FC = () => {
|
const EnvironmentList: React.FC = () => {
|
||||||
const [environments, setEnvironments] = useState<Environment[]>([]);
|
const [environments, setEnvironments] = useState<Environment[]>([]);
|
||||||
@ -96,8 +76,6 @@ const EnvironmentList: React.FC = () => {
|
|||||||
|
|
||||||
const EnvironmentCard = ({environment}: { environment: Environment }) => {
|
const EnvironmentCard = ({environment}: { environment: Environment }) => {
|
||||||
const buildType = buildTypeMap[environment.buildType];
|
const buildType = buildTypeMap[environment.buildType];
|
||||||
const deployType = deployTypeMap[environment.deployType];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
hoverable
|
hoverable
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import type {ProjectGroup} from '../types';
|
|||||||
import type {Environment} from '../../../Environment/List/types';
|
import type {Environment} from '../../../Environment/List/types';
|
||||||
import {createProjectGroup, updateProjectGroup} from '../service';
|
import {createProjectGroup, updateProjectGroup} from '../service';
|
||||||
import {getEnvironmentList} from '../../../Environment/List/service';
|
import {getEnvironmentList} from '../../../Environment/List/service';
|
||||||
|
import {BuildTypeEnum} from "../../../Environment/List/types";
|
||||||
|
import {ProjectGroupTypeEnum} from "../types";
|
||||||
|
|
||||||
interface ProjectGroupModalProps {
|
interface ProjectGroupModalProps {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
@ -12,6 +14,11 @@ interface ProjectGroupModalProps {
|
|||||||
initialValues?: ProjectGroup;
|
initialValues?: ProjectGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const buildProjectGroupTypes = [
|
||||||
|
{label: '产品', value: ProjectGroupTypeEnum.PRODUCT},
|
||||||
|
{label: '项目', value: ProjectGroupTypeEnum.PROJECT}
|
||||||
|
];
|
||||||
|
|
||||||
const ProjectGroupModal: React.FC<ProjectGroupModalProps> = ({
|
const ProjectGroupModal: React.FC<ProjectGroupModalProps> = ({
|
||||||
visible,
|
visible,
|
||||||
onCancel,
|
onCancel,
|
||||||
@ -90,6 +97,17 @@ const ProjectGroupModal: React.FC<ProjectGroupModalProps> = ({
|
|||||||
layout="vertical"
|
layout="vertical"
|
||||||
initialValues={{projectGroupStatus: 'ENABLE', sort: 0}}
|
initialValues={{projectGroupStatus: 'ENABLE', sort: 0}}
|
||||||
>
|
>
|
||||||
|
<Form.Item
|
||||||
|
name="type"
|
||||||
|
label="项目组类型"
|
||||||
|
rules={[{required: true, message: '请选择项目组类型'}]}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
placeholder="请选择项目组类型"
|
||||||
|
options={buildProjectGroupTypes}
|
||||||
|
style={{width: '100%'}}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="projectGroupCode"
|
name="projectGroupCode"
|
||||||
label="项目组编码"
|
label="项目组编码"
|
||||||
@ -141,6 +159,13 @@ const ProjectGroupModal: React.FC<ProjectGroupModalProps> = ({
|
|||||||
<Radio value="DISABLE">禁用</Radio>
|
<Radio value="DISABLE">禁用</Radio>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="sort"
|
||||||
|
label="排序"
|
||||||
|
rules={[{required: true, message: '请输入排序值'}]}
|
||||||
|
>
|
||||||
|
<InputNumber min={0} placeholder="请输入排序值" style={{width: '100%'}}/>
|
||||||
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -61,32 +61,33 @@ const ProjectList: React.FC = () => {
|
|||||||
setModalVisible(true);
|
setModalVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getProjectTypeInfo = (code: string) => {
|
const getProjectTypeInfo = (type: string) => {
|
||||||
if (code.toUpperCase().includes('DEMO')) {
|
switch (type) {
|
||||||
return {
|
case 'PRODUCT':
|
||||||
type: 'DEMO',
|
return {
|
||||||
label: '示例项目组',
|
type: 'PRODUCT',
|
||||||
color: '#1890ff',
|
label: '产品项目组',
|
||||||
icon: <RocketOutlined/>,
|
color: '#1890ff',
|
||||||
description: '用于演示和测试的项目组'
|
icon: <RocketOutlined/>,
|
||||||
};
|
description: '产品相关的项目组'
|
||||||
|
};
|
||||||
|
case 'PLATFORM':
|
||||||
|
return {
|
||||||
|
type: 'PLATFORM',
|
||||||
|
label: '平台项目组',
|
||||||
|
color: '#52c41a',
|
||||||
|
icon: <EnvironmentOutlined/>,
|
||||||
|
description: '平台相关的项目组'
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
type: 'BUSINESS',
|
||||||
|
label: '业务项目组',
|
||||||
|
color: '#722ed1',
|
||||||
|
icon: <TeamOutlined/>,
|
||||||
|
description: '业务相关的项目组'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (code.toUpperCase().includes('PLATFORM')) {
|
|
||||||
return {
|
|
||||||
type: 'PLATFORM',
|
|
||||||
label: '平台项目组',
|
|
||||||
color: '#52c41a',
|
|
||||||
icon: <EnvironmentOutlined/>,
|
|
||||||
description: '平台相关的核心项目组'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
type: 'BUSINESS',
|
|
||||||
label: '业务项目组',
|
|
||||||
color: '#722ed1',
|
|
||||||
icon: <TeamOutlined/>,
|
|
||||||
description: '具体业务相关的项目组'
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const filteredProjects = projects.filter(project => {
|
const filteredProjects = projects.filter(project => {
|
||||||
@ -97,13 +98,13 @@ const ProjectList: React.FC = () => {
|
|||||||
) : true;
|
) : true;
|
||||||
|
|
||||||
const matchesType = projectType === 'ALL' ? true :
|
const matchesType = projectType === 'ALL' ? true :
|
||||||
getProjectTypeInfo(project.projectGroupCode).type === projectType;
|
getProjectTypeInfo(project.type).type === projectType;
|
||||||
|
|
||||||
return matchesSearch && matchesType;
|
return matchesSearch && matchesType;
|
||||||
});
|
});
|
||||||
|
|
||||||
const ProjectCard = ({project}: { project: ProjectGroup }) => {
|
const ProjectCard = ({projectGroup}: { projectGroup: ProjectGroup }) => {
|
||||||
const typeInfo = getProjectTypeInfo(project.projectGroupCode);
|
const typeInfo = getProjectTypeInfo(projectGroup.type);
|
||||||
const Icon = typeInfo.icon;
|
const Icon = typeInfo.icon;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -146,7 +147,7 @@ const ProjectList: React.FC = () => {
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '8px'
|
gap: '8px'
|
||||||
}}>
|
}}>
|
||||||
{project.projectGroupName}
|
{projectGroup.projectGroupName}
|
||||||
<Tag
|
<Tag
|
||||||
color={typeInfo.color}
|
color={typeInfo.color}
|
||||||
style={{
|
style={{
|
||||||
@ -172,7 +173,7 @@ const ProjectList: React.FC = () => {
|
|||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{project.projectGroupDesc || '暂无描述'}
|
{projectGroup.projectGroupDesc || '暂无描述'}
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
<div style={{
|
<div style={{
|
||||||
@ -205,7 +206,7 @@ const ProjectList: React.FC = () => {
|
|||||||
borderRadius: '6px',
|
borderRadius: '6px',
|
||||||
letterSpacing: '0.5px',
|
letterSpacing: '0.5px',
|
||||||
}}>
|
}}>
|
||||||
{project.projectGroupCode}
|
{projectGroup.projectGroupCode}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -213,7 +214,7 @@ const ProjectList: React.FC = () => {
|
|||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Statistic
|
<Statistic
|
||||||
title={<Text type="secondary" style={{fontSize: '13px'}}>环境数量</Text>}
|
title={<Text type="secondary" style={{fontSize: '13px'}}>环境数量</Text>}
|
||||||
value={2}
|
value={projectGroup.environments.length}
|
||||||
prefix={<EnvironmentOutlined/>}
|
prefix={<EnvironmentOutlined/>}
|
||||||
valueStyle={{fontSize: '16px', color: typeInfo.color}}
|
valueStyle={{fontSize: '16px', color: typeInfo.color}}
|
||||||
/>
|
/>
|
||||||
@ -221,7 +222,7 @@ const ProjectList: React.FC = () => {
|
|||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Statistic
|
<Statistic
|
||||||
title={<Text type="secondary" style={{fontSize: '13px'}}>项目个数</Text>}
|
title={<Text type="secondary" style={{fontSize: '13px'}}>项目个数</Text>}
|
||||||
value={5}
|
value={projectGroup.applications.length}
|
||||||
prefix={<TeamOutlined/>}
|
prefix={<TeamOutlined/>}
|
||||||
valueStyle={{fontSize: '16px', color: typeInfo.color}}
|
valueStyle={{fontSize: '16px', color: typeInfo.color}}
|
||||||
/>
|
/>
|
||||||
@ -229,7 +230,6 @@ const ProjectList: React.FC = () => {
|
|||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Statistic
|
<Statistic
|
||||||
title={<Text type="secondary" style={{fontSize: '13px'}}>成员数量</Text>}
|
title={<Text type="secondary" style={{fontSize: '13px'}}>成员数量</Text>}
|
||||||
value={5}
|
|
||||||
prefix={<TeamOutlined/>}
|
prefix={<TeamOutlined/>}
|
||||||
valueStyle={{fontSize: '16px', color: typeInfo.color}}
|
valueStyle={{fontSize: '16px', color: typeInfo.color}}
|
||||||
/>
|
/>
|
||||||
@ -242,7 +242,7 @@ const ProjectList: React.FC = () => {
|
|||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
icon={<EditOutlined/>}
|
icon={<EditOutlined/>}
|
||||||
onClick={() => handleEdit(project)}
|
onClick={() => handleEdit(projectGroup)}
|
||||||
style={{
|
style={{
|
||||||
borderRadius: '6px',
|
borderRadius: '6px',
|
||||||
background: typeInfo.color,
|
background: typeInfo.color,
|
||||||
@ -254,7 +254,7 @@ const ProjectList: React.FC = () => {
|
|||||||
<Popconfirm
|
<Popconfirm
|
||||||
title="确定要删除该项目组吗?"
|
title="确定要删除该项目组吗?"
|
||||||
description="删除后将无法恢复,请谨慎操作"
|
description="删除后将无法恢复,请谨慎操作"
|
||||||
onConfirm={() => handleDelete(project.id)}
|
onConfirm={() => handleDelete(projectGroup.id)}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
danger
|
danger
|
||||||
@ -312,6 +312,21 @@ const ProjectList: React.FC = () => {
|
|||||||
style={{width: '100%'}}
|
style={{width: '100%'}}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Select
|
||||||
|
placeholder="项目组类型"
|
||||||
|
style={{ width: 200 }}
|
||||||
|
value={projectType}
|
||||||
|
onChange={setProjectType}
|
||||||
|
options={[
|
||||||
|
{ label: '全部类型', value: 'ALL' },
|
||||||
|
{ label: '产品项目组', value: 'PRODUCT' },
|
||||||
|
{ label: '平台项目组', value: 'PLATFORM' },
|
||||||
|
{ label: '业务项目组', value: 'BUSINESS' }
|
||||||
|
]}
|
||||||
|
size="large"
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -319,7 +334,7 @@ const ProjectList: React.FC = () => {
|
|||||||
<Row gutter={[24, 24]}>
|
<Row gutter={[24, 24]}>
|
||||||
{filteredProjects.map(project => (
|
{filteredProjects.map(project => (
|
||||||
<Col xs={24} sm={12} md={8} lg={6} key={project.id}>
|
<Col xs={24} sm={12} md={8} lg={6} key={project.id}>
|
||||||
<ProjectCard project={project}/>
|
<ProjectCard projectGroup={project}/>
|
||||||
</Col>
|
</Col>
|
||||||
))}
|
))}
|
||||||
<Col xs={24} sm={12} md={8} lg={6}>
|
<Col xs={24} sm={12} md={8} lg={6}>
|
||||||
|
|||||||
@ -1,20 +1,31 @@
|
|||||||
import { BaseResponse, BaseRequest, BaseQuery } from '@/types/base';
|
import {BaseResponse, BaseRequest, BaseQuery} from '@/types/base';
|
||||||
import { Environment } from '../../Environment/List/types';
|
import {Environment} from '../../Environment/List/types';
|
||||||
|
import {Application} from "@/pages/Deploy/Application/List/types";
|
||||||
|
|
||||||
|
|
||||||
|
export enum ProjectGroupTypeEnum {
|
||||||
|
PRODUCT = 'PRODUCT',
|
||||||
|
PROJECT = 'PROJECT'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 项目基础信息
|
// 项目基础信息
|
||||||
export interface ProjectGroup extends BaseResponse {
|
export interface ProjectGroup extends BaseResponse {
|
||||||
tenantCode: string;
|
tenantCode: string;
|
||||||
|
type: ProjectGroupTypeEnum;
|
||||||
projectGroupCode: string;
|
projectGroupCode: string;
|
||||||
projectGroupName: string;
|
projectGroupName: string;
|
||||||
projectGroupDesc?: string;
|
projectGroupDesc?: string;
|
||||||
projectGroupStatus: 'ENABLE' | 'DISABLE';
|
projectGroupStatus: 'ENABLE' | 'DISABLE';
|
||||||
environments: Environment[];
|
environments: Environment[];
|
||||||
|
applications: Application[];
|
||||||
sort: number;
|
sort: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建项目请求参数
|
// 创建项目请求参数
|
||||||
export interface CreateProjectGroupRequest extends BaseRequest {
|
export interface CreateProjectGroupRequest extends BaseRequest {
|
||||||
tenantCode: string;
|
tenantCode: string;
|
||||||
|
type: ProjectGroupTypeEnum;
|
||||||
projectGroupCode: string;
|
projectGroupCode: string;
|
||||||
projectGroupName: string;
|
projectGroupName: string;
|
||||||
projectGroupDesc?: string;
|
projectGroupDesc?: string;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user