From 7ab6d3354e684da4d2624fab8176c059539bc872 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Wed, 29 Oct 2025 10:10:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=A2=E9=98=9F=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/Deploy/Team/Application/schema.ts | 18 +++++ .../pages/Deploy/Team/Application/service.ts | 40 +++++++++++ .../pages/Deploy/Team/Application/types.ts | 30 ++++++++ .../List/components/MemberManageDialog.tsx | 28 +++----- .../Deploy/Team/List/components/TeamModal.tsx | 16 ++--- frontend/src/pages/Deploy/Team/List/index.tsx | 71 +++++++++++++++++-- 6 files changed, 168 insertions(+), 35 deletions(-) create mode 100644 frontend/src/pages/Deploy/Team/Application/schema.ts create mode 100644 frontend/src/pages/Deploy/Team/Application/service.ts create mode 100644 frontend/src/pages/Deploy/Team/Application/types.ts diff --git a/frontend/src/pages/Deploy/Team/Application/schema.ts b/frontend/src/pages/Deploy/Team/Application/schema.ts new file mode 100644 index 00000000..0f8751f3 --- /dev/null +++ b/frontend/src/pages/Deploy/Team/Application/schema.ts @@ -0,0 +1,18 @@ +import { z } from 'zod'; + +/** + * 团队应用关联表单验证 + */ +export const teamApplicationFormSchema = z.object({ + teamId: z.number({ + required_error: '团队ID不能为空', + invalid_type_error: '团队ID必须是数字', + }), + applicationId: z.number({ + required_error: '请选择应用', + invalid_type_error: '应用ID必须是数字', + }), +}); + +export type TeamApplicationFormValues = z.infer; + diff --git a/frontend/src/pages/Deploy/Team/Application/service.ts b/frontend/src/pages/Deploy/Team/Application/service.ts new file mode 100644 index 00000000..67437807 --- /dev/null +++ b/frontend/src/pages/Deploy/Team/Application/service.ts @@ -0,0 +1,40 @@ +import request from '@/utils/request'; +import type { Page } from '@/types/base'; +import type { + TeamApplicationQuery, + TeamApplicationResponse, + TeamApplicationRequest, +} from './types'; + +const BASE_URL = '/api/v1/team-applications'; + +/** + * 分页查询团队应用关联 + */ +export const getTeamApplications = (params?: TeamApplicationQuery) => + request.get>(`${BASE_URL}/page`, { params }); + +/** + * 根据ID获取团队应用关联 + */ +export const getTeamApplicationById = (id: number) => + request.get(`${BASE_URL}/${id}`); + +/** + * 创建团队应用关联 + */ +export const createTeamApplication = (data: TeamApplicationRequest) => + request.post(BASE_URL, data); + +/** + * 更新团队应用关联 + */ +export const updateTeamApplication = (id: number, data: TeamApplicationRequest) => + request.put(`${BASE_URL}/${id}`, data); + +/** + * 删除团队应用关联 + */ +export const deleteTeamApplication = (id: number) => + request.delete(`${BASE_URL}/${id}`); + diff --git a/frontend/src/pages/Deploy/Team/Application/types.ts b/frontend/src/pages/Deploy/Team/Application/types.ts new file mode 100644 index 00000000..0b5701f8 --- /dev/null +++ b/frontend/src/pages/Deploy/Team/Application/types.ts @@ -0,0 +1,30 @@ +import type { BaseResponse } from '@/types/base'; + +/** + * 团队应用关联查询参数 + */ +export interface TeamApplicationQuery { + teamId?: number; + applicationId?: number; + pageNum?: number; + pageSize?: number; +} + +/** + * 团队应用关联响应 + */ +export interface TeamApplicationResponse extends BaseResponse { + teamId: number; + applicationId: number; + applicationName?: string; + applicationCode?: string; +} + +/** + * 团队应用关联请求 + */ +export interface TeamApplicationRequest { + teamId: number; + applicationId: number; +} + diff --git a/frontend/src/pages/Deploy/Team/List/components/MemberManageDialog.tsx b/frontend/src/pages/Deploy/Team/List/components/MemberManageDialog.tsx index b7a1e018..5b730cd1 100644 --- a/frontend/src/pages/Deploy/Team/List/components/MemberManageDialog.tsx +++ b/frontend/src/pages/Deploy/Team/List/components/MemberManageDialog.tsx @@ -65,13 +65,13 @@ import type { TeamMemberQuery } from '../../Member/types'; import type { Page } from '@/types/base'; -import { getUserList } from '@/pages/System/User/service'; import type { UserResponse } from '@/pages/System/User/types'; interface MemberManageDialogProps { open: boolean; teamId: number; teamName: string; + users: UserResponse[]; onOpenChange: (open: boolean) => void; onSuccess?: () => void; } @@ -83,6 +83,7 @@ const MemberManageDialog: React.FC = ({ open, teamId, teamName, + users, onOpenChange, onSuccess }) => { @@ -94,7 +95,6 @@ const MemberManageDialog: React.FC = ({ const [editRecord, setEditRecord] = useState(null); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [deleteRecord, setDeleteRecord] = useState(null); - const [users, setUsers] = useState([]); // 分页状态 const [pageNum, setPageNum] = useState(DEFAULT_CURRENT - 1); @@ -110,20 +110,6 @@ const MemberManageDialog: React.FC = ({ } }); - // 加载用户列表 - const loadUsers = async () => { - try { - const result = await getUserList(); - setUsers(result || []); - } catch (error) { - console.error('加载用户列表失败:', error); - toast({ - variant: "destructive", - title: "加载用户列表失败", - description: error instanceof Error ? error.message : '未知错误', - }); - } - }; // 加载成员列表 const loadMembers = async () => { @@ -153,7 +139,6 @@ const MemberManageDialog: React.FC = ({ useEffect(() => { if (open) { - loadUsers(); loadMembers(); } }, [open, pageNum, pageSize]); @@ -287,7 +272,8 @@ const MemberManageDialog: React.FC = ({ {/* 表格 */} -
+
+
@@ -357,10 +343,11 @@ const MemberManageDialog: React.FC = ({ )}
+
{/* 分页 */} {data && data.totalElements > 0 && ( -
+
= ({
)}
+
) : ( +
= ({
+ )} diff --git a/frontend/src/pages/Deploy/Team/List/components/TeamModal.tsx b/frontend/src/pages/Deploy/Team/List/components/TeamModal.tsx index f352ad59..548fde5b 100644 --- a/frontend/src/pages/Deploy/Team/List/components/TeamModal.tsx +++ b/frontend/src/pages/Deploy/Team/List/components/TeamModal.tsx @@ -6,7 +6,6 @@ import { DialogContent, DialogHeader, DialogTitle, - DialogFooter, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { @@ -24,7 +23,6 @@ import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { teamFormSchema, type TeamFormValues } from "../schema"; import { Textarea } from "@/components/ui/textarea"; -import { ScrollArea } from "@/components/ui/scroll-area"; interface TeamModalProps { open: boolean; @@ -111,14 +109,14 @@ const TeamModal: React.FC = ({ return ( !open && onCancel()}> - - + + {isEdit ? '编辑' : '新建'}团队
- -
+
+
= ({
- - +
+
@@ -270,7 +268,7 @@ const TeamModal: React.FC = ({ > 确定 - +
diff --git a/frontend/src/pages/Deploy/Team/List/index.tsx b/frontend/src/pages/Deploy/Team/List/index.tsx index 0c2f3d1f..88c1643a 100644 --- a/frontend/src/pages/Deploy/Team/List/index.tsx +++ b/frontend/src/pages/Deploy/Team/List/index.tsx @@ -5,6 +5,11 @@ import type { TeamResponse, TeamQuery } from './types'; import TeamModal from './components/TeamModal'; import DeleteDialog from './components/DeleteDialog'; import MemberManageDialog from './components/MemberManageDialog'; +import ApplicationManageDialog from './components/ApplicationManageDialog'; +import { getUserList } from '@/pages/System/User/service'; +import type { UserResponse } from '@/pages/System/User/types'; +import { getApplicationList } from '@/pages/Deploy/Application/List/service'; +import type { Application } from '@/pages/Deploy/Application/List/types'; import { Table, TableHeader, @@ -45,6 +50,7 @@ import { Activity, Server, Database, + Package, } from 'lucide-react'; type Column = { @@ -67,6 +73,9 @@ const TeamList: React.FC = () => { const [currentTeam, setCurrentTeam] = useState(); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [memberDialogOpen, setMemberDialogOpen] = useState(false); + const [applicationDialogOpen, setApplicationDialogOpen] = useState(false); + const [users, setUsers] = useState([]); + const [applications, setApplications] = useState([]); const form = useForm({ resolver: zodResolver(searchFormSchema), @@ -110,6 +119,34 @@ const TeamList: React.FC = () => { } }; + // 加载用户列表和应用列表(仅一次) + useEffect(() => { + loadUsers(); + loadApplications(); + }, []); + + const loadUsers = async () => { + try { + const response = await getUserList(); + if (response) { + setUsers(response); + } + } catch (error) { + console.error('加载用户列表失败:', error); + } + }; + + const loadApplications = async () => { + try { + const response = await getApplicationList(); + if (response) { + setApplications(response); + } + } catch (error) { + console.error('加载应用列表失败:', error); + } + }; + useEffect(() => { loadData(); }, [pagination.pageNum, pagination.pageSize]); @@ -138,6 +175,11 @@ const TeamList: React.FC = () => { setMemberDialogOpen(true); }; + const handleManageApplications = (record: TeamResponse) => { + setCurrentTeam(record); + setApplicationDialogOpen(true); + }; + const handleModalClose = () => { setModalVisible(false); setCurrentTeam(undefined); @@ -214,6 +256,10 @@ const TeamList: React.FC = () => { 成员 +