"use client" import { useState, useEffect } from "react" import Link from "next/link" import { useSearchParams, useRouter, usePathname } from "next/navigation" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu" import { Plus, Search, MoreHorizontal, Edit, Eye, Trash } from "lucide-react" import { toast } from "sonner" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { Badge } from "@/components/ui/badge" import { PaginationControls } from "@/components/ui/pagination-controls" interface Project { id: number name: string status: number tenantId: number companyId: number memo: string | null userCount: number createTime: string deviceCount: number } export default function ProjectsPage() { const searchParams = useSearchParams() const router = useRouter() const pathname = usePathname() const [searchTerm, setSearchTerm] = useState("") const [projects, setProjects] = useState([]) const [isLoading, setIsLoading] = useState(true) const [currentPage, setCurrentPage] = useState(parseInt(searchParams.get("page") || "1")) const [totalPages, setTotalPages] = useState(1) const [pageSize, setPageSize] = useState(parseInt(searchParams.get("pageSize") || "10")) const [totalItems, setTotalItems] = useState(0) const [deleteDialogOpen, setDeleteDialogOpen] = useState(false) const [deletingProjectId, setDeletingProjectId] = useState(null) const [isDeleting, setIsDeleting] = useState(false) // 从URL更新状态 useEffect(() => { const page = parseInt(searchParams.get("page") || "1") const size = parseInt(searchParams.get("pageSize") || "10") setCurrentPage(page) setPageSize(size) }, [searchParams]) // 更新URL查询参数 const updateUrlParams = (page: number, size: number) => { const params = new URLSearchParams() params.set("page", page.toString()) params.set("pageSize", size.toString()) if (searchTerm) { params.set("search", searchTerm) } router.replace(`${pathname}?${params.toString()}`) } // 获取项目列表 useEffect(() => { const fetchProjects = async () => { setIsLoading(true) try { const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/list?page=${currentPage}&limit=${pageSize}`) const data = await response.json() if (data.code === 200) { setProjects(data.data.list) setTotalItems(data.data.total) setTotalPages(Math.ceil(data.data.total / pageSize)) } else { toast.error(data.msg || "获取项目列表失败") setProjects([]) setTotalItems(0) setTotalPages(0) } } catch (error) { toast.error("获取项目列表失败") setProjects([]) setTotalItems(0) setTotalPages(0) } finally { setIsLoading(false) } } fetchProjects() // 更新URL参数 updateUrlParams(currentPage, pageSize) }, [currentPage, pageSize, pathname]) // 处理页面大小变化 const handlePageSizeChange = (newSize: number) => { setPageSize(newSize) setCurrentPage(1) updateUrlParams(1, newSize) } // 处理页面变化 const handlePageChange = (newPage: number) => { setCurrentPage(newPage) updateUrlParams(newPage, pageSize) } const handleDeleteClick = (projectId: number) => { setDeletingProjectId(projectId) setDeleteDialogOpen(true) } const handleConfirmDelete = async () => { if (!deletingProjectId) return setIsDeleting(true) try { const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/delete`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ id: deletingProjectId }), }) const data = await response.json() if (data.code === 200) { toast.success("删除成功") // Fetch projects again after delete const fetchProjects = async () => { setIsLoading(true) try { const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/list?page=${currentPage}&limit=${pageSize}`) const data = await response.json() if (data.code === 200) { setProjects(data.data.list) setTotalItems(data.data.total) setTotalPages(Math.ceil(data.data.total / pageSize)) if (currentPage > Math.ceil(data.data.total / pageSize) && Math.ceil(data.data.total / pageSize) > 0) { setCurrentPage(Math.ceil(data.data.total / pageSize)); } } else { setProjects([]); setTotalItems(0); setTotalPages(0); } } catch (error) { setProjects([]); setTotalItems(0); setTotalPages(0); } finally { setIsLoading(false); } } fetchProjects(); } else { toast.error(data.msg || "删除失败") } } catch (error) { toast.error("网络错误,请稍后重试") } finally { setIsDeleting(false) setDeleteDialogOpen(false) setDeletingProjectId(null) } } return (

项目列表

setSearchTerm(e.target.value)} />
项目名称 状态 用户数量 设备数量 创建时间 操作 {isLoading ? ( 加载中... ) : projects.length > 0 ? ( projects.map((project) => ( {project.name} {project.status === 1 ? "启用" : "禁用"} {project.userCount} {project.deviceCount} {project.createTime} 查看详情 编辑项目 handleDeleteClick(project.id)} > 删除项目 )) ) : ( 未找到项目 )}
确认删除 删除项目将会删除本项目关联的所有账号,项目删除后不可恢复,是否确认删除?
) }