diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 81e8777f..3e2543ef 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,15 +1,13 @@ import React from 'react'; import { RouterProvider } from 'react-router-dom'; -import { ConfigProvider, App as AntdApp } from 'antd'; +import { ConfigProvider } from 'antd'; import zhCN from 'antd/locale/zh_CN'; import router from './router'; const App: React.FC = () => { return ( - - - + ); }; diff --git a/frontend/src/pages/Deploy/Application/List/components/ApplicationModal.tsx b/frontend/src/pages/Deploy/Application/List/components/ApplicationModal.tsx index 24a6babf..7378d248 100644 --- a/frontend/src/pages/Deploy/Application/List/components/ApplicationModal.tsx +++ b/frontend/src/pages/Deploy/Application/List/components/ApplicationModal.tsx @@ -1,5 +1,5 @@ import React, {useState} from 'react'; -import {Modal, Form, Input, Select, Switch, InputNumber, App} from 'antd'; +import {Modal, Form, Input, Select, Switch, InputNumber, message} from 'antd'; import type {Application} from '../types'; import {DevelopmentLanguageTypeEnum} from '../types'; import {createApplication, updateApplication} from '../service'; @@ -21,7 +21,6 @@ const ApplicationModal: React.FC = ({ }) => { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); - const {message: messageApi} = App.useApp(); const isEdit = !!initialValues?.id; const handleSubmit = async () => { @@ -39,14 +38,14 @@ const ApplicationModal: React.FC = ({ projectGroupId, }); } - messageApi.success(`${isEdit ? '更新' : '创建'}成功`); + message.success(`${isEdit ? '更新' : '创建'}成功`); form.resetFields(); onSuccess(); } catch (error) { if (error instanceof Error) { - messageApi.error(`${isEdit ? '更新' : '创建'}失败: ${error.message}`); + message.error(`${isEdit ? '更新' : '创建'}失败: ${error.message}`); } else { - messageApi.error(`${isEdit ? '更新' : '创建'}失败`); + message.error(`${isEdit ? '更新' : '创建'}失败`); } } finally { setLoading(false); diff --git a/frontend/src/pages/Deploy/Deployment/List/components/DeploymentConfigModal.tsx b/frontend/src/pages/Deploy/Deployment/List/components/DeploymentConfigModal.tsx index 3ce204ae..9f74e4de 100644 --- a/frontend/src/pages/Deploy/Deployment/List/components/DeploymentConfigModal.tsx +++ b/frontend/src/pages/Deploy/Deployment/List/components/DeploymentConfigModal.tsx @@ -1,5 +1,5 @@ import React, {useEffect, useState, useCallback} from 'react'; -import {Modal, Form, Select, message, Switch, InputNumber, App} from 'antd'; +import {Modal, Form, Select, message, Switch, InputNumber, Input} from 'antd'; import type {DeploymentConfig, DeployConfigTemplate} from '../types'; import {createDeploymentConfig, updateDeploymentConfig, getDeployConfigTemplates} from '../service'; import {getApplicationList} from '../../../Application/List/service'; @@ -31,9 +31,8 @@ const DeploymentConfigModal: React.FC = ({ const [applications, setApplications] = useState([]); const [templates, setTemplates] = useState([]); const [selectedTemplate, setSelectedTemplate] = useState(); - const [buildVariables, setBuildVariables] = useState>({}); + const [buildVariables, setBuildVariables] = useState({}); const [loading, setLoading] = useState(false); - const {message: messageApi} = App.useApp(); const isEdit = !!initialValues?.id; // 获取应用列表 @@ -42,9 +41,9 @@ const DeploymentConfigModal: React.FC = ({ const data = await getApplicationList(); setApplications(data); } catch (error) { - messageApi.error('获取应用列表失败'); + message.error('获取应用列表失败'); } - }, [messageApi]); + }, []); // 获取配置模板 const fetchTemplates = useCallback(async () => { @@ -52,9 +51,9 @@ const DeploymentConfigModal: React.FC = ({ const data = await getDeployConfigTemplates(); setTemplates(data); } catch (error) { - messageApi.error('获取配置模板失败'); + message.error('获取配置模板失败'); } - }, [messageApi]); + }, []); // 在模态框显示时获取数据 useEffect(() => { @@ -69,8 +68,13 @@ const DeploymentConfigModal: React.FC = ({ if (!open) return; if (initialValues) { - form.setFieldsValue(initialValues); - const template = templates.find(t => t.code === initialValues.templateCode); + // 设置基础字段 + form.setFieldsValue({ + applicationId: initialValues.applicationId, + enabled: initialValues.enabled + }); + + const template = templates.find(t => t.buildType === initialValues.buildType && t.languageType === initialValues.languageType); if (template) { setSelectedTemplate(template); setBuildVariables(initialValues.buildVariables || {}); @@ -78,34 +82,49 @@ const DeploymentConfigModal: React.FC = ({ } else { form.resetFields(); form.setFieldsValue({ - envId, - enabled: true, - sort: 0, + enabled: true }); setSelectedTemplate(undefined); setBuildVariables({}); } - }, [open, initialValues, envId, form, templates]); + }, [open, initialValues, form, templates]); - const handleAppChange = useCallback((appId: number) => { - const app = applications.find(a => a.id === appId); + const handleAppChange = useCallback((applicationId: number) => { + const app = applications.find(a => a.id === applicationId); if (app) { const template = templates.find(t => t.languageType === app.language); if (template) { setSelectedTemplate(template); setBuildVariables({}); - form.setFieldValue('templateCode', template.code); } } - }, [applications, templates, form]); + }, [applications, templates]); const handleSubmit = async () => { try { setLoading(true); const values = await form.validateFields(); + + // 获取选中的应用信息 + const selectedApp = applications.find(app => app.id === values.applicationId); + if (!selectedApp) { + throw new Error('请选择应用'); + } + + // 获取对应的模板 + const template = templates.find(t => t.languageType === selectedApp.language); + if (!template) { + throw new Error('未找到匹配的配置模板'); + } + + // 构建提交数据 const submitData = { - ...values, - buildVariables, + environmentId: envId, + applicationId: values.applicationId, + buildType: template.buildType, + languageType: selectedApp.language, + buildVariables, // 动态表单的值都在这里 + enabled: values.enabled }; if (isEdit) { @@ -116,14 +135,14 @@ const DeploymentConfigModal: React.FC = ({ } else { await createDeploymentConfig(submitData); } - messageApi.success(`${isEdit ? '更新' : '创建'}成功`); + message.success(`${isEdit ? '更新' : '创建'}成功`); form.resetFields(); onSuccess(); } catch (error) { if (error instanceof Error) { - messageApi.error(`${isEdit ? '更新' : '创建'}失败: ${error.message}`); + message.error(`${isEdit ? '更新' : '创建'}失败: ${error.message}`); } else { - messageApi.error(`${isEdit ? '更新' : '创建'}失败`); + message.error(`${isEdit ? '更新' : '创建'}失败`); } } finally { setLoading(false); @@ -152,9 +171,9 @@ const DeploymentConfigModal: React.FC = ({ defaultLanguage={property.editorConfig.language || 'shell'} theme={property.editorConfig.theme || 'vs-dark'} value={buildVariables[key] || property.default || ''} - onChange={(value: string) => setBuildVariables(prev => ({ + onChange={(value) => setBuildVariables(prev => ({ ...prev, - [key]: value || '' + [key]: value }))} options={{ minimap: { enabled: property.editorConfig.minimap ?? false }, @@ -187,25 +206,24 @@ const DeploymentConfigModal: React.FC = ({ } /> - ) : null + ) : ( + + ) => setBuildVariables(prev => ({ + ...prev, + [key]: e.target.value + }))} + placeholder={`请输入${property.title || key}`} + /> + + ) ))} - - {/* 其他配置项 */} - !prop.editorConfig) - ), - required: selectedTemplate.buildVariablesSchema.required || [] - })} - initialValues={buildVariables} - onValuesChange={(_, values) => setBuildVariables(prev => ({ - ...prev, - ...values - }))} - /> ); }; @@ -235,7 +253,7 @@ const DeploymentConfigModal: React.FC = ({ > {/* 应用选择 */} = ({ > - - - - ); diff --git a/frontend/src/pages/Deploy/Deployment/List/index.tsx b/frontend/src/pages/Deploy/Deployment/List/index.tsx index 415a088a..0d4bfd29 100644 --- a/frontend/src/pages/Deploy/Deployment/List/index.tsx +++ b/frontend/src/pages/Deploy/Deployment/List/index.tsx @@ -1,6 +1,6 @@ import React, {useState, useEffect} from 'react'; import {PageContainer} from '@ant-design/pro-layout'; -import {Button, message, Popconfirm, Select, Space, App} from 'antd'; +import {Button, message, Popconfirm, Select, Space} from 'antd'; import {PlusOutlined, EditOutlined, DeleteOutlined} from '@ant-design/icons'; import {getDeploymentConfigPage, deleteDeploymentConfig} from './service'; import {getEnvironmentList} from '../../Environment/List/service'; @@ -18,7 +18,6 @@ const DeploymentConfigList: React.FC = () => { const [modalVisible, setModalVisible] = useState(false); const [currentConfig, setCurrentConfig] = useState(); const actionRef = React.useRef(); - const {message: messageApi} = App.useApp(); // 获取环境列表 const fetchEnvironments = async () => { @@ -29,7 +28,7 @@ const DeploymentConfigList: React.FC = () => { setSelectedEnvId(data[0].id); } } catch (error) { - messageApi.error('获取环境列表失败'); + message.error('获取环境列表失败'); } }; @@ -40,16 +39,16 @@ const DeploymentConfigList: React.FC = () => { const handleDelete = async (id: number) => { try { await deleteDeploymentConfig(id); - messageApi.success('删除成功'); + message.success('删除成功'); actionRef.current?.reload(); } catch (error) { - messageApi.error('删除失败'); + message.error('删除失败'); } }; const handleAdd = () => { if (!selectedEnvId) { - messageApi.warning('请先选择环境'); + message.warning('请先选择环境'); return; } setCurrentConfig(undefined); @@ -228,7 +227,7 @@ const DeploymentConfigList: React.FC = () => { total: data.totalElements || 0, }; } catch (error) { - messageApi.error('获取部署配置列表失败'); + message.error('获取部署配置列表失败'); return { data: [], success: false, diff --git a/frontend/src/pages/Deploy/Deployment/List/service.ts b/frontend/src/pages/Deploy/Deployment/List/service.ts index 64e130ae..79dffcbf 100644 --- a/frontend/src/pages/Deploy/Deployment/List/service.ts +++ b/frontend/src/pages/Deploy/Deployment/List/service.ts @@ -2,8 +2,7 @@ import request from '@/utils/request'; import type {DeploymentConfig, CreateDeploymentConfigRequest, UpdateDeploymentConfigRequest, DeploymentConfigQueryParams, DeployConfigTemplate} from './types'; import type {Page} from '@/types/base'; -const BASE_URL = '/api/v1/deployment-configs'; -const TEMPLATE_URL = '/api/v1/deploy-app-config'; +const BASE_URL = '/api/v1/deploy-app-config'; // 获取部署配置分页列表 export const getDeploymentConfigPage = (params: DeploymentConfigQueryParams) => @@ -26,9 +25,9 @@ export const getDeploymentConfig = (id: number) => request.get(`${BASE_URL}/${id}`); // 获取环境下的所有部署配置 -export const getDeploymentConfigsByEnv = (envId: number) => - request.get(`${BASE_URL}/env/${envId}`); +export const getDeploymentConfigsByEnv = (environmentId: number) => + request.get(`${BASE_URL}/env/${environmentId}`); // 获取部署配置模板列表 export const getDeployConfigTemplates = () => - request.get(`${TEMPLATE_URL}/defined`); \ No newline at end of file + request.get(`${BASE_URL}/defined`); \ No newline at end of file diff --git a/frontend/src/pages/Deploy/Deployment/List/types.ts b/frontend/src/pages/Deploy/Deployment/List/types.ts index a1602d8a..60a9e85e 100644 --- a/frontend/src/pages/Deploy/Deployment/List/types.ts +++ b/frontend/src/pages/Deploy/Deployment/List/types.ts @@ -16,26 +16,24 @@ export interface DeployConfigTemplate { // 部署配置基础信息 export interface DeploymentConfig extends BaseResponse { - tenantCode: string; - envId: number; + environmentId: number; environment: Environment; - appId: number; + applicationId: number; application: Application; - templateCode: string; - buildVariables: Record; + buildType: BuildTypeEnum; + languageType: DevelopmentLanguageTypeEnum; + buildVariables: JsonNode; enabled: boolean; - sort: number; } // 创建部署配置请求参数 export interface CreateDeploymentConfigRequest extends BaseRequest { - tenantCode: string; - envId: number; - appId: number; - templateCode: string; - buildVariables: Record; + environmentId: number; + applicationId: number; + buildType: BuildTypeEnum; + languageType: DevelopmentLanguageTypeEnum; + buildVariables: JsonNode; enabled: boolean; - sort: number; } // 更新部署配置请求参数 @@ -45,7 +43,7 @@ export interface UpdateDeploymentConfigRequest extends CreateDeploymentConfigReq // 分页查询参数 export interface DeploymentConfigQueryParams extends BaseQuery { - envId?: number; - appId?: number; + environmentId?: number; + applicationId?: number; enabled?: boolean; } \ No newline at end of file diff --git a/frontend/src/pages/Deploy/Environment/List/components/EnvironmentModal.tsx b/frontend/src/pages/Deploy/Environment/List/components/EnvironmentModal.tsx index 68cbb275..fa33f69a 100644 --- a/frontend/src/pages/Deploy/Environment/List/components/EnvironmentModal.tsx +++ b/frontend/src/pages/Deploy/Environment/List/components/EnvironmentModal.tsx @@ -1,5 +1,5 @@ import React, {useState} from 'react'; -import {Modal, Form, Input, Select, Switch, InputNumber, App} from 'antd'; +import {Modal, Form, Input, Select, Switch, InputNumber, message} from 'antd'; import type {Environment} from '../types'; import {BuildTypeEnum, DeployTypeEnum} from '../types'; import {createEnvironment, updateEnvironment} from '../service'; @@ -19,7 +19,6 @@ const EnvironmentModal: React.FC = ({ }) => { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); - const {message: messageApi} = App.useApp(); const isEdit = !!initialValues?.id; const handleSubmit = async () => { @@ -34,14 +33,14 @@ const EnvironmentModal: React.FC = ({ } else { await createEnvironment(values); } - messageApi.success(`${isEdit ? '更新' : '创建'}成功`); + message.success(`${isEdit ? '更新' : '创建'}成功`); form.resetFields(); onSuccess(); } catch (error) { if (error instanceof Error) { - messageApi.error(`${isEdit ? '更新' : '创建'}失败: ${error.message}`); + message.error(`${isEdit ? '更新' : '创建'}失败: ${error.message}`); } else { - messageApi.error(`${isEdit ? '更新' : '创建'}失败`); + message.error(`${isEdit ? '更新' : '创建'}失败`); } } finally { setLoading(false); @@ -111,8 +110,9 @@ const EnvironmentModal: React.FC = ({ placeholder="请选择构建类型" disabled={isEdit} > - 本地构建 - 远程构建 + Jenkins + GitLab Runner + GitHub Action @@ -126,8 +126,9 @@ const EnvironmentModal: React.FC = ({ placeholder="请选择部署类型" disabled={isEdit} > - Kubernetes + Kubernetes Docker + 虚拟机 diff --git a/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx b/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx index bc42b7f0..78dbf518 100644 --- a/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx +++ b/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx @@ -1,5 +1,5 @@ import React, {useState} from 'react'; -import {Modal, Form, Input, Select, Switch, InputNumber, App} from 'antd'; +import {Modal, Form, Input, Select, Switch, InputNumber, message} from 'antd'; import type {ProjectGroup} from '../types'; import {ProjectGroupTypeEnum} from '../types'; import {createProjectGroup, updateProjectGroup} from '../service'; @@ -19,7 +19,6 @@ const ProjectGroupModal: React.FC = ({ }) => { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); - const {message: messageApi} = App.useApp(); const isEdit = !!initialValues?.id; const handleSubmit = async () => { @@ -34,14 +33,14 @@ const ProjectGroupModal: React.FC = ({ } else { await createProjectGroup(values); } - messageApi.success(`${isEdit ? '更新' : '创建'}成功`); + message.success(`${isEdit ? '更新' : '创建'}成功`); form.resetFields(); onSuccess(); } catch (error) { if (error instanceof Error) { - messageApi.error(`${isEdit ? '更新' : '创建'}失败: ${error.message}`); + message.error(`${isEdit ? '更新' : '创建'}失败: ${error.message}`); } else { - messageApi.error(`${isEdit ? '更新' : '创建'}失败`); + message.error(`${isEdit ? '更新' : '创建'}失败`); } } finally { setLoading(false);