killapp/Assets/Scripts/UI/Pages/Login/LoginPageCtrl.cs
“虞渠成” c3910747dd chore: 优化登录流程,更新版本号并调整UI
1. 重构第三方登录逻辑,统一登录处理流程
2. 移除BindFireBaseRequest多余的code字段
3. 更新项目版本号至1.0.4
4. 调整登录页面按钮布局与图标
5. 修复权限描述文本格式
2026-08-13 16:11:31 +08:00

694 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using Kill.Utils;
using Kill.Managers;
using Kill.Network;
using Kill.UI.Components;
namespace Kill.UI.Pages
{
public class LoginPageCtrl : MonoBehaviour
{
public enum SubPageType
{
Login, // 登录-邮箱输入页
LoginPassword, // 登录-密码输入页
Register,
VerificationCode,
SetPassword,
ThirdPartyBind
}
public LoginSubPageBase[] subPages;
public GameObject PrivacyAgreementTip;
public GameObject[] PrivacyAgreementPlane;
private SubPageType currentSubPage = SubPageType.Login;
private Stack<SubPageType> pageHistory = new Stack<SubPageType>();
public static LoginPageCtrl Instance { get; private set; }
private void Awake()
{
Instance = this;
InitializeSubPages();
foreach(LoginSubPageBase page in subPages)
{
if(page.pageType==SubPageType.Login)
{
page.gameObject.SetActive(true);
}
else
{
page.gameObject.SetActive(false);
}
}
}
private void OnEnable()
{
ShowSubPage(SubPageType.Login, false);
RegisterBackEvent();
}
private void OnDisable()
{
UnregisterBackEvent();
}
/// <summary>
/// 注册返回事件到UIManager
/// </summary>
private void RegisterBackEvent()
{
if (UIManager.Instance != null)
{
UIManager.Instance.RegisterBackAction(OnBackPressed);
}
}
/// <summary>
/// 取消注册返回事件
/// </summary>
private void UnregisterBackEvent()
{
if (UIManager.Instance != null)
{
UIManager.Instance.ClearBackAction();
}
}
/// <summary>
/// 返回键处理
/// </summary>
private void OnBackPressed()
{
// 如果隐私协议提示正在显示,先关闭它
if (PrivacyAgreementTip != null && PrivacyAgreementTip.activeSelf)
{
PrivacyAgreementTip.SetActive(false);
return;
}
// 如果隐私协议面板正在显示,先关闭它
if (PrivacyAgreementPlane != null)
{
foreach (var plane in PrivacyAgreementPlane)
{
if (plane != null && plane.activeSelf)
{
plane.SetActive(false);
return;
}
}
}
// 如果当前在登录页让UIManager处理退出不注销事件只是不拦截
if (currentSubPage == SubPageType.Login)
{
UnregisterBackEvent();
return;
}
// 返回上一页
GoBack();
}
/// <summary>
/// 初始化所有子页面
/// </summary>
private void InitializeSubPages()
{
if (subPages == null) return;
foreach (var page in subPages)
{
if (page != null)
{
page.Initialize(this);
page.Hide();
}
}
}
/// <summary>
/// 显示指定子页面
/// </summary>
public void ShowSubPage(SubPageType pageType, bool recordHistory = true)
{
if( UIManager.Instance.GetBackAction() == null)
{
RegisterBackEvent();
}
// 隐藏当前页面
var currentPage = GetSubPage(currentSubPage);
if (currentPage != null)
{
currentPage.Hide();
}
// 记录历史
if (recordHistory && currentSubPage != pageType)
{
pageHistory.Push(currentSubPage);
}
// 显示新页面
var nextPage = GetSubPage(pageType);
if (nextPage != null)
{
nextPage.Show();
}
currentSubPage = pageType;
}
/// <summary>
/// 返回上一页
/// </summary>
public void GoBack()
{
if (pageHistory.Count > 0)
{
SubPageType previousPage = pageHistory.Pop();
ShowSubPage(previousPage, false);
}
else
{
ShowSubPage(SubPageType.Login, false);
}
}
/// <summary>
/// 清空历史并跳转到指定页面
/// </summary>
public void ClearHistoryAndShow(SubPageType pageType)
{
pageHistory.Clear();
ShowSubPage(pageType, false);
}
/// <summary>
/// 获取子页面控制器
/// </summary>
public LoginSubPageBase GetSubPage(SubPageType pageType)
{
if (subPages == null) return null;
foreach (var page in subPages)
{
if (page != null && page.PageType == pageType)
{
return page;
}
}
return null;
}
/// <summary>
/// 获取当前页面类型
/// </summary>
public SubPageType GetCurrentPageType()
{
return currentSubPage;
}
private void OnDestroy()
{
Instance = null;
}
public void ShowPrivacyAgreementTip(Action onAgreementClick)
{
PrivacyAgreementTip.SetActive(true);
PrivacyTipPanel privacyTipPanel = PrivacyAgreementTip.GetComponent<PrivacyTipPanel>();
privacyTipPanel.Init(onAgreementClick);
}
public void ShowPrivacyAgreementPlane()
{
var currentLang = LanguageManager.Instance.languageType;
if (currentLang == LanguageManager.LanguageType.English)
{
PrivacyAgreementPlane[1].SetActive(true);
}
else
{
PrivacyAgreementPlane[0].SetActive(true);
}
}
#region
/// <summary>
/// 调用登录接口(自定义错误版)
/// </summary>
public async void Login(string email, string password, Action<LoginData> onSuccess, Action<int, string> onError)
{
await LoginWithError(email, password, onSuccess, onError);
}
private async Task LoginWithError(string email, string password, Action<LoginData> onSuccess, Action<int, string> onError)
{
var requestData = new LoginRequest
{
email = email,
password = password
};
LoadingUI.Show();
try
{
var response = await NetworkCtrl.Instance.Post<LoginResponse>("/api/v1/auth/login", requestData);
LoadingUI.Hide();
if(response.Data.code==200)
{
onSuccess?.Invoke(response.Data.data);
DataManager.Instance.SetToken(response.Data.data.token,response.Data.data.user);
}
else
{
onError?.Invoke(response.Data.code, response.Data.message);
}
}
catch (Exception ex)
{
LoadingUI.Hide();
Debug.LogError("登录异常: " + ex.Message);
onError?.Invoke(-1, "登录异常");
}
}
#endregion
#region
private string currentEmail = "";
/// <summary>
/// 设置当前登录邮箱
/// </summary>
public void SetCurrentEmail(string email)
{
currentEmail = email;
}
/// <summary>
/// 获取当前登录邮箱
/// </summary>
public string GetCurrentEmail()
{
return currentEmail;
}
#endregion
#region
/// <summary>
/// 验证邮箱是否已注册
/// </summary>
public async Task CheckEmailRegistered(string email, Action<bool> onSuccess, Action<int, string> onError)
{
LoadingUI.Show();
var requestData = new EmailCodeRequest
{
email = email
};
var response = await NetworkCtrl.Instance.Post<BoolResponse>("/api/v1/auth/email/check", requestData);
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
Debug.Log(data.data.registered);
// 安全访问,防止 data 或 data.data 为 null
bool isRegistered = data?.data?.registered ?? false;
onSuccess?.Invoke(isRegistered);
},
onError: onError
);
}
#endregion
#region
public async Task SendCode(string email, Action onSuccess)
{
LoadingUI.Show();
var requestData = new EmailCodeRequest
{
email = email
};
try
{
var response = await NetworkCtrl.Instance.Post<NoDataResponse>("/api/v1/auth/email/code", requestData);
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
Debug.Log("验证码发送成功");
onSuccess?.Invoke();
},
onError: null
);
}
catch (Exception ex)
{
LoadingUI.Hide();
Debug.LogError("发送验证码异常: " + ex.Message);
}
}
#endregion
#region
/// <summary>
/// 校验验证码
/// </summary>
public async void VerifyCode(string email, string code, Action onSuccess, Action<int, string> onError)
{
LoadingUI.Show();
var requestData = new VerifyCodeRequest
{
email = email,
code = code
};
try
{
var response = await NetworkCtrl.Instance.Post<NoDataResponse>("/api/v1/auth/email/verify", requestData);
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
Debug.Log("验证码校验成功");
onSuccess?.Invoke();
},
onError: onError
);
}
catch (Exception ex)
{
LoadingUI.Hide();
Debug.LogError("校验验证码异常: " + ex.Message);
onError?.Invoke(-1, ex.Message);
}
}
#endregion
#region
/// <summary>
/// 注册账号
/// </summary>
public async void Register(string email, string password, int password_type, Action onSuccess, Action<int, string> onError)
{
LoadingUI.Show();
var requestData = new RegisterRequest
{
email = email,
password = password,
password_type = password_type
};
try
{
var response = await NetworkCtrl.Instance.Post<LoginResponse>("/api/v1/auth/register", requestData);
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
Debug.Log("注册成功");
DataManager.Instance.SetToken(response.Data.data.token,response.Data.data.user);
onSuccess?.Invoke();
},
onError: onError
);
}
catch (Exception ex)
{
LoadingUI.Hide();
Debug.LogError("注册异常: " + ex.Message);
onError?.Invoke(-1, ex.Message);
}
}
#endregion
#region
/// <summary>
/// 重置密码(忘记密码)
/// </summary>
public async void ResetPassword(string email, string password, int password_type, Action onSuccess, Action<int, string> onError)
{
LoadingUI.Show();
var requestData = new ResetPasswordRequest
{
email = email,
password = password,
password_type = password_type
};
try
{
var response = await NetworkCtrl.Instance.Post<NoDataResponse>("/api/v1/auth/password/reset", requestData);
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
Debug.Log("重置密码成功");
onSuccess?.Invoke();
},
onError: onError
);
}
catch (Exception ex)
{
LoadingUI.Hide();
Debug.LogError("重置密码异常: " + ex.Message);
onError?.Invoke(-1, ex.Message);
}
}
#endregion
#region Id
private string currentFireBaseId="";
public string GetCurrentFireBaseId()
{
return currentFireBaseId;
}
public void SetCurrentFireBaseId(string id)
{
currentFireBaseId = id;
}
#endregion
#region
/// <summary>
/// 验证邮箱是已绑定第三方帐号
/// </summary>
public async Task CheckEmailRegisteredFireBase(string email, Action<bool> onSuccess, Action<int, string> onError)
{
LoadingUI.Show();
var requestData = new EmailCodeRequest
{
email = email
};
var response = await NetworkCtrl.Instance.Post<FirebaseBindResponse>("/api/v1/auth/firebase/check", requestData);
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (response) =>
{
Debug.Log(response.data.firebase_bind);
bool isRegistered =response.data.firebase_bind;
onSuccess?.Invoke(isRegistered);
},
onError: onError
);
}
#endregion
#region
/// <summary>
/// 谷歌登录
/// </summary>
public void OnGoogleLogin()
{
Debug.Log("开始谷歌登录...");
LoadingUI.Show();
FirebaseAuthManager.Instance.SignInWithGoogle(
onSuccess: (result) =>
{
LoadingUI.Hide();
Debug.Log($"谷歌登录成功: {result.DisplayName}, FirebaseID: {result.FirebaseUserId}");
HandleThirdPartyLogin(result);
},
onError: (error) =>
{
LoadingUI.Hide();
Debug.LogError($"谷歌登录失败: {error}");
ToastUI.Show("100042"); // 登录失败提示
}
);
}
/// <summary>
/// 苹果登录
/// </summary>
public void OnAppleLogin()
{
Debug.Log("开始苹果登录...");
LoadingUI.Show();
FirebaseAuthManager.Instance.SignInWithApple(
onSuccess: (result) =>
{
LoadingUI.Hide();
Debug.Log($"苹果登录成功: {result.DisplayName}, FirebaseID: {result.FirebaseUserId}");
HandleThirdPartyLogin(result);
},
onError: (error) =>
{
LoadingUI.Hide();
Debug.LogError($"苹果登录失败: {error}");
ToastUI.Show("100042"); // 登录失败提示
}
);
}
/// <summary>
/// Firebase登录
/// </summary>
public async void FireBaseLogin(string firebaseUserId, Action<LoginData> onSuccess, Action<int, string> onError)
{
LoadingUI.Show();
var requestData = new FireBaseLoginRequest
{
firebase_token = firebaseUserId
};
try
{
var response = await NetworkCtrl.Instance.Post<LoginResponse>("/api/v1/auth/firebase/login", requestData);
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
Debug.Log("Firebase登录成功");
onSuccess?.Invoke(response.Data.data);
DataManager.Instance.SetToken(response.Data.data.token,response.Data.data.user);
UIManager.Instance.OpenPage(UIManager.PageName.homePage,null,true);
},
onError: onError
);
}
catch (Exception ex)
{
LoadingUI.Hide();
Debug.LogError("Firebase登录异常: " + ex.Message);
onError?.Invoke(-1, ex.Message);
}
}
/// <summary>
/// 第三方登录成功后的统一处理
/// 新流程:邮箱直接取自第三方授权,不再强制用户输入邮箱、不再需要验证码
/// 已绑定帐号走 firebase/login 直接登录;未绑定则用第三方邮箱调 firebase/bind 自动绑定并登录
/// </summary>
private void HandleThirdPartyLogin(GoogleLoginResult result)
{
if (result == null || string.IsNullOrEmpty(result.FirebaseUserId))
{
Debug.LogError("第三方登录结果无效");
ToastUI.Show("100042"); // 登录失败提示
return;
}
SetCurrentFireBaseId(result.FirebaseUserId);
// 新流程:邮箱必须由第三方授权提供
if (string.IsNullOrEmpty(result.Email))
{
Debug.LogError("第三方登录未获取到邮箱");
ToastUI.Show("100042"); // 登录失败提示
return;
}
SetCurrentEmail(result.Email);
FireBaseLogin(result.FirebaseUserId,
onSuccess: (response) =>
{
Debug.Log(response.token);
},
onError: (code, message) =>
{
Debug.Log(message);
// 未绑定过第三方帐号 → 使用第三方邮箱直接绑定登录,无需验证码
BindFireBase("",
onSuccess: (data) =>
{
Debug.Log(data.token);
UIManager.Instance.OpenPage(UIManager.PageName.homePage, null, true);
},
onError: (bindCode, bindMessage) =>
{
Debug.LogError($"第三方绑定失败: {bindMessage}");
ToastUI.Show("100042"); // 登录失败提示
});
});
}
#endregion
#region
public async Task BindFireBase(string code, Action<LoginData> onSuccess, Action<int, string> onError)
{
LoadingUI.Show();
var requestData = new BindFireBaseRequest
{
temp_token = currentFireBaseId,
email = currentEmail
};
try
{
var response = await NetworkCtrl.Instance.Post<LoginResponse>("/api/v1/auth/firebase/bind", requestData);
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (response) =>
{
Debug.Log("绑定Firebase成功");
DataManager.Instance.SetToken(response.data.token,response.data.user);
onSuccess?.Invoke(response.data);
},
onError: onError
);
}
catch (Exception ex)
{
LoadingUI.Hide();
Debug.LogError("绑定Firebase异常: " + ex.Message);
onError?.Invoke(-1, ex.Message);
}
}
#endregion
}
}