using AppUI; using AppUI.Localization; using AppUI.Manager; using AppUI.View.Component; using JCUnityLib; using System.Collections; using System.Text.RegularExpressions; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; namespace AppUI.View { /// /// AppUI 登录页:账号 + 密码 +(可选)图形验证码,逻辑对齐旧版 LoginNormal。 /// 第三方登录(微信/Apple 等)暂不接入,见 Docs。 /// public class LoginView : MonoBehaviour { [Header("输入(可留空,运行时按路径自动绑定)")] [SerializeField] TMP_InputField accountInput; [SerializeField] TMP_InputField passwordInput; [Header("验证码(可选,与旧版图形验证码一致;未绑定则跳过校验)")] [SerializeField] Image captchaDisplayImage; [SerializeField] InputField captchaLegacyInput; string _expectedCaptchaText = ""; bool _captchaReady; readonly Throttler _throttlerLoginNormal = new Throttler(2000); void Awake() { TryAutoBindCaptcha(); InitPasswordAlphanumericFilter(); } void Start() { if (IsCaptchaConfigured()) ReloadCaptcha(); } /// /// 与旧版通过父节点名定位验证码一致;支持父节点未激活时的子节点查找。 /// void TryAutoBindCaptcha() { if (captchaDisplayImage != null && captchaLegacyInput != null) return; foreach (var tr in GetComponentsInChildren(true)) { if (captchaDisplayImage == null && tr.name == "CodeImage") { var img = tr.GetComponent(); if (img != null) captchaDisplayImage = img; } if (captchaLegacyInput == null && tr.name == "InputField" && tr.parent != null && tr.parent.name == "_InCaptcha1") { var field = tr.GetComponent(); if (field != null) captchaLegacyInput = field; } } } void InitPasswordAlphanumericFilter() { if (passwordInput == null) return; passwordInput.onValueChanged.AddListener(text => { var match = new Regex("[^A-Za-z0-9]").Match(text); if (match.Success) passwordInput.text = text.Replace(match.Value, ""); }); } bool IsCaptchaConfigured() => captchaDisplayImage != null && captchaLegacyInput != null; /// 供「换一张验证码」按钮调用,对齐旧版 ChnageCaptcha1 public void ReloadCaptcha() { if (!IsCaptchaConfigured()) return; _captchaReady = false; StartCoroutine(CaptchaController.Instance.GetCaptcha(captchaDisplayImage, code => { _expectedCaptchaText = code.ToString(); _captchaReady = true; })); } /// 对齐旧版 LoginNormal:账号/密码登录(不含第三方)。 public void Login() { if (accountInput == null || passwordInput == null) { Debug.LogError("[AppUI.LoginView] 未绑定账号或密码 TMP_InputField。"); return; } string account = accountInput.text.Trim(); if (account.Length == 0) { ModuleViewMgr.ins.Show(AppUILocalization.GetTextByCNKey("请输入账号")); return; } if (CommonConfig.AppArea == 0) { if (!ValidateHelper.IsMobilePhone(account)) { ModuleViewMgr.ins.Show(AppUILocalization.GetTextByKey("RelateValidateView-a1")); return; } } else { if (!ValidateHelper.IsEmail(account)) { ModuleViewMgr.ins.Show(AppUILocalization.GetTextByKey("RelateValidateView-a0")); return; } } string pwd = passwordInput.text.Trim(); if (pwd.Length == 0) { ModuleViewMgr.ins.Show(AppUILocalization.GetTextByCNKey("请输入密码")); return; } //if (IsCaptchaConfigured()) //{ // if (!_captchaReady) // { // PopupMgr.ins.ShowTip(TextAutoLanguage2.GetTextByCNKey("验证码错误")); // return; // } // if (!captchaLegacyInput.text.Equals(_expectedCaptchaText)) // { // PopupMgr.ins.ShowTip(TextAutoLanguage2.GetTextByCNKey("验证码错误")); // return; // } //} //if (!AgreenmentOption.ins.IsAgreementChecked()) //{ // PopupMgr.ins.ShowTip(TextAutoLanguage2.GetTextByCNKey("请阅读并同意App协议")); // return; //} if (!_throttlerLoginNormal.CanPass()) { ModuleViewMgr.ins.Show(AppUILocalization.GetTextByCNKey("操作过于频繁")); return; } StartCoroutine(LoginController.Instance.LoginNormal(account, pwd, res => { //ModuleViewMgr.ins.Show(TextAutoLanguage2.GetTextByCNKey(res.msg)); //PopupMgr.ins.ShowTip(TextAutoLanguage2.GetTextByCNKey(res.msg)); if (res.code == 0) { string loginToken = (string)res.data; GoToHome(loginToken); } })); } void GoToHome(string loginToken) { CommonConfig.businessServerWsURL = loginToken.Split('&')[2]; PlayerPrefs.SetString(LoginMgr.LoginTokenKey, loginToken); ScreenOrientationHelper.SwitchToLandscapeAndLoadScene("Home"); } /// 对齐旧版 FillLoginInput public void FillLoginInput(string username, string password) { if (accountInput != null) accountInput.text = username; if (passwordInput != null) passwordInput.text = password; } } }