feat(pages): 添加管理页面功能和配置
- 创建 .editorconfig 文件统一代码风格配置 - 配置 .eslintrc 使用 taro/react 规则集 - 完善 .gitignore 忽略编译产物和敏感文件 - 添加 admin/article/add 页面实现文章管理功能 - 添加 dealer/apply/add 页面实现经销商申请功能 - 添加 dealer/bank/add 页面实现银行卡管理功能 - 添加 dealer/customer/add 页面实现客户管理功能 - 添加 user/address/add 页面实现用户地址管理功能 - 添加 user/chat/message/add 页面实现消息功能 - 添加 user/gift/add 页面实现礼品管理功能 - 配置各页面导航栏标题和样式 - 实现表单验证和数据提交功能 - 集成图片上传和头像选择功能 - 添加日期选择和数据校验逻辑 - 实现编辑和新增模式切换 - 集成用户权限和角色管理功能
This commit is contained in:
302
src/utils/errorHandler.ts
Normal file
302
src/utils/errorHandler.ts
Normal file
@@ -0,0 +1,302 @@
|
||||
import Taro from '@tarojs/taro';
|
||||
|
||||
// 定义本地的RequestError类,避免循环依赖
|
||||
export class RequestError extends Error {
|
||||
public type: string;
|
||||
public code?: number;
|
||||
public data?: any;
|
||||
|
||||
constructor(message: string, type: string, code?: number, data?: any) {
|
||||
super(message);
|
||||
this.name = 'RequestError';
|
||||
this.type = type;
|
||||
this.code = code;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
// 错误类型枚举
|
||||
export enum ErrorType {
|
||||
NETWORK_ERROR = 'NETWORK_ERROR',
|
||||
TIMEOUT_ERROR = 'TIMEOUT_ERROR',
|
||||
BUSINESS_ERROR = 'BUSINESS_ERROR',
|
||||
AUTH_ERROR = 'AUTH_ERROR',
|
||||
UNKNOWN_ERROR = 'UNKNOWN_ERROR'
|
||||
}
|
||||
|
||||
// 错误级别枚举
|
||||
export enum ErrorLevel {
|
||||
INFO = 'info',
|
||||
WARNING = 'warning',
|
||||
ERROR = 'error',
|
||||
FATAL = 'fatal'
|
||||
}
|
||||
|
||||
// 错误信息接口
|
||||
export interface ErrorInfo {
|
||||
message: string;
|
||||
level: ErrorLevel;
|
||||
type: string;
|
||||
stack?: string;
|
||||
extra?: any;
|
||||
timestamp: number;
|
||||
userId?: string;
|
||||
page?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局错误处理器
|
||||
*/
|
||||
class GlobalErrorHandler {
|
||||
private static instance: GlobalErrorHandler;
|
||||
private errorQueue: ErrorInfo[] = [];
|
||||
private maxQueueSize = 50;
|
||||
|
||||
private constructor() {
|
||||
this.setupGlobalErrorHandlers();
|
||||
}
|
||||
|
||||
public static getInstance(): GlobalErrorHandler {
|
||||
if (!GlobalErrorHandler.instance) {
|
||||
GlobalErrorHandler.instance = new GlobalErrorHandler();
|
||||
}
|
||||
return GlobalErrorHandler.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局错误处理器
|
||||
*/
|
||||
private setupGlobalErrorHandlers() {
|
||||
// 捕获未处理的Promise rejection
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('unhandledrejection', (event) => {
|
||||
this.handleError(event.reason, ErrorLevel.ERROR, 'UnhandledPromiseRejection');
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理错误
|
||||
*/
|
||||
public handleError(
|
||||
error: any,
|
||||
level: ErrorLevel = ErrorLevel.ERROR,
|
||||
type: string = 'Unknown',
|
||||
extra?: any
|
||||
) {
|
||||
const errorInfo = this.createErrorInfo(error, level, type, extra);
|
||||
|
||||
// 添加到错误队列
|
||||
this.addToQueue(errorInfo);
|
||||
|
||||
// 根据错误级别决定处理方式
|
||||
switch (level) {
|
||||
case ErrorLevel.FATAL:
|
||||
this.handleFatalError(errorInfo);
|
||||
break;
|
||||
case ErrorLevel.ERROR:
|
||||
this.handleNormalError(errorInfo);
|
||||
break;
|
||||
case ErrorLevel.WARNING:
|
||||
this.handleWarning(errorInfo);
|
||||
break;
|
||||
case ErrorLevel.INFO:
|
||||
this.handleInfo(errorInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
// 上报错误
|
||||
this.reportError(errorInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建错误信息对象
|
||||
*/
|
||||
private createErrorInfo(
|
||||
error: any,
|
||||
level: ErrorLevel,
|
||||
type: string,
|
||||
extra?: any
|
||||
): ErrorInfo {
|
||||
let message = '未知错误';
|
||||
let stack: string | undefined;
|
||||
|
||||
if (error instanceof Error) {
|
||||
message = error.message;
|
||||
stack = error.stack;
|
||||
} else if (error instanceof RequestError) {
|
||||
message = error.message;
|
||||
type = error.type;
|
||||
extra = { ...extra, code: error.code, data: error.data };
|
||||
} else if (typeof error === 'string') {
|
||||
message = error;
|
||||
} else if (error && typeof error === 'object') {
|
||||
message = error.message || error.errMsg || JSON.stringify(error);
|
||||
}
|
||||
|
||||
return {
|
||||
message,
|
||||
level,
|
||||
type,
|
||||
stack,
|
||||
extra,
|
||||
timestamp: Date.now(),
|
||||
userId: Taro.getStorageSync('UserId') || undefined,
|
||||
page: this.getCurrentPage()
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前页面路径
|
||||
*/
|
||||
private getCurrentPage(): string {
|
||||
try {
|
||||
const pages = Taro.getCurrentPages();
|
||||
const currentPage = pages[pages.length - 1];
|
||||
return currentPage?.route || 'unknown';
|
||||
} catch {
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加到错误队列
|
||||
*/
|
||||
private addToQueue(errorInfo: ErrorInfo) {
|
||||
this.errorQueue.push(errorInfo);
|
||||
|
||||
// 保持队列大小
|
||||
if (this.errorQueue.length > this.maxQueueSize) {
|
||||
this.errorQueue.shift();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理致命错误
|
||||
*/
|
||||
private handleFatalError(errorInfo: ErrorInfo) {
|
||||
console.error('Fatal Error:', errorInfo);
|
||||
|
||||
Taro.showModal({
|
||||
title: '严重错误',
|
||||
content: '应用遇到严重错误,需要重启',
|
||||
showCancel: false,
|
||||
confirmText: '重启应用',
|
||||
success: () => {
|
||||
Taro.reLaunch({ url: '/pages/index/index' });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理普通错误
|
||||
*/
|
||||
private handleNormalError(errorInfo: ErrorInfo) {
|
||||
console.error('Error:', errorInfo);
|
||||
|
||||
// 根据错误类型显示不同的提示
|
||||
let title = '操作失败';
|
||||
|
||||
if (errorInfo.type === ErrorType.NETWORK_ERROR) {
|
||||
title = '网络连接失败';
|
||||
} else if (errorInfo.type === ErrorType.TIMEOUT_ERROR) {
|
||||
title = '请求超时';
|
||||
} else if (errorInfo.type === ErrorType.AUTH_ERROR) {
|
||||
title = '认证失败';
|
||||
}
|
||||
|
||||
Taro.showToast({
|
||||
title: errorInfo.message || title,
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理警告
|
||||
*/
|
||||
private handleWarning(errorInfo: ErrorInfo) {
|
||||
console.warn('Warning:', errorInfo);
|
||||
|
||||
// 警告通常不需要用户交互,只记录日志
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理信息
|
||||
*/
|
||||
private handleInfo(errorInfo: ErrorInfo) {
|
||||
console.info('Info:', errorInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上报错误到服务器
|
||||
*/
|
||||
private reportError(errorInfo: ErrorInfo) {
|
||||
try {
|
||||
// 这里可以实现错误上报逻辑
|
||||
// 例如发送到后端日志系统、第三方监控服务等
|
||||
|
||||
// 示例:发送到后端
|
||||
// request.post('/api/error/report', errorInfo).catch(() => {
|
||||
// // 上报失败也不要影响用户体验
|
||||
// });
|
||||
|
||||
// 开发环境下打印详细信息
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.group('🚨 Error Report');
|
||||
console.log('Message:', errorInfo.message);
|
||||
console.log('Level:', errorInfo.level);
|
||||
console.log('Type:', errorInfo.type);
|
||||
console.log('Page:', errorInfo.page);
|
||||
console.log('UserId:', errorInfo.userId);
|
||||
console.log('Timestamp:', new Date(errorInfo.timestamp).toLocaleString());
|
||||
if (errorInfo.stack) {
|
||||
console.log('Stack:', errorInfo.stack);
|
||||
}
|
||||
if (errorInfo.extra) {
|
||||
console.log('Extra:', errorInfo.extra);
|
||||
}
|
||||
console.groupEnd();
|
||||
}
|
||||
} catch (reportError) {
|
||||
console.error('Failed to report error:', reportError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取错误队列
|
||||
*/
|
||||
public getErrorQueue(): ErrorInfo[] {
|
||||
return [...this.errorQueue];
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空错误队列
|
||||
*/
|
||||
public clearErrorQueue() {
|
||||
this.errorQueue = [];
|
||||
}
|
||||
}
|
||||
|
||||
// 导出单例实例
|
||||
export const errorHandler = GlobalErrorHandler.getInstance();
|
||||
|
||||
// 便捷方法
|
||||
export const handleError = (error: any, level?: ErrorLevel, type?: string, extra?: any) => {
|
||||
errorHandler.handleError(error, level, type, extra);
|
||||
};
|
||||
|
||||
export const handleFatalError = (error: any, extra?: any) => {
|
||||
errorHandler.handleError(error, ErrorLevel.FATAL, 'FatalError', extra);
|
||||
};
|
||||
|
||||
export const handleWarning = (error: any, extra?: any) => {
|
||||
errorHandler.handleError(error, ErrorLevel.WARNING, 'Warning', extra);
|
||||
};
|
||||
|
||||
export const handleInfo = (message: string, extra?: any) => {
|
||||
errorHandler.handleError(message, ErrorLevel.INFO, 'Info', extra);
|
||||
};
|
||||
|
||||
export default errorHandler;
|
||||
Reference in New Issue
Block a user