This commit is contained in:
dengqichen 2024-12-24 10:36:37 +08:00
parent b9d559a683
commit 7ad20a0cbd
5 changed files with 90 additions and 73 deletions

View File

@ -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="环境描述"

View File

@ -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

View File

@ -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>
); );

View File

@ -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) {
case 'PRODUCT':
return { return {
type: 'DEMO', type: 'PRODUCT',
label: '示例项目组', label: '产品项目组',
color: '#1890ff', color: '#1890ff',
icon: <RocketOutlined/>, icon: <RocketOutlined/>,
description: '用于演示和测试的项目组' description: '产品相关的项目组'
}; };
} case 'PLATFORM':
if (code.toUpperCase().includes('PLATFORM')) {
return { return {
type: 'PLATFORM', type: 'PLATFORM',
label: '平台项目组', label: '平台项目组',
color: '#52c41a', color: '#52c41a',
icon: <EnvironmentOutlined/>, icon: <EnvironmentOutlined/>,
description: '平台相关的核心项目组' description: '平台相关的项目组'
}; };
} default:
return { return {
type: 'BUSINESS', type: 'BUSINESS',
label: '业务项目组', label: '业务项目组',
color: '#722ed1', color: '#722ed1',
icon: <TeamOutlined/>, icon: <TeamOutlined/>,
description: '具体业务相关的项目组' 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}>

View File

@ -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;