|
|
@@ -1,18 +1,17 @@
|
|
|
import React, { useState } from 'react';
|
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
|
-import { Button } from '@d8d/shared-ui-components';
|
|
|
-import { Input } from '@d8d/shared-ui-components';
|
|
|
-import { Card, CardContent, CardHeader, CardTitle } from '@d8d/shared-ui-components';
|
|
|
-import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@d8d/shared-ui-components';
|
|
|
-import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@d8d/shared-ui-components';
|
|
|
-import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@d8d/shared-ui-components';
|
|
|
-import { Badge } from '@d8d/shared-ui-components';
|
|
|
-import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@d8d/shared-ui-components';
|
|
|
+import { Button } from '@d8d/shared-ui-components/components/ui/button';
|
|
|
+import { Input } from '@d8d/shared-ui-components/components/ui/input';
|
|
|
+import { Card, CardContent, CardHeader, CardTitle } from '@d8d/shared-ui-components/components/ui/card';
|
|
|
+import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@d8d/shared-ui-components/components/ui/dialog';
|
|
|
+import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@d8d/shared-ui-components/components/ui/form';
|
|
|
+import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@d8d/shared-ui-components/components/ui/table';
|
|
|
+import { Badge } from '@d8d/shared-ui-components/components/ui/badge';
|
|
|
import { useForm } from 'react-hook-form';
|
|
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
|
import { toast } from 'sonner';
|
|
|
import { Eye, Download, Edit, Trash2, Search, FileText, Upload } from 'lucide-react';
|
|
|
-import { fileClient } from '../api/fileClient';
|
|
|
+import { fileClientManager, fileClient } from '../api/fileClient';
|
|
|
import type { InferResponseType, InferRequestType } from 'hono/client';
|
|
|
import dayjs from 'dayjs';
|
|
|
import MinioUploader from './MinioUploader';
|
|
|
@@ -20,8 +19,8 @@ import { UpdateFileDto } from '@d8d/file-module/schemas';
|
|
|
import * as z from 'zod';
|
|
|
|
|
|
// 定义类型
|
|
|
-type FileItem = InferResponseType<typeof fileClient.$get, 200>['data'][0];
|
|
|
-type FileListResponse = InferResponseType<typeof fileClient.$get, 200>;
|
|
|
+type FileItem = InferResponseType<typeof fileClient.index.$get, 200>['data'][0];
|
|
|
+type FileListResponse = InferResponseType<typeof fileClient.index.$get, 200>;
|
|
|
type UpdateFileRequest = InferRequestType<typeof fileClient[':id']['$put']>['json'];
|
|
|
type FileFormData = z.infer<typeof UpdateFileDto>;
|
|
|
|
|
|
@@ -67,7 +66,7 @@ export const FileManagement: React.FC<FileManagementProps> = ({
|
|
|
|
|
|
// 获取文件列表数据
|
|
|
const fetchFiles = async ({ page, pageSize }: { page: number; pageSize: number }): Promise<FileListResponse> => {
|
|
|
- const response = await fileClient.$get({ query: { page, pageSize, keyword: searchText } });
|
|
|
+ const response = await fileClientManager.get().index.$get({ query: { page, pageSize, keyword: searchText } });
|
|
|
if (!response.ok) throw new Error('Failed to fetch files');
|
|
|
return await response.json() as FileListResponse;
|
|
|
};
|
|
|
@@ -80,7 +79,7 @@ export const FileManagement: React.FC<FileManagementProps> = ({
|
|
|
// 更新文件记录
|
|
|
const updateFile = useMutation({
|
|
|
mutationFn: ({ id, data }: { id: number; data: UpdateFileRequest }) =>
|
|
|
- fileClient[':id'].$put({ param: { id: Number(id) }, json: data }),
|
|
|
+ fileClientManager.get()[':id'].$put({ param: { id: Number(id) }, json: data }),
|
|
|
onSuccess: () => {
|
|
|
toast.success('文件记录更新成功');
|
|
|
queryClient.invalidateQueries({ queryKey: ['files'] });
|
|
|
@@ -94,7 +93,7 @@ export const FileManagement: React.FC<FileManagementProps> = ({
|
|
|
|
|
|
// 删除文件记录
|
|
|
const deleteFile = useMutation({
|
|
|
- mutationFn: (id: number) => fileClient[':id'].$delete({ param: { id: Number(id) } }),
|
|
|
+ mutationFn: (id: number) => fileClientManager.get()[':id'].$delete({ param: { id: Number(id) } }),
|
|
|
onSuccess: () => {
|
|
|
toast.success('文件记录删除成功');
|
|
|
queryClient.invalidateQueries({ queryKey: ['files'] });
|
|
|
@@ -206,7 +205,10 @@ export const FileManagement: React.FC<FileManagementProps> = ({
|
|
|
<div className="flex justify-between items-center">
|
|
|
<h1 className="text-3xl font-bold">文件管理</h1>
|
|
|
{showUploadButton && (
|
|
|
- <Button onClick={() => setIsUploadModalOpen(true)}>
|
|
|
+ <Button
|
|
|
+ onClick={() => setIsUploadModalOpen(true)}
|
|
|
+ data-testid="upload-file-button"
|
|
|
+ >
|
|
|
<Upload className="h-4 w-4 mr-2" />
|
|
|
上传文件
|
|
|
</Button>
|
|
|
@@ -384,7 +386,7 @@ export const FileManagement: React.FC<FileManagementProps> = ({
|
|
|
|
|
|
{/* 上传文件对话框 */}
|
|
|
<Dialog open={isUploadModalOpen} onOpenChange={setIsUploadModalOpen}>
|
|
|
- <DialogContent className="sm:max-w-[600px]">
|
|
|
+ <DialogContent className="sm:max-w-[600px]" data-testid="upload-file-dialog">
|
|
|
<DialogHeader>
|
|
|
<DialogTitle>上传文件</DialogTitle>
|
|
|
<DialogDescription>
|
|
|
@@ -467,22 +469,22 @@ export const FileManagement: React.FC<FileManagementProps> = ({
|
|
|
</Dialog>
|
|
|
|
|
|
{/* 删除确认对话框 */}
|
|
|
- <AlertDialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
|
|
|
- <AlertDialogContent>
|
|
|
- <AlertDialogHeader>
|
|
|
- <AlertDialogTitle>确认删除</AlertDialogTitle>
|
|
|
- <AlertDialogDescription>
|
|
|
+ <Dialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
|
|
|
+ <DialogContent>
|
|
|
+ <DialogHeader>
|
|
|
+ <DialogTitle>确认删除</DialogTitle>
|
|
|
+ <DialogDescription>
|
|
|
确定要删除这个文件记录吗?此操作不可恢复。
|
|
|
- </AlertDialogDescription>
|
|
|
- </AlertDialogHeader>
|
|
|
- <AlertDialogFooter>
|
|
|
- <AlertDialogCancel>取消</AlertDialogCancel>
|
|
|
- <AlertDialogAction onClick={handleDeleteConfirm} className="bg-red-600 hover:bg-red-700">
|
|
|
+ </DialogDescription>
|
|
|
+ </DialogHeader>
|
|
|
+ <DialogFooter>
|
|
|
+ <Button variant="outline" onClick={() => setIsDeleteDialogOpen(false)}>取消</Button>
|
|
|
+ <Button onClick={handleDeleteConfirm} className="bg-red-600 hover:bg-red-700">
|
|
|
确认删除
|
|
|
- </AlertDialogAction>
|
|
|
- </AlertDialogFooter>
|
|
|
- </AlertDialogContent>
|
|
|
- </AlertDialog>
|
|
|
+ </Button>
|
|
|
+ </DialogFooter>
|
|
|
+ </DialogContent>
|
|
|
+ </Dialog>
|
|
|
</div>
|
|
|
);
|
|
|
};
|