608 lines
20 KiB
C#
608 lines
20 KiB
C#
using HandyControl.Controls;
|
||
using HandyControl.Tools.Extension;
|
||
using SqlSugar;
|
||
using System.Diagnostics;
|
||
using System.Windows;
|
||
using YY.Admin.Core;
|
||
using YY.Admin.Core.Extension;
|
||
using YY.Admin.Core.Helper;
|
||
using YY.Admin.Services.Service;
|
||
using YY.Admin.Services.Service.User;
|
||
using YY.Admin.ViewModels.Control;
|
||
using YY.Admin.Views.SysManage;
|
||
|
||
namespace YY.Admin.ViewModels.SysManage
|
||
{
|
||
public class UserManagementViewModel : BaseViewModel
|
||
{
|
||
private PaginationDataGridViewModel<UserOutput> _paginationDataGridViewModel;
|
||
|
||
private PageUserInput _userInput;
|
||
|
||
private readonly ISysUserService _sysUserService;
|
||
|
||
private readonly IDialogService _dialogService;
|
||
private SubscriptionToken? _jeecgSyncToken;
|
||
public PaginationDataGridViewModel<UserOutput> PaginationDataGridViewModel
|
||
{
|
||
get => _paginationDataGridViewModel;
|
||
set => SetProperty(ref _paginationDataGridViewModel, value);
|
||
}
|
||
|
||
|
||
public PageUserInput UserInput
|
||
{ get => _userInput;
|
||
set => SetProperty(ref _userInput, value);
|
||
}
|
||
|
||
// 性别枚举列表属性
|
||
public List<GenderEnum> GenderList =>
|
||
[.. Enum.GetValues(typeof(GenderEnum)).Cast<GenderEnum>()];
|
||
|
||
// 状态枚举列表属性
|
||
public List<KeyValuePair<string, int>> StatusList =>
|
||
Enum.GetValues(typeof(StatusEnum))
|
||
.Cast<StatusEnum>()
|
||
.Select(e => new KeyValuePair<string, int>(e.GetDescription(), (int)e))
|
||
.ToList();
|
||
|
||
// 全选
|
||
//private bool? _isAllSelected = false;
|
||
//public bool? IsAllSelected
|
||
//{
|
||
// get => _isAllSelected;
|
||
// set
|
||
// {
|
||
// if (SetProperty(ref _isAllSelected, value) && value.HasValue)
|
||
// {
|
||
// // 只有当值真正改变时才执行全选逻辑
|
||
// SelectAll(value.Value);
|
||
// }
|
||
// }
|
||
//}
|
||
|
||
// 选中用户数量
|
||
private int _selectedCount;
|
||
public int SelectedCount
|
||
{
|
||
get => _selectedCount;
|
||
set
|
||
{
|
||
if (SetProperty(ref _selectedCount, value))
|
||
{
|
||
// 当 SelectedCount 变化时,触发 HasSelectedItems 通知
|
||
RaisePropertyChanged(nameof(HasSelectedItems));
|
||
}
|
||
}
|
||
}
|
||
|
||
// 是否有选中项
|
||
public bool HasSelectedItems => SelectedCount > 0;
|
||
|
||
// 批量删除
|
||
public DelegateCommand BatchDeleteCommand { get; private set; }
|
||
|
||
// 单个删除
|
||
public DelegateCommand<long?> DeleteCommand { get; private set; }
|
||
|
||
// 查询
|
||
public DelegateCommand SearchCommand { get; private set; }
|
||
|
||
public DelegateCommand ResetCommand { get; private set; }
|
||
|
||
public DelegateCommand AddCommand { get; private set; }
|
||
public DelegateCommand<UserOutput> EditCommand { get; private set; }
|
||
|
||
public DelegateCommand<UserOutput> StatusToggleCommand { get; private set; }
|
||
|
||
|
||
// 行选择改变命令
|
||
//public DelegateCommand<UserOutput> RowSelectionChangedCommand { get; private set; }
|
||
|
||
public UserManagementViewModel(
|
||
ISysUserService sysUserService,
|
||
IContainerExtension container,
|
||
IDialogService dialogService,
|
||
IRegionManager regionManager
|
||
) : base(container, regionManager)
|
||
{
|
||
_sysUserService= sysUserService;
|
||
_dialogService = dialogService;
|
||
// 创建分页控件的 ViewModel,传递一个获取数据的委托
|
||
_paginationDataGridViewModel = new PaginationDataGridViewModel<UserOutput>(FetchUsersAsync);
|
||
_userInput = new PageUserInput();
|
||
|
||
// 初始化批量删除命令
|
||
BatchDeleteCommand = new DelegateCommand(async () => await BatchDelete(),
|
||
() => HasSelectedItems);
|
||
|
||
DeleteCommand = new DelegateCommand<long?>(async (id) => {
|
||
if (id.HasValue)
|
||
{
|
||
await Delete(id.Value);
|
||
}
|
||
});
|
||
|
||
SearchCommand = new DelegateCommand(async () => await ReadAsync());
|
||
|
||
ResetCommand = new DelegateCommand(async () => await ResetFormAsync());
|
||
|
||
AddCommand = new DelegateCommand(async () => await ShowAddDialog());
|
||
|
||
EditCommand = new DelegateCommand<UserOutput>(async (user) => await ShowEditDialog(user));
|
||
|
||
StatusToggleCommand = new DelegateCommand<UserOutput>(async (user) => await ToggleStatus(user));
|
||
|
||
//RowSelectionChangedCommand = new DelegateCommand<UserOutput>(OnRowSelectionChanged);
|
||
|
||
// 监听数据变化
|
||
//PaginationDataGridViewModel.PropertyChanged += OnPaginationDataChanged;
|
||
//_ = PaginationDataGridViewModel.LoadDataAsync(); // 默认加载第一页数据
|
||
|
||
//_dataList = GetDemoDataList(10);
|
||
|
||
// 启动异步初始化,但不等待
|
||
_ = InitializeAsync();
|
||
|
||
// Jeecg 同构用户表同步完成后,自动刷新当前列表
|
||
_jeecgSyncToken = _eventAggregator
|
||
.GetEvent<SysUserEvents.JeecgMirrorUsersSyncedEvent>()
|
||
.Subscribe(async _ =>
|
||
{
|
||
await PaginationDataGridViewModel.LoadDataAsync();
|
||
}, ThreadOption.UIThread);
|
||
}
|
||
|
||
private async Task InitializeAsync()
|
||
{
|
||
try
|
||
{
|
||
// 不阻塞UI线程,让UI先渲染(效果就是先看到界面,然后再加载表格数据,提升用户体验)
|
||
await UIHelper.WaitForRenderAsync();
|
||
|
||
// 然后异步加载数据
|
||
await PaginationDataGridViewModel.LoadDataAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"初始化失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
protected override void CleanUp()
|
||
{
|
||
base.CleanUp();
|
||
if (_jeecgSyncToken != null)
|
||
{
|
||
_eventAggregator.GetEvent<SysUserEvents.JeecgMirrorUsersSyncedEvent>().Unsubscribe(_jeecgSyncToken);
|
||
_jeecgSyncToken = null;
|
||
}
|
||
}
|
||
|
||
// 行选择改变事件处理
|
||
//private void OnRowSelectionChanged(UserOutput user)
|
||
//{
|
||
// if (user == null) return;
|
||
|
||
// user.IsSelected = !user.IsSelected;
|
||
|
||
// // 更新选中数量
|
||
// UpdateSelectedCount();
|
||
|
||
// // 更新全选状态
|
||
// UpdateSelectAllStatus();
|
||
|
||
// // 更新批量删除命令状态
|
||
// BatchDeleteCommand.RaiseCanExecuteChanged();
|
||
|
||
// // 调试输出
|
||
// //System.Diagnostics.Debug.WriteLine($"用户 {user.UserName} 选中状态: {user.IsSelected}");
|
||
//}
|
||
|
||
|
||
//private void OnPaginationDataChanged(object sender, PropertyChangedEventArgs e)
|
||
//{
|
||
// if (e.PropertyName == nameof(PaginationDataGridViewModel.Data))
|
||
// {
|
||
// RegisterSelectionEvents();
|
||
// UpdateSelectedCount();
|
||
// }
|
||
//}
|
||
|
||
// 注册选择事件监听
|
||
//private void RegisterSelectionEvents()
|
||
//{
|
||
// if (PaginationDataGridViewModel.Data == null) return;
|
||
|
||
// foreach (var user in PaginationDataGridViewModel.Data.OfType<UserOutput>())
|
||
// {
|
||
// user.SelectionChanged -= OnUserSelectionChanged;
|
||
// user.SelectionChanged += OnUserSelectionChanged;
|
||
// }
|
||
//}
|
||
|
||
//private void OnUserSelectionChanged(object sender, EventArgs e)
|
||
//{
|
||
// UpdateSelectedCount();
|
||
// // 更新全选状态
|
||
// UpdateSelectAllStatus();
|
||
// BatchDeleteCommand.RaiseCanExecuteChanged();
|
||
//}
|
||
|
||
|
||
public void UpdateSelectionState()
|
||
{
|
||
UpdateSelectedCount();
|
||
//UpdateSelectAllStatus();
|
||
BatchDeleteCommand.RaiseCanExecuteChanged();
|
||
}
|
||
|
||
// 更新选中数量
|
||
private void UpdateSelectedCount()
|
||
{
|
||
if (PaginationDataGridViewModel.Data == null)
|
||
{
|
||
SelectedCount = 0;
|
||
return;
|
||
}
|
||
|
||
SelectedCount = PaginationDataGridViewModel.Data.Count(user =>
|
||
user is UserOutput output && output.IsSelected);
|
||
}
|
||
|
||
// 获取选中的用户ID列表
|
||
private List<long> GetSelectedUserIds()
|
||
{
|
||
if (PaginationDataGridViewModel.Data == null)
|
||
return new List<long>();
|
||
|
||
return PaginationDataGridViewModel.Data
|
||
.Where(user => user is UserOutput output && output.IsSelected)
|
||
.Select(user => (user as UserOutput).Id)
|
||
.ToList();
|
||
}
|
||
|
||
// 批量删除执行方法
|
||
private async Task BatchDelete()
|
||
{
|
||
var selectedUserIds = GetSelectedUserIds();
|
||
if (selectedUserIds.Count == 0) return;
|
||
|
||
var messageBoxResult = HandyControl.Controls.MessageBox.Show(
|
||
$"确定要删除选中的 {selectedUserIds.Count} 个用户吗?此操作不可恢复!",
|
||
"确认删除",
|
||
MessageBoxButton.OKCancel,
|
||
MessageBoxImage.Question);
|
||
|
||
if (messageBoxResult != MessageBoxResult.OK) return;
|
||
|
||
int count = await _sysUserService.BatchDeleteAsync(selectedUserIds);
|
||
|
||
if (count > 0)
|
||
{
|
||
PaginationDataGridViewModel.PageIndex = 1;
|
||
await PaginationDataGridViewModel.LoadDataAsync();
|
||
}
|
||
|
||
// 1. 准备传递给对话框的参数
|
||
//var parameters = new DialogParameters();
|
||
//parameters.Add("Title", "操作确认");
|
||
//parameters.Add("Message", "确定要执行此操作吗?");
|
||
//parameters.Add("ConfirmButtonText", "确认"); // 可选:自定义确认按钮文本
|
||
//parameters.Add("CancelButtonText", "取消"); // 可选:自定义取消按钮文本
|
||
|
||
// 2. 显示对话框并处理返回结果
|
||
//_dialogService.ShowDialog(
|
||
// "ConfirmDialog", // 注册时使用的对话框名称
|
||
// parameters,
|
||
// result =>
|
||
// {
|
||
// // 3. 根据对话框返回结果执行后续逻辑
|
||
// if (result.Result == ButtonResult.OK)
|
||
// {
|
||
// // 用户点击了确认按钮
|
||
// //ExecuteConfirmedAction();
|
||
// }
|
||
// else if (result.Result == ButtonResult.Cancel)
|
||
// {
|
||
// // 用户点击了取消按钮
|
||
// //ExecuteCancelledAction();
|
||
// }
|
||
// }
|
||
//);
|
||
}
|
||
|
||
// 删除执行方法
|
||
private async Task Delete(long id)
|
||
{
|
||
var messageBoxResult = HandyControl.Controls.MessageBox.Show(
|
||
$"确定删除ID为 {id} 的用户吗?此操作不可恢复!",
|
||
"确认删除",
|
||
MessageBoxButton.OKCancel,
|
||
MessageBoxImage.Question,
|
||
MessageBoxResult.No);
|
||
|
||
if (messageBoxResult != MessageBoxResult.OK) return;
|
||
|
||
int count = await _sysUserService.DeleteAsync(id);
|
||
|
||
if (count > 0)
|
||
{
|
||
PaginationDataGridViewModel.PageIndex = 1;
|
||
await PaginationDataGridViewModel.LoadDataAsync();
|
||
}
|
||
}
|
||
|
||
private async Task<(IEnumerable<UserOutput> data, int totalCount)> FetchUsersAsync()
|
||
{
|
||
if (UserInput.EndTime.HasValue && UserInput.EndTime.HasValue && UserInput.EndTime < UserInput.BeginTime)
|
||
{
|
||
HandyControl.Controls.MessageBox.Error("开始时间不能大于结束时间!");
|
||
//return (PaginationDataGridViewModel.Data, PaginationDataGridViewModel.TotalCount);
|
||
throw new OperationCanceledException("时间条件不合法,取消查询");
|
||
}
|
||
UserInput.Page = PaginationDataGridViewModel.PageIndex;
|
||
UserInput.PageSize = PaginationDataGridViewModel.DataCountPerPage;
|
||
|
||
// 延迟10秒
|
||
//await Task.Delay(10000);
|
||
|
||
var rlt = await _sysUserService.PageAsync(UserInput);
|
||
return (rlt.Items, rlt.Total); // 返回分页数据和总条目数
|
||
}
|
||
|
||
private async Task ReadAsync()
|
||
{
|
||
PaginationDataGridViewModel.PageIndex = 1;
|
||
await PaginationDataGridViewModel.LoadDataAsync();
|
||
|
||
}
|
||
|
||
public async Task ResetFormAsync()
|
||
{
|
||
UserInput = new PageUserInput();
|
||
|
||
// 立即更新UI
|
||
await UIHelper.WaitForRenderAsync();
|
||
|
||
await ReadAsync();
|
||
}
|
||
|
||
// 显示新增对话框
|
||
private async Task ShowAddDialog()
|
||
{
|
||
try
|
||
{
|
||
//var vm = new UserEditDialogViewModel(_sysUserService, _container);
|
||
//var view = new UserEditDialogView { DataContext = vm };
|
||
|
||
var result = await HandyControl.Controls.Dialog.Show<UserEditDialogView>()
|
||
.Initialize<UserEditDialogViewModel>(v => v.InitializeForAdd())
|
||
.GetResultAsync<bool>();
|
||
// 使用泛型方式,通过 Initialize 方法设置数据
|
||
//var result = await HandyControl.Controls.Dialog.Show<UserEditDialogView>()
|
||
// .Initialize<UserEditDialogViewModel>(vm =>
|
||
// {
|
||
// vm.InitializeForAdd();
|
||
// })
|
||
// .GetResultAsync<bool?>();
|
||
|
||
if (result)
|
||
{
|
||
await PaginationDataGridViewModel.LoadDataAsync();
|
||
//Growl.Success("用户新增成功!");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Growl.Error($"打开对话框失败:{ex.Message}");
|
||
}
|
||
}
|
||
|
||
// 显示编辑对话框
|
||
private async Task ShowEditDialog(UserOutput user)
|
||
{
|
||
if (user == null) return;
|
||
|
||
try
|
||
{
|
||
var result = await HandyControl.Controls.Dialog.Show<UserEditDialogView>()
|
||
.Initialize<UserEditDialogViewModel>(vm =>
|
||
{
|
||
vm.InitializeForEdit(user);
|
||
})
|
||
.GetResultAsync<bool>();
|
||
|
||
if (result)
|
||
{
|
||
await PaginationDataGridViewModel.LoadDataAsync();
|
||
//Growl.Success("用户修改成功!");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Growl.Error($"打开对话框失败:{ex.Message}");
|
||
}
|
||
}
|
||
|
||
private async Task ToggleStatus(UserOutput user)
|
||
{
|
||
if (user == null) return;
|
||
|
||
// 保存原始状态以便回滚
|
||
var originalStatus = user.Status;
|
||
try
|
||
{
|
||
// 先切换本地状态(提供即时反馈)
|
||
user.Status = originalStatus == StatusEnum.Enable
|
||
? StatusEnum.Disable
|
||
: StatusEnum.Enable;
|
||
|
||
SysUser sysUser = new SysUser();
|
||
sysUser.Id = user.Id;
|
||
sysUser.Status = user.Status;
|
||
|
||
int count = await _sysUserService.ToggleStatus(sysUser);
|
||
|
||
if (count <= 0)
|
||
{
|
||
// 如果服务调用失败,回滚状态
|
||
user.Status = originalStatus;
|
||
Growl.Warning("状态切换失败");
|
||
}
|
||
} catch (Exception)
|
||
{
|
||
user.Status = originalStatus;
|
||
Growl.Warning("状态切换失败");
|
||
}
|
||
}
|
||
|
||
// 全选/取消全选方法
|
||
//private void SelectAll(bool isSelected)
|
||
//{
|
||
// if (PaginationDataGridViewModel?.Data == null) return;
|
||
|
||
// foreach (var user in PaginationDataGridViewModel.Data.OfType<UserOutput>())
|
||
// {
|
||
// user.IsSelected = isSelected;
|
||
// }
|
||
|
||
// // 更新选中数量
|
||
// UpdateSelectedCount();
|
||
//}
|
||
|
||
// 更新全选状态(根据当前选中情况)
|
||
//public void UpdateSelectAllStatus()
|
||
//{
|
||
// if (PaginationDataGridViewModel?.Data == null || !PaginationDataGridViewModel.Data.Any())
|
||
// {
|
||
// IsAllSelected = false;
|
||
// return;
|
||
// }
|
||
|
||
// var selectedCount = PaginationDataGridViewModel.Data.Count(user =>
|
||
// user is UserOutput output && output.IsSelected);
|
||
// var totalCount = PaginationDataGridViewModel.Data.Count;
|
||
|
||
// if (selectedCount == 0)
|
||
// {
|
||
// IsAllSelected = false;
|
||
// }
|
||
// else if (selectedCount == totalCount)
|
||
// {
|
||
// IsAllSelected = true;
|
||
// }
|
||
// else
|
||
// {
|
||
// IsAllSelected = null; // 部分选中状态
|
||
// }
|
||
|
||
//}
|
||
|
||
//private string _searchText;
|
||
//public string SearchText
|
||
//{
|
||
// get => _searchText;
|
||
// set
|
||
// {
|
||
// if (SetProperty(ref _searchText, value))
|
||
// {
|
||
// Debug.WriteLine($"SearchText Updated: {value}");
|
||
// FilterItems(value);
|
||
// }
|
||
// }
|
||
//}
|
||
|
||
//private DemoDataModel? _selectedItem;
|
||
//public DemoDataModel? SelectedItem
|
||
//{
|
||
// get => _selectedItem;
|
||
// set
|
||
// {
|
||
// if (SetProperty(ref _selectedItem, value))
|
||
// {
|
||
// Debug.WriteLine($"SelectedItem Updated: {value}");
|
||
// }
|
||
// }
|
||
//}
|
||
|
||
//// 修改 Items 属性为 ManualObservableCollection
|
||
//private ManualObservableCollection<DemoDataModel> _items = new();
|
||
//public ManualObservableCollection<DemoDataModel> Items
|
||
//{
|
||
// get => _items;
|
||
// set => SetProperty(ref _items, value);
|
||
//}
|
||
|
||
//private readonly List<DemoDataModel> _dataList;
|
||
|
||
//private void FilterItems(string key)
|
||
//{
|
||
// //Items.CanNotify = false;
|
||
|
||
// Items.Clear();
|
||
|
||
// foreach (var data in _dataList)
|
||
// {
|
||
// if (data.Name.ToLower().Contains(key.ToLower()))
|
||
// {
|
||
// Items.Add(data);
|
||
// }
|
||
// }
|
||
|
||
// //RaisePropertyChanged(nameof(Items));
|
||
// //Items.CanNotify = true;
|
||
//}
|
||
//List<DemoDataModel> GetDemoDataList(int count)
|
||
//{
|
||
// var list = new List<DemoDataModel>();
|
||
// for (var i = 1; i <= count; i++)
|
||
// {
|
||
// var index = i % 6 + 1;
|
||
// var model = new DemoDataModel
|
||
// {
|
||
// Index = i,
|
||
// IsSelected = i % 2 == 0,
|
||
// Name = $"Name{i}",
|
||
// Type = (DemoType)index,
|
||
// ImgPath = $"/HandyControlDemo;component/Resources/Img/Avatar/avatar{index}.png",
|
||
// Remark = new string(i.ToString()[0], 10)
|
||
// };
|
||
// list.Add(model);
|
||
// }
|
||
|
||
// return list;
|
||
//}
|
||
}
|
||
|
||
|
||
// public class DemoDataModel
|
||
//{
|
||
// public int Index { get; set; }
|
||
|
||
// public string Name { get; set; } = string.Empty;
|
||
|
||
// public bool IsSelected { get; set; }
|
||
|
||
// public string Remark { get; set; } = string.Empty;
|
||
|
||
// public DemoType Type { get; set; }
|
||
|
||
// public string ImgPath { get; set; } = string.Empty;
|
||
|
||
// public List<DemoDataModel> DataList { get; set; } = [];
|
||
//}
|
||
|
||
//public enum DemoType
|
||
//{
|
||
// Type1 = 1,
|
||
// Type2,
|
||
// Type3,
|
||
// Type4,
|
||
// Type5,
|
||
// Type6
|
||
//}
|
||
|
||
}
|
||
|