extends Node # 响应处理器 - 统一处理API响应和错误 # 响应处理结果 class ResponseResult: var success: bool var message: String var toast_type: String # "success" 或 "error" var data: Dictionary var should_show_toast: bool var custom_action: Callable func _init(): success = false message = "" toast_type = "error" data = {} should_show_toast = true custom_action = Callable() # 错误码映射表 - 根据API v1.1.1更新 const ERROR_CODE_MESSAGES = { # 登录相关 "LOGIN_FAILED": "登录失败", "VERIFICATION_CODE_LOGIN_FAILED": "验证码错误或已过期", "EMAIL_NOT_VERIFIED": "请先验证邮箱", # 注册相关 "REGISTER_FAILED": "注册失败", # 验证码相关 "SEND_CODE_FAILED": "发送验证码失败", "SEND_LOGIN_CODE_FAILED": "发送登录验证码失败", "SEND_EMAIL_VERIFICATION_FAILED": "发送邮箱验证码失败", "RESEND_EMAIL_VERIFICATION_FAILED": "重新发送验证码失败", "EMAIL_VERIFICATION_FAILED": "邮箱验证失败", "RESET_PASSWORD_FAILED": "重置密码失败", "CHANGE_PASSWORD_FAILED": "修改密码失败", "VERIFICATION_CODE_EXPIRED": "验证码已过期", "VERIFICATION_CODE_INVALID": "验证码无效", "VERIFICATION_CODE_ATTEMPTS_EXCEEDED": "验证码尝试次数过多", "VERIFICATION_CODE_RATE_LIMITED": "验证码发送过于频繁", "VERIFICATION_CODE_HOURLY_LIMIT": "验证码每小时发送次数已达上限", # 用户状态相关 "USER_NOT_FOUND": "用户不存在", "INVALID_IDENTIFIER": "请输入有效的邮箱或手机号", "USER_STATUS_UPDATE_FAILED": "用户状态更新失败", # 系统状态相关 "TEST_MODE_ONLY": "测试模式", "TOO_MANY_REQUESTS": "请求过于频繁,请稍后再试", "SERVICE_UNAVAILABLE": "系统维护中,请稍后再试", # 权限相关 "UNAUTHORIZED": "未授权访问", "FORBIDDEN": "权限不足", "ADMIN_LOGIN_FAILED": "管理员登录失败", # 其他 "VALIDATION_FAILED": "参数验证失败", "UNSUPPORTED_MEDIA_TYPE": "不支持的请求格式", "REQUEST_TIMEOUT": "请求超时" } # HTTP状态码消息映射 - 根据API v1.1.1更新 const HTTP_STATUS_MESSAGES = { 200: "请求成功", 201: "创建成功", 206: "测试模式", 400: "请求参数错误", 401: "认证失败", 403: "权限不足", 404: "资源不存在", 408: "请求超时", 409: "资源冲突", 415: "不支持的媒体类型", 429: "请求过于频繁", 500: "服务器内部错误", 503: "服务不可用" } # ============ 主要处理方法 ============ # 处理登录响应 static func handle_login_response(success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: var result = ResponseResult.new() if success: result.success = true result.message = "登录成功!正在进入鲸鱼镇..." result.toast_type = "success" result.data = data # 自定义动作:延迟发送登录成功信号 result.custom_action = func(): await Engine.get_main_loop().create_timer(1.0).timeout # 这里可以发送登录成功信号或执行其他逻辑 else: result = _handle_login_error(data, error_info) return result # 处理验证码登录响应 static func handle_verification_code_login_response(success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: var result = ResponseResult.new() if success: result.success = true result.message = "验证码登录成功!正在进入鲸鱼镇..." result.toast_type = "success" result.data = data result.custom_action = func(): await Engine.get_main_loop().create_timer(1.0).timeout # 登录成功后的处理逻辑 else: result = _handle_verification_code_login_error(data, error_info) return result # 处理发送验证码响应 - 支持邮箱冲突检测 static func handle_send_verification_code_response(success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: var result = ResponseResult.new() if success: var error_code = data.get("error_code", "") if error_code == "TEST_MODE_ONLY": result.success = true result.message = "🧪 测试模式:验证码已生成,请查看控制台" result.toast_type = "success" # 在控制台显示验证码 if data.has("data") and data.data.has("verification_code"): print("🔑 测试模式验证码: ", data.data.verification_code) result.message += "\n验证码: " + str(data.data.verification_code) else: result.success = true result.message = "📧 验证码已发送到您的邮箱,请查收" result.toast_type = "success" # 开发环境下显示验证码 if data.has("data") and data.data.has("verification_code"): print("🔑 开发环境验证码: ", data.data.verification_code) else: result = _handle_send_code_error(data, error_info) return result # 处理发送登录验证码响应 static func handle_send_login_code_response(success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: var result = ResponseResult.new() if success: var error_code = data.get("error_code", "") if error_code == "TEST_MODE_ONLY": result.success = true result.message = "测试模式:登录验证码已生成,请查看控制台" result.toast_type = "success" if data.has("data") and data.data.has("verification_code"): print("测试模式登录验证码: ", data.data.verification_code) else: result.success = true result.message = "登录验证码已发送,请查收" result.toast_type = "success" if data.has("data") and data.data.has("verification_code"): print("开发环境登录验证码: ", data.data.verification_code) else: result = _handle_send_login_code_error(data, error_info) return result # 处理注册响应 static func handle_register_response(success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: var result = ResponseResult.new() if success: result.success = true result.message = "注册成功!欢迎加入鲸鱼镇" result.toast_type = "success" result.data = data # 自定义动作:清空表单,切换到登录界面 result.custom_action = func(): # 这里可以执行清空表单、切换界面等操作 pass else: result = _handle_register_error(data, error_info) return result # 处理邮箱验证响应 static func handle_verify_email_response(success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: var result = ResponseResult.new() if success: result.success = true result.message = "邮箱验证成功,正在注册..." result.toast_type = "success" result.data = data else: result = _handle_verify_email_error(data, error_info) return result # 处理重新发送邮箱验证码响应 static func handle_resend_email_verification_response(success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: var result = ResponseResult.new() if success: var error_code = data.get("error_code", "") if error_code == "TEST_MODE_ONLY": result.success = true result.message = "🧪 测试模式:验证码已重新生成,请查看控制台" result.toast_type = "success" if data.has("data") and data.data.has("verification_code"): print("🔑 测试模式重新发送验证码: ", data.data.verification_code) else: result.success = true result.message = "📧 验证码已重新发送到您的邮箱,请查收" result.toast_type = "success" if data.has("data") and data.data.has("verification_code"): print("🔑 开发环境重新发送验证码: ", data.data.verification_code) else: result = _handle_resend_email_verification_error(data, error_info) return result # 处理忘记密码响应 static func handle_forgot_password_response(success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: var result = ResponseResult.new() if success: var error_code = data.get("error_code", "") if error_code == "TEST_MODE_ONLY": result.success = true result.message = "🧪 测试模式:重置验证码已生成,请查看控制台" result.toast_type = "success" if data.has("data") and data.data.has("verification_code"): print("🔑 测试模式重置验证码: ", data.data.verification_code) else: result.success = true result.message = "📧 重置验证码已发送,请查收" result.toast_type = "success" if data.has("data") and data.data.has("verification_code"): print("🔑 开发环境重置验证码: ", data.data.verification_code) else: result = _handle_forgot_password_error(data, error_info) return result # 处理重置密码响应 static func handle_reset_password_response(success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: var result = ResponseResult.new() if success: result.success = true result.message = "🔒 密码重置成功,请使用新密码登录" result.toast_type = "success" result.data = data else: result = _handle_reset_password_error(data, error_info) return result # ============ 错误处理方法 ============ # 处理登录错误 static func _handle_login_error(data: Dictionary, error_info: Dictionary) -> ResponseResult: var result = ResponseResult.new() var error_code = data.get("error_code", "") var message = data.get("message", "登录失败") match error_code: "LOGIN_FAILED": # 根据消息内容进一步判断用户状态 if "账户已锁定" in message or "locked" in message.to_lower(): result.message = "账户已被锁定,请联系管理员" elif "账户已禁用" in message or "banned" in message.to_lower(): result.message = "账户已被禁用,请联系管理员" elif "账户待审核" in message or "pending" in message.to_lower(): result.message = "账户待审核,请等待管理员审核" elif "邮箱未验证" in message or "inactive" in message.to_lower(): result.message = "请先验证邮箱后再登录" else: result.message = "用户名或密码错误,请检查后重试" _: result.message = _get_error_message(error_code, message, error_info) return result # 处理验证码登录错误 static func _handle_verification_code_login_error(data: Dictionary, error_info: Dictionary) -> ResponseResult: var result = ResponseResult.new() var error_code = data.get("error_code", "") var message = data.get("message", "验证码登录失败") match error_code: "VERIFICATION_CODE_LOGIN_FAILED": result.message = "验证码错误或已过期" "EMAIL_NOT_VERIFIED": result.message = "邮箱未验证,请先验证邮箱后再使用验证码登录" "USER_NOT_FOUND": result.message = "用户不存在,请先注册" "INVALID_IDENTIFIER": result.message = "请输入有效的邮箱或手机号" _: result.message = _get_error_message(error_code, message, error_info) return result # 处理发送验证码错误 - 支持邮箱冲突检测和频率限制 static func _handle_send_code_error(data: Dictionary, error_info: Dictionary) -> ResponseResult: var result = ResponseResult.new() var error_code = data.get("error_code", "") var message = data.get("message", "发送验证码失败") var response_code = error_info.get("response_code", 0) match error_code: "SEND_EMAIL_VERIFICATION_FAILED": # 检查是否是邮箱冲突(409状态码) if response_code == 409: result.message = "⚠️ 邮箱已被注册,请使用其他邮箱或直接登录" result.toast_type = "error" elif "邮箱格式" in message: result.message = "📧 请输入有效的邮箱地址" else: result.message = message "TOO_MANY_REQUESTS": # 处理频率限制,提供重试建议 result.toast_type = "error" # 如果有throttle_info,显示更详细的信息 if data.has("throttle_info"): var throttle_info = data.throttle_info var reset_time = throttle_info.get("reset_time", "") if reset_time != "": var relative_time = StringUtils.get_relative_time_until(reset_time) var local_time = StringUtils.format_utc_to_local_time(reset_time) result.message = "⏰ 验证码发送过于频繁" result.message += "\n请" + relative_time + "再试" result.message += "\n重试时间: " + local_time else: result.message = "⏰ 验证码发送过于频繁,请稍后再试" else: result.message = "⏰ 验证码发送过于频繁,请稍后再试" "VERIFICATION_CODE_RATE_LIMITED": result.message = "⏰ 验证码发送过于频繁,请稍后再试" "VERIFICATION_CODE_HOURLY_LIMIT": result.message = "⏰ 每小时发送次数已达上限,请稍后再试" _: result.message = _get_error_message(error_code, message, error_info) return result # 处理发送登录验证码错误 static func _handle_send_login_code_error(data: Dictionary, error_info: Dictionary) -> ResponseResult: var result = ResponseResult.new() var error_code = data.get("error_code", "") var message = data.get("message", "发送登录验证码失败") match error_code: "SEND_LOGIN_CODE_FAILED": if "用户不存在" in message: result.message = "用户不存在,请先注册" else: result.message = "发送登录验证码失败" "USER_NOT_FOUND": result.message = "用户不存在,请先注册" "INVALID_IDENTIFIER": result.message = "请输入有效的邮箱或手机号" _: result.message = _get_error_message(error_code, message, error_info) return result # 处理注册错误 - 支持409冲突状态码 static func _handle_register_error(data: Dictionary, error_info: Dictionary) -> ResponseResult: var result = ResponseResult.new() var error_code = data.get("error_code", "") var message = data.get("message", "注册失败") var response_code = error_info.get("response_code", 0) match error_code: "REGISTER_FAILED": # 检查409冲突状态码 if response_code == 409: if "邮箱已存在" in message or "邮箱已被使用" in message: result.message = "📧 邮箱已被注册,请使用其他邮箱或直接登录" elif "用户名已存在" in message or "用户名已被使用" in message: result.message = "👤 用户名已被使用,请换一个" else: result.message = "⚠️ 资源冲突:" + message elif "邮箱验证码" in message or "verification_code" in message: result.message = "🔑 请先获取并输入邮箱验证码" elif "用户名" in message: result.message = "👤 用户名格式不正确" elif "邮箱" in message: result.message = "📧 邮箱格式不正确" elif "密码" in message: result.message = "🔒 密码格式不符合要求" elif "验证码" in message: result.message = "🔑 验证码错误或已过期" else: result.message = message _: result.message = _get_error_message(error_code, message, error_info) return result # 处理邮箱验证错误 static func _handle_verify_email_error(data: Dictionary, error_info: Dictionary) -> ResponseResult: var result = ResponseResult.new() var error_code = data.get("error_code", "") var message = data.get("message", "邮箱验证失败") match error_code: "EMAIL_VERIFICATION_FAILED": if "验证码错误" in message: result.message = "🔑 验证码错误" elif "验证码已过期" in message: result.message = "🔑 验证码已过期,请重新获取" else: result.message = message "VERIFICATION_CODE_INVALID": result.message = "🔑 验证码错误或已过期" "VERIFICATION_CODE_EXPIRED": result.message = "🔑 验证码已过期,请重新获取" _: result.message = _get_error_message(error_code, message, error_info) return result # 处理网络测试响应 static func handle_network_test_response(success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: var result = ResponseResult.new() if success: result.success = true result.message = "🌐 网络连接正常" result.toast_type = "success" else: result.success = false result.message = "🌐 网络连接异常" result.toast_type = "error" return result # 处理重新发送邮箱验证码错误 static func _handle_resend_email_verification_error(data: Dictionary, error_info: Dictionary) -> ResponseResult: var result = ResponseResult.new() var error_code = data.get("error_code", "") var message = data.get("message", "重新发送验证码失败") match error_code: "RESEND_EMAIL_VERIFICATION_FAILED": if "邮箱已验证" in message: result.message = "📧 邮箱已验证,无需重复验证" else: result.message = message _: result.message = _get_error_message(error_code, message, error_info) return result # 处理忘记密码错误 static func _handle_forgot_password_error(data: Dictionary, error_info: Dictionary) -> ResponseResult: var result = ResponseResult.new() var error_code = data.get("error_code", "") var message = data.get("message", "发送重置验证码失败") match error_code: "SEND_CODE_FAILED": if "用户不存在" in message: result.message = "👤 用户不存在,请检查邮箱或手机号" else: result.message = message "USER_NOT_FOUND": result.message = "👤 用户不存在,请检查邮箱或手机号" _: result.message = _get_error_message(error_code, message, error_info) return result # 处理重置密码错误 static func _handle_reset_password_error(data: Dictionary, error_info: Dictionary) -> ResponseResult: var result = ResponseResult.new() var error_code = data.get("error_code", "") var message = data.get("message", "重置密码失败") match error_code: "RESET_PASSWORD_FAILED": if "验证码" in message: result.message = "🔑 验证码错误或已过期" else: result.message = message _: result.message = _get_error_message(error_code, message, error_info) return result # ============ 工具方法 ============ # 获取错误消息 - 支持更多状态码和错误处理 static func _get_error_message(error_code: String, original_message: String, error_info: Dictionary) -> String: # 优先使用错误码映射 if ERROR_CODE_MESSAGES.has(error_code): return ERROR_CODE_MESSAGES[error_code] # 处理频率限制 if error_code == "TOO_MANY_REQUESTS": return _handle_rate_limit_message(original_message, error_info) # 处理维护模式 if error_code == "SERVICE_UNAVAILABLE": return _handle_maintenance_message(original_message, error_info) # 处理测试模式 if error_code == "TEST_MODE_ONLY": return "🧪 测试模式:" + original_message # 根据HTTP状态码处理 if error_info.has("response_code"): var response_code = error_info.response_code match response_code: 409: return "⚠️ 资源冲突:" + original_message 206: return "🧪 测试模式:" + original_message 429: return "⏰ 请求过于频繁,请稍后再试" _: if HTTP_STATUS_MESSAGES.has(response_code): return HTTP_STATUS_MESSAGES[response_code] + ":" + original_message # 返回原始消息 return original_message if original_message != "" else "操作失败" # 处理频率限制消息 static func _handle_rate_limit_message(message: String, error_info: Dictionary) -> String: # 可以根据throttle_info提供更详细的信息 return message + ",请稍后再试" # 处理维护模式消息 static func _handle_maintenance_message(message: String, error_info: Dictionary) -> String: # 可以根据maintenance_info提供更详细的信息 return "系统维护中,请稍后再试" # 通用响应处理器 - 支持更多操作类型 static func handle_response(operation_type: String, success: bool, data: Dictionary, error_info: Dictionary = {}) -> ResponseResult: match operation_type: "login": return handle_login_response(success, data, error_info) "verification_code_login": return handle_verification_code_login_response(success, data, error_info) "send_code": return handle_send_verification_code_response(success, data, error_info) "send_login_code": return handle_send_login_code_response(success, data, error_info) "register": return handle_register_response(success, data, error_info) "verify_email": return handle_verify_email_response(success, data, error_info) "resend_email_verification": return handle_resend_email_verification_response(success, data, error_info) "forgot_password": return handle_forgot_password_response(success, data, error_info) "reset_password": return handle_reset_password_response(success, data, error_info) "network_test": return handle_network_test_response(success, data, error_info) _: # 通用处理 var result = ResponseResult.new() if success: result.success = true result.message = "✅ 操作成功" result.toast_type = "success" else: result.success = false result.message = _get_error_message(data.get("error_code", ""), data.get("message", "操作失败"), error_info) result.toast_type = "error" return result