This commit is contained in:
dengqichen 2024-12-26 13:37:14 +08:00
parent e8cd2575eb
commit 656413d3f7
7 changed files with 324 additions and 182 deletions

View File

@ -1,7 +1,8 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { Modal, Form, Input, InputNumber, Radio, message } from 'antd'; import { Modal, Form, Input, InputNumber, Radio, message, Select } from 'antd';
import type { Application } from '../types'; import type { Application } from '../types';
import { createApplication, updateApplication } from '../service'; import { createApplication, updateApplication } from '../service';
import { DevelopmentLanguageTypeEnum } from '../types';
interface ApplicationModalProps { interface ApplicationModalProps {
visible: boolean; visible: boolean;
@ -24,12 +25,15 @@ const ApplicationModal: React.FC<ApplicationModalProps> = ({
useEffect(() => { useEffect(() => {
if (visible) { if (visible) {
if (initialValues) { if (initialValues) {
form.setFieldsValue(initialValues); form.setFieldsValue({
...initialValues,
});
} else { } else {
form.setFieldsValue({ form.setFieldsValue({
appStatus: 'ENABLE', projectGroupId,
enabled: true,
sort: 0, sort: 0,
projectGroupId: projectGroupId // 设置项目组ID的初始值 language: DevelopmentLanguageTypeEnum.JAVA,
}); });
} }
} }
@ -40,7 +44,7 @@ const ApplicationModal: React.FC<ApplicationModalProps> = ({
const values = await form.validateFields(); const values = await form.validateFields();
const submitData = { const submitData = {
...values, ...values,
projectGroupId: projectGroupId // 确保提交时包含项目组ID projectGroupId,
}; };
if (isEdit) { if (isEdit) {
@ -70,13 +74,18 @@ const ApplicationModal: React.FC<ApplicationModalProps> = ({
onOk={handleSubmit} onOk={handleSubmit}
onCancel={handleCancel} onCancel={handleCancel}
destroyOnClose destroyOnClose
width={600}
> >
<Form <Form
form={form} form={form}
layout="vertical" layout="vertical"
initialValues={{ appStatus: 'ENABLE', sort: 0 }} initialValues={{
enabled: true,
sort: 0,
language: DevelopmentLanguageTypeEnum.JAVA,
}}
> >
{/* 添加一个隐藏的表单项来存储项目组ID */} {/* 隐藏的项目组ID字段 */}
<Form.Item name="projectGroupId" hidden> <Form.Item name="projectGroupId" hidden>
<Input /> <Input />
</Form.Item> </Form.Item>
@ -108,13 +117,37 @@ const ApplicationModal: React.FC<ApplicationModalProps> = ({
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name="appStatus" name="repoUrl"
label="仓库地址"
rules={[
{ required: true, message: '请输入仓库地址' },
{ type: 'url', message: '请输入有效的URL地址' },
]}
>
<Input placeholder="请输入仓库地址" />
</Form.Item>
<Form.Item
name="language"
label="开发语言"
rules={[{ required: true, message: '请选择开发语言' }]}
>
<Select placeholder="请选择开发语言">
<Select.Option value={DevelopmentLanguageTypeEnum.JAVA}>Java</Select.Option>
<Select.Option value={DevelopmentLanguageTypeEnum.NODE_JS}>NodeJS</Select.Option>
<Select.Option value={DevelopmentLanguageTypeEnum.PYTHON}>Python</Select.Option>
<Select.Option value={DevelopmentLanguageTypeEnum.GO}>Go</Select.Option>
</Select>
</Form.Item>
<Form.Item
name="enabled"
label="应用状态" label="应用状态"
rules={[{ required: true, message: '请选择应用状态' }]} rules={[{ required: true, message: '请选择应用状态' }]}
> >
<Radio.Group> <Radio.Group>
<Radio value="ENABLE"></Radio> <Radio value={true}></Radio>
<Radio value="DISABLE"></Radio> <Radio value={false}></Radio>
</Radio.Group> </Radio.Group>
</Form.Item> </Form.Item>

View File

@ -1,11 +1,25 @@
import React, {useState, useEffect} from 'react'; import React, {useState, useEffect} from 'react';
import {PageContainer} from '@ant-design/pro-layout'; import {PageContainer} from '@ant-design/pro-layout';
import {Button, message, Popconfirm, Tag, Space, Tooltip, Select} from 'antd'; import {Button, message, Popconfirm, Tag, Space, Tooltip, Select} from 'antd';
import {PlusOutlined, EditOutlined, DeleteOutlined, CodeOutlined, CloudUploadOutlined, ApiOutlined} from '@ant-design/icons'; import {
PlusOutlined,
EditOutlined,
DeleteOutlined,
CodeOutlined,
CloudUploadOutlined,
ApiOutlined,
GithubOutlined,
JavaOutlined,
NodeIndexOutlined,
PythonOutlined,
} from '@ant-design/icons';
import {getApplicationPage, deleteApplication} from './service'; import {getApplicationPage, deleteApplication} from './service';
import {getProjectGroupList} from '../../ProjectGroup/List/service'; import {getProjectGroupList} from '../../ProjectGroup/List/service';
import type {Application, ApplicationQuery} from './types'; import type {Application, ApplicationQuery} from './types';
import {DevelopmentLanguageTypeEnum} from './types';
import type {ProjectGroup} from '../../ProjectGroup/List/types'; import type {ProjectGroup} from '../../ProjectGroup/List/types';
import {ProjectGroupTypeEnum} from '../../ProjectGroup/List/types';
import {getProjectTypeInfo} from '../../ProjectGroup/List/utils';
import ApplicationModal from './components/ApplicationModal'; import ApplicationModal from './components/ApplicationModal';
import {ProTable} from '@ant-design/pro-components'; import {ProTable} from '@ant-design/pro-components';
import type {ProColumns, ActionType} from '@ant-design/pro-components'; import type {ProColumns, ActionType} from '@ant-design/pro-components';
@ -65,11 +79,40 @@ const ApplicationList: React.FC = () => {
actionRef.current?.reload(); actionRef.current?.reload();
}; };
// 根据应用编码推测应用类型 // 获取开发语言信息
const getAppType = (appCode: string) => { const getLanguageInfo = (language: DevelopmentLanguageTypeEnum) => {
if (appCode.toLowerCase().includes('web')) return {icon: <CodeOutlined/>, name: '前端应用', color: '#1890ff'}; switch (language) {
if (appCode.toLowerCase().includes('api')) return {icon: <ApiOutlined/>, name: 'API服务', color: '#52c41a'}; case DevelopmentLanguageTypeEnum.JAVA:
return {icon: <CloudUploadOutlined/>, name: '后端服务', color: '#722ed1'}; return {
label: 'Java',
icon: <JavaOutlined/>,
color: '#E76F00'
};
case DevelopmentLanguageTypeEnum.NODE_JS:
return {
label: 'NodeJS',
icon: <NodeIndexOutlined/>,
color: '#339933'
};
case DevelopmentLanguageTypeEnum.PYTHON:
return {
label: 'Python',
icon: <PythonOutlined/>,
color: '#3776AB'
};
case DevelopmentLanguageTypeEnum.GO:
return {
label: 'Go',
icon: <CodeOutlined/>,
color: '#00ADD8'
};
default:
return {
label: language || '未知',
icon: <CodeOutlined/>,
color: '#666666'
};
}
}; };
const columns: ProColumns<Application>[] = [ const columns: ProColumns<Application>[] = [
@ -80,17 +123,6 @@ const ApplicationList: React.FC = () => {
copyable: true, copyable: true,
ellipsis: true, ellipsis: true,
fixed: 'left', fixed: 'left',
render: (text, record) => {
const appType = getAppType(record.appCode);
return (
<Space>
<Tooltip title={appType.name}>
{appType.icon}
</Tooltip>
{text}
</Space>
);
},
}, },
{ {
title: '应用名称', title: '应用名称',
@ -98,6 +130,22 @@ const ApplicationList: React.FC = () => {
width: 150, width: 150,
ellipsis: true, ellipsis: true,
}, },
{
title: '项目组',
dataIndex: ['projectGroup', 'projectGroupName'],
width: 150,
ellipsis: true,
render: (_, record) => (
<Space>
{record.projectGroup?.projectGroupName}
{record.projectGroup?.type && (
<Tag color={getProjectTypeInfo(record.projectGroup.type).color}>
{getProjectTypeInfo(record.projectGroup.type).label}
</Tag>
)}
</Space>
),
},
{ {
title: '应用描述', title: '应用描述',
dataIndex: 'appDesc', dataIndex: 'appDesc',
@ -105,12 +153,50 @@ const ApplicationList: React.FC = () => {
width: 200, width: 200,
}, },
{ {
title: '应用状态', title: '仓库地址',
dataIndex: 'appStatus', dataIndex: 'repoUrl',
width: 200,
ellipsis: true,
render: (_, record) => record.repoUrl ? (
<Space>
<GithubOutlined/>
<a href={record.repoUrl} target="_blank" rel="noopener noreferrer">
{record.repoUrl}
</a>
</Space>
) : '-',
},
{
title: '开发语言',
dataIndex: 'language',
width: 120,
render: (language) => {
const langInfo = getLanguageInfo(language as DevelopmentLanguageTypeEnum);
return (
<Tag color={langInfo.color}>
<Space>
{langInfo.icon}
{langInfo.label}
</Space>
</Tag>
);
},
filters: [
{text: 'Java', value: DevelopmentLanguageTypeEnum.JAVA},
{text: 'NodeJS', value: DevelopmentLanguageTypeEnum.NODE_JS},
{text: 'Python', value: DevelopmentLanguageTypeEnum.PYTHON},
{text: 'Go', value: DevelopmentLanguageTypeEnum.GO},
],
filterMode: 'menu',
filtered: false,
},
{
title: '状态',
dataIndex: 'enabled',
width: 100, width: 100,
valueEnum: { valueEnum: {
'ENABLE': {text: '启用', status: 'Success'}, true: {text: '启用', status: 'Success'},
'DISABLE': {text: '禁用', status: 'Default'}, false: {text: '禁用', status: 'Default'},
}, },
}, },
{ {
@ -121,7 +207,7 @@ const ApplicationList: React.FC = () => {
}, },
{ {
title: '操作', title: '操作',
width: 200, width: 150,
key: 'action', key: 'action',
valueType: 'option', valueType: 'option',
fixed: 'right', fixed: 'right',
@ -149,19 +235,37 @@ const ApplicationList: React.FC = () => {
</Button> </Button>
</Popconfirm>, </Popconfirm>,
<Button
key="deploy"
type="link"
icon={<CloudUploadOutlined/>}
>
</Button>
], ],
}, },
]; ];
return ( return (
<> <PageContainer
header={{
title: '应用管理',
subTitle: (
<Space>
<span></span>
<Select
value={selectedProjectGroupId}
onChange={handleProjectChange}
style={{width: 200}}
options={projectGroups.map(project => ({
label: (
<Space>
{project.projectGroupName}
<Tag color={getProjectTypeInfo(project.type).color}>
{getProjectTypeInfo(project.type).label}
</Tag>
</Space>
),
value: project.id,
}))}
/>
</Space>
),
}}
>
<ProTable<Application> <ProTable<Application>
columns={columns} columns={columns}
actionRef={actionRef} actionRef={actionRef}
@ -178,10 +282,9 @@ const ApplicationList: React.FC = () => {
const queryParams: ApplicationQuery = { const queryParams: ApplicationQuery = {
pageSize: params.pageSize, pageSize: params.pageSize,
pageNum: params.current, pageNum: params.current,
projectGroupId: selectedProjectGroupId,
appCode: params.appCode as string, appCode: params.appCode as string,
appName: params.appName as string, appName: params.appName as string,
appStatus: params.appStatus as string, enabled: params.enabled as boolean,
}; };
const data = await getApplicationPage(queryParams); const data = await getApplicationPage(queryParams);
return { return {
@ -240,7 +343,7 @@ const ApplicationList: React.FC = () => {
projectGroupId={selectedProjectGroupId} projectGroupId={selectedProjectGroupId}
/> />
)} )}
</> </PageContainer>
); );
}; };

View File

@ -1,31 +1,43 @@
import type { BaseQuery } from '@/types/base'; import type {BaseQuery} from '@/types/base';
import {ProjectGroup} from "@/pages/Deploy/ProjectGroup/List/types";
export enum DevelopmentLanguageTypeEnum {
JAVA = 'JAVA',
NODE_JS = 'NODE_JS',
PYTHON = 'PYTHON',
GO = 'GO'
}
export interface Application { export interface Application {
id: number; id: number;
projectGroupId: number; appCode: string;
appCode: string; appName: string;
appName: string; appDesc?: string;
appDesc?: string; repoUrl: string;
appStatus: 'ENABLE' | 'DISABLE'; language: DevelopmentLanguageTypeEnum;
sort: number; enabled: boolean;
sort: number;
projectGroup: ProjectGroup;
} }
export interface CreateApplicationRequest { export interface CreateApplicationRequest {
projectGroupId: number; projectGroupId: number;
appCode: string; appCode: string;
appName: string; appName: string;
appDesc?: string; appDesc?: string;
appStatus: string; repoUrl: string;
sort: number; language: DevelopmentLanguageTypeEnum;
enabled: boolean;
sort: number;
} }
export interface UpdateApplicationRequest extends CreateApplicationRequest { export interface UpdateApplicationRequest extends CreateApplicationRequest {
id: number; id: number;
} }
export interface ApplicationQuery extends BaseQuery { export interface ApplicationQuery extends BaseQuery {
projectGroupId?: number; projectGroupId?: number;
appCode?: string; appCode?: string;
appName?: string; appName?: string;
appStatus?: string; enabled?: boolean;
} }

View File

@ -1,11 +1,8 @@
import React, {useEffect, useState} from 'react'; import React, {useEffect} from 'react';
import {Modal, Form, Input, InputNumber, Radio, message, Select} from 'antd'; import {Modal, Form, Input, InputNumber, Radio, message} from 'antd';
import type {ProjectGroup} from '../types'; import type {ProjectGroup} from '../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 {ProjectGroupTypeEnum} from '../types';
import {BuildTypeEnum} from "../../../Environment/List/types";
import {ProjectGroupTypeEnum} from "../types";
interface ProjectGroupModalProps { interface ProjectGroupModalProps {
visible: boolean; visible: boolean;
@ -14,57 +11,44 @@ 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,
onSuccess, onSuccess,
initialValues, initialValues,
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [environments, setEnvironments] = useState<Environment[]>([]);
const isEdit = !!initialValues; const isEdit = !!initialValues;
// 获取环境列表
useEffect(() => { useEffect(() => {
const fetchEnvironments = async () => { if (visible) {
try { if (initialValues) {
const data = await getEnvironmentList(); // 将布尔值转换为字符串
setEnvironments(data); form.setFieldsValue({
} catch (error) { ...initialValues,
message.error('获取环境列表失败'); enabled: initialValues.enabled?.toString()
});
} else {
form.setFieldsValue({
type: ProjectGroupTypeEnum.PROJECT,
enabled: 'true',
sort: 0
});
} }
};
fetchEnvironments();
}, []);
useEffect(() => {
if (visible && initialValues) {
// 设置初始值包括环境ID列表
const envIds = initialValues.environments?.map(env => env.id) || [];
form.setFieldsValue({
...initialValues,
environments: envIds
});
} }
}, [visible, initialValues, form]); }, [visible, initialValues, form]);
const handleSubmit = async () => { const handleSubmit = async () => {
try { try {
const values = await form.validateFields(); const values = await form.validateFields();
// 转换环境ID数组为对象数组 // 将字符串转换回布尔值
const environments = (values.environments || []).map((id: number) => ({id}));
const submitData = { const submitData = {
...values, ...values,
environments enabled: values.enabled === 'true'
}; };
if (isEdit) { if (isEdit) {
await updateProjectGroup({...submitData, id: initialValues.id}); await updateProjectGroup({...submitData, id: initialValues?.id});
message.success('更新成功'); message.success('更新成功');
} else { } else {
await createProjectGroup(submitData); await createProjectGroup(submitData);
@ -90,24 +74,16 @@ const ProjectGroupModal: React.FC<ProjectGroupModalProps> = ({
onOk={handleSubmit} onOk={handleSubmit}
onCancel={handleCancel} onCancel={handleCancel}
destroyOnClose destroyOnClose
width={560}
> >
<Form <Form
form={form} form={form}
layout="vertical" layout="vertical"
initialValues={{projectGroupStatus: 'ENABLE', sort: 0}} initialValues={{
type: ProjectGroupTypeEnum.PROJECT,
enabled: 'true',
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="项目组编码"
@ -133,32 +109,29 @@ const ProjectGroupModal: React.FC<ProjectGroupModalProps> = ({
> >
<Input.TextArea rows={4} placeholder="请输入项目组描述"/> <Input.TextArea rows={4} placeholder="请输入项目组描述"/>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name="environments" name="type"
label="关联环境" label="项目组类型"
rules={[{required: true, message: '请选择关联环境'}]} rules={[{required: true, message: '请选择项目组类型'}]}
>
<Select
mode="multiple"
placeholder="请选择关联环境"
optionFilterProp="label"
options={environments.map(env => ({
label: env.envName,
value: env.id,
}))}
/>
</Form.Item>
<Form.Item
name="projectGroupStatus"
label="项目组状态"
rules={[{required: true, message: '请选择项目组状态'}]}
initialValue="ENABLE"
> >
<Radio.Group> <Radio.Group>
<Radio value="ENABLE"></Radio> <Radio value={ProjectGroupTypeEnum.PRODUCT}></Radio>
<Radio value="DISABLE"></Radio> <Radio value={ProjectGroupTypeEnum.PROJECT}></Radio>
</Radio.Group> </Radio.Group>
</Form.Item> </Form.Item>
<Form.Item
name="enabled"
label="项目组状态"
rules={[{required: true, message: '请选择项目组状态'}]}
>
<Radio.Group>
<Radio value="true"></Radio>
<Radio value="false"></Radio>
</Radio.Group>
</Form.Item>
<Form.Item <Form.Item
name="sort" name="sort"
label="排序" label="排序"

View File

@ -7,14 +7,14 @@ import {
DeleteOutlined, DeleteOutlined,
TeamOutlined, TeamOutlined,
EnvironmentOutlined, EnvironmentOutlined,
RocketOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import {getProjectGroupPage, deleteProjectGroup} from './service'; import {getProjectGroupPage, deleteProjectGroup} from './service';
import type {ProjectGroup, ProjectGroupQueryParams} from './types'; import type {ProjectGroup, ProjectGroupQueryParams} from './types';
import {ProjectGroupTypeEnum} from './types';
import {getProjectTypeInfo} from './utils';
import ProjectGroupModal from './components/ProjectGroupModal'; import ProjectGroupModal from './components/ProjectGroupModal';
import { ProjectGroupTypeEnum } from './types'; import {ProTable} from '@ant-design/pro-components';
import { ProTable } from '@ant-design/pro-components'; import type {ProColumns, ActionType} from '@ant-design/pro-components';
import type { ProColumns, ActionType } from '@ant-design/pro-components';
const ProjectGroupList: React.FC = () => { const ProjectGroupList: React.FC = () => {
const [modalVisible, setModalVisible] = useState(false); const [modalVisible, setModalVisible] = useState(false);
@ -41,35 +41,6 @@ const ProjectGroupList: React.FC = () => {
setModalVisible(true); setModalVisible(true);
}; };
const getProjectTypeInfo = (type: ProjectGroupTypeEnum) => {
switch (type) {
case ProjectGroupTypeEnum.PRODUCT:
return {
type: ProjectGroupTypeEnum.PRODUCT,
label: '产品型',
color: '#1890ff',
icon: <RocketOutlined/>,
description: '产品型相关的项目组'
};
case ProjectGroupTypeEnum.PROJECT:
return {
type: ProjectGroupTypeEnum.PROJECT,
label: '项目型',
color: '#52c41a',
icon: <EnvironmentOutlined/>,
description: '项目型相关的项目组'
};
default:
return {
type: ProjectGroupTypeEnum.PROJECT,
label: '项目型',
color: '#722ed1',
icon: <TeamOutlined/>,
description: '项目型相关的项目组'
};
}
};
const columns: ProColumns<ProjectGroup>[] = [ const columns: ProColumns<ProjectGroup>[] = [
{ {
title: '项目组编码', title: '项目组编码',
@ -93,18 +64,32 @@ const ProjectGroupList: React.FC = () => {
{ {
title: '项目组类型', title: '项目组类型',
dataIndex: 'type', dataIndex: 'type',
width: 100, width: 150,
render: (type) => { render: (type) => {
const typeInfo = getProjectTypeInfo(type as ProjectGroupTypeEnum); const typeInfo = getProjectTypeInfo(type as ProjectGroupTypeEnum);
return ( return (
<Tag color={typeInfo.color}> <Tag color={typeInfo.color}>
{typeInfo.label} <Space>
{typeInfo.icon}
{typeInfo.label}
</Space>
</Tag> </Tag>
); );
}, },
filters: [
{text: '产品型', value: ProjectGroupTypeEnum.PRODUCT},
{text: '项目型', value: ProjectGroupTypeEnum.PROJECT},
],
filterMode: 'menu',
filtered: false,
},
{
title: '状态',
dataIndex: 'enabled',
width: 100,
valueEnum: { valueEnum: {
[ProjectGroupTypeEnum.PRODUCT]: { text: '产品型' }, true: {text: '启用', status: 'Success'},
[ProjectGroupTypeEnum.PROJECT]: { text: '项目型' }, false: {text: '禁用', status: 'Default'},
}, },
}, },
{ {
@ -114,7 +99,7 @@ const ProjectGroupList: React.FC = () => {
render: (_, record) => ( render: (_, record) => (
<Tooltip title="环境数量"> <Tooltip title="环境数量">
<Space> <Space>
<EnvironmentOutlined /> <EnvironmentOutlined/>
{record.environments?.length || 0} {record.environments?.length || 0}
</Space> </Space>
</Tooltip> </Tooltip>
@ -127,7 +112,7 @@ const ProjectGroupList: React.FC = () => {
render: (_, record) => ( render: (_, record) => (
<Tooltip title="项目数量"> <Tooltip title="项目数量">
<Space> <Space>
<TeamOutlined /> <TeamOutlined/>
{record.applications?.length || 0} {record.applications?.length || 0}
</Space> </Space>
</Tooltip> </Tooltip>
@ -145,6 +130,7 @@ const ProjectGroupList: React.FC = () => {
key: 'action', key: 'action',
valueType: 'option', valueType: 'option',
fixed: 'right', fixed: 'right',
align: 'center',
render: (_, record) => ( render: (_, record) => (
<Space> <Space>
<Button <Button
@ -184,7 +170,7 @@ const ProjectGroupList: React.FC = () => {
pageNum: params.current, pageNum: params.current,
projectGroupName: params.projectGroupName as string, projectGroupName: params.projectGroupName as string,
projectGroupCode: params.projectGroupCode as string, projectGroupCode: params.projectGroupCode as string,
projectGroupStatus: params.projectGroupStatus as string, enabled: params.enabled as boolean,
}; };
const data = await getProjectGroupPage(queryParams); const data = await getProjectGroupPage(queryParams);
return { return {

View File

@ -2,13 +2,11 @@ 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"; import {Application} from "@/pages/Deploy/Application/List/types";
export enum ProjectGroupTypeEnum { export enum ProjectGroupTypeEnum {
PRODUCT = 'PRODUCT', PRODUCT = 'PRODUCT',
PROJECT = 'PROJECT' PROJECT = 'PROJECT'
} }
// 项目基础信息 // 项目基础信息
export interface ProjectGroup extends BaseResponse { export interface ProjectGroup extends BaseResponse {
tenantCode: string; tenantCode: string;
@ -16,7 +14,7 @@ export interface ProjectGroup extends BaseResponse {
projectGroupCode: string; projectGroupCode: string;
projectGroupName: string; projectGroupName: string;
projectGroupDesc?: string; projectGroupDesc?: string;
projectGroupStatus: 'ENABLE' | 'DISABLE'; enabled: boolean;
environments: Environment[]; environments: Environment[];
applications: Application[]; applications: Application[];
sort: number; sort: number;
@ -29,7 +27,7 @@ export interface CreateProjectGroupRequest extends BaseRequest {
projectGroupCode: string; projectGroupCode: string;
projectGroupName: string; projectGroupName: string;
projectGroupDesc?: string; projectGroupDesc?: string;
projectGroupStatus: string; enabled: boolean;
sort: number; sort: number;
} }
@ -42,5 +40,5 @@ export interface UpdateProjectGroupRequest extends CreateProjectGroupRequest {
export interface ProjectGroupQueryParams extends BaseQuery { export interface ProjectGroupQueryParams extends BaseQuery {
projectGroupName?: string; projectGroupName?: string;
projectGroupCode?: string; projectGroupCode?: string;
projectGroupStatus?: string; enabled?: boolean;
} }

View File

@ -0,0 +1,37 @@
import React from 'react';
import {ProjectOutlined, RocketOutlined} from '@ant-design/icons';
import {ProjectGroupTypeEnum} from './types';
interface ProjectTypeInfo {
type: ProjectGroupTypeEnum;
label: string;
color: string;
icon: React.ReactNode;
}
// 获取项目组类型信息
export const getProjectTypeInfo = (type: ProjectGroupTypeEnum): ProjectTypeInfo => {
switch (type) {
case ProjectGroupTypeEnum.PRODUCT:
return {
type: ProjectGroupTypeEnum.PRODUCT,
label: '产品型',
color: '#1890ff',
icon: <RocketOutlined/>,
};
case ProjectGroupTypeEnum.PROJECT:
return {
type: ProjectGroupTypeEnum.PROJECT,
label: '项目型',
color: '#52c41a',
icon: <ProjectOutlined/>,
};
default:
return {
type: type,
label: type || '未知',
color: '#666666',
icon: <ProjectOutlined/>,
};
}
};