Files
gongxue-base/apps/admin/src/hooks/useDownload.ts
wangziqi 00e2bc5acf fix(admin): 通知分页、登录过期提示、附件打开反馈与导出统一 loading
- 通知中心改为游标分页 + 加载更多,历史通知不再被 50 条上限截断;
  加载失败显示错误态与重试
- AI 流式请求 401 被登出时,登录页提示"登录已过期",不再无声踢出
- AI 附件/引用来源打开失败时给出明确错误提示,不再"点了没反应"
- 新增 useDownload hook:统一导出/下载的防重复、loading 与成功/失败反馈;
  接入学生/账单/房间/入住/费用五个页面的模板下载与导出按钮
- 学生页移除不检查响应状态的私有下载实现,统一走 downloadBlob
2026-08-07 17:33:58 +08:00

47 lines
1.3 KiB
TypeScript

import { useCallback, useRef, useState } from 'react';
import { downloadBlob } from '../utils/download';
import { message } from '../ui/app-message';
export interface DownloadOptions {
/** 成功提示文案;默认「下载成功」 */
successMsg?: string;
/** 失败提示文案;默认使用接口返回的错误信息 */
errorMsg?: string;
}
/**
* 统一下载/导出状态:防重复点击 + 成功/失败反馈。
*
* 用法:
* const { downloading, run } = useDownload();
* <Button loading={downloading} onClick={() => run('/students/export', '名单.xlsx')}>
*/
export function useDownload() {
const [downloading, setDownloading] = useState(false);
const busyRef = useRef(false);
const run = useCallback(
async (endpoint: string, filename: string, options?: DownloadOptions) => {
if (busyRef.current) return;
busyRef.current = true;
setDownloading(true);
try {
await downloadBlob(endpoint, filename);
message.success(options?.successMsg ?? '下载成功');
} catch (error: unknown) {
message.error(
options?.errorMsg ?? (error instanceof Error ? error.message : '下载失败,请重试'),
);
} finally {
busyRef.current = false;
setDownloading(false);
}
},
[],
);
return { downloading, run };
}
export default useDownload;