diff --git a/frontend/src/pages/Deploy/External/index.tsx b/frontend/src/pages/Deploy/External/index.tsx index 9aacac42..2bdc8842 100644 --- a/frontend/src/pages/Deploy/External/index.tsx +++ b/frontend/src/pages/Deploy/External/index.tsx @@ -1,365 +1,344 @@ -import React, { useState } from 'react'; -import { Card, Table, Button, Space, Modal, Form, Input, message, Select, InputNumber, Switch, Tag, Tooltip } from 'antd'; -import { PlusOutlined, EditOutlined, DeleteOutlined, SyncOutlined, CheckCircleOutlined, CloseCircleOutlined, LinkOutlined, MinusCircleOutlined } from '@ant-design/icons'; -import type { ColumnsType } from 'antd/es/table'; -import { useTableData } from '@/hooks/useTableData'; +import React, {useState} from 'react'; +import {Card, Table, Button, Space, Modal, Form, Input, message, Select, InputNumber, Switch, Tag, Tooltip} from 'antd'; +import {PlusOutlined, EditOutlined, DeleteOutlined, SyncOutlined, CheckCircleOutlined, CloseCircleOutlined, LinkOutlined, MinusCircleOutlined} from '@ant-design/icons'; +import type {ColumnsType} from 'antd/es/table'; +import {useTableData} from '@/hooks/useTableData'; import * as service from './service'; -import { SystemType, AuthType, SyncStatus, ExternalSystemResponse, ExternalSystemRequest, ExternalSystemQuery } from './types'; +import {SystemType, AuthType, SyncStatus, ExternalSystemResponse, ExternalSystemRequest, ExternalSystemQuery} from './types'; const ExternalPage: React.FC = () => { - const [form] = Form.useForm(); - const [modalVisible, setModalVisible] = useState(false); - const [editingSystem, setEditingSystem] = useState(null); + const [form] = Form.useForm(); + const [modalVisible, setModalVisible] = useState(false); + const [editingSystem, setEditingSystem] = useState(null); - const { - list, - loading, - pagination, - handleTableChange, - handleCreate, - handleUpdate, - handleDelete, - refresh - } = useTableData({ - service: { - list: service.getExternalSystemsPage, - create: service.createExternalSystem, - update: service.updateExternalSystem, - delete: service.deleteExternalSystem - }, - config: { - message: { - createSuccess: '创建系统成功', - updateSuccess: '更新系统成功', - deleteSuccess: '删除系统成功' - } - } - }); - - const handleAdd = () => { - setEditingSystem(null); - form.resetFields(); - form.setFieldsValue({ - enabled: true, - sort: 1, - authType: AuthType.BASIC - }); - setModalVisible(true); - }; - - const handleEdit = (record: ExternalSystemResponse) => { - setEditingSystem(record); - form.setFieldsValue({ - ...record, - password: undefined // 不显示密码 - }); - setModalVisible(true); - }; - - const handleTestConnection = async (id: number) => { - try { - const success = await service.testConnection(id); - message.success(success ? '连接成功' : '连接失败'); - } catch (error) { - message.error('测试连接失败'); - } - }; - - const handleStatusChange = async (id: number, enabled: boolean) => { - try { - await service.updateStatus(id, enabled); - message.success('更新状态成功'); - refresh(); - } catch (error) { - message.error('更新状态失败'); - } - }; - - const handleSubmit = async () => { - try { - const values = await form.validateFields(); - let success = false; - - if (editingSystem) { - success = await handleUpdate(editingSystem.id, values); - } else { - success = await handleCreate(values); - } - - if (success) { - setModalVisible(false); - } - } catch (error: any) { - // 如果是表单验证错误,不显示错误消息 - if (!error.errorFields) { - // 如果是后端返回的错误,显示后端的错误消息 - if (error.response?.data) { - message.error(error.response.data.message || '操作失败'); - } else { - message.error(error.message || '操作失败'); + const { + list, + loading, + pagination, + handleTableChange, + handleCreate, + handleUpdate, + handleDelete, + refresh + } = useTableData({ + service: { + list: service.getExternalSystemsPage, + create: service.createExternalSystem, + update: service.updateExternalSystem, + delete: service.deleteExternalSystem + }, + config: { + message: { + createSuccess: '创建系统成功', + updateSuccess: '更新系统成功', + deleteSuccess: '删除系统成功' + } } - } - } - }; + }); - const columns: ColumnsType = [ - { - title: '系统名称', - dataIndex: 'name', - width: 200, - }, - { - title: '系统类型', - dataIndex: 'type', - width: 120, - render: (type: SystemType) => { - const typeMap = { - [SystemType.JENKINS]: 'Jenkins', - [SystemType.GIT]: 'Git', - [SystemType.ZENTAO]: '禅道' - }; - return typeMap[type]; - } - }, - { - title: '系统地址', - dataIndex: 'url', - width: 300, - render: (url: string) => ( - - {url} - - ), - }, - { - title: '认证方式', - dataIndex: 'authType', - width: 120, - render: (authType: AuthType) => { - const authTypeMap = { - [AuthType.BASIC]: '用户名密码', - [AuthType.TOKEN]: '令牌', - [AuthType.OAUTH]: 'OAuth2' - }; - return authTypeMap[authType]; - } - }, - { - title: '同步状态', - dataIndex: 'syncStatus', - width: 120, - render: (status: SyncStatus, record) => { - const statusConfig = { - [SyncStatus.SUCCESS]: { icon: , color: 'success', text: '成功' }, - [SyncStatus.FAILED]: { icon: , color: 'error', text: '失败' }, - [SyncStatus.RUNNING]: { icon: , color: 'processing', text: '同步中' }, - NONE: { icon: , color: 'default', text: '未同步' } - }; - const config = statusConfig[status] || statusConfig.NONE; - return ( - - - {config.text} - - - ); - } - }, - { - title: '最后连接时间', - dataIndex: 'lastConnectTime', - width: 150, - render: (time: string) => time || '-' - }, - { - title: '状态', - dataIndex: 'enabled', - width: 100, - render: (enabled: boolean, record) => ( - handleStatusChange(record.id, checked)} - checkedChildren="否" - unCheckedChildren="是" - /> - ) - }, - { - title: '操作', - key: 'action', - width: 280, - render: (_, record) => ( - - - - - - ), - }, - ]; + const handleAdd = () => { + setEditingSystem(null); + form.resetFields(); + form.setFieldsValue({ + enabled: true, + sort: 1, + authType: AuthType.BASIC + }); + setModalVisible(true); + }; - return ( -
- -
- + const handleEdit = (record: ExternalSystemResponse) => { + setEditingSystem(record); + form.setFieldsValue({ + ...record, + password: undefined // 不显示密码 + }); + setModalVisible(true); + }; + + const handleTestConnection = async (id: number) => { + try { + const success = await service.testConnection(id); + message.success(success ? '连接成功' : '连接失败'); + } catch (error) { + message.error('测试连接失败'); + } + }; + + const handleStatusChange = async (id: number, enabled: boolean) => { + try { + await service.updateStatus(id, enabled); + message.success('更新状态成功'); + refresh(); + } catch (error) { + message.error('更新状态失败'); + } + }; + + const handleSubmit = async () => { + try { + const values = await form.validateFields(); + let success = false; + + if (editingSystem) { + success = await handleUpdate(editingSystem.id, values); + } else { + success = await handleCreate(values); + } + + if (success) { + setModalVisible(false); + } + } catch (error: any) { + // 如果是表单验证错误,不显示错误消息 + if (!error.errorFields) { + // 如果是后端返回的错误,显示后端的错误消息 + if (error.response?.data) { + message.error(error.response.data.message || '操作失败'); + } else { + message.error(error.message || '操作失败'); + } + } + } + }; + + const columns: ColumnsType = [ + { + title: '系统名称', + dataIndex: 'name', + width: 200, + }, + { + title: '系统类型', + dataIndex: 'type', + width: 120, + render: (type: SystemType) => { + const typeMap = { + [SystemType.JENKINS]: 'Jenkins', + [SystemType.GIT]: 'Git', + [SystemType.ZENTAO]: '禅道' + }; + return typeMap[type]; + } + }, + { + title: '系统地址', + dataIndex: 'url', + width: 300, + render: (url: string) => ( + + {url} + + ), + }, + { + title: '认证方式', + dataIndex: 'authType', + width: 120, + render: (authType: AuthType) => { + const authTypeMap = { + [AuthType.BASIC]: '用户名密码', + [AuthType.TOKEN]: '令牌', + [AuthType.OAUTH]: 'OAuth2' + }; + return authTypeMap[authType]; + } + }, + { + title: '最后连接时间', + dataIndex: 'lastConnectTime', + width: 150, + render: (time: string) => time || '-' + }, + { + title: '状态', + dataIndex: 'enabled', + width: 100, + render: (enabled: boolean, record) => ( + handleStatusChange(record.id, checked)} + checkedChildren="否" + unCheckedChildren="是" + /> + ) + }, + { + title: '操作', + key: 'action', + width: 280, + render: (_, record) => ( + + + + + + ), + }, + ]; + + return ( +
+ +
+ +
+ + + + setModalVisible(false)} + width={600} + > +
+ + + + + + + + + + + + + + + + + prevValues.authType !== currentValues.authType} + > + {({getFieldValue}) => { + const authType = getFieldValue('authType'); + if (authType === AuthType.BASIC) { + return ( + <> + + + + + + + + ); + } + if (authType === AuthType.TOKEN) { + return ( + + + + ); + } + return null; + }} + + + + + + + + + + + + + + +
-
- - - setModalVisible(false)} - width={600} - > -
- - - - - - - - - - - - - - - - - prevValues.authType !== currentValues.authType} - > - {({ getFieldValue }) => { - const authType = getFieldValue('authType'); - if (authType === AuthType.BASIC) { - return ( - <> - - - - - - - - ); - } - if (authType === AuthType.TOKEN) { - return ( - - - - ); - } - return null; - }} - - - - - - - - - - - - - - -
- - ); + ); }; export default ExternalPage; \ No newline at end of file diff --git a/frontend/src/pages/Deploy/External/types.ts b/frontend/src/pages/Deploy/External/types.ts index a84dc623..480f8df3 100644 --- a/frontend/src/pages/Deploy/External/types.ts +++ b/frontend/src/pages/Deploy/External/types.ts @@ -1,5 +1,4 @@ -import { BaseResponse } from '@/types/base/response'; -import {BaseQuery} from "@/types/base"; +import {BaseQuery, BaseResponse} from "@/types/base"; // 系统类型枚举 export enum SystemType { @@ -41,8 +40,6 @@ export interface ExternalSystemResponse extends BaseResponse { username?: string; password?: string; token?: string; - syncStatus: SyncStatus; - lastSyncTime?: string; lastConnectTime?: string; config?: string; }