394 lines
13 KiB
C#
394 lines
13 KiB
C#
using System.ComponentModel;
|
||
using System.Runtime.CompilerServices;
|
||
using System.Windows.Media;
|
||
using OrpaonVision.Core.Security;
|
||
using OrpaonVision.Core.Security.Contracts;
|
||
using OrpaonVision.Core.Security.Contracts.Commands;
|
||
using OrpaonVision.Core.Security.Contracts.Queries;
|
||
|
||
namespace OrpaonVision.ConfigApp.ViewModels;
|
||
|
||
/// <summary>
|
||
/// 用户管理ViewModel。
|
||
/// </summary>
|
||
public sealed class UserManagementViewModel : INotifyPropertyChanged
|
||
{
|
||
private readonly IUserAppService _userAppService;
|
||
|
||
private string _statusText = "准备就绪。";
|
||
private Brush _statusBrush = Brushes.DarkGreen;
|
||
private string _outputText = string.Empty;
|
||
private UserDetailDto? _selectedUser;
|
||
private string _searchKeyword = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 构造函数。
|
||
/// </summary>
|
||
public UserManagementViewModel(IUserAppService userAppService)
|
||
{
|
||
_userAppService = userAppService;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 状态文本。
|
||
/// </summary>
|
||
public string StatusText
|
||
{
|
||
get => _statusText;
|
||
private set => SetProperty(ref _statusText, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 状态画刷。
|
||
/// </summary>
|
||
public Brush StatusBrush
|
||
{
|
||
get => _statusBrush;
|
||
private set => SetProperty(ref _statusBrush, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 输出文本。
|
||
/// </summary>
|
||
public string OutputText
|
||
{
|
||
get => _outputText;
|
||
private set => SetProperty(ref _outputText, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 选中的用户。
|
||
/// </summary>
|
||
public UserDetailDto? SelectedUser
|
||
{
|
||
get => _selectedUser;
|
||
private set => SetProperty(ref _selectedUser, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 搜索关键词。
|
||
/// </summary>
|
||
public string SearchKeyword
|
||
{
|
||
get => _searchKeyword;
|
||
set => SetProperty(ref _searchKeyword, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询用户详情。
|
||
/// </summary>
|
||
public async Task QueryUserDetailAsync()
|
||
{
|
||
try
|
||
{
|
||
StatusBrush = Brushes.DarkGreen;
|
||
StatusText = "正在查询用户详情...";
|
||
|
||
if (string.IsNullOrWhiteSpace(SearchKeyword))
|
||
{
|
||
StatusBrush = Brushes.Orange;
|
||
StatusText = "请输入用户ID或用户名";
|
||
return;
|
||
}
|
||
|
||
// 这里演示如何查询用户详情
|
||
// 实际实现需要根据SearchKeyword判断是用户ID还是用户名
|
||
var userId = Guid.TryParse(SearchKeyword, out var parsedId) ? parsedId : Guid.NewGuid();
|
||
var result = await _userAppService.GetDetailAsync(userId);
|
||
|
||
if (result.Succeeded && result.Data != null)
|
||
{
|
||
SelectedUser = result.Data;
|
||
StatusText = "用户详情查询成功";
|
||
OutputText = $"用户名:{result.Data.UserName}\n" +
|
||
$"显示名称:{result.Data.DisplayName}\n" +
|
||
$"邮箱:{result.Data.Email}\n" +
|
||
$"状态:{result.Data.Status}\n" +
|
||
$"角色数:{result.Data.Roles.Count}\n" +
|
||
$"权限数:{result.Data.Permissions.Count}\n" +
|
||
$"最后登录:{result.Data.LastLoginAtUtc:yyyy-MM-dd HH:mm}";
|
||
}
|
||
else
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "查询用户详情失败";
|
||
OutputText = $"错误:{result.Message}";
|
||
SelectedUser = null;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "查询用户详情异常";
|
||
OutputText = $"异常:{ex.Message}";
|
||
SelectedUser = null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建新用户。
|
||
/// </summary>
|
||
public async Task CreateUserAsync()
|
||
{
|
||
try
|
||
{
|
||
StatusBrush = Brushes.DarkGreen;
|
||
StatusText = "正在创建新用户...";
|
||
|
||
// 这里演示如何创建用户
|
||
var command = new OrpaonVision.Core.Security.Contracts.Commands.CreateUserCommand
|
||
{
|
||
UserName = "newuser_" + DateTime.Now.Ticks,
|
||
DisplayName = "新用户",
|
||
Email = "newuser@example.com",
|
||
Password = "TempPassword123!",
|
||
Roles = ["Operator"],
|
||
Permissions = ["production.view", "training.view"],
|
||
CreatedBy = "Admin"
|
||
};
|
||
|
||
var result = await _userAppService.CreateAsync(command);
|
||
|
||
if (result.Succeeded)
|
||
{
|
||
StatusText = "用户创建成功";
|
||
OutputText = $"用户ID:{result.Data}\n" +
|
||
$"用户名:{command.UserName}\n" +
|
||
$"显示名称:{command.DisplayName}\n" +
|
||
$"角色:{string.Join(", ", command.Roles)}\n" +
|
||
$"请及时修改初始密码";
|
||
}
|
||
else
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "创建用户失败";
|
||
OutputText = $"错误:{result.Message}";
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "创建用户异常";
|
||
OutputText = $"异常:{ex.Message}";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新用户信息。
|
||
/// </summary>
|
||
public async Task UpdateUserAsync()
|
||
{
|
||
try
|
||
{
|
||
StatusBrush = Brushes.DarkGreen;
|
||
StatusText = "正在更新用户信息...";
|
||
|
||
if (SelectedUser == null)
|
||
{
|
||
StatusBrush = Brushes.Orange;
|
||
StatusText = "请先选择要更新的用户";
|
||
return;
|
||
}
|
||
|
||
// 这里演示如何更新用户信息
|
||
var command = new OrpaonVision.Core.Security.Contracts.Commands.UpdateUserCommand
|
||
{
|
||
UserId = SelectedUser.UserId,
|
||
DisplayName = SelectedUser.DisplayName + " (已更新)",
|
||
Email = SelectedUser.Email,
|
||
IsActive = SelectedUser.IsActive,
|
||
Roles = SelectedUser.Roles.ToList(),
|
||
UpdatedBy = "Admin"
|
||
};
|
||
|
||
var result = await _userAppService.UpdateAsync(command);
|
||
|
||
if (result.Succeeded)
|
||
{
|
||
StatusText = "用户信息更新成功";
|
||
OutputText = $"用户ID:{command.UserId}\n" +
|
||
$"显示名称:{command.DisplayName}\n" +
|
||
$"状态:{(command.IsActive ? "激活" : "停用")}\n" +
|
||
$"角色:{string.Join(", ", command.Roles)}";
|
||
|
||
// 重新查询用户详情以更新显示
|
||
await QueryUserDetailAsync();
|
||
}
|
||
else
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "更新用户信息失败";
|
||
OutputText = $"错误:{result.Message}";
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "更新用户信息异常";
|
||
OutputText = $"异常:{ex.Message}";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除用户。
|
||
/// </summary>
|
||
public async Task DeleteUserAsync()
|
||
{
|
||
try
|
||
{
|
||
StatusBrush = Brushes.DarkGreen;
|
||
StatusText = "正在删除用户...";
|
||
|
||
if (SelectedUser == null)
|
||
{
|
||
StatusBrush = Brushes.Orange;
|
||
StatusText = "请先选择要删除的用户";
|
||
return;
|
||
}
|
||
|
||
// 这里演示如何删除用户
|
||
var command = new OrpaonVision.Core.Security.Contracts.Commands.DeleteUserCommand
|
||
{
|
||
UserId = SelectedUser.UserId,
|
||
DeletedBy = "Admin"
|
||
};
|
||
|
||
var result = await _userAppService.DeleteAsync(command);
|
||
|
||
if (result.Succeeded)
|
||
{
|
||
StatusText = "用户删除成功";
|
||
OutputText = $"已删除用户:{SelectedUser.UserName} ({SelectedUser.DisplayName})\n" +
|
||
$"用户ID:{command.UserId}\n" +
|
||
$"操作时间:{DateTime.UtcNow:yyyy-MM-dd HH:mm:ss}";
|
||
|
||
SelectedUser = null;
|
||
SearchKeyword = string.Empty;
|
||
}
|
||
else
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "删除用户失败";
|
||
OutputText = $"错误:{result.Message}";
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "删除用户异常";
|
||
OutputText = $"异常:{ex.Message}";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重置用户密码。
|
||
/// </summary>
|
||
public async Task ResetUserPasswordAsync()
|
||
{
|
||
try
|
||
{
|
||
StatusBrush = Brushes.DarkGreen;
|
||
StatusText = "正在重置用户密码...";
|
||
|
||
if (SelectedUser == null)
|
||
{
|
||
StatusBrush = Brushes.Orange;
|
||
StatusText = "请先选择要重置密码的用户";
|
||
return;
|
||
}
|
||
|
||
// 这里演示如何重置用户密码
|
||
var command = new OrpaonVision.Core.Security.Contracts.Commands.ResetUserPasswordCommand
|
||
{
|
||
UserId = SelectedUser.UserId,
|
||
NewPassword = "NewTempPassword123!",
|
||
ForceChangeOnNextLogin = true,
|
||
ResetBy = "Admin"
|
||
};
|
||
|
||
var result = await _userAppService.ResetPasswordAsync(command);
|
||
|
||
if (result.Succeeded)
|
||
{
|
||
StatusText = "密码重置成功";
|
||
OutputText = $"用户:{SelectedUser.UserName}\n" +
|
||
$"新密码:{command.NewPassword}\n" +
|
||
$"下次登录必须修改:{(command.ForceChangeOnNextLogin ? "是" : "否")}\n" +
|
||
$"请及时通知用户";
|
||
}
|
||
else
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "重置密码失败";
|
||
OutputText = $"错误:{result.Message}";
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "重置密码异常";
|
||
OutputText = $"异常:{ex.Message}";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 分页查询用户列表。
|
||
/// </summary>
|
||
public async Task QueryUserListAsync()
|
||
{
|
||
try
|
||
{
|
||
StatusBrush = Brushes.DarkGreen;
|
||
StatusText = "正在查询用户列表...";
|
||
|
||
// 这里演示如何分页查询用户列表
|
||
var query = new OrpaonVision.Core.Security.Contracts.Queries.UserQueryDto
|
||
{
|
||
Keyword = SearchKeyword,
|
||
PageIndex = 1,
|
||
PageSize = 20,
|
||
SortField = "UserName",
|
||
SortDirection = "ASC"
|
||
};
|
||
|
||
var result = await _userAppService.GetPagedListAsync(query);
|
||
|
||
if (result.Succeeded && result.Data != null)
|
||
{
|
||
StatusText = "用户列表查询成功";
|
||
OutputText = $"查询条件:{query.Keyword ?? "全部"}\n" +
|
||
$"用户总数:{result.Data.TotalCount}\n" +
|
||
$"当前页:{result.Data.PageIndex}/{result.Data.TotalPages}\n" +
|
||
$"本页记录:{result.Data.Items.Count}\n" +
|
||
$"查询时间:{DateTime.UtcNow:yyyy-MM-dd HH:mm:ss}";
|
||
}
|
||
else
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "查询用户列表失败";
|
||
OutputText = $"错误:{result.Message}";
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
StatusBrush = Brushes.OrangeRed;
|
||
StatusText = "查询用户列表异常";
|
||
OutputText = $"异常:{ex.Message}";
|
||
}
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public event PropertyChangedEventHandler? PropertyChanged;
|
||
|
||
private void SetProperty<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
|
||
{
|
||
if (EqualityComparer<T>.Default.Equals(field, value))
|
||
{
|
||
return;
|
||
}
|
||
|
||
field = value;
|
||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||
}
|
||
}
|