DCS/ruiyiweiUX/Assets/Scripts/Services/PersistentAuthenticationSer...

474 lines
14 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.IO;
using UnityEngine;
/// <summary>
/// 持久化认证服务
/// 将用户数据保存到本地JSON文件支持运行时增删改查
/// 使用 persistentDataPath 确保跨平台兼容性特别是Android系统
/// </summary>
public class PersistentAuthenticationService : IAuthenticationService
{
private readonly string _dataFilePath;
private UserDatabase _userDatabase;
private const string DATA_FILE_NAME = "users.json";
private const int MAX_USER_COUNT = 10; // 最大用户数量限制
public bool IsLoggedIn { get; private set; }
public string CurrentUsername { get; private set; }
public UserRole CurrentRole { get; private set; }
public CurrentUser CurrentUser { get; private set; }
public PersistentAuthenticationService()
{
// 使用 persistentDataPath 而不是 streamingAssetsPath
// persistentDataPath 在所有平台上都是可读写的,包括 Android
_dataFilePath = Path.Combine(Application.persistentDataPath, DATA_FILE_NAME);
LoadUserDatabase();
Debug.Log($"用户数据存储路径: {_dataFilePath}");
}
public bool Login(string username, string password, out UserRole role)
{
role = UserRole.User;
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
return false;
}
var user = _userDatabase.FindUser(username);
if (user != null && user.Password == password)
{
IsLoggedIn = true;
CurrentUsername = username;
CurrentRole = user.Role;
CurrentUser = new CurrentUser { Username = username, Role = user.Role };
role = user.Role;
// 更新最后登录时间
user.LastLoginTime = DateTime.Now;
SaveUserDatabase();
// 记录登录日志
var logService = ServiceLocator.Get<UserLogService>();
logService?.LogUserOperation(username, "用户登录", $"角色: {user.Role}", true);
Debug.Log($"用户 {username} 登录成功,角色: {user.Role}");
return true;
}
// 记录登录失败日志
var logServiceFailed = ServiceLocator.Get<UserLogService>();
logServiceFailed?.LogUserOperation(username, "用户登录", "密码错误或用户不存在", false);
IsLoggedIn = false;
CurrentUsername = null;
CurrentRole = UserRole.User;
CurrentUser = null;
return false;
}
public void Logout()
{
// 记录登出日志
if (!string.IsNullOrEmpty(CurrentUsername))
{
var logService = ServiceLocator.Get<UserLogService>();
logService?.LogUserOperation(CurrentUsername, "用户登出", "正常登出", true);
}
Debug.Log($"用户 {CurrentUsername} 登出");
IsLoggedIn = false;
CurrentUsername = null;
CurrentRole = UserRole.User;
CurrentUser = null;
}
/// <summary>
/// 添加新用户
/// </summary>
public bool AddUser(string username, string password, UserRole role)
{
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
Debug.LogError("用户名和密码不能为空");
return false;
}
// 检查用户数量限制
if (_userDatabase.Users.Count >= MAX_USER_COUNT)
{
Debug.LogError($"用户数量已达到上限({MAX_USER_COUNT}个),无法添加新用户");
return false;
}
// 验证用户名格式(只允许字母、数字和下划线,区分大小写)
if (!IsValidUsername(username))
{
Debug.LogError("用户名只能包含字母、数字和下划线,不允许特殊字符");
return false;
}
// 检查用户是否已存在(区分大小写)
if (_userDatabase.FindUser(username) != null)
{
Debug.LogError($"用户 {username} 已存在");
return false;
}
var newUser = new UserInfo
{
Username = username,
Password = password,
Role = role,
CreatedTime = DateTime.Now,
IsActive = true
};
_userDatabase.Users.Add(newUser);
SaveUserDatabase();
// 记录添加用户日志
var logService = ServiceLocator.Get<UserLogService>();
logService?.LogUserOperation(CurrentUsername ?? "system", "添加用户",
$"新用户: {username}, 角色: {role}", true);
Debug.Log($"成功添加用户 {username},角色: {role}");
return true;
}
/// <summary>
/// 删除用户
/// </summary>
public bool RemoveUser(string username)
{
if (string.IsNullOrEmpty(username))
{
return false;
}
// 不能删除admin用户(区分大小写)
if (username == "admin")
{
Debug.LogError("不能删除管理员账户");
return false;
}
// 不能删除当前登录用户(区分大小写)
if (username == CurrentUsername)
{
Debug.LogError("不能删除当前登录用户");
return false;
}
var user = _userDatabase.FindUser(username);
if (user != null)
{
_userDatabase.Users.Remove(user);
SaveUserDatabase();
// 记录删除用户日志
var logService = ServiceLocator.Get<UserLogService>();
logService?.LogUserOperation(CurrentUsername ?? "system", "删除用户",
$"删除用户: {username}, 角色: {user.Role}", true);
Debug.Log($"成功删除用户 {username}");
return true;
}
Debug.LogError($"用户 {username} 不存在");
return false;
}
/// <summary>
/// 修改用户密码 - 支持管理员重置和用户自改密码
/// </summary>
public bool ChangePassword(string username, string oldPassword, string newPassword)
{
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(newPassword))
{
Debug.LogError("用户名和新密码不能为空");
return false;
}
var user = _userDatabase.FindUser(username);
if (user == null)
{
Debug.LogError($"用户 {username} 不存在");
return false;
}
// 检查操作权限(区分大小写)
bool isAdmin = CurrentRole == UserRole.Admin;
bool isSelfChange = username == CurrentUsername;
// 如果是管理员操作且不是修改自己的密码,可以跳过旧密码验证
if (isAdmin && !isSelfChange)
{
user.Password = newPassword;
user.PasswordChangedTime = DateTime.Now;
SaveUserDatabase();
// 记录管理员重置密码日志
var logService = ServiceLocator.Get<UserLogService>();
logService?.LogUserOperation(CurrentUsername, "重置用户密码",
$"管理员重置用户 {username} 的密码", true);
Debug.Log($"管理员重置用户 {username} 密码成功");
return true;
}
// 其他情况需要验证旧密码
if (string.IsNullOrEmpty(oldPassword))
{
Debug.LogError("修改密码需要提供旧密码");
return false;
}
if (user.Password != oldPassword)
{
Debug.LogError("旧密码错误");
return false;
}
user.Password = newPassword;
user.PasswordChangedTime = DateTime.Now;
SaveUserDatabase();
// 记录修改密码日志
var logService2 = ServiceLocator.Get<UserLogService>();
logService2?.LogUserOperation(username, "修改密码",
isSelfChange ? "用户修改自己的密码" : $"修改用户 {username} 的密码", true);
Debug.Log($"用户 {username} 密码修改成功");
return true;
}
/// <summary>
/// 获取所有用户信息(不包含密码)
/// </summary>
public List<UserInfo> GetAllUsers()
{
var result = new List<UserInfo>();
foreach (var user in _userDatabase.Users)
{
result.Add(new UserInfo
{
Username = user.Username,
Role = user.Role,
CreatedTime = user.CreatedTime,
LastLoginTime = user.LastLoginTime,
IsActive = user.IsActive
// 不返回密码信息
});
}
return result;
}
/// <summary>
/// 加载用户数据库
/// </summary>
private void LoadUserDatabase()
{
try
{
if (File.Exists(_dataFilePath))
{
string json = File.ReadAllText(_dataFilePath);
_userDatabase = JsonUtility.FromJson<UserDatabase>(json);
if (_userDatabase == null || _userDatabase.Users == null)
{
Debug.LogWarning("用户数据库格式错误,创建新的数据库");
CreateDefaultUserDatabase();
}
else
{
Debug.Log($"成功加载用户数据库,共 {_userDatabase.Users.Count} 个用户");
}
}
else
{
// 创建默认用户数据库
CreateDefaultUserDatabase();
}
}
catch (Exception ex)
{
Debug.LogError($"加载用户数据库失败: {ex.Message}");
CreateDefaultUserDatabase();
}
// 确保数据库不为空
if (_userDatabase == null)
{
CreateDefaultUserDatabase();
}
}
public bool ValidCurrentPassword(string password)
{
if (CurrentUser != null && CurrentUser.Username != null)
{
var user = _userDatabase.FindUser(CurrentUser.Username);
if (user != null && user.Password == password)
{
Debug.Log("当前密码验证成功");
return true;
}
}
Debug.Log("当前密码验证失败");
return false;
}
/// <summary>
/// 保存用户数据库
/// </summary>
private void SaveUserDatabase()
{
try
{
// 确保目录存在persistentDataPath 通常已存在,但为了安全起见还是检查一下)
string directory = Path.GetDirectoryName(_dataFilePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
string json = JsonUtility.ToJson(_userDatabase, true);
File.WriteAllText(_dataFilePath, json);
Debug.Log($"用户数据库保存成功到: {_dataFilePath}");
}
catch (Exception ex)
{
Debug.LogError($"保存用户数据库失败: {ex.Message}");
}
}
/// <summary>
/// 创建默认用户数据库
/// </summary>
private void CreateDefaultUserDatabase()
{
_userDatabase = new UserDatabase
{
Version = "1.0",
Users = new List<UserInfo>
{
new UserInfo
{
Username = "admin",
Password = "admin",
Role = UserRole.Admin,
CreatedTime = DateTime.Now,
IsActive = true
},
new UserInfo
{
Username = "user",
Password = "123456",
Role = UserRole.User,
CreatedTime = DateTime.Now,
IsActive = true
}
}
};
SaveUserDatabase();
Debug.Log("创建默认用户数据库");
}
/// <summary>
/// 验证用户名格式
/// 只允许字母、数字和下划线长度3-20个字符
/// </summary>
private bool IsValidUsername(string username)
{
if (string.IsNullOrEmpty(username))
return false;
// 长度限制
if (username.Length < 3 || username.Length > 20)
{
Debug.LogError("用户名长度必须在3-20个字符之间");
return false;
}
// 只允许字母、数字和下划线
foreach (char c in username)
{
if (!char.IsLetterOrDigit(c) && c != '_')
{
return false;
}
}
return true;
}
/// <summary>
/// 获取当前用户数量
/// </summary>
public int GetUserCount()
{
return _userDatabase?.Users?.Count ?? 0;
}
/// <summary>
/// 获取最大用户数量限制
/// </summary>
public int GetMaxUserCount()
{
return MAX_USER_COUNT;
}
/// <summary>
/// 获取数据文件路径(用于调试)
/// </summary>
public string GetDataFilePath()
{
return _dataFilePath;
}
}
// /// <summary>
// /// 用户数据库结构
// /// </summary>
// [System.Serializable]
// public class UserDatabase
// {
// public string Version = "1.0";
// public List<UserInfo> Users = new List<UserInfo>();
// public UserInfo FindUser(string username)
// {
// return Users.Find(u => u.Username.Equals(username, StringComparison.OrdinalIgnoreCase) && u.IsActive);
// }
// }
// /// <summary>
// /// 用户信息扩展
// /// </summary>
// [System.Serializable]
// public class UserInfo
// {
// public string Username;
// public string Password;
// public UserRole Role;
// public DateTime CreatedTime;
// public DateTime LastLoginTime;
// public DateTime PasswordChangedTime;
// public bool IsActive = true;
// }
// public class UseLogEvent
// {
// public int Id;
// public string OperationContentText;
// public DateTime Time;
// public string Account;
// }