feat: add taskbook onboarding UI
This commit is contained in:
128
_Core/managers/TaskManager.gd
Normal file
128
_Core/managers/TaskManager.gd
Normal file
@@ -0,0 +1,128 @@
|
||||
extends Node
|
||||
|
||||
# 玩家任务书状态与后端任务接口的唯一入口。
|
||||
signal board_changed(board: Dictionary)
|
||||
signal board_failed(message: String)
|
||||
signal reward_claimed(task_id: String, wallet: Dictionary)
|
||||
|
||||
var _board: Dictionary = {}
|
||||
var _loading_board: bool = false
|
||||
var _account_generation: int = -1
|
||||
|
||||
func _ready() -> void:
|
||||
var auth_manager := get_node_or_null("/root/AuthManager")
|
||||
if auth_manager != null and auth_manager.has_signal("auth_state_changed"):
|
||||
var callback := Callable(self, "_on_auth_state_changed")
|
||||
if not auth_manager.is_connected("auth_state_changed", callback):
|
||||
auth_manager.connect("auth_state_changed", callback)
|
||||
call_deferred("_refresh_after_ready")
|
||||
|
||||
func get_board() -> Dictionary:
|
||||
return _board.duplicate(true)
|
||||
|
||||
func is_loaded() -> bool:
|
||||
return not _board.is_empty()
|
||||
|
||||
func refresh_board() -> void:
|
||||
if not _is_authenticated() or _loading_board:
|
||||
return
|
||||
var api := _api_client()
|
||||
if api == null:
|
||||
board_failed.emit("任务服务不可用")
|
||||
return
|
||||
_loading_board = true
|
||||
_account_generation = _current_account_generation()
|
||||
api.call("get_json", "/tasks/board", Callable(self, "_on_board_response").bind(_account_generation), true)
|
||||
|
||||
func report_activity(activity: String, target_id: String = "") -> void:
|
||||
if not _is_authenticated():
|
||||
return
|
||||
var api := _api_client()
|
||||
if api == null:
|
||||
return
|
||||
var payload := {"activity": activity}
|
||||
if not target_id.strip_edges().is_empty():
|
||||
payload["target_id"] = target_id.strip_edges()
|
||||
var request_generation := _current_account_generation()
|
||||
api.call("post_json", "/tasks/activities", payload, Callable(self, "_on_activity_response").bind(request_generation), true)
|
||||
|
||||
func claim_task(task_id: String) -> void:
|
||||
if task_id.strip_edges().is_empty() or not _is_authenticated():
|
||||
return
|
||||
var api := _api_client()
|
||||
if api == null:
|
||||
board_failed.emit("任务服务不可用")
|
||||
return
|
||||
var request_generation := _current_account_generation()
|
||||
api.call("post_json", "/tasks/%s/claim" % task_id.uri_encode(), {}, Callable(self, "_on_claim_response").bind(task_id, request_generation), true)
|
||||
|
||||
func _refresh_after_ready() -> void:
|
||||
if _is_authenticated():
|
||||
refresh_board()
|
||||
|
||||
func _on_auth_state_changed(is_authenticated: bool, _user: Dictionary) -> void:
|
||||
if not is_authenticated:
|
||||
_board.clear()
|
||||
_loading_board = false
|
||||
_account_generation = -1
|
||||
board_changed.emit({})
|
||||
return
|
||||
refresh_board()
|
||||
|
||||
func _on_board_response(success: bool, response: Dictionary, error_info: Dictionary, request_generation: int) -> void:
|
||||
if request_generation != _current_account_generation():
|
||||
return
|
||||
_loading_board = false
|
||||
if not success:
|
||||
board_failed.emit(str(error_info.get("message", "任务书读取失败")))
|
||||
return
|
||||
_apply_board_response(response)
|
||||
|
||||
func _on_activity_response(success: bool, response: Dictionary, _error_info: Dictionary, request_generation: int) -> void:
|
||||
if not success or request_generation != _current_account_generation():
|
||||
return
|
||||
_apply_board_response(response)
|
||||
|
||||
func _on_claim_response(success: bool, response: Dictionary, error_info: Dictionary, task_id: String, request_generation: int) -> void:
|
||||
if request_generation != _current_account_generation():
|
||||
return
|
||||
if not success:
|
||||
board_failed.emit(str(error_info.get("message", "奖励领取失败")))
|
||||
return
|
||||
var data_variant: Variant = response.get("data", {})
|
||||
if not (data_variant is Dictionary):
|
||||
board_failed.emit("任务奖励响应格式错误")
|
||||
return
|
||||
var data: Dictionary = data_variant as Dictionary
|
||||
var board_variant: Variant = data.get("board", {})
|
||||
if board_variant is Dictionary:
|
||||
_apply_board(board_variant as Dictionary)
|
||||
var wallet_variant: Variant = data.get("wallet", {})
|
||||
if wallet_variant is Dictionary:
|
||||
var wallet: Dictionary = wallet_variant as Dictionary
|
||||
var player_state := get_node_or_null("/root/PlayerStateManager")
|
||||
if player_state != null and player_state.has_method("apply_wallet"):
|
||||
player_state.call("apply_wallet", wallet)
|
||||
reward_claimed.emit(task_id, wallet.duplicate(true))
|
||||
|
||||
func _apply_board_response(response: Dictionary) -> void:
|
||||
var data_variant: Variant = response.get("data", {})
|
||||
if data_variant is Dictionary:
|
||||
_apply_board(data_variant as Dictionary)
|
||||
else:
|
||||
board_failed.emit("任务书响应格式错误")
|
||||
|
||||
func _apply_board(board: Dictionary) -> void:
|
||||
_board = board.duplicate(true)
|
||||
board_changed.emit(get_board())
|
||||
|
||||
func _api_client() -> Node:
|
||||
return get_node_or_null("/root/ApiClient")
|
||||
|
||||
func _is_authenticated() -> bool:
|
||||
var auth_manager := get_node_or_null("/root/AuthManager")
|
||||
return auth_manager != null and auth_manager.has_method("is_authenticated") and bool(auth_manager.call("is_authenticated"))
|
||||
|
||||
func _current_account_generation() -> int:
|
||||
var auth_manager := get_node_or_null("/root/AuthManager")
|
||||
return int(auth_manager.call("get_account_generation")) if auth_manager != null and auth_manager.has_method("get_account_generation") else 0
|
||||
1
_Core/managers/TaskManager.gd.uid
Normal file
1
_Core/managers/TaskManager.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://byurfu7d8qyfb
|
||||
Reference in New Issue
Block a user