import React, { createContext, useContext, useState, useCallback, ReactNode } from 'react'; import Toast, { ToastType } from '../components/Toast'; import ConfirmDialog from '../components/ConfirmDialog'; // Toast 配置 interface ToastConfig { message: string; type: ToastType; } // Confirm 配置 interface ConfirmConfig { title?: string; message: string; confirmText?: string; cancelText?: string; danger?: boolean; } // Context 类型 interface NotificationContextType { showToast: (message: string, type: ToastType) => void; showConfirm: (config: ConfirmConfig) => Promise; } const NotificationContext = createContext(undefined); // Provider Props interface NotificationProviderProps { children: ReactNode; } export const NotificationProvider: React.FC = ({ children }) => { // Toast 状态 const [toast, setToast] = useState(null); // Confirm 状态 const [confirmConfig, setConfirmConfig] = useState(null); const [confirmResolver, setConfirmResolver] = useState<((value: boolean) => void) | null>(null); const normalizeToastMessage = useCallback((message: string): string => { // 去掉服务端可能携带的状态码前缀 let normalized = message.replace(/^\s*\d{3}\s*:\s*/, '').trim(); return normalized || message; }, []); // 显示 Toast const showToast = useCallback((message: string, type: ToastType) => { setToast({ message: normalizeToastMessage(message), type }); }, [normalizeToastMessage]); // 显示 Confirm const showConfirm = useCallback((config: ConfirmConfig): Promise => { return new Promise((resolve) => { setConfirmConfig(config); setConfirmResolver(() => resolve); }); }, []); // 处理确认 const handleConfirm = useCallback(() => { if (confirmResolver) { confirmResolver(true); setConfirmResolver(null); } setConfirmConfig(null); }, [confirmResolver]); // 处理取消 const handleCancel = useCallback(() => { if (confirmResolver) { confirmResolver(false); setConfirmResolver(null); } setConfirmConfig(null); }, [confirmResolver]); return ( {children} {/* Toast 组件 */} setToast(null)} /> {/* Confirm 对话框 */} ); }; // useToast Hook export const useToast = () => { const context = useContext(NotificationContext); if (!context) { throw new Error('useToast must be used within NotificationProvider'); } return { showToast: context.showToast }; }; // useConfirm Hook export const useConfirm = () => { const context = useContext(NotificationContext); if (!context) { throw new Error('useConfirm must be used within NotificationProvider'); } return { showConfirm: context.showConfirm }; };