using FATrace.Model; using FATrace.WPLApp.Core; using FATrace.WPLApp.Services; using FreeSql; using Prism.Commands; using Prism.Services.Dialogs; using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Threading.Tasks; using System.Windows; namespace FATrace.WPLApp.ViewModels { /// /// 用户管理页面 VM(TbUser 增删改查) /// public class UserManageViewModel : NavigationViewModel { private readonly IFreeSql _fsql; private readonly ILogService _log; private readonly IDialogService _dialog; private readonly SysRunService _sys; public UserManageViewModel(IFreeSql fsql, ILogService log, IDialogService dialogService, SysRunService sys) { _fsql = fsql; _log = log; _dialog = dialogService; _sys = sys; AccessLevelOptions = new ObservableCollection(new[] { AccessLevels.All, AccessLevels.Admin, AccessLevels.Operator, AccessLevels.Guest }); AccessLevel = AccessLevels.All; Items = new ObservableCollection(); SearchCommand = new DelegateCommand(async () => await SearchAsync(), () => !IsBusy) .ObservesProperty(() => IsBusy); ClearCommand = new DelegateCommand(ClearFilters, () => !IsBusy) .ObservesProperty(() => IsBusy); AddCommand = new DelegateCommand(AddUser, () => !IsBusy && CanEditUsers) .ObservesProperty(() => IsBusy) .ObservesProperty(() => CanEditUsers); EditCommand = new DelegateCommand(EditUser, () => !IsBusy && CanEditUsers && SelectedItem != null) .ObservesProperty(() => IsBusy) .ObservesProperty(() => CanEditUsers) .ObservesProperty(() => SelectedItem); DeleteCommand = new DelegateCommand(async () => await DeleteUserAsync(), () => !IsBusy && CanEditUsers && SelectedItem != null) .ObservesProperty(() => IsBusy) .ObservesProperty(() => CanEditUsers) .ObservesProperty(() => SelectedItem); FirstPageCommand = new DelegateCommand(async () => { if (PageIndex == 1) return; PageIndex = 1; await SearchAsync(); }, () => !IsBusy && PageIndex > 1) .ObservesProperty(() => IsBusy) .ObservesProperty(() => PageIndex); PrevPageCommand = new DelegateCommand(async () => { if (PageIndex <= 1) return; PageIndex -= 1; await SearchAsync(); }, () => !IsBusy && PageIndex > 1) .ObservesProperty(() => IsBusy) .ObservesProperty(() => PageIndex); NextPageCommand = new DelegateCommand(async () => { if (PageIndex >= TotalPages) return; PageIndex += 1; await SearchAsync(); }, () => !IsBusy && PageIndex < TotalPages) .ObservesProperty(() => IsBusy) .ObservesProperty(() => PageIndex) .ObservesProperty(() => TotalPages); LastPageCommand = new DelegateCommand(async () => { if (TotalPages <= 0 || PageIndex == TotalPages) return; PageIndex = TotalPages; await SearchAsync(); }, () => !IsBusy && PageIndex < TotalPages) .ObservesProperty(() => IsBusy) .ObservesProperty(() => PageIndex) .ObservesProperty(() => TotalPages); _sys.PropertyChanged += SysOnPropertyChanged; RaisePropertyChanged(nameof(CanEditUsers)); } private void SysOnPropertyChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(SysRunService.CurAccessLevel) || e.PropertyName == nameof(SysRunService.CurUser)) { RaisePropertyChanged(nameof(CanEditUsers)); } } /// /// 是否允许编辑用户(仅管理员) /// public bool CanEditUsers => string.Equals(_sys.CurAccessLevel, AccessLevels.Admin, StringComparison.OrdinalIgnoreCase); #region 查询条件 private string? _userName; /// /// 用户名(模糊匹配) /// public string? UserName { get => _userName; set { _userName = value; RaisePropertyChanged(); } } private string? _accessLevel; /// /// 等级(精确匹配) /// public string? AccessLevel { get => _accessLevel; set { _accessLevel = value; RaisePropertyChanged(); } } /// /// 等级下拉选项 /// public ObservableCollection AccessLevelOptions { get; } #endregion #region 列表与分页 public ObservableCollection Items { get; } private TbUser? _selectedItem; /// /// 当前选中行 /// public TbUser? SelectedItem { get => _selectedItem; set { _selectedItem = value; RaisePropertyChanged(); } } private bool _isBusy; /// /// 是否忙碌 /// public bool IsBusy { get => _isBusy; set { _isBusy = value; RaisePropertyChanged(); } } private int _totalCount; /// /// 总数 /// public int TotalCount { get => _totalCount; set { _totalCount = value; RaisePropertyChanged(); } } private int _pageIndex = 1; /// /// 页码(从1开始) /// public int PageIndex { get => _pageIndex; set { _pageIndex = value < 1 ? 1 : value; RaisePropertyChanged(); } } private int _pageSize = 20; /// /// 页大小 /// public int PageSize { get => _pageSize; set { var v = value <= 0 ? 20 : value; if (_pageSize != v) { _pageSize = v; RaisePropertyChanged(); PageIndex = 1; if (!IsBusy) _ = SearchAsync(); } } } private int _totalPages; /// /// 总页数 /// public int TotalPages { get => _totalPages; set { _totalPages = value; RaisePropertyChanged(); } } #endregion #region 命令 public DelegateCommand SearchCommand { get; } public DelegateCommand ClearCommand { get; } public DelegateCommand AddCommand { get; } public DelegateCommand EditCommand { get; } public DelegateCommand DeleteCommand { get; } public DelegateCommand FirstPageCommand { get; } public DelegateCommand PrevPageCommand { get; } public DelegateCommand NextPageCommand { get; } public DelegateCommand LastPageCommand { get; } #endregion private void ClearFilters() { UserName = string.Empty; AccessLevel = AccessLevels.All; } private async Task SearchAsync() { if (IsBusy) return; try { IsBusy = true; await SearchCoreAsync(); } catch (Exception ex) { _log.Error($"TbUser 查询失败: {ex}"); MessageBox.Show($"查询失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } finally { IsBusy = false; } } private async Task SearchCoreAsync() { _log.Info("TbUser 查询开始"); var data = await Task.Run(() => { var q = _fsql.Select(); if (!string.IsNullOrWhiteSpace(UserName)) q = q.Where(a => a.UserName != null && a.UserName.Contains(UserName)); if (!string.IsNullOrWhiteSpace(AccessLevel) && !string.Equals(AccessLevel, AccessLevels.All, StringComparison.OrdinalIgnoreCase)) { q = q.Where(a => a.AccessLevel == AccessLevel); } q = q.OrderByDescending(a => a.Id); var page = PageIndex < 1 ? 1 : PageIndex; var size = PageSize <= 0 ? 20 : PageSize; var list = q.Count(out var total) .Page(page, size) .ToList(); var pages = total <= 0 || size <= 0 ? 0 : (int)Math.Ceiling(total * 1.0 / size); if (pages > 0 && page > pages) { page = pages; list = q.Page(page, size).ToList(); } return (items: list, total: (int)total, normalizedPage: page, totalPages: pages); }); Application.Current.Dispatcher.Invoke(() => { Items.Clear(); foreach (var it in data.items) Items.Add(it); TotalCount = data.total; TotalPages = data.totalPages; PageIndex = data.normalizedPage == 0 ? 1 : data.normalizedPage; }); _log.Info($"TbUser 查询完成,记录数: {TotalCount}"); } private void AddUser() { var p = new DialogParameters { { DialogKeys.Mode, DialogModes.Add } }; _dialog.ShowDialog("DialogUserEditView", p, async r => { if (r.Result == ButtonResult.OK) { PageIndex = 1; await SearchAsync(); } }); } private void EditUser() { if (SelectedItem == null) { MessageBox.Show("请选择要编辑的用户", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return; } var p = new DialogParameters { { DialogKeys.Mode, DialogModes.Edit }, { DialogKeys.UserId, SelectedItem.Id } }; _dialog.ShowDialog("DialogUserEditView", p, async r => { if (r.Result == ButtonResult.OK) { await SearchAsync(); } }); } private async Task DeleteUserAsync() { if (SelectedItem == null) { MessageBox.Show("请选择要删除的用户", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return; } if (!string.IsNullOrWhiteSpace(_sys.CurUser) && string.Equals(_sys.CurUser, SelectedItem.UserName, StringComparison.OrdinalIgnoreCase)) { MessageBox.Show("不能删除当前登录用户", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); return; } var ok = MessageBox.Show($"确认删除用户:{SelectedItem.UserName} ?", "确认", MessageBoxButton.YesNo, MessageBoxImage.Question); if (ok != MessageBoxResult.Yes) return; if (IsBusy) return; try { IsBusy = true; var id = SelectedItem.Id; await Task.Run(() => { _fsql.Delete(id).ExecuteAffrows(); }); _log.Info($"删除用户成功,Id={id}"); SelectedItem = null; await SearchCoreAsync(); } catch (Exception ex) { _log.Error($"删除用户失败: {ex}"); MessageBox.Show($"删除失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } finally { IsBusy = false; } } /// /// 进入页面自动加载 /// /// 导航上下文 public override async void OnNavigatedTo(Prism.Regions.NavigationContext navigationContext) { await SearchAsync(); } /// /// 权限等级常量 /// public static class AccessLevels { public const string All = "全部"; public const string Admin = "管理员"; public const string Operator = "操作员"; public const string Guest = "访客"; } /// /// 弹窗参数 Key /// public static class DialogKeys { public const string Mode = "Mode"; public const string UserId = "UserId"; } /// /// 弹窗模式 /// public static class DialogModes { public const string Add = "Add"; public const string Edit = "Edit"; } } }