| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- using CommunityToolkit.Mvvm.ComponentModel;
- using CommunityToolkit.Mvvm.Input;
- using Serilog;
- using System.ComponentModel;
- using YZWater.Core.Models;
- using YZWater.Core.Services;
- namespace YZWater.Core.ViewModels;
- /// <summary>
- /// 主窗口 ViewModel
- /// </summary>
- public partial class MainViewModel : ObservableObject, IDisposable
- {
- private readonly ViewAViewModel _viewAViewModel;
- private readonly ViewBViewModel _viewBViewModel;
- private readonly ViewCViewModel _viewCViewModel;
- private readonly ViewDViewModel _viewDViewModel;
- private readonly ViewEViewModel _viewEViewModel;
- private readonly ViewFViewModel _viewFViewModel;
- private ProjectViewModel? _projectViewModel;
- private readonly ThemeService _themeService = ThemeService.Instance;
- private readonly LanguageService _langService = LanguageService.Instance;
- private readonly SynchronizationContext? _uiContext = SynchronizationContext.Current;
- private System.Timers.Timer? _clockTimer;
- private bool _disposed;
- [ObservableProperty]
- private ObservableObject _currentView;
- [ObservableProperty]
- private string _title;
- [ObservableProperty]
- private string _currentTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- [ObservableProperty]
- private bool _isPlcConnected;
- [ObservableProperty]
- private int _selectedTabIndex;
- // 各 Tab 激活状态
- [ObservableProperty] private bool _isTabAActive = true;
- [ObservableProperty] private bool _isTabBActive;
- [ObservableProperty] private bool _isTabCActive;
- [ObservableProperty] private bool _isTabDActive;
- [ObservableProperty] private bool _isTabEActive;
- [ObservableProperty] private bool _isTabFActive;
- // 当前 Tab 标题
- [ObservableProperty] private string _tabTitle;
- // 主题/语言状态
- [ObservableProperty] private bool _isDarkTheme = true;
- [ObservableProperty] private bool _isChinese = true;
- [ObservableProperty] private string _themeIcon = "🌙";
- [ObservableProperty] private string _langIcon = "中";
- // 导航标签
- [ObservableProperty] private string _navProcess;
- [ObservableProperty] private string _navParams;
- [ObservableProperty] private string _navFlow;
- [ObservableProperty] private string _navAlarm;
- [ObservableProperty] private string _navAbout;
- [ObservableProperty] private string _navAudit;
- // ═══ 用户管理翻译 ═══
- [ObservableProperty] private string _userManageText;
- [ObservableProperty] private string _createNewUserText;
- [ObservableProperty] private string _userNameLabel;
- [ObservableProperty] private string _passwordLabel;
- [ObservableProperty] private string _displayNameLabel;
- [ObservableProperty] private string _roleLabel;
- [ObservableProperty] private string _statusLabel;
- [ObservableProperty] private string _lastLoginLabel;
- [ObservableProperty] private string _actionLabel;
- [ObservableProperty] private string _createText;
- [ObservableProperty] private string _closeText;
- [ObservableProperty] private string _logoutText;
- // ═══ 运行模式与连接状态 ═══
- [ObservableProperty] private string _runMode = "Direct";
- [ObservableProperty] private string _hubStatusText = "";
- [ObservableProperty] private string _plcStatusText = "";
- [ObservableProperty] private string _plcStatusColor = "#E74C3C";
- // ═══ 子 ViewModel(供 View 绑定 DataContext) ═══
- public ViewAViewModel ViewA => _viewAViewModel;
- public ViewBViewModel ViewB => _viewBViewModel;
- public ViewCViewModel ViewC => _viewCViewModel;
- public ViewDViewModel ViewD => _viewDViewModel;
- public ViewEViewModel ViewE => _viewEViewModel;
- public ViewFViewModel ViewF => _viewFViewModel;
- /// <summary>项目化 ViewModel(当加载了项目档案时可用)</summary>
- public ProjectViewModel? ProjectView => _projectViewModel;
- /// <summary>是否加载了项目档案</summary>
- [ObservableProperty] private bool _hasProject;
- // ═══ 用户与权限 ═══
- [ObservableProperty] private string _currentUserName = string.Empty;
- [ObservableProperty] private string _currentUserRole = string.Empty;
- [ObservableProperty] private bool _canControl;
- [ObservableProperty] private bool _canModifyParams;
- [ObservableProperty] private bool _canManageUsers;
- [ObservableProperty] private bool _showUserDialog;
- public MainViewModel()
- {
- _viewAViewModel = new ViewAViewModel();
- _viewBViewModel = new ViewBViewModel();
- _viewCViewModel = new ViewCViewModel();
- _viewDViewModel = new ViewDViewModel();
- _viewEViewModel = new ViewEViewModel();
- _viewFViewModel = new ViewFViewModel();
- _currentView = _viewAViewModel;
- UpdateAllTexts();
- RefreshUserInfo();
- LoadRunMode();
- _langService.LanguageChanged += OnLanguageChanged;
- _themeService.PropertyChanged += OnThemeServicePropertyChanged;
- // PLC 连接状态监听
- PlcPollingService.Instance.ConnectionStateChanged += OnConnectionStateChanged;
- StartTimer();
- // 项目档案初始化
- InitializeProject();
- }
- /// <summary>
- /// 根据当前配置初始化项目 ViewModel
- /// </summary>
- private void InitializeProject()
- {
- var profile = ProjectService.Current;
- if (profile != null)
- {
- _projectViewModel = new ProjectViewModel(profile);
- CurrentView = _projectViewModel;
- HasProject = true;
- Log.Information("已初始化项目视图: {Name}", profile.Name);
- }
- }
- private void OnLanguageChanged()
- {
- RunOnUi(() =>
- {
- IsChinese = _langService.IsChinese;
- UpdateAllTexts();
- RefreshUserInfo();
- });
- }
- private void OnThemeServicePropertyChanged(object? sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName != nameof(ThemeService.IsDarkTheme)) return;
- RunOnUi(() =>
- {
- IsDarkTheme = _themeService.IsDarkTheme;
- ThemeIcon = IsDarkTheme ? "🌙" : "☀️";
- });
- }
- private void OnConnectionStateChanged(bool connected)
- {
- RunOnUi(() =>
- {
- PlcStatusText = connected ? _langService.Get("PlcConnectedStatus") : _langService.Get("PlcDisconnected");
- PlcStatusColor = connected ? "#27AE60" : "#E74C3C";
- IsPlcConnected = connected;
- });
- }
- private void RunOnUi(Action action)
- {
- if (_disposed) return;
- if (_uiContext != null && SynchronizationContext.Current != _uiContext)
- _uiContext.Post(_ =>
- {
- if (!_disposed) action();
- }, null);
- else
- action();
- }
- private void UpdateAllTexts()
- {
- Title = _langService.Get("AppName");
- TabTitle = _langService.Get("ProcessFlow");
- NavProcess = _langService.Get("NavProcess");
- NavParams = _langService.Get("NavParams");
- NavFlow = _langService.Get("NavFlow");
- NavAlarm = _langService.Get("NavAlarm");
- NavAbout = _langService.Get("NavAbout");
- NavAudit = _langService.Get("AuditLog");
- UserManageText = _langService.Get("UserManage");
- CreateNewUserText = _langService.Get("CreateNewUser");
- UserNameLabel = _langService.Get("UserName");
- PasswordLabel = _langService.Get("Password");
- DisplayNameLabel = _langService.Get("DisplayName");
- RoleLabel = _langService.Get("Role");
- StatusLabel = _langService.Get("Status");
- LastLoginLabel = _langService.Get("LastLogin");
- ActionLabel = _langService.Get("Action");
- CreateText = _langService.Get("Create");
- CloseText = _langService.Get("Close");
- LogoutText = _langService.Get("Logout");
- IsChinese = _langService.IsChinese;
- LangIcon = IsChinese ? "中" : "EN";
- IsDarkTheme = _themeService.IsDarkTheme;
- ThemeIcon = IsDarkTheme ? "🌙" : "☀️";
- }
- /// <summary>
- /// 加载运行模式
- /// </summary>
- private void LoadRunMode()
- {
- var config = ConfigService.GetConfig();
- RunMode = config?.RunMode ?? "Direct";
- HubStatusText = RunMode switch
- {
- "Server" => $"{_langService.Get("ServerMode")} :{config?.HubPort ?? 8765}",
- "Client" => $"{_langService.Get("ClientMode")} → {config?.HubServerUrl ?? "ws://localhost:8765"}",
- "Mock" => _langService.Get("MockMode"),
- _ => _langService.Get("DirectMode")
- };
- }
- [RelayCommand]
- private void ToggleTheme()
- {
- _themeService.ToggleTheme();
- }
- [RelayCommand]
- private void ToggleLanguage()
- {
- _langService.ToggleLanguage();
- }
- [RelayCommand]
- private async Task ConnectPlcAsync() => await _viewAViewModel.ConnectPlcCommand.ExecuteAsync(null);
- [RelayCommand]
- private void DisconnectPlc() => _viewAViewModel.DisconnectPlcCommand.Execute(null);
- [RelayCommand]
- private async Task RefreshDataAsync() => await _viewAViewModel.RefreshDataCommand.ExecuteAsync(null);
- // ─── Tab 切换 ───
- private readonly string[] _tabTitleKeys = { "ProcessFlow", "Parameters", "FlowRecords", "AlarmLog", "About", "AuditLog" };
- private void SetActiveTab(int index)
- {
- IsTabAActive = index == 0;
- IsTabBActive = index == 1;
- IsTabCActive = index == 2;
- IsTabDActive = index == 3;
- IsTabEActive = index == 4;
- IsTabFActive = index == 5;
- TabTitle = _langService.Get(_tabTitleKeys[index]);
- }
- [RelayCommand] private void ShowViewA()
- {
- CurrentView = HasProject && _projectViewModel != null
- ? _projectViewModel
- : _viewAViewModel;
- SetActiveTab(0);
- }
- [RelayCommand] private void ShowViewB() { CurrentView = _viewBViewModel; SetActiveTab(1); }
- [RelayCommand] private void ShowViewC() { CurrentView = _viewCViewModel; SetActiveTab(2); }
- [RelayCommand] private void ShowViewD() { CurrentView = _viewDViewModel; SetActiveTab(3); }
- [RelayCommand] private void ShowViewE() { CurrentView = _viewEViewModel; SetActiveTab(4); }
- [RelayCommand] private void ShowViewF() { CurrentView = _viewFViewModel; SetActiveTab(5); }
- private void StartTimer()
- {
- _clockTimer = new System.Timers.Timer(1000);
- _clockTimer.Elapsed += (s, e) =>
- {
- var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- RunOnUi(() => CurrentTime = time);
- };
- _clockTimer.Start();
- }
- private void StopTimer()
- {
- _clockTimer?.Stop();
- _clockTimer?.Dispose();
- _clockTimer = null;
- }
- private void RefreshUserInfo()
- {
- var user = AuthService.CurrentUser;
- if (user != null)
- {
- // 管理员显示名跟随语言更新
- if (user.UserName == "admin")
- {
- var adminDisplayName = _langService.Get("AdminName");
- if (user.DisplayName != adminDisplayName)
- {
- user.DisplayName = adminDisplayName;
- DatabaseService.Db.Updateable(user).UpdateColumns(u => u.DisplayName).ExecuteCommand();
- }
- }
- CurrentUserName = user.DisplayName;
- CurrentUserRole = user.Role switch
- {
- UserRole.Viewer => _langService.Get("Viewer"),
- UserRole.Operator => _langService.Get("OperatorRole"),
- UserRole.Engineer => _langService.Get("Engineer"),
- UserRole.Admin => _langService.Get("AdminRole"),
- _ => "Unknown"
- };
- CanControl = AuthService.HasPermission(UserRole.Operator);
- CanModifyParams = AuthService.HasPermission(UserRole.Engineer);
- CanManageUsers = AuthService.HasPermission(UserRole.Admin);
- }
- }
- [RelayCommand]
- private void Logout()
- {
- AuthService.Logout();
- }
- [RelayCommand]
- private void ToggleUserDialog()
- {
- ShowUserDialog = !ShowUserDialog;
- if (ShowUserDialog)
- {
- LoadUsers();
- }
- }
- // ═══ 用户管理 ═══
- [ObservableProperty] private List<User> _userList = new();
- [ObservableProperty] private string _newUserName = string.Empty;
- [ObservableProperty] private string _newUserPassword = string.Empty;
- [ObservableProperty] private string _newUserDisplayName = string.Empty;
- [ObservableProperty] private UserRole _newUserRole = UserRole.Operator;
- [ObservableProperty] private string _userManageMessage = string.Empty;
- private void LoadUsers()
- {
- UserList = AuthService.GetAllUsers();
- }
- [RelayCommand]
- private void CreateUser()
- {
- if (string.IsNullOrWhiteSpace(NewUserName) || string.IsNullOrWhiteSpace(NewUserPassword))
- {
- UserManageMessage = _langService.Get("UserNamePasswordRequired");
- return;
- }
- var (success, message) = AuthService.CreateUser(NewUserName, NewUserPassword, NewUserDisplayName, NewUserRole);
- UserManageMessage = message;
- if (success)
- {
- NewUserName = string.Empty;
- NewUserPassword = string.Empty;
- NewUserDisplayName = string.Empty;
- NewUserRole = UserRole.Operator;
- LoadUsers();
- }
- }
- [RelayCommand]
- private void ToggleUserActive(User? user)
- {
- if (user == null) return;
- AuthService.SetUserActive(user.UserName, !user.IsActive);
- LoadUsers();
- }
- public void Dispose()
- {
- if (_disposed) return;
- _disposed = true;
- StopTimer();
- _langService.LanguageChanged -= OnLanguageChanged;
- _themeService.PropertyChanged -= OnThemeServicePropertyChanged;
- PlcPollingService.Instance.ConnectionStateChanged -= OnConnectionStateChanged;
- _viewAViewModel.Dispose();
- _viewBViewModel.Dispose();
- _viewCViewModel.Dispose();
- _viewDViewModel.Dispose();
- _viewEViewModel.Dispose();
- _viewFViewModel.Dispose();
- _projectViewModel?.Dispose();
- }
- }
|