class_name AuthManager # ============================================================================ # AuthManager.gd - 认证管理器 # ============================================================================ # 认证系统的业务逻辑管理器,负责处理所有认证相关的业务逻辑 # # 核心职责: # - 用户登录业务逻辑(密码登录 + 验证码登录) # - 用户注册业务逻辑 # - 表单验证逻辑 # - 验证码管理逻辑 # - 网络请求管理 # - 响应处理和状态管理 # # 使用方式: # var auth_manager = AuthManager.new() # auth_manager.login_success.connect(_on_login_success) # auth_manager.execute_password_login(username, password) # # 注意事项: # - 这是业务逻辑层,不包含任何UI相关代码 # - 通过信号与UI层通信 # - 所有验证逻辑都在这里实现 # ============================================================================ extends RefCounted # ============ 信号定义 ============ # 登录成功信号 signal login_success(username: String, token: String) # 登录失败信号 signal login_failed(message: String) # 注册成功信号 signal register_success(message: String) # 注册失败信号 signal register_failed(message: String) # 验证码发送成功信号 signal verification_code_sent(message: String) # 验证码发送失败信号 signal verification_code_failed(message: String) # 表单验证失败信号 signal form_validation_failed(field: String, message: String) # 网络状态变化信号 signal network_status_changed(is_connected: bool, message: String) # 按钮状态变化信号 signal button_state_changed(button_name: String, is_loading: bool, text: String) # Toast消息信号 signal show_toast_message(message: String, is_success: bool) # ============ 枚举定义 ============ # 登录模式枚举 enum LoginMode { PASSWORD, # 密码登录模式 VERIFICATION # 验证码登录模式 } # ============ 成员变量 ============ # 登录状态 var current_login_mode: LoginMode = LoginMode.PASSWORD var is_processing: bool = false # 验证码管理 var verification_codes_sent: Dictionary = {} var code_cooldown: float = 60.0 var current_email: String = "" # 网络请求管理 var active_request_ids: Array = [] # 当前登录用户ID (静态变量,全局访问) static var current_user_id: String = "" # ============ 生命周期方法 ============ # 初始化管理器 func _init(): print("AuthManager 初始化完成") # 清理资源 func cleanup(): # 取消所有活动的网络请求 for request_id in active_request_ids: NetworkManager.cancel_request(request_id) active_request_ids.clear() # ============ 登录相关方法 ============ # 执行密码登录 # # 参数: # username: String - 用户名/邮箱 # password: String - 密码 # # 功能: # - 验证输入参数 # - 发送登录请求 # - 处理响应结果 func execute_password_login(username: String, password: String): if is_processing: show_toast_message.emit("请等待当前操作完成", false) return # 验证输入 var validation_result = validate_login_inputs(username, password) if not validation_result.valid: form_validation_failed.emit(validation_result.field, validation_result.message) return # 设置处理状态 is_processing = true button_state_changed.emit("main_btn", true, "登录中...") show_toast_message.emit("正在验证登录信息...", true) # 发送网络请求 var request_id = NetworkManager.login(username, password, _on_login_response) if request_id != "": active_request_ids.append(request_id) else: _reset_login_state() show_toast_message.emit("网络请求失败", false) # 执行验证码登录 # # 参数: # identifier: String - 用户标识符 # verification_code: String - 验证码 func execute_verification_login(identifier: String, verification_code: String): if is_processing: show_toast_message.emit("请等待当前操作完成", false) return # 验证输入 if identifier.is_empty(): form_validation_failed.emit("username", "请输入用户名/手机/邮箱") return if verification_code.is_empty(): form_validation_failed.emit("verification", "请输入验证码") return # 设置处理状态 is_processing = true button_state_changed.emit("main_btn", true, "登录中...") show_toast_message.emit("正在验证验证码...", true) # 发送网络请求 var request_id = NetworkManager.verification_code_login(identifier, verification_code, _on_verification_login_response) if request_id != "": active_request_ids.append(request_id) else: _reset_login_state() show_toast_message.emit("网络请求失败", false) # 切换登录模式 func toggle_login_mode(): if current_login_mode == LoginMode.PASSWORD: current_login_mode = LoginMode.VERIFICATION else: current_login_mode = LoginMode.PASSWORD # 获取当前登录模式 func get_current_login_mode() -> LoginMode: return current_login_mode # ============ 注册相关方法 ============ # 执行用户注册 # # 参数: # username: String - 用户名 # email: String - 邮箱 # password: String - 密码 # confirm_password: String - 确认密码 # verification_code: String - 邮箱验证码 func execute_register(username: String, email: String, password: String, confirm_password: String, verification_code: String): if is_processing: show_toast_message.emit("请等待当前操作完成", false) return # 验证注册表单 var validation_result = validate_register_form(username, email, password, confirm_password, verification_code) if not validation_result.valid: form_validation_failed.emit(validation_result.field, validation_result.message) return # 设置处理状态 is_processing = true button_state_changed.emit("register_btn", true, "注册中...") show_toast_message.emit("正在创建账户...", true) # 发送注册请求 var request_id = NetworkManager.register(username, password, username, email, verification_code, _on_register_response) if request_id != "": active_request_ids.append(request_id) else: _reset_register_state() show_toast_message.emit("网络请求失败", false) # ============ 验证码相关方法 ============ # 发送邮箱验证码 # # 参数: # email: String - 邮箱地址 func send_email_verification_code(email: String): # 验证邮箱格式 var email_validation = validate_email(email) if not email_validation.valid: form_validation_failed.emit("email", email_validation.message) return # 检查冷却时间 if not _can_send_verification_code(email): var remaining = get_remaining_cooldown_time(email) show_toast_message.emit("该邮箱请等待 %d 秒后再次发送" % remaining, false) return # 记录发送状态 _record_verification_code_sent(email) # 发送请求 var request_id = NetworkManager.send_email_verification(email, _on_send_code_response) if request_id != "": active_request_ids.append(request_id) else: _reset_verification_code_state(email) show_toast_message.emit("网络请求失败", false) # 发送登录验证码 # # 参数: # identifier: String - 用户标识符 func send_login_verification_code(identifier: String): if identifier.is_empty(): form_validation_failed.emit("username", "请先输入用户名/手机/邮箱") return button_state_changed.emit("get_code_btn", true, "发送中...") show_toast_message.emit("正在发送登录验证码...", true) var request_id = NetworkManager.send_login_verification_code(identifier, _on_send_login_code_response) if request_id != "": active_request_ids.append(request_id) else: button_state_changed.emit("get_code_btn", false, "获取验证码") show_toast_message.emit("网络请求失败", false) # 发送密码重置验证码 # # 参数: # identifier: String - 用户标识符 func send_password_reset_code(identifier: String): if identifier.is_empty(): show_toast_message.emit("请先输入邮箱或手机号", false) return if not _is_valid_identifier(identifier): show_toast_message.emit("请输入有效的邮箱或手机号", false) return button_state_changed.emit("forgot_password_btn", true, "发送中...") show_toast_message.emit("正在发送密码重置验证码...", true) var request_id = NetworkManager.forgot_password(identifier, _on_forgot_password_response) if request_id != "": active_request_ids.append(request_id) else: button_state_changed.emit("forgot_password_btn", false, "忘记密码") show_toast_message.emit("网络请求失败", false) # ============ 验证方法 ============ # 验证登录输入 func validate_login_inputs(username: String, password: String) -> Dictionary: var result = {"valid": false, "field": "", "message": ""} if username.is_empty(): result.field = "username" result.message = "用户名不能为空" return result if password.is_empty(): result.field = "password" result.message = "密码不能为空" return result result.valid = true return result # 验证注册表单 func validate_register_form(username: String, email: String, password: String, confirm_password: String, verification_code: String) -> Dictionary: var result = {"valid": false, "field": "", "message": ""} # 验证用户名 var username_validation = validate_username(username) if not username_validation.valid: result.field = "username" result.message = username_validation.message return result # 验证邮箱 var email_validation = validate_email(email) if not email_validation.valid: result.field = "email" result.message = email_validation.message return result # 验证密码 var password_validation = validate_password(password) if not password_validation.valid: result.field = "password" result.message = password_validation.message return result # 验证确认密码 var confirm_validation = validate_confirm_password(password, confirm_password) if not confirm_validation.valid: result.field = "confirm" result.message = confirm_validation.message return result # 验证验证码 var code_validation = validate_verification_code(verification_code) if not code_validation.valid: result.field = "verification" result.message = code_validation.message return result # 检查是否已发送验证码 if not _has_sent_verification_code(email): result.field = "verification" result.message = "请先获取邮箱验证码" return result result.valid = true return result # 验证用户名 func validate_username(username: String) -> Dictionary: var result = {"valid": false, "message": ""} if username.is_empty(): result.message = "用户名不能为空" return result if not StringUtils.is_valid_username(username): if username.length() > 50: result.message = "用户名长度不能超过50字符" else: result.message = "用户名只能包含字母、数字和下划线" return result result.valid = true return result # 验证邮箱 func validate_email(email: String) -> Dictionary: var result = {"valid": false, "message": ""} if email.is_empty(): result.message = "邮箱不能为空" return result if not StringUtils.is_valid_email(email): result.message = "请输入有效的邮箱地址" return result result.valid = true return result # 验证密码 func validate_password(password: String) -> Dictionary: return StringUtils.validate_password_strength(password) # 验证确认密码 func validate_confirm_password(password: String, confirm: String) -> Dictionary: var result = {"valid": false, "message": ""} if confirm.is_empty(): result.message = "确认密码不能为空" return result if password != confirm: result.message = "两次输入的密码不一致" return result result.valid = true return result # 验证验证码 func validate_verification_code(code: String) -> Dictionary: var result = {"valid": false, "message": ""} if code.is_empty(): result.message = "验证码不能为空" return result if code.length() != 6: result.message = "验证码必须是6位数字" return result for i in range(code.length()): var character = code[i] if not (character >= '0' and character <= '9'): result.message = "验证码必须是6位数字" return result result.valid = true return result # ============ 网络响应处理 ============ # 处理登录响应 func _on_login_response(success: bool, data: Dictionary, error_info: Dictionary): _reset_login_state() var result = ResponseHandler.handle_login_response(success, data, error_info) if result.should_show_toast: show_toast_message.emit(result.message, result.success) if result.success: var username = "" if data.has("data") and data.data.has("user"): var user_data = data.data.user if user_data.has("username"): username = user_data.username if user_data.has("id"): current_user_id = user_data.id print("AuthManager: Current User ID set to ", current_user_id) # 延迟发送登录成功信号 await Engine.get_main_loop().create_timer(1.0).timeout var token = "" if data.has("data") and data.data.has("access_token"): token = data.data.access_token login_success.emit(username, token) else: login_failed.emit(result.message) # 处理验证码登录响应 func _on_verification_login_response(success: bool, data: Dictionary, error_info: Dictionary): _reset_login_state() var result = ResponseHandler.handle_verification_code_login_response(success, data, error_info) if result.should_show_toast: show_toast_message.emit(result.message, result.success) if result.success: var username = "" if data.has("data") and data.data.has("user"): var user_data = data.data.user if user_data.has("username"): username = user_data.username if user_data.has("id"): current_user_id = user_data.id print("AuthManager: Current User ID set to ", current_user_id) await Engine.get_main_loop().create_timer(1.0).timeout login_success.emit(username, data.get("access_token", "")) else: login_failed.emit(result.message) # 处理注册响应 func _on_register_response(success: bool, data: Dictionary, error_info: Dictionary): _reset_register_state() var result = ResponseHandler.handle_register_response(success, data, error_info) if result.should_show_toast: show_toast_message.emit(result.message, result.success) if result.success: register_success.emit(result.message) else: register_failed.emit(result.message) # 处理发送验证码响应 func _on_send_code_response(success: bool, data: Dictionary, error_info: Dictionary): var result = ResponseHandler.handle_send_verification_code_response(success, data, error_info) if result.should_show_toast: show_toast_message.emit(result.message, result.success) if result.success: verification_code_sent.emit(result.message) else: verification_code_failed.emit(result.message) _reset_verification_code_state(current_email) # 处理发送登录验证码响应 func _on_send_login_code_response(success: bool, data: Dictionary, error_info: Dictionary): button_state_changed.emit("get_code_btn", false, "获取验证码") var result = ResponseHandler.handle_send_login_code_response(success, data, error_info) if result.should_show_toast: show_toast_message.emit(result.message, result.success) # 处理忘记密码响应 func _on_forgot_password_response(success: bool, data: Dictionary, error_info: Dictionary): button_state_changed.emit("forgot_password_btn", false, "忘记密码") var result = ResponseHandler.handle_send_login_code_response(success, data, error_info) if result.should_show_toast: show_toast_message.emit(result.message, result.success) # ============ 网络测试 ============ # 测试网络连接 func test_network_connection(): var request_id = NetworkManager.get_app_status(_on_network_test_response) if request_id != "": active_request_ids.append(request_id) # 处理网络测试响应 func _on_network_test_response(success: bool, data: Dictionary, error_info: Dictionary): var result = ResponseHandler.handle_network_test_response(success, data, error_info) network_status_changed.emit(result.success, result.message) # ============ 私有辅助方法 ============ # 重置登录状态 func _reset_login_state(): is_processing = false button_state_changed.emit("main_btn", false, "进入小镇") # 重置注册状态 func _reset_register_state(): is_processing = false button_state_changed.emit("register_btn", false, "注册") # 检查是否可以发送验证码 func _can_send_verification_code(email: String) -> bool: if not verification_codes_sent.has(email): return true var email_data = verification_codes_sent[email] if not email_data.sent: return true var current_time = Time.get_time_dict_from_system() var current_timestamp = current_time.hour * 3600 + current_time.minute * 60 + current_time.second return (current_timestamp - email_data.time) >= code_cooldown # 获取剩余冷却时间 func get_remaining_cooldown_time(email: String) -> int: if not verification_codes_sent.has(email): return 0 var email_data = verification_codes_sent[email] var current_time = Time.get_time_dict_from_system() var current_timestamp = current_time.hour * 3600 + current_time.minute * 60 + current_time.second return int(code_cooldown - (current_timestamp - email_data.time)) # 记录验证码发送状态 func _record_verification_code_sent(email: String): var current_time = Time.get_time_dict_from_system() var current_timestamp = current_time.hour * 3600 + current_time.minute * 60 + current_time.second if not verification_codes_sent.has(email): verification_codes_sent[email] = {} verification_codes_sent[email].sent = true verification_codes_sent[email].time = current_timestamp current_email = email # 重置验证码状态 func _reset_verification_code_state(email: String): if verification_codes_sent.has(email): verification_codes_sent[email].sent = false # 检查是否已发送验证码 func _has_sent_verification_code(email: String) -> bool: if not verification_codes_sent.has(email): return false return verification_codes_sent[email].get("sent", false) # 验证标识符格式 func _is_valid_identifier(identifier: String) -> bool: return StringUtils.is_valid_email(identifier) or _is_valid_phone(identifier) # 验证手机号格式 func _is_valid_phone(phone: String) -> bool: var regex = RegEx.new() regex.compile("^\\+?[1-9]\\d{1,14}$") return regex.search(phone) != null