465 lines
14 KiB
C#
465 lines
14 KiB
C#
|
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using TMPro;
|
||
|
|
using UnityEngine;
|
||
|
|
using UnityEngine.UI;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 修改密码面板
|
||
|
|
/// 提供选择用户和修改密码功能
|
||
|
|
/// </summary>
|
||
|
|
public class ChangePasswordPanel : BasePanel
|
||
|
|
{
|
||
|
|
[Header("用户选择")]
|
||
|
|
public TMP_Dropdown UserDropdown; // 用户选择下拉框
|
||
|
|
public TextMeshProUGUI UserInfoText; // 用户信息显示
|
||
|
|
|
||
|
|
[Header("密码输入")]
|
||
|
|
public TMP_InputField CurrentPasswordInput; // 当前密码输入框(仅自己修改时需要)
|
||
|
|
public TMP_InputField NewPasswordInput; // 新密码输入框
|
||
|
|
public TMP_InputField ConfirmPasswordInput; // 确认新密码输入框
|
||
|
|
|
||
|
|
// [Header("标签")]
|
||
|
|
// public TextMeshProUGUI CurrentPasswordLabel;
|
||
|
|
// public TextMeshProUGUI NewPasswordLabel;
|
||
|
|
// public TextMeshProUGUI ConfirmPasswordLabel;
|
||
|
|
|
||
|
|
[Header("操作按钮")]
|
||
|
|
public Button HomeButton;
|
||
|
|
public Button ChangeButton; // 修改密码按钮
|
||
|
|
// public Button CancelButton; // 取消按钮
|
||
|
|
public Button BackButton; // 返回按钮
|
||
|
|
|
||
|
|
[Header("状态显示")]
|
||
|
|
public TextMeshProUGUI StatusText; // 状态文本
|
||
|
|
|
||
|
|
[Header("验证设置")]
|
||
|
|
public int MinPasswordLength = 6;
|
||
|
|
|
||
|
|
private IAuthenticationService _authService;
|
||
|
|
private List<UserInfo> _allUsers = new List<UserInfo>();
|
||
|
|
private UserInfo _selectedUser;
|
||
|
|
private bool _isChangingOwnPassword;
|
||
|
|
|
||
|
|
public override void Init()
|
||
|
|
{
|
||
|
|
_authService = ServiceLocator.Get<IAuthenticationService>();
|
||
|
|
|
||
|
|
InitializeUI();
|
||
|
|
LoadUserList();
|
||
|
|
SetupValidation();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void InitializeUI()
|
||
|
|
{
|
||
|
|
// 设置标签文本
|
||
|
|
// if (CurrentPasswordLabel != null) CurrentPasswordLabel.text = "当前密码:";
|
||
|
|
// if (NewPasswordLabel != null) NewPasswordLabel.text = "新密码:";
|
||
|
|
// if (ConfirmPasswordLabel != null) ConfirmPasswordLabel.text = "确认新密码:";
|
||
|
|
|
||
|
|
// 设置密码输入框为密码模式
|
||
|
|
if (CurrentPasswordInput != null)
|
||
|
|
{
|
||
|
|
CurrentPasswordInput.contentType = TMP_InputField.ContentType.Password;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (NewPasswordInput != null)
|
||
|
|
{
|
||
|
|
NewPasswordInput.contentType = TMP_InputField.ContentType.Password;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ConfirmPasswordInput != null)
|
||
|
|
{
|
||
|
|
ConfirmPasswordInput.contentType = TMP_InputField.ContentType.Password;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 设置按钮事件
|
||
|
|
if (HomeButton != null)
|
||
|
|
{
|
||
|
|
HomeButton.onClick.AddListener(() =>
|
||
|
|
{
|
||
|
|
ReturnToHome();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ChangeButton != null)
|
||
|
|
{
|
||
|
|
ChangeButton.onClick.AddListener(OnChangeButtonClicked);
|
||
|
|
ChangeButton.interactable = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// if (CancelButton != null)
|
||
|
|
// {
|
||
|
|
// CancelButton.onClick.AddListener(OnCancelButtonClicked);
|
||
|
|
// }
|
||
|
|
|
||
|
|
if (BackButton != null)
|
||
|
|
{
|
||
|
|
BackButton.onClick.AddListener(OnBackButtonClicked);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 设置用户选择事件
|
||
|
|
if (UserDropdown != null)
|
||
|
|
{
|
||
|
|
UserDropdown.onValueChanged.AddListener(OnUserSelectionChanged);
|
||
|
|
}
|
||
|
|
|
||
|
|
SetStatus("请选择要修改密码的用户", true);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void LoadUserList()
|
||
|
|
{
|
||
|
|
if (_authService == null)
|
||
|
|
{
|
||
|
|
SetStatus("认证服务不可用", false);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 清空下拉框
|
||
|
|
if (UserDropdown != null)
|
||
|
|
{
|
||
|
|
UserDropdown.ClearOptions();
|
||
|
|
}
|
||
|
|
|
||
|
|
_allUsers.Clear();
|
||
|
|
|
||
|
|
// 获取所有用户
|
||
|
|
var users = _authService.GetAllUsers();
|
||
|
|
if (users == null || users.Count == 0)
|
||
|
|
{
|
||
|
|
SetStatus("没有可用用户", false);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var options = new List<string>();
|
||
|
|
|
||
|
|
// 如果是管理员,可以修改所有用户密码
|
||
|
|
// 如果是普通用户,只能修改自己的密码
|
||
|
|
string currentUser = _authService.CurrentUsername;
|
||
|
|
bool isAdmin = _authService.CurrentRole == UserRole.Admin;
|
||
|
|
|
||
|
|
foreach (var user in users)
|
||
|
|
{
|
||
|
|
// 普通用户只能修改自己的密码
|
||
|
|
if (!isAdmin && !user.Username.Equals(currentUser, System.StringComparison.OrdinalIgnoreCase))
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
_allUsers.Add(user);
|
||
|
|
string displayName = user.Username;
|
||
|
|
if (user.Username.Equals(currentUser, System.StringComparison.OrdinalIgnoreCase))
|
||
|
|
{
|
||
|
|
displayName += " (当前用户)";
|
||
|
|
}
|
||
|
|
if (user.Role == UserRole.Admin)
|
||
|
|
{
|
||
|
|
displayName += " [管理员]";
|
||
|
|
}
|
||
|
|
options.Add(displayName);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (UserDropdown != null)
|
||
|
|
{
|
||
|
|
UserDropdown.AddOptions(options);
|
||
|
|
|
||
|
|
// 默认选择当前用户
|
||
|
|
int currentUserIndex = _allUsers.FindIndex(u => u.Username.Equals(currentUser, System.StringComparison.OrdinalIgnoreCase));
|
||
|
|
if (currentUserIndex >= 0)
|
||
|
|
{
|
||
|
|
UserDropdown.value = currentUserIndex;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 触发选择变化事件
|
||
|
|
OnUserSelectionChanged(UserDropdown?.value ?? 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnUserSelectionChanged(int index)
|
||
|
|
{
|
||
|
|
if (index < 0 || index >= _allUsers.Count)
|
||
|
|
{
|
||
|
|
_selectedUser = null;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_selectedUser = _allUsers[index];
|
||
|
|
_isChangingOwnPassword = _selectedUser.Username.Equals(_authService.CurrentUsername, System.StringComparison.OrdinalIgnoreCase);
|
||
|
|
|
||
|
|
UpdateUIForSelectedUser();
|
||
|
|
ValidateInputs();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void UpdateUIForSelectedUser()
|
||
|
|
{
|
||
|
|
if (_selectedUser == null) return;
|
||
|
|
|
||
|
|
// 更新用户信息显示
|
||
|
|
if (UserInfoText != null)
|
||
|
|
{
|
||
|
|
var roleText = _selectedUser.Role == UserRole.Admin ? "管理员" : "普通用户";
|
||
|
|
var infoText = $"用户: {_selectedUser.Username}\n角色: {roleText}";
|
||
|
|
if (_isChangingOwnPassword)
|
||
|
|
{
|
||
|
|
infoText += "\n正在修改自己的密码";
|
||
|
|
}
|
||
|
|
UserInfoText.text = infoText;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 根据是否修改自己的密码来显示/隐藏当前密码输入框
|
||
|
|
if (CurrentPasswordInput != null)
|
||
|
|
{
|
||
|
|
CurrentPasswordInput.gameObject.SetActive(_isChangingOwnPassword);
|
||
|
|
}
|
||
|
|
|
||
|
|
// if (CurrentPasswordLabel != null)
|
||
|
|
// {
|
||
|
|
// CurrentPasswordLabel.gameObject.SetActive(_isChangingOwnPassword);
|
||
|
|
// }
|
||
|
|
|
||
|
|
ClearPasswordInputs();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void SetupValidation()
|
||
|
|
{
|
||
|
|
// 添加输入验证监听器
|
||
|
|
if (CurrentPasswordInput != null)
|
||
|
|
{
|
||
|
|
CurrentPasswordInput.onValueChanged.AddListener(OnPasswordInputChanged);
|
||
|
|
if (CurrentPasswordInput != null)
|
||
|
|
{
|
||
|
|
CustomKeyboardManager.SetupInputField(CurrentPasswordInput, KeyboardLayout.Default,
|
||
|
|
(newValue) =>
|
||
|
|
{
|
||
|
|
CurrentPasswordInput.text = newValue;
|
||
|
|
OnPasswordInputChanged(newValue);
|
||
|
|
},
|
||
|
|
clearOnFirstInput: true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (NewPasswordInput != null)
|
||
|
|
{
|
||
|
|
NewPasswordInput.onValueChanged.AddListener(OnPasswordInputChanged);
|
||
|
|
if (NewPasswordInput != null)
|
||
|
|
{
|
||
|
|
CustomKeyboardManager.SetupInputField(NewPasswordInput, KeyboardLayout.Default,
|
||
|
|
(newValue) =>
|
||
|
|
{
|
||
|
|
NewPasswordInput.text = newValue;
|
||
|
|
OnPasswordInputChanged(newValue);
|
||
|
|
},
|
||
|
|
clearOnFirstInput: true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ConfirmPasswordInput != null)
|
||
|
|
{
|
||
|
|
ConfirmPasswordInput.onValueChanged.AddListener(OnPasswordInputChanged);
|
||
|
|
if (ConfirmPasswordInput != null)
|
||
|
|
{
|
||
|
|
CustomKeyboardManager.SetupInputField(ConfirmPasswordInput, KeyboardLayout.Default,
|
||
|
|
(newValue) =>
|
||
|
|
{
|
||
|
|
ConfirmPasswordInput.text = newValue;
|
||
|
|
OnPasswordInputChanged(newValue);
|
||
|
|
},
|
||
|
|
clearOnFirstInput: true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnPasswordInputChanged(string value)
|
||
|
|
{
|
||
|
|
ValidateInputs();
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool ValidateInputs()
|
||
|
|
{
|
||
|
|
if (_selectedUser == null)
|
||
|
|
{
|
||
|
|
SetStatus("请选择用户", false);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
string currentPassword = CurrentPasswordInput?.text ?? "";
|
||
|
|
string newPassword = NewPasswordInput?.text ?? "";
|
||
|
|
string confirmPassword = ConfirmPasswordInput?.text ?? "";
|
||
|
|
|
||
|
|
// 如果是修改自己的密码,需要验证当前密码
|
||
|
|
if (_isChangingOwnPassword && string.IsNullOrEmpty(currentPassword))
|
||
|
|
{
|
||
|
|
SetStatus("请输入当前密码", false);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 验证新密码
|
||
|
|
if (string.IsNullOrEmpty(newPassword))
|
||
|
|
{
|
||
|
|
SetStatus("请输入新密码", false);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (newPassword.Length < MinPasswordLength)
|
||
|
|
{
|
||
|
|
SetStatus($"新密码至少需要{MinPasswordLength}个字符", false);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 验证确认密码
|
||
|
|
if (newPassword != confirmPassword)
|
||
|
|
{
|
||
|
|
SetStatus("两次输入的新密码不一致", false);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 检查新密码是否与当前密码相同
|
||
|
|
if (_isChangingOwnPassword && currentPassword == newPassword)
|
||
|
|
{
|
||
|
|
SetStatus("新密码不能与当前密码相同", false);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
SetStatus("密码验证通过", true);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void SetStatus(string message, bool isSuccess)
|
||
|
|
{
|
||
|
|
if (StatusText != null)
|
||
|
|
{
|
||
|
|
StatusText.text = message;
|
||
|
|
StatusText.color = isSuccess ? Color.green : Color.red;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 根据验证结果启用/禁用修改按钮
|
||
|
|
if (ChangeButton != null)
|
||
|
|
{
|
||
|
|
ChangeButton.interactable = isSuccess;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnChangeButtonClicked()
|
||
|
|
{
|
||
|
|
if (!ValidateInputs()) return;
|
||
|
|
|
||
|
|
string newPassword = NewPasswordInput.text;
|
||
|
|
string actionText = _isChangingOwnPassword ? "修改自己的密码" : $"修改用户 '{_selectedUser.Username}' 的密码";
|
||
|
|
|
||
|
|
// 显示确认对话框
|
||
|
|
ConfirmDialog.ShowActionConfirm(
|
||
|
|
"修改密码",
|
||
|
|
_selectedUser.Username,
|
||
|
|
() => ChangePassword(),
|
||
|
|
() => Debug.Log("取消修改密码")
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void ChangePassword()
|
||
|
|
{
|
||
|
|
if (_authService == null || _selectedUser == null)
|
||
|
|
{
|
||
|
|
SetStatus("操作失败:服务不可用", false);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
string currentPassword = CurrentPasswordInput?.text ?? "";
|
||
|
|
string newPassword = NewPasswordInput.text;
|
||
|
|
|
||
|
|
bool success;
|
||
|
|
|
||
|
|
if (_isChangingOwnPassword)
|
||
|
|
{
|
||
|
|
// 修改自己的密码,需要验证当前密码
|
||
|
|
success = _authService.ChangePassword(_selectedUser.Username, currentPassword, newPassword);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// 管理员重置其他用户密码,不需要提供旧密码
|
||
|
|
// AuthenticationService 会根据当前用户角色自动处理权限
|
||
|
|
success = _authService.ChangePassword(_selectedUser.Username, null, newPassword);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (success)
|
||
|
|
{
|
||
|
|
SetStatus("密码修改成功!", true);
|
||
|
|
string actionType = _isChangingOwnPassword ? "修改" : "重置";
|
||
|
|
Debug.Log($"成功{actionType}用户 {_selectedUser.Username} 的密码");
|
||
|
|
|
||
|
|
ClearPasswordInputs();
|
||
|
|
|
||
|
|
// 延迟关闭面板
|
||
|
|
StartCoroutine(CloseAfterDelay(1.5f));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (_isChangingOwnPassword)
|
||
|
|
{
|
||
|
|
SetStatus("密码修改失败:当前密码错误或新密码无效", false);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
SetStatus("密码重置失败:权限不足或新密码无效", false);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private System.Collections.IEnumerator CloseAfterDelay(float delay)
|
||
|
|
{
|
||
|
|
yield return new WaitForSeconds(delay);
|
||
|
|
ClosePanel();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void ClearPasswordInputs()
|
||
|
|
{
|
||
|
|
if (CurrentPasswordInput != null) CurrentPasswordInput.text = "";
|
||
|
|
if (NewPasswordInput != null) NewPasswordInput.text = "";
|
||
|
|
if (ConfirmPasswordInput != null) ConfirmPasswordInput.text = "";
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnCancelButtonClicked()
|
||
|
|
{
|
||
|
|
if (HasUnsavedChanges())
|
||
|
|
{
|
||
|
|
ConfirmDialog.Show("确认取消", "确定要取消修改密码吗?已输入的信息将丢失。",
|
||
|
|
() => UIManager.Instance.HidePanel<ChangePasswordPanel>(), null, "确认", "继续编辑", true);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
ClosePanel();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnBackButtonClicked()
|
||
|
|
{
|
||
|
|
OnCancelButtonClicked();
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool HasUnsavedChanges()
|
||
|
|
{
|
||
|
|
return !string.IsNullOrEmpty(CurrentPasswordInput?.text) ||
|
||
|
|
!string.IsNullOrEmpty(NewPasswordInput?.text) ||
|
||
|
|
!string.IsNullOrEmpty(ConfirmPasswordInput?.text);
|
||
|
|
}
|
||
|
|
|
||
|
|
// public void ClosePanel()
|
||
|
|
// {
|
||
|
|
// UIManager.Instance.HidePanel<ChangePasswordPanel>();
|
||
|
|
// }
|
||
|
|
|
||
|
|
void OnDestroy()
|
||
|
|
{
|
||
|
|
// 清理事件监听器
|
||
|
|
if (CurrentPasswordInput != null)
|
||
|
|
CurrentPasswordInput.onValueChanged.RemoveListener(OnPasswordInputChanged);
|
||
|
|
if (NewPasswordInput != null)
|
||
|
|
NewPasswordInput.onValueChanged.RemoveListener(OnPasswordInputChanged);
|
||
|
|
if (ConfirmPasswordInput != null)
|
||
|
|
ConfirmPasswordInput.onValueChanged.RemoveListener(OnPasswordInputChanged);
|
||
|
|
if (CustomKeyboardManager.Instance != null && CustomKeyboardManager.Instance.IsKeyboardShowing())
|
||
|
|
{
|
||
|
|
CustomKeyboardManager.Instance.HideKeyboard();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|