🎉 first commit

This commit is contained in:
LIlGG
2025-09-24 13:06:25 +08:00
commit 1f4fb103e9
409 changed files with 61222 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
import type { ErrorInfo, ReactNode } from 'react';
import { Component } from 'react';
import { toast } from 'sonner';
import { logger } from '~/utils/logger';
interface Props {
children: ReactNode;
fallback?: ReactNode;
onError?: (error: Error, errorInfo: ErrorInfo) => void;
}
interface State {
hasError: boolean;
error?: Error;
}
/**
* 错误边界组件
*/
export class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error: Error): State {
// 更新状态,下次渲染时显示降级 UI
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
// 记录错误信息
logger.error('组件错误边界捕获到错误:', { error, errorInfo });
// 显示错误提示
toast.error(`组件发生错误: ${error.message}`);
// 调用可选的 onError 回调
if (this.props.onError) {
this.props.onError(error, errorInfo);
}
}
render(): ReactNode {
if (this.state.hasError) {
// 如果提供了自定义的降级 UI则使用它
if (this.props.fallback) {
return this.props.fallback;
}
// 默认的降级 UI
return (
<div className="p-4 border border-red-300 bg-red-50 rounded-md">
<h3 className="text-red-800 font-medium mb-2"></h3>
<p className="text-red-600 text-sm mb-2">{this.state.error?.message || '发生了未知错误'}</p>
<button
onClick={() => this.setState({ hasError: false })}
className="px-3 py-1 bg-red-100 text-red-800 rounded text-sm hover:bg-red-200"
>
</button>
</div>
);
}
return this.props.children;
}
}