diff --git a/.idea/.idea.detect/.idea/avalonia.xml b/.idea/.idea.detect/.idea/avalonia.xml index a74366f..b0f6fcb 100644 --- a/.idea/.idea.detect/.idea/avalonia.xml +++ b/.idea/.idea.detect/.idea/avalonia.xml @@ -8,12 +8,15 @@ + + + diff --git a/detect.gui/Api/ApiService.cs b/detect.gui/Api/ApiService.cs index 706e24d..a2b3785 100644 --- a/detect.gui/Api/ApiService.cs +++ b/detect.gui/Api/ApiService.cs @@ -15,13 +15,9 @@ public class ApiService { private static ApiService? _instance; - public static ApiService Instance + public static ApiService Instance() { - get - { - _instance = new ApiService(); - return _instance; - } + return _instance ??= new ApiService(); } private WebApplication? _webApp = null; diff --git a/detect.gui/App.axaml.cs b/detect.gui/App.axaml.cs index b64215b..7ee4e86 100644 --- a/detect.gui/App.axaml.cs +++ b/detect.gui/App.axaml.cs @@ -5,7 +5,9 @@ using detect.gui.Drivers; using detect.gui.Services; using detect.gui.Services.Detect; using detect.gui.ViewModels; -using detect.gui.Views; +using detect.gui.VWMS; +// using detect.gui.Views; +using detect.gui.VWS; using ReactiveUI; using Splat; @@ -22,26 +24,22 @@ public class App : Application RxApp.SuspensionHost.SetupDefaultSuspendResume(new NewtonsoftJsonSuspensionDriver("app.state.json")); suspension.OnFrameworkInitializationCompleted(); - Locator.CurrentMutable.RegisterConstant(RxApp.SuspensionHost.GetAppState()); - Locator.CurrentMutable.Register(() => new LoginView(), typeof(IViewFor)); - Locator.CurrentMutable.Register(() => new HomeView(), typeof(IViewFor)); - Locator.CurrentMutable.Register(() => new DetectTaskView(), typeof(IViewFor)); - Locator.CurrentMutable.Register(() => new DeviceView(), typeof(IViewFor)); - Locator.CurrentMutable.Register(() => new LogView(), typeof(IViewFor)); - Locator.CurrentMutable.Register(() => new UserView(), typeof(IViewFor)); - - Locator.CurrentMutable.Register(() => new DetectUserService(), typeof(DetectUserService)); - Locator.CurrentMutable.Register(() => new DetectAuthorityService(), typeof(DetectAuthorityService)); - Locator.CurrentMutable.Register(() => new DetectDeviceService(), typeof(DetectDeviceService)); - Locator.CurrentMutable.Register(() => new DetectTaskService(), typeof(DetectTaskService)); - Locator.CurrentMutable.Register(() => new DetectTaskLogService(), typeof(DetectTaskLogService)); - Locator.CurrentMutable.Register(() => new DetectTaskProgressService(), typeof(DetectTaskProgressService)); - Locator.CurrentMutable.Register(() => new DetectLogService(), typeof(DetectLogService)); + Locator.CurrentMutable.Register(DetectUserService.Instance, typeof(DetectUserService)); + Locator.CurrentMutable.Register(DetectAuthorityService.Instance, typeof(DetectAuthorityService)); + Locator.CurrentMutable.Register(DetectDeviceService.Instance, typeof(DetectDeviceService)); + Locator.CurrentMutable.Register( DetectTaskService.Instance, typeof(DetectTaskService)); + Locator.CurrentMutable.Register(DetectTaskLogService.Instance, typeof(DetectTaskLogService)); + Locator.CurrentMutable.Register(DetectTaskProgressService.Instance, typeof(DetectTaskProgressService)); + Locator.CurrentMutable.Register(DetectLogService.Instance, typeof(DetectLogService)); Locator.CurrentMutable.Register(DeviceClientService.Instance, typeof(DeviceClientService)); Locator.Current.GetService(); + + Locator.CurrentMutable.Register( MainWindow.Instance, typeof(MainWindow)); + Locator.CurrentMutable.Register(MainWindowModel.Instance, typeof(MainWindowModel)); + Locator.CurrentMutable.Register(LoginControlModel.Instance, typeof(LoginControlModel)); - new MainView { DataContext = Locator.Current.GetService() }.Show(); + Locator.Current.GetService()!.Show(); base.OnFrameworkInitializationCompleted(); } diff --git a/detect.gui/Services/Detect/DetectAuthorityService.cs b/detect.gui/Services/Detect/DetectAuthorityService.cs index afba73d..ba340cf 100644 --- a/detect.gui/Services/Detect/DetectAuthorityService.cs +++ b/detect.gui/Services/Detect/DetectAuthorityService.cs @@ -7,7 +7,7 @@ using detect.gui.Models.Entities; namespace detect.gui.Services.Detect; -public class DetectAuthorityService : ServiceBase +public class DetectAuthorityService : ServiceBase { public ApiResponse> Search(int? id, string? name = "", int pageNum = 1, int pageSize = 10) { diff --git a/detect.gui/Services/Detect/DetectDeviceService.cs b/detect.gui/Services/Detect/DetectDeviceService.cs index 481c4c0..04efa9e 100644 --- a/detect.gui/Services/Detect/DetectDeviceService.cs +++ b/detect.gui/Services/Detect/DetectDeviceService.cs @@ -7,7 +7,7 @@ using detect.gui.Models.Entities; namespace detect.gui.Services.Detect; -public class DetectDeviceService : ServiceBase +public class DetectDeviceService : ServiceBase { public ApiResponse ListByDeviceIp(string ip) { diff --git a/detect.gui/Services/Detect/DetectLogService.cs b/detect.gui/Services/Detect/DetectLogService.cs index 4e8c882..506c00b 100644 --- a/detect.gui/Services/Detect/DetectLogService.cs +++ b/detect.gui/Services/Detect/DetectLogService.cs @@ -7,7 +7,7 @@ using detect.gui.Models.Entities; namespace detect.gui.Services.Detect; -public class DetectLogService : ServiceBase +public class DetectLogService : ServiceBase { public ApiResponse> Search(int? userId, string? description = "", int pageNum = 1, int pageSize = 10) { diff --git a/detect.gui/Services/Detect/DetectTaskLogService.cs b/detect.gui/Services/Detect/DetectTaskLogService.cs index 7504e15..911d4ae 100644 --- a/detect.gui/Services/Detect/DetectTaskLogService.cs +++ b/detect.gui/Services/Detect/DetectTaskLogService.cs @@ -7,7 +7,7 @@ using detect.gui.Models.Entities; namespace detect.gui.Services.Detect; -public class DetectTaskLogService : ServiceBase +public class DetectTaskLogService : ServiceBase { public ApiResponse ListById(long id) { diff --git a/detect.gui/Services/Detect/DetectTaskProgressService.cs b/detect.gui/Services/Detect/DetectTaskProgressService.cs index 288a002..31f480e 100644 --- a/detect.gui/Services/Detect/DetectTaskProgressService.cs +++ b/detect.gui/Services/Detect/DetectTaskProgressService.cs @@ -7,7 +7,7 @@ using detect.gui.Models.Entities; namespace detect.gui.Services.Detect; -public class DetectTaskProgressService : ServiceBase +public class DetectTaskProgressService : ServiceBase { public ApiResponse ListById(long id) { diff --git a/detect.gui/Services/Detect/DetectTaskService.cs b/detect.gui/Services/Detect/DetectTaskService.cs index 4caaf07..1a87b34 100644 --- a/detect.gui/Services/Detect/DetectTaskService.cs +++ b/detect.gui/Services/Detect/DetectTaskService.cs @@ -7,7 +7,7 @@ using detect.gui.Models.Entities; namespace detect.gui.Services.Detect; -public class DetectTaskService : ServiceBase +public class DetectTaskService : ServiceBase { public ApiResponse ListById(long id) { diff --git a/detect.gui/Services/Detect/DetectUserService.cs b/detect.gui/Services/Detect/DetectUserService.cs index e9a9890..8b4b06c 100644 --- a/detect.gui/Services/Detect/DetectUserService.cs +++ b/detect.gui/Services/Detect/DetectUserService.cs @@ -8,7 +8,7 @@ using Microsoft.EntityFrameworkCore; namespace detect.gui.Services.Detect; -public class DetectUserService : ServiceBase +public class DetectUserService : ServiceBase { public ApiResponse Login(string? username, string? password) { diff --git a/detect.gui/Services/ServiceBase.cs b/detect.gui/Services/ServiceBase.cs index 3fad596..80184b8 100644 --- a/detect.gui/Services/ServiceBase.cs +++ b/detect.gui/Services/ServiceBase.cs @@ -6,8 +6,15 @@ using detect.gui.Context; namespace detect.gui.Services; -public class ServiceBase where T : class +public class ServiceBase where S : new() where T : class { + private static S? _instance; + + public static S Instance() + { + return _instance ??= new S(); + } + protected readonly DetectContext? Context = new DetectContext(); protected T Add(T entity) diff --git a/detect.gui/VWMS/LoginControlModel.cs b/detect.gui/VWMS/LoginControlModel.cs new file mode 100644 index 0000000..cdc149d --- /dev/null +++ b/detect.gui/VWMS/LoginControlModel.cs @@ -0,0 +1,82 @@ +using System.Reactive; +using System.Threading.Tasks; +using Avalonia.Controls.Notifications; +using detect.gui.Api.Helpers; +using detect.gui.Commons; +using detect.gui.Models; +using detect.gui.Models.Entities; +using ReactiveUI; +using Splat; + +namespace detect.gui.VWMS; + +public class LoginControlModel : ViewModelBase +{ + private long? _userId; + public long? UserId + { + get => _userId; + set => this.RaiseAndSetIfChanged(ref _userId, value); + } + + private string? _username; + public string? Username + { + get => _username; + set => this.RaiseAndSetIfChanged(ref _username, value); + } + + private string? _password; + public string? Password + { + get => _password; + set => this.RaiseAndSetIfChanged(ref _password, value); + } + + private string? _realName; + public string? RealName + { + get => _realName; + set => this.RaiseAndSetIfChanged(ref _realName, value); + } + + public LoginControlModel() + { + Username = "admin"; + Password = "winner!"; + + LoginCommand = ReactiveCommand.Create(Login); + } + + public ReactiveCommand LoginCommand { get; } + + /// + /// 登录 + /// + public async void Login() + { + Message = null; + + IsLoading = true; + + await Task.Factory.StartNew(() => + { + + var data = UserHelper.Login(Username, Password); + if (data?.Code != 0) + { + Message = new MessageItem(data?.Message, NotificationType.Error); + return; + } + Locator.Current.GetService()!.CurrentUser = data.Result?.Convert();; + // RootViewModel!.CurrentUser = data.Result?.Convert(); + Message = new MessageItem("欢迎," + data.Result?.RealName, NotificationType.Success); + }); + + IsLoading = false; + + if (Message is not { NotificationType: NotificationType.Error }) + Locator.Current.GetService()!.IsHomeView = true; + // HostScreen?.Router.Navigate.Execute(new HomeViewModel()); + } +} \ No newline at end of file diff --git a/detect.gui/VWMS/MainWindowModel.cs b/detect.gui/VWMS/MainWindowModel.cs new file mode 100644 index 0000000..a7c7107 --- /dev/null +++ b/detect.gui/VWMS/MainWindowModel.cs @@ -0,0 +1,141 @@ +using System; +using System.Reactive; +using detect.gui.Api; +using detect.gui.Models; +using ReactiveUI; +using Serilog; +using xwd.utils; + +namespace detect.gui.VWMS; + +public class MainWindowModel : ViewModelBase +{ + /// + /// 当前登录用户 + /// + private UserModel? _currentUser; + + public UserModel? CurrentUser + { + get => _currentUser; + set => this.RaiseAndSetIfChanged(ref _currentUser, value); + } + + private bool _isHomeView; + + public bool IsHomeView + { + get => _isHomeView; + set => this.RaiseAndSetIfChanged(ref _isHomeView, value); + } + + private bool _isDetectTaskView; + + public bool IsDetectTaskView + { + get => _isDetectTaskView; + set => this.RaiseAndSetIfChanged(ref _isDetectTaskView, value); + } + + private bool _isDeviceView; + + public bool IsDeviceView + { + get => _isDeviceView; + set => this.RaiseAndSetIfChanged(ref _isDeviceView, value); + } + + private bool _isLogView; + + public bool IsLogView + { + get => _isLogView; + set => this.RaiseAndSetIfChanged(ref _isLogView, value); + } + + private bool _isUserView; + + public bool IsUserView + { + get => _isUserView; + set => this.RaiseAndSetIfChanged(ref _isUserView, value); + } + + private readonly string[] _localRoutes = + [ + "#/dashboard", + "#/data/task", + "#/data/device", + "#/system/log", + "#/system/user" + ]; + + private string? _address; + + public string? Address + { + get => _address; + set => this.RaiseAndSetIfChanged(ref _address, value); + } + + // public ReactiveCommand GotoCommand { get; } + public ReactiveCommand LogoutCommand { get; } + + public MainWindowModel() + { + ApiService.Instance().StartService(); + + // GotoCommand = ReactiveCommand.Create((p) => Goto(p)); + LogoutCommand = ReactiveCommand.Create(Logout); + + this.WhenAnyValue(x => x.IsHomeView).Subscribe(p => + { + if (!p) return; + SetAddress(0); + }); + + this.WhenAnyValue(x => x.IsDetectTaskView).Subscribe(p => + { + if (!p) return; + SetAddress(1); + }); + + this.WhenAnyValue(x => x.IsDeviceView).Subscribe(p => + { + if (!p) return; + SetAddress(2); + }); + + + this.WhenAnyValue(x => x.IsLogView).Subscribe(p => + { + if (!p) return; + SetAddress(3); + }); + + this.WhenAnyValue(x => x.IsUserView).Subscribe(p => + { + if (!p) return; + SetAddress(4); + }); + } + + public void Dispose() + { + ApiService.Instance().StopService(); + } + + private void Logout() + { + CurrentUser = null; + } + + public void SetAddress(int index) + { + var isOnLine = AppSettingsManager.Manager().GetBool("Embedded.IsOnline"); + var path = AppSettingsManager.Manager().GetString("Embedded.Path", "./dist/index.html"); + var prefix = isOnLine ? path : AppDomain.CurrentDomain.BaseDirectory + path; + Address = $"{prefix}{_localRoutes[index]}"; + Log.Information("current address: {address}", Address); + } +} \ No newline at end of file diff --git a/detect.gui/VWMS/ViewModelBase.cs b/detect.gui/VWMS/ViewModelBase.cs new file mode 100644 index 0000000..75b3bf2 --- /dev/null +++ b/detect.gui/VWMS/ViewModelBase.cs @@ -0,0 +1,78 @@ +using System; +using Avalonia.Controls.Notifications; +using Avalonia.Threading; +using detect.gui.Classes; +using detect.gui.ViewModels; +using detect.gui.VWS; +using ReactiveUI; + +namespace detect.gui.VWMS; + + +public class ViewModelBase : ReactiveObject where T : new() +{ + private static T? _instance; + + public static T Instance() + { + return _instance ??= new T(); + } + + private bool _isLoading; + public bool IsLoading + { + get => _isLoading; + set => this.RaiseAndSetIfChanged(ref _isLoading, value); + } + + private MessageItem? _message; + + protected MessageItem? Message + { + get => _message; + set => this.RaiseAndSetIfChanged(ref _message, value); + } + + protected ViewModelBase() + { + this.WhenAnyValue(x => x.Message).Subscribe(m => + { + if (m == null) return; + Dispatcher.UIThread.Invoke(() => + { + var title = m.NotificationType switch + { + NotificationType.Error => "错误信息", + NotificationType.Success => "成功信息", + NotificationType.Information => "提示信息", + NotificationType.Warning => "警告信息", + _ => "" + }; + NotificationService.Show(title, m.Text, m.NotificationType); + }); + }); + } +} + +public class MessageItem : ReactiveObject +{ + private readonly string? _text; + public string? Text + { + get => _text; + init => this.RaiseAndSetIfChanged(ref _text, value); + } + + private readonly NotificationType _notificationType; + public NotificationType NotificationType + { + get => _notificationType; + init => this.RaiseAndSetIfChanged(ref _notificationType, value); + } + + public MessageItem(string? text, NotificationType notificationType) + { + _text = text; + _notificationType = notificationType; + } +} \ No newline at end of file diff --git a/detect.gui/VWS/LoginControl.axaml b/detect.gui/VWS/LoginControl.axaml new file mode 100644 index 0000000..5796e72 --- /dev/null +++ b/detect.gui/VWS/LoginControl.axaml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +