feature/project-structure-refactor #7

Merged
moyin merged 7 commits from feature/project-structure-refactor into main 2026-01-02 01:03:07 +08:00
9 changed files with 0 additions and 1798 deletions
Showing only changes of commit a18c7a54b1 - Show all commits

File diff suppressed because it is too large Load Diff

View File

@@ -1 +0,0 @@
uid://bs1vy3ierj66t

View File

@@ -1,561 +0,0 @@
[gd_scene load_steps=10 format=3 uid="uid://by7m8snb4xllf"]
[ext_resource type="Texture2D" uid="uid://bx17oy8lvaca4" path="res://assets/ui/auth/bg_auth_scene.png" id="1_background"]
[ext_resource type="Texture2D" uid="uid://de4q4s1gxivtf" path="res://assets/ui/auth/login_frame_smart_transparent.png" id="2_frame"]
[ext_resource type="Script" uid="uid://bs1vy3ierj66t" path="res://UI/Windows/AuthScene.gd" id="3_script"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_1"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hover"]
bg_color = Color(0.3, 0.6, 0.9, 1)
border_width_left = 2
border_width_top = 2
border_width_right = 2
border_width_bottom = 2
border_color = Color(0.2, 0.5, 0.8, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_normal"]
bg_color = Color(0.2, 0.5, 0.8, 1)
border_width_left = 2
border_width_top = 2
border_width_right = 2
border_width_bottom = 2
border_color = Color(0.15, 0.4, 0.7, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pressed"]
bg_color = Color(0.4, 0.7, 1, 1)
border_width_left = 2
border_width_top = 2
border_width_right = 2
border_width_bottom = 2
border_color = Color(0.3, 0.6, 0.9, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
[sub_resource type="Theme" id="Theme_main_button"]
Button/colors/font_color = Color(1, 1, 1, 1)
Button/colors/font_hover_color = Color(1, 1, 1, 1)
Button/colors/font_pressed_color = Color(1, 1, 1, 1)
Button/font_sizes/font_size = 18
Button/styles/hover = SubResource("StyleBoxFlat_hover")
Button/styles/normal = SubResource("StyleBoxFlat_normal")
Button/styles/pressed = SubResource("StyleBoxFlat_pressed")
[sub_resource type="Theme" id="Theme_button"]
Button/colors/font_color = Color(1, 1, 1, 1)
Button/colors/font_hover_color = Color(1, 1, 1, 1)
Button/colors/font_pressed_color = Color(1, 1, 1, 1)
Button/styles/hover = SubResource("StyleBoxFlat_hover")
Button/styles/normal = SubResource("StyleBoxFlat_normal")
Button/styles/pressed = SubResource("StyleBoxFlat_pressed")
[node name="AuthScene" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("3_script")
[node name="HTTPRequest" type="HTTPRequest" parent="."]
[node name="BackgroundImage" type="TextureRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("1_background")
expand_mode = 1
stretch_mode = 6
[node name="WhaleFrame" type="TextureRect" parent="."]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -300.0
offset_top = -300.0
offset_right = 300.0
offset_bottom = 300.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("2_frame")
expand_mode = 1
stretch_mode = 5
[node name="CenterContainer" type="CenterContainer" parent="."]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -175.0
offset_top = -184.0
offset_right = 175.0
offset_bottom = 236.0
grow_horizontal = 2
grow_vertical = 2
[node name="LoginPanel" type="Panel" parent="CenterContainer"]
custom_minimum_size = Vector2(350, 400)
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_1")
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/LoginPanel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 30.0
offset_top = 30.0
offset_right = -30.0
offset_bottom = -30.0
grow_horizontal = 2
grow_vertical = 2
[node name="TitleLabel" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_font_sizes/font_size = 24
text = "Whaletown"
horizontal_alignment = 1
vertical_alignment = 1
[node name="SubtitleLabel" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_font_sizes/font_size = 14
text = "开始你的小镇之旅!"
horizontal_alignment = 1
vertical_alignment = 1
[node name="HSeparator" type="HSeparator" parent="CenterContainer/LoginPanel/VBoxContainer"]
layout_mode = 2
[node name="LoginForm" type="VBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="UsernameContainer" type="VBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm"]
layout_mode = 2
[node name="UsernameLabelContainer" type="HBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/UsernameContainer"]
layout_mode = 2
[node name="UsernameLabel" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/UsernameContainer/UsernameLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "用户名/手机/邮箱"
[node name="RequiredStar" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/UsernameContainer/UsernameLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
text = " *"
[node name="Spacer" type="Control" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/UsernameContainer/UsernameLabelContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="UsernameError" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/UsernameContainer/UsernameLabelContainer"]
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
theme_override_font_sizes/font_size = 12
text = "用户名不能为空"
horizontal_alignment = 2
[node name="UsernameInput" type="LineEdit" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/UsernameContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_colors/font_placeholder_color = Color(0.5, 0.5, 0.5, 1)
placeholder_text = "用户名/手机/邮箱"
[node name="PasswordContainer" type="VBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm"]
layout_mode = 2
[node name="PasswordLabelContainer" type="HBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/PasswordContainer"]
layout_mode = 2
[node name="PasswordLabel" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/PasswordContainer/PasswordLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "密码"
[node name="RequiredStar" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/PasswordContainer/PasswordLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
text = " *"
[node name="Spacer" type="Control" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/PasswordContainer/PasswordLabelContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="PasswordError" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/PasswordContainer/PasswordLabelContainer"]
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
theme_override_font_sizes/font_size = 12
text = "密码不能为空"
horizontal_alignment = 2
[node name="PasswordInput" type="LineEdit" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/PasswordContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_colors/font_placeholder_color = Color(0.5, 0.5, 0.5, 1)
placeholder_text = "请输入密码"
secret = true
[node name="VerificationContainer" type="VBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm"]
visible = false
layout_mode = 2
[node name="VerificationLabelContainer" type="HBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/VerificationContainer"]
layout_mode = 2
[node name="VerificationLabel" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/VerificationContainer/VerificationLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "验证码"
[node name="RequiredStar" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/VerificationContainer/VerificationLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
text = " *"
[node name="Spacer" type="Control" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/VerificationContainer/VerificationLabelContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="VerificationError" type="Label" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/VerificationContainer/VerificationLabelContainer"]
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
theme_override_font_sizes/font_size = 12
text = "请输入验证码"
horizontal_alignment = 2
[node name="VerificationInputContainer" type="HBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/VerificationContainer"]
layout_mode = 2
[node name="VerificationInput" type="LineEdit" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/VerificationContainer/VerificationInputContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_colors/font_placeholder_color = Color(0.5, 0.5, 0.5, 1)
placeholder_text = "请输入6位验证码"
max_length = 6
[node name="GetCodeBtn" type="Button" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/VerificationContainer/VerificationInputContainer"]
layout_mode = 2
text = "获取验证码"
[node name="CheckboxContainer" type="HBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm"]
layout_mode = 2
[node name="RememberPassword" type="CheckBox" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/CheckboxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "记住密码"
[node name="AutoLogin" type="CheckBox" parent="CenterContainer/LoginPanel/VBoxContainer/LoginForm/CheckboxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "自动登录"
[node name="HSeparator2" type="HSeparator" parent="CenterContainer/LoginPanel/VBoxContainer"]
layout_mode = 2
[node name="MainButton" type="Button" parent="CenterContainer/LoginPanel/VBoxContainer"]
custom_minimum_size = Vector2(280, 50)
layout_mode = 2
theme = SubResource("Theme_main_button")
text = "进入小镇"
[node name="HSeparator3" type="HSeparator" parent="CenterContainer/LoginPanel/VBoxContainer"]
layout_mode = 2
[node name="ButtonContainer" type="HBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer"]
layout_mode = 2
alignment = 1
[node name="LoginBtn" type="Button" parent="CenterContainer/LoginPanel/VBoxContainer/ButtonContainer"]
custom_minimum_size = Vector2(100, 35)
layout_mode = 2
theme = SubResource("Theme_button")
text = "密码登录"
[node name="BottomLinks" type="HBoxContainer" parent="CenterContainer/LoginPanel/VBoxContainer"]
layout_mode = 2
alignment = 1
[node name="ForgotPassword" type="Button" parent="CenterContainer/LoginPanel/VBoxContainer/BottomLinks"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "忘记密码?"
flat = true
[node name="RegisterLink" type="Button" parent="CenterContainer/LoginPanel/VBoxContainer/BottomLinks"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "注册居民身份"
flat = true
[node name="RegisterPanel" type="Panel" parent="CenterContainer"]
visible = false
custom_minimum_size = Vector2(400, 570)
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_1")
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/RegisterPanel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 30.0
offset_top = 75.0
offset_right = -30.0
offset_bottom = -72.0
grow_horizontal = 2
grow_vertical = 2
alignment = 1
[node name="TitleLabel" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_font_sizes/font_size = 20
text = "注册新居民"
horizontal_alignment = 1
vertical_alignment = 1
[node name="HSeparator" type="HSeparator" parent="CenterContainer/RegisterPanel/VBoxContainer"]
layout_mode = 2
[node name="RegisterForm" type="VBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
alignment = 1
[node name="UsernameContainer" type="VBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm"]
layout_mode = 2
[node name="UsernameLabelContainer" type="HBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/UsernameContainer"]
layout_mode = 2
[node name="UsernameLabel" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/UsernameContainer/UsernameLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "用户名"
[node name="RequiredStar" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/UsernameContainer/UsernameLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
text = " *"
[node name="Spacer" type="Control" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/UsernameContainer/UsernameLabelContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="UsernameError" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/UsernameContainer/UsernameLabelContainer"]
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
theme_override_font_sizes/font_size = 12
text = "用户名不能为空"
horizontal_alignment = 2
[node name="UsernameInput" type="LineEdit" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/UsernameContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_colors/font_placeholder_color = Color(0.5, 0.5, 0.5, 1)
placeholder_text = "请输入用户名"
[node name="EmailContainer" type="VBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm"]
layout_mode = 2
[node name="EmailLabelContainer" type="HBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/EmailContainer"]
layout_mode = 2
[node name="EmailLabel" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/EmailContainer/EmailLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "邮箱"
[node name="RequiredStar" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/EmailContainer/EmailLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
text = " *"
[node name="Spacer" type="Control" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/EmailContainer/EmailLabelContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="EmailError" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/EmailContainer/EmailLabelContainer"]
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
theme_override_font_sizes/font_size = 12
text = "邮箱不能为空"
horizontal_alignment = 2
[node name="EmailInput" type="LineEdit" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/EmailContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_colors/font_placeholder_color = Color(0.5, 0.5, 0.5, 1)
placeholder_text = "请输入邮箱地址"
[node name="PasswordContainer" type="VBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm"]
layout_mode = 2
[node name="PasswordLabelContainer" type="HBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/PasswordContainer"]
layout_mode = 2
[node name="PasswordLabel" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/PasswordContainer/PasswordLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "密码"
[node name="RequiredStar" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/PasswordContainer/PasswordLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
text = " *"
[node name="Spacer" type="Control" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/PasswordContainer/PasswordLabelContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="PasswordError" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/PasswordContainer/PasswordLabelContainer"]
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
theme_override_font_sizes/font_size = 12
text = "密码不能为空"
horizontal_alignment = 2
[node name="PasswordInput" type="LineEdit" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/PasswordContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_colors/font_placeholder_color = Color(0.5, 0.5, 0.5, 1)
placeholder_text = "请输入密码(至少8位)"
secret = true
[node name="ConfirmContainer" type="VBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm"]
layout_mode = 2
[node name="ConfirmLabelContainer" type="HBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/ConfirmContainer"]
layout_mode = 2
[node name="ConfirmLabel" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/ConfirmContainer/ConfirmLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "确认密码"
[node name="RequiredStar" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/ConfirmContainer/ConfirmLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
text = " *"
[node name="Spacer" type="Control" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/ConfirmContainer/ConfirmLabelContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="ConfirmError" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/ConfirmContainer/ConfirmLabelContainer"]
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
theme_override_font_sizes/font_size = 12
text = "确认密码不能为空"
horizontal_alignment = 2
[node name="ConfirmInput" type="LineEdit" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/ConfirmContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_colors/font_placeholder_color = Color(0.5, 0.5, 0.5, 1)
placeholder_text = "请再次输入密码"
secret = true
[node name="VerificationContainer" type="VBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm"]
layout_mode = 2
[node name="VerificationLabelContainer" type="HBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/VerificationContainer"]
layout_mode = 2
[node name="VerificationLabel" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/VerificationContainer/VerificationLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "邮箱验证码"
[node name="RequiredStar" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/VerificationContainer/VerificationLabelContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
text = " *"
[node name="Spacer" type="Control" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/VerificationContainer/VerificationLabelContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="VerificationError" type="Label" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/VerificationContainer/VerificationLabelContainer"]
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
theme_override_font_sizes/font_size = 12
text = "验证码不能为空"
horizontal_alignment = 2
[node name="VerificationInputContainer" type="HBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/VerificationContainer"]
layout_mode = 2
[node name="VerificationInput" type="LineEdit" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/VerificationContainer/VerificationInputContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_colors/font_placeholder_color = Color(0.5, 0.5, 0.5, 1)
placeholder_text = "请输入6位验证码"
max_length = 6
[node name="SendCodeBtn" type="Button" parent="CenterContainer/RegisterPanel/VBoxContainer/RegisterForm/VerificationContainer/VerificationInputContainer"]
layout_mode = 2
text = "发送验证码"
[node name="HSeparator2" type="HSeparator" parent="CenterContainer/RegisterPanel/VBoxContainer"]
layout_mode = 2
[node name="ButtonContainer" type="HBoxContainer" parent="CenterContainer/RegisterPanel/VBoxContainer"]
layout_mode = 2
alignment = 1
[node name="RegisterBtn" type="Button" parent="CenterContainer/RegisterPanel/VBoxContainer/ButtonContainer"]
custom_minimum_size = Vector2(120, 45)
layout_mode = 2
theme = SubResource("Theme_button")
text = "注册"
[node name="ToLoginBtn" type="Button" parent="CenterContainer/RegisterPanel/VBoxContainer/ButtonContainer"]
custom_minimum_size = Vector2(120, 45)
layout_mode = 2
theme = SubResource("Theme_button")
text = "返回登录"
[node name="ToastContainer" type="Control" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2

View File

@@ -1,199 +0,0 @@
class_name StringUtils
# 字符串工具类 - 提供常用的字符串处理功能
# 验证邮箱格式
static func is_valid_email(email: String) -> bool:
var regex = RegEx.new()
regex.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")
return regex.search(email) != null
# 验证用户名格式(字母、数字、下划线)
static func is_valid_username(username: String) -> bool:
if username.is_empty() or username.length() > 50:
return false
var regex = RegEx.new()
regex.compile("^[a-zA-Z0-9_]+$")
return regex.search(username) != null
# 验证密码强度
static func validate_password_strength(password: String) -> Dictionary:
var result = {"valid": false, "message": "", "strength": 0}
if password.length() < 8:
result.message = "密码长度至少8位"
return result
if password.length() > 128:
result.message = "密码长度不能超过128位"
return result
var has_letter = false
var has_digit = false
var has_special = false
for i in range(password.length()):
var character = password[i]
if character >= 'a' and character <= 'z' or character >= 'A' and character <= 'Z':
has_letter = true
elif character >= '0' and character <= '9':
has_digit = true
elif character in "!@#$%^&*()_+-=[]{}|;:,.<>?":
has_special = true
var strength = 0
if has_letter:
strength += 1
if has_digit:
strength += 1
if has_special:
strength += 1
if password.length() >= 12:
strength += 1
result.strength = strength
if not (has_letter and has_digit):
result.message = "密码必须包含字母和数字"
return result
result.valid = true
result.message = "密码强度: " + ["", "", "", "很强"][min(strength - 1, 3)]
return result
# 截断字符串
static func truncate(text: String, max_length: int, suffix: String = "...") -> String:
if text.length() <= max_length:
return text
return text.substr(0, max_length - suffix.length()) + suffix
# 首字母大写
static func capitalize_first(text: String) -> String:
if text.is_empty():
return text
return text[0].to_upper() + text.substr(1)
# 转换为标题格式(每个单词首字母大写)
static func to_title_case(text: String) -> String:
var words = text.split(" ")
var result = []
for word in words:
if not word.is_empty():
result.append(capitalize_first(word.to_lower()))
return " ".join(result)
# 移除HTML标签
static func strip_html_tags(html: String) -> String:
var regex = RegEx.new()
regex.compile("<[^>]*>")
return regex.sub(html, "", true)
# 格式化文件大小
static func format_file_size(bytes: int) -> String:
var units = ["B", "KB", "MB", "GB", "TB"]
var size = float(bytes)
var unit_index = 0
while size >= 1024.0 and unit_index < units.size() - 1:
size /= 1024.0
unit_index += 1
if unit_index == 0:
return str(int(size)) + " " + units[unit_index]
else:
return "%.1f %s" % [size, units[unit_index]]
# 将UTC时间字符串转换为本地时间显示
static func format_utc_to_local_time(utc_time_str: String) -> String:
# 解析UTC时间字符串 (格式: 2025-12-25T11:23:52.175Z)
var regex = RegEx.new()
regex.compile("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})")
var result = regex.search(utc_time_str)
if result == null:
return utc_time_str # 如果解析失败,返回原字符串
# 提取时间组件
var year = int(result.get_string(1))
var month = int(result.get_string(2))
var day = int(result.get_string(3))
var hour = int(result.get_string(4))
var minute = int(result.get_string(5))
var second = int(result.get_string(6))
# 创建UTC时间字典
var utc_dict = {
"year": year,
"month": month,
"day": day,
"hour": hour,
"minute": minute,
"second": second
}
# 转换为Unix时间戳UTC
var utc_timestamp = Time.get_unix_time_from_datetime_dict(utc_dict)
# 获取本地时间Godot会自动处理时区转换
var local_dict = Time.get_datetime_dict_from_unix_time(utc_timestamp)
# 格式化为易读的本地时间
return "%04d%02d%02d%02d:%02d:%02d" % [
local_dict.year,
local_dict.month,
local_dict.day,
local_dict.hour,
local_dict.minute,
local_dict.second
]
# 获取相对时间描述(多少分钟后)
static func get_relative_time_until(utc_time_str: String) -> String:
# 解析UTC时间字符串
var regex = RegEx.new()
regex.compile("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})")
var result = regex.search(utc_time_str)
if result == null:
return "时间格式错误"
# 提取时间组件
var year = int(result.get_string(1))
var month = int(result.get_string(2))
var day = int(result.get_string(3))
var hour = int(result.get_string(4))
var minute = int(result.get_string(5))
var second = int(result.get_string(6))
# 创建UTC时间字典
var utc_dict = {
"year": year,
"month": month,
"day": day,
"hour": hour,
"minute": minute,
"second": second
}
# 转换为Unix时间戳
var target_timestamp = Time.get_unix_time_from_datetime_dict(utc_dict)
var current_timestamp = Time.get_unix_time_from_system()
# 计算时间差(秒)
var diff_seconds = target_timestamp - current_timestamp
if diff_seconds <= 0:
return "现在可以重试"
elif diff_seconds < 60:
return "%d秒后" % diff_seconds
elif diff_seconds < 3600:
var minutes = int(diff_seconds / 60)
return "%d分钟后" % minutes
else:
var hours = int(diff_seconds / 3600)
var minutes = int((diff_seconds % 3600) / 60)
if minutes > 0:
return "%d小时%d分钟后" % [hours, minutes]
else:
return "%d小时后" % hours

View File

@@ -1 +0,0 @@
uid://csxag1y8yq57j

View File

@@ -1 +0,0 @@
# 保持目录结构 - 角色预制体目录

View File

@@ -1 +0,0 @@
# 保持目录结构 - 特效预制体目录

View File

@@ -1 +0,0 @@
# 保持目录结构 - 物品预制体目录

View File

@@ -1 +0,0 @@
# 保持目录结构 - UI预制体目录