forked from wangziqi/gongxue-base
fix(admin): UX improvements — silent fetch failures, empty states, batch loading guards, dashboard refresh
- Replace console.error-only catches with message.error user-facing notifications
across Bills, Classes, ClassroomRentals, ClassroomSchedule, Classrooms, Deposits,
Expenses, OperationLogs, Permissions, Roles, RoomVisual, Rooms, Students,
Tenants, Users
- Add Empty component via Table locale prop on list pages: Bills, Classes,
ClassroomRentals, Classrooms, Deposits, Expenses (room+personal), Occupancies,
Rooms, Students, Tenants, Roles
- Add batchLoading state to batch delete/update operations: Bills (batchDelete,
batchUpdateStatus), Expenses (batchDeleteRoom, batchDeletePersonal),
Occupancies (batchCheckOut, batchDelete), Rooms (batchDelete),
Students (batchDelete)
- Add refreshLoading indicator to Dashboard header when re-fetching data
- Consistent error pattern: catch (e: unknown) { const err = e as { message?: string }; message.error(...); }
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
Select,
|
||||
Tooltip,
|
||||
Spin,
|
||||
Empty,
|
||||
} from 'antd';
|
||||
import {
|
||||
FileTextOutlined,
|
||||
@@ -54,6 +55,7 @@ const BillsPage: React.FC = () => {
|
||||
const [generateForm] = Form.useForm();
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [detailLoading, setDetailLoading] = useState(false);
|
||||
const [batchLoading, setBatchLoading] = useState(false);
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
setLoading(true);
|
||||
@@ -63,8 +65,8 @@ const BillsPage: React.FC = () => {
|
||||
if (filterExpenseType) params.expenseType = filterExpenseType;
|
||||
const res = await api.get('/bills', { params }) as unknown[];
|
||||
setBills(res);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} catch (e: any) {
|
||||
message.error(e?.message || '加载失败,请稍后重试');
|
||||
}
|
||||
setLoading(false);
|
||||
}, [filterStatus, filterExpenseType]);
|
||||
@@ -110,8 +112,9 @@ const BillsPage: React.FC = () => {
|
||||
try {
|
||||
const res = await api.get(`/bills/${id}`);
|
||||
setDetailModal(res);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} catch (e: any) {
|
||||
message.error(e?.message || '加载详情失败');
|
||||
}
|
||||
} finally {
|
||||
setDetailLoading(false);
|
||||
}
|
||||
@@ -132,6 +135,7 @@ const BillsPage: React.FC = () => {
|
||||
|
||||
const batchUpdateStatus = async (status: string) => {
|
||||
if (selectedRows.length === 0) return message.warning('请先选择账单');
|
||||
setBatchLoading(true);
|
||||
try {
|
||||
await api.put('/bills/batch/status', { ids: selectedRows, status });
|
||||
message.success(`已批量更新 ${selectedRows.length} 条账单`);
|
||||
@@ -139,6 +143,8 @@ const BillsPage: React.FC = () => {
|
||||
fetchData();
|
||||
} catch (e: any) {
|
||||
message.error(e?.message || '操作失败');
|
||||
} finally {
|
||||
setBatchLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -151,9 +157,9 @@ const BillsPage: React.FC = () => {
|
||||
message.error(e?.message || '删除失败');
|
||||
}
|
||||
};
|
||||
|
||||
const batchDelete = async () => {
|
||||
if (selectedRows.length === 0) return message.warning('请先选择账单');
|
||||
setBatchLoading(true);
|
||||
try {
|
||||
await api.post('/bills/batch/delete', { ids: selectedRows });
|
||||
message.success(`已删除 ${selectedRows.length} 条账单`);
|
||||
@@ -161,6 +167,8 @@ const BillsPage: React.FC = () => {
|
||||
fetchData();
|
||||
} catch (e: any) {
|
||||
message.error(e?.message || '操作失败');
|
||||
} finally {
|
||||
setBatchLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -334,6 +342,7 @@ const BillsPage: React.FC = () => {
|
||||
permission="bill:confirm"
|
||||
onClick={() => batchUpdateStatus('confirmed')}
|
||||
disabled={selectedRows.length === 0}
|
||||
loading={batchLoading}
|
||||
>
|
||||
批量确认
|
||||
</PermissionButton>
|
||||
@@ -342,6 +351,7 @@ const BillsPage: React.FC = () => {
|
||||
type="primary"
|
||||
onClick={() => batchUpdateStatus('paid')}
|
||||
disabled={selectedRows.length === 0}
|
||||
loading={batchLoading}
|
||||
>
|
||||
批量标记已付
|
||||
</PermissionButton>
|
||||
@@ -357,6 +367,7 @@ const BillsPage: React.FC = () => {
|
||||
danger
|
||||
disabled={selectedRows.length === 0}
|
||||
icon={<DeleteOutlined />}
|
||||
loading={batchLoading}
|
||||
>
|
||||
批量删除
|
||||
</PermissionButton>
|
||||
@@ -389,6 +400,7 @@ const BillsPage: React.FC = () => {
|
||||
dataSource={filteredBills}
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
locale={{ emptyText: <Empty description="暂无数据" /> }}
|
||||
pagination={{ pageSize: 15, showTotal: (total) => `共 ${total} 条` }}
|
||||
rowSelection={{
|
||||
selectedRowKeys: selectedRows,
|
||||
|
||||
Reference in New Issue
Block a user