killapp/Assets/Scripts/UI/Pages/SelfPage/SelfSetPasswordPanel.cs
“虞渠成” 4d0448c80d feat: 新增重置密码功能并完善密码校验逻辑
1.  新增加速度传感器设备不稳定错误提示
2.  新增多套密码校验规则与多语言文案
3.  重构个人页面与密码设置面板的校验逻辑
4.  优化设备状态错误展示与UI布局
5.  新增重置密码相关的UI资源与逻辑
2026-07-28 14:54:36 +08:00

284 lines
11 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 UnityEngine;
using UnityEngine.UI;
using Kill.Utils;
using Kill.Managers;
using System.Threading.Tasks;
using System;
using System.Text.RegularExpressions;
using Kill.UI.Components;
using Kill.Network;
namespace Kill.UI.Pages
{
/// <summary>
/// 设置密码页面
/// 用于注册设置密码和忘记密码重置密码
/// </summary>
public class SelfSetPasswordPanel : MonoBehaviour
{
[Header("输入组件")]
public InputField newPasswordInput;
public InputField confirmPasswordInput;
[Header("按钮")]
public Button confirmBtn;
public GameObject confirmBtnDisabled;
public Button backBtn;
/// <summary>
/// 切换简单/复杂密码按钮 0简单密码选中 1简单密码未选中 2复杂密码选中 3复杂密码未选中 未选中可点击
/// </summary>
public GameObject[] changeTypeBtns;
[Header("密码规则验证")]
public Sprite correctIconSprite;
public Sprite incorrectIconSprite;
public Image[] simplePasswordRules;
public Image[] complexPasswordRules;
public Image simpleConfirmMatchRule;
public Image complexConfirmMatchRule;
public GameObject simpleRulesContainer;
public GameObject complexRulesContainer;
private int passwordType = 0;
private bool isConfirmEnabled = false;
Action callback;
public void Init( Action callback)
{
passwordType = 0;
this.callback = callback;
if (confirmBtn != null)
{
confirmBtn.onClick.RemoveAllListeners();
confirmBtn.onClick.AddListener(OnConfirm);
}
if (backBtn != null)
{
backBtn.onClick.RemoveAllListeners();
backBtn.onClick.AddListener(OnBack);
}
if (changeTypeBtns != null && changeTypeBtns.Length == 4)
{
changeTypeBtns[1].GetComponent<Button>().onClick.AddListener(() => ChangePasswordType(0));
changeTypeBtns[3].GetComponent<Button>().onClick.AddListener(() => ChangePasswordType(1));
}
newPasswordInput.onValueChanged.AddListener(OnPasswordValueChanged);
confirmPasswordInput.onValueChanged.AddListener(OnPasswordValueChanged);
// 页面显示时初始化密码输入框
ChangePasswordType(0);
}
private void OnPasswordValueChanged(string value)
{
CheckPasswordRules();
UpdateSubmitButton();
}
/// <summary>
/// 切换密码类型
/// </summary>
/// <param name="type">密码类型0简单密码1复杂密码</param>
private void ChangePasswordType(int type)
{
passwordType = type;
newPasswordInput.text = "";
confirmPasswordInput.text = "";
if (type == 0)
{
newPasswordInput.characterLimit = 6;
confirmPasswordInput.characterLimit = 6;
newPasswordInput.contentType = InputField.ContentType.Pin;
confirmPasswordInput.contentType = InputField.ContentType.Pin;
changeTypeBtns[0].SetActive(true);
changeTypeBtns[1].SetActive(false);
changeTypeBtns[2].SetActive(false);
changeTypeBtns[3].SetActive(true);
}
else
{
newPasswordInput.characterLimit = 16;
confirmPasswordInput.characterLimit = 16;
newPasswordInput.contentType = InputField.ContentType.Password;
confirmPasswordInput.contentType = InputField.ContentType.Password;
changeTypeBtns[0].SetActive(false);
changeTypeBtns[1].SetActive(true);
changeTypeBtns[2].SetActive(true);
changeTypeBtns[3].SetActive(false);
}
// 切换规则容器并重置显示
UpdateRulesContainerVisibility();
ResetRulesDisplay();
UpdateSubmitButton();
}
private void UpdateRulesContainerVisibility()
{
if (simpleRulesContainer != null)
simpleRulesContainer.SetActive(passwordType == 0);
if (complexRulesContainer != null)
complexRulesContainer.SetActive(passwordType == 1);
}
private void ResetRulesDisplay()
{
var rules = passwordType == 0 ? simplePasswordRules : complexPasswordRules;
if (rules != null)
{
foreach (var image in rules)
{
if (image != null)
image.sprite = incorrectIconSprite;
}
}
var matchRule = passwordType == 0 ? simpleConfirmMatchRule : complexConfirmMatchRule;
if (matchRule != null)
matchRule.sprite = incorrectIconSprite;
}
/// <summary>
/// 逐条检查密码规则并更新UI图标
/// </summary>
private void CheckPasswordRules()
{
string newPwd = newPasswordInput != null ? newPasswordInput.text : "";
string confirmPwd = confirmPasswordInput != null ? confirmPasswordInput.text : "";
bool pwdRulesValid = false;
if (passwordType == 0)
{
// 简单密码 - 1条规则6位数字
bool isValid = ValidationUtils.IsValidSimplePassword(newPwd);
pwdRulesValid = isValid;
if (simplePasswordRules != null && simplePasswordRules.Length > 0 && simplePasswordRules[0] != null)
simplePasswordRules[0].sprite = isValid ? correctIconSprite : incorrectIconSprite;
}
else
{
// 复杂密码 - 4条规则
// 规则1长度8-16位不能有空格
bool rule1Valid = newPwd.Length >= 8 && newPwd.Length <= 16 && !newPwd.Contains(" ");
// 规则2至少包含大写字母、小写字母、数字、特殊字符中的三种
bool hasUpper = Regex.IsMatch(newPwd, @"[A-Z]");
bool hasLower = Regex.IsMatch(newPwd, @"[a-z]");
bool hasDigit = Regex.IsMatch(newPwd, @"\d");
bool hasSpecial = !string.IsNullOrEmpty(newPwd) && Regex.IsMatch(newPwd, @"[!@#$%^&*()_+\-=\[\]{};':""\\|,.<>\/?]|\p{P}");
int typeCount = (hasUpper ? 1 : 0) + (hasLower ? 1 : 0) + (hasDigit ? 1 : 0) + (hasSpecial ? 1 : 0);
bool rule2Valid = typeCount >= 3;
// 规则3不能包含连续或重复的三个及以上的数字或字母大小写不敏感
bool rule3Valid = ValidationUtils.IsValidNoRepeatOrConsecutive(newPwd);
// 规则4密码不能包含邮箱中任意连续两个字符
string email = DataManager.Instance.userInfo.email;
bool rule4Valid = ValidationUtils.IsValidNotEmailPart(newPwd, email);
pwdRulesValid = rule1Valid && rule2Valid && rule3Valid && rule4Valid;
if (complexPasswordRules != null && complexPasswordRules.Length >= 4)
{
if (complexPasswordRules[0] != null) complexPasswordRules[0].sprite = rule1Valid ? correctIconSprite : incorrectIconSprite;
if (complexPasswordRules[1] != null) complexPasswordRules[1].sprite = rule2Valid ? correctIconSprite : incorrectIconSprite;
if (complexPasswordRules[2] != null) complexPasswordRules[2].sprite = rule3Valid ? correctIconSprite : incorrectIconSprite;
if (complexPasswordRules[3] != null) complexPasswordRules[3].sprite = rule4Valid ? correctIconSprite : incorrectIconSprite;
}
}
// 两条密码一致
bool matchValid = !string.IsNullOrEmpty(newPwd) && newPwd == confirmPwd;
var matchRule = passwordType == 0 ? simpleConfirmMatchRule : complexConfirmMatchRule;
if (matchRule != null)
matchRule.sprite = matchValid ? correctIconSprite : incorrectIconSprite;
isConfirmEnabled = pwdRulesValid && matchValid;
}
/// <summary>
/// 更新提交按钮显示状态
/// </summary>
private void UpdateSubmitButton()
{
if (confirmBtn != null)
confirmBtn.gameObject.SetActive(isConfirmEnabled);
if (confirmBtnDisabled != null)
confirmBtnDisabled.SetActive(!isConfirmEnabled);
}
/// <summary>
/// 确认设置密码
/// </summary>
private void OnConfirm()
{
if (!isConfirmEnabled)
return;
string newPwd = newPasswordInput != null ? newPasswordInput.text : "";
string email = DataManager.Instance.userInfo.email;
// 重置密码模式 - 调用重置密码接口
ResetPassword(email, newPwd, passwordType,
onSuccess: () =>
{
if (passwordType == 0)
{
DataManager.Instance.userInfo.has_simple_password = true;
}
else
{
DataManager.Instance.userInfo.has_complex_password = true;
}
callback?.Invoke();
},
onError: (code, msg) =>
{
ToastUI.ShowText(code.ToString());
}
);
}
public void OnBack()
{
UIManager.Instance.RegisterBackAction(GetComponentInParent<SelfInfoPage>().OnBack);
Destroy(gameObject);
}
/// <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("重置密码成功");
ToastUI.Show("100319");
onSuccess?.Invoke();
},
onError: onError
);
}
catch (Exception ex)
{
LoadingUI.Hide();
Debug.LogError("重置密码异常: " + ex.Message);
onError?.Invoke(-1, ex.Message);
}
}
}
}