This commit is contained in:
Your Name 2025-05-27 22:06:16 +08:00
parent 678ad87c2f
commit 944fc48568
1 changed files with 201 additions and 26 deletions

View File

@ -1,18 +1,13 @@
import { api } from '@nice/client'; import { api } from '@nice/client';
import { Pagination } from 'antd'; import { Button, Input, Pagination, Space, Modal, Form, message, Switch } from 'antd';
import React, { useState } from 'react'; import { SearchOutlined, EditOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons';
import React, { useState, useRef, useEffect } from 'react';
// 定义 TrainSituation 接口
interface TrainSituation {
id: string;
staffId: string;
score: number;
}
// 定义 Staff 接口 // 定义 Staff 接口
interface Staff { interface Staff {
id: string; id: string;
username: string; username: string;
showname: string;
absent: boolean; absent: boolean;
// trainSituations: TrainSituation[]; // trainSituations: TrainSituation[];
} }
@ -24,64 +19,244 @@ interface PaginatedResponse {
const TestPage: React.FC = () => { const TestPage: React.FC = () => {
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const [searchText, setSearchText] = useState('');
const [isModalVisible, setIsModalVisible] = useState(false);
const [editingStaff, setEditingStaff] = useState<Staff | null>(null);
const [form] = Form.useForm();
const pageSize = 10; const pageSize = 10;
// 使用 findManyWithPagination 替换原来的两个查询 // 添加 useRef 处理查询
const { data, isLoading } = api.staff.findManyWithPagination.useQuery<PaginatedResponse>({ const searchRef = useRef(false);
// 优化查询逻辑
const { data, isLoading, refetch } = api.staff.findManyWithPagination.useQuery<PaginatedResponse>({
page: currentPage, page: currentPage,
pageSize: pageSize, pageSize: pageSize,
where: { deletedAt: null }, where: {
deletedAt: null,
OR: searchText ? [
{ username: { contains: searchText } },
{ showname: { contains: searchText } }
] : undefined
},
select: { select: {
id: true, id: true,
username: true, username: true,
showname: true,
absent: true, absent: true,
} }
}, {
enabled: searchRef.current, // 控制查询启用
refetchOnWindowFocus: false,
keepPreviousData: true, // 保持之前的数据直到新数据加载完成
}); });
console.log(data);
// data 中包含了分页数据和总记录数 // 删除方法
const staffs = (data?.items || []) as Staff[]; const deleteMutation = api.staff.softDeleteByIds.useMutation({
const totalCount = data?.total || 0; onSuccess: () => {
message.success('删除成功');
refetch();
},
onError: (error) => {
message.error('删除失败:' + error.message);
}
});
// 分页处理函数 // 更新方法
const updateMutation = api.staff.update.useMutation({
onSuccess: () => {
message.success('更新成功');
setIsModalVisible(false);
refetch();
}
});
// 创建方法
const createMutation = api.staff.create.useMutation({
onSuccess: () => {
message.success('创建成功');
setIsModalVisible(false);
refetch();
}
});
const handleSearch = () => {
setCurrentPage(1);
searchRef.current = true;
refetch();
};
// 修改分页处理
const handlePageChange = (page: number) => { const handlePageChange = (page: number) => {
setCurrentPage(page); setCurrentPage(page);
searchRef.current = true;
refetch();
};
// 添加数据监听
useEffect(() => {
if (data && searchRef.current) {
searchRef.current = false;
}
}, [data]);
// 处理删除的函数
const handleDelete = async (id: string) => {
Modal.confirm({
title: '确认删除',
content: '确定要删除这条记录吗?',
onOk: async () => {
try {
await deleteMutation.mutateAsync({
ids: [id],
data: {} // 添加空的 data 对象
});
} catch (error) {
console.error('删除失败:', error);
}
}
});
};
const handleEdit = (staff: Staff) => {
setEditingStaff(staff);
form.setFieldsValue(staff);
setIsModalVisible(true);
};
const handleAdd = () => {
setEditingStaff(null);
form.resetFields();
setIsModalVisible(true);
};
const handleModalOk = () => {
form.validateFields().then(values => {
if (editingStaff) {
updateMutation.mutate({
where: { id: editingStaff.id },
data: values
});
} else {
createMutation.mutate({
data: values
});
}
});
}; };
return ( return (
<div className="p-6"> <div className="p-6">
<h1 className="text-2xl font-bold mb-4 text-center"></h1> <h1 className="text-2xl font-bold mb-4 text-center"></h1>
{/* 搜索和添加按钮 */}
<div className="mb-4 flex justify-between">
<Space>
<Input
placeholder="搜索员工姓名或用户名"
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
onPressEnter={handleSearch}
prefix={<SearchOutlined />}
/>
<Button type="primary" onClick={handleSearch}></Button>
</Space>
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
</Button>
</div>
{/* 修改表格,添加操作列 */}
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="min-w-full bg-white shadow-md rounded-lg"> <table className="min-w-full bg-white shadow-md rounded-lg">
<thead> <thead>
<tr className="bg-gray-100 border-b"> <tr className="bg-gray-100 border-b">
<th className="px-6 py-3 text-center text-xs font-medium text-gray-600 uppercase tracking-wider">ID</th> <th className="px-6 py-3 text-center text-xs font-medium text-gray-600 uppercase tracking-wider"></th>
<th className="px-6 py-3 text-center text-xs font-medium text-gray-600 uppercase tracking-wider">ID</th> <th className="px-6 py-3 text-center text-xs font-medium text-gray-600 uppercase tracking-wider"></th>
<th className="px-6 py-3 text-center text-xs font-medium text-gray-600 uppercase tracking-wider"></th> <th className="px-6 py-3 text-center text-xs font-medium text-gray-600 uppercase tracking-wider"></th>
<th className="px-6 py-3 text-center text-xs font-medium text-gray-600 uppercase tracking-wider">
</th>
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-gray-200"> <tbody className="divide-y divide-gray-200">
{staffs.map((staff) => ( {(data?.items || []).map((staff) => (
<tr key={staff.id} className="hover:bg-gray-50"> <tr key={staff.id} className="hover:bg-gray-50">
<td className="px-6 py-4 whitespace-nowrap text-center">
{staff.id}
</td>
<td className="px-6 py-4 whitespace-nowrap text-center"> <td className="px-6 py-4 whitespace-nowrap text-center">
{staff.username} {staff.username}
</td> </td>
<td className="px-6 py-4 whitespace-nowrap text-center">
{staff.showname}
</td>
<td className="px-6 py-4 whitespace-nowrap text-center"> <td className="px-6 py-4 whitespace-nowrap text-center">
{staff.absent ? '在位' : '不在位'} {staff.absent ? '在位' : '不在位'}
</td> </td>
<td className="px-6 py-4 whitespace-nowrap text-center">
<Space>
<Button
type="primary"
icon={<EditOutlined />}
onClick={() => handleEdit(staff)}
size="small"
>
</Button>
<Button
type="primary"
danger
icon={<DeleteOutlined />}
onClick={() => handleDelete(staff.id)}
size="small"
>
</Button>
</Space>
</td>
</tr> </tr>
))} ))}
</tbody> </tbody>
</table> </table>
</div> </div>
{/* 编辑/添加模态框 */}
<Modal
title={editingStaff ? "编辑员工" : "添加员工"}
open={isModalVisible}
onOk={handleModalOk}
onCancel={() => setIsModalVisible(false)}
>
<Form form={form} layout="vertical">
<Form.Item
name="username"
label="用户名"
rules={[{ required: true, message: '请输入用户名' }]}
>
<Input />
</Form.Item>
<Form.Item
name="showname"
label="名称"
rules={[{ required: true, message: '请输入名称' }]}
>
<Input />
</Form.Item>
<Form.Item
name="absent"
label="是否在位"
valuePropName="checked"
>
<Switch
checkedChildren="在位"
unCheckedChildren="不在位"
/>
</Form.Item>
</Form>
</Modal>
<div className="mt-4 flex justify-center"> <div className="mt-4 flex justify-center">
<Pagination <Pagination
current={currentPage} current={currentPage}
total={totalCount} total={data?.total || 0}
pageSize={pageSize} pageSize={pageSize}
onChange={handlePageChange} onChange={handlePageChange}
showTotal={(total) => `${total} 条记录`} showTotal={(total) => `${total} 条记录`}