feat(机架管理): 添加后端筛选功能并优化前端交互

- 后端路由添加对房间ID、状态和关键字的筛选支持
- 前端移除本地筛选逻辑,改为使用后端筛选参数
- 添加筛选条件变化时自动重置分页并重新加载数据
This commit is contained in:
zhang1106
2026-02-09 16:55:07 +08:00
parent 93a5de2106
commit d0d34aee2f
2 changed files with 39 additions and 18 deletions
+23 -4
View File
@@ -17,11 +17,30 @@ router.get('/', async (req, res) => {
const pageSize = parseInt(req.query.pageSize) || 10; const pageSize = parseInt(req.query.pageSize) || 10;
const offset = (page - 1) * pageSize; const offset = (page - 1) * pageSize;
// 获取总记录 // 筛选参
const total = await Rack.count(); const { roomId, status, keyword } = req.query;
// 构建查询条件
const where = {};
if (roomId && roomId !== 'all') {
where.roomId = roomId;
}
if (status && status !== 'all') {
where.status = status;
}
if (keyword) {
where[require('sequelize').Op.or] = [
{ rackId: { [require('sequelize').Op.like]: `%${keyword}%` } },
{ name: { [require('sequelize').Op.like]: `%${keyword}%` } }
];
}
// 获取总记录数(带筛选条件)
const total = await Rack.count({ where });
// 获取分页数据 // 获取分页数据
const racks = await Rack.findAll({ const racks = await Rack.findAll({
where,
include: [ include: [
{ model: Room }, { model: Room },
{ model: Device } { model: Device }
@@ -29,7 +48,7 @@ router.get('/', async (req, res) => {
limit: pageSize, limit: pageSize,
offset: offset offset: offset
}); });
// 返回带分页信息的响应 // 返回带分页信息的响应
res.json({ res.json({
racks, racks,
+16 -14
View File
@@ -283,7 +283,13 @@ function RackManagement() {
try { try {
setLoading(true); setLoading(true);
const response = await axios.get('/api/racks', { const response = await axios.get('/api/racks', {
params: { page, pageSize } params: {
page,
pageSize,
roomId: roomFilter,
status: statusFilter,
keyword: searchKeyword || undefined
}
}); });
const { racks: data, total } = response.data; const { racks: data, total } = response.data;
setRacks(data); setRacks(data);
@@ -294,7 +300,7 @@ function RackManagement() {
} finally { } finally {
setLoading(false); setLoading(false);
} }
}, []); }, [roomFilter, statusFilter, searchKeyword]);
const fetchRooms = useCallback(async () => { const fetchRooms = useCallback(async () => {
try { try {
@@ -311,6 +317,12 @@ function RackManagement() {
fetchRooms(); fetchRooms();
}, [fetchRacks, fetchRooms]); }, [fetchRacks, fetchRooms]);
// 当筛选条件变化时,重置到第一页并重新加载
useEffect(() => {
setPagination(prev => ({ ...prev, current: 1 }));
fetchRacks(1, pagination.pageSize);
}, [roomFilter, statusFilter, searchKeyword]);
const handleTableChange = useCallback((pagination) => { const handleTableChange = useCallback((pagination) => {
fetchRacks(pagination.current, pagination.pageSize); fetchRacks(pagination.current, pagination.pageSize);
}, [fetchRacks]); }, [fetchRacks]);
@@ -482,18 +494,8 @@ function RackManagement() {
} }
}, [fetchRacks]); }, [fetchRacks]);
const filteredRacks = useMemo(() => { // 后端已过滤,直接使用 racks 数据
return racks.filter(rack => { const filteredRacks = racks;
const matchKeyword = !searchKeyword ||
rack.name?.toLowerCase().includes(searchKeyword.toLowerCase()) ||
rack.rackId?.toLowerCase().includes(searchKeyword.toLowerCase());
const matchStatus = statusFilter === 'all' || rack.status === statusFilter;
const matchRoom = roomFilter === 'all' || rack.roomId === roomFilter;
return matchKeyword && matchStatus && matchRoom;
});
}, [racks, searchKeyword, statusFilter, roomFilter]);
const stats = useMemo(() => ({ const stats = useMemo(() => ({
total: racks.length, total: racks.length,