diff --git a/Sln.Wcs.UI/App.xaml b/Sln.Wcs.UI/App.xaml
new file mode 100644
index 0000000..c040570
--- /dev/null
+++ b/Sln.Wcs.UI/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/Sln.Wcs.UI/App.xaml.cs b/Sln.Wcs.UI/App.xaml.cs
new file mode 100644
index 0000000..12a8d0b
--- /dev/null
+++ b/Sln.Wcs.UI/App.xaml.cs
@@ -0,0 +1,105 @@
+using System.Reflection;
+using Com.Ctrip.Framework.Apollo;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using NeoSmart.Caching.Sqlite;
+using Sln.Wcs.Repository;
+using Sln.Wcs.Serilog;
+using ZiggyCreatures.Caching.Fusion;
+using ZiggyCreatures.Caching.Fusion.Serialization.NewtonsoftJson;
+using System.Windows;
+using System.IO;
+
+namespace Sln.Wcs.UI
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+
+ public static IServiceProvider ServiceProvider { get; private set; }
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ base.OnStartup(e);
+
+ var services = new ServiceCollection();
+
+ ConfigureServices(services);
+
+ ServiceProvider = services.BuildServiceProvider();
+
+ ServiceProvider.UseSerilogExtensions();
+ var config = ServiceProvider.GetService();
+ var log = ServiceProvider.GetService();
+
+ log.Info($"系统启动成功,日志存放位置:{config["logPath"]}");
+ }
+
+ private static void ConfigureServices(IServiceCollection services)
+ {
+ var basePath = AppContext.BaseDirectory;
+
+ ApolloConfigureServices(services, ref basePath, out IConfiguration apolloConfiguration);
+
+ Assembly[] assemblies = {
+ Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Common.dll")),
+ Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Cache.dll")),
+ Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Repository.dll")),
+ Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HikRoBotApi.dll")),
+ //Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HikRoBotSdk.dll")),
+ };
+
+ services.Scan(scan => scan.FromAssemblies(assemblies)
+ .AddClasses()
+ .AsImplementedInterfaces()
+ .AsSelf()
+ .WithTransientLifetime());
+
+ services.AddSingleton(typeof(SerilogHelper));
+
+ services.AddSqlSugarSetup();
+
+ services.AddFusionCache()
+ .WithSerializer(
+ new FusionCacheNewtonsoftJsonSerializer()
+ )
+ .WithDistributedCache(new SqliteCache(new SqliteCacheOptions
+ {
+ CachePath = apolloConfiguration["cachePath"]
+ }));
+ }
+
+ ///
+ /// Apollo 配置中心
+ ///
+ ///
+ ///
+ ///
+ private static void ApolloConfigureServices(IServiceCollection services, ref string basePath, out IConfiguration apolloConfiguration)
+ {
+
+
+ var localConfiguration = new ConfigurationBuilder()
+ .SetBasePath(basePath)
+ .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
+ .Build();
+
+ var apolloConfigSection = localConfiguration.GetSection("apollo");
+
+ services.AddSingleton(localConfiguration);
+
+ var configurationBuilder = new ConfigurationBuilder()
+ .SetBasePath(basePath)
+ .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
+ .AddApollo(apolloConfigSection)
+ .AddDefault();
+
+ apolloConfiguration = configurationBuilder.Build();
+
+ services.Remove(new ServiceDescriptor(typeof(IConfiguration), localConfiguration));
+ services.AddSingleton(apolloConfiguration);
+ }
+ }
+
+}
diff --git a/Sln.Wcs.UI/AssemblyInfo.cs b/Sln.Wcs.UI/AssemblyInfo.cs
new file mode 100644
index 0000000..b0ec827
--- /dev/null
+++ b/Sln.Wcs.UI/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Sln.Wcs.UI/Attribute/RegisterAsSingletonAttribute.cs b/Sln.Wcs.UI/Attribute/RegisterAsSingletonAttribute.cs
new file mode 100644
index 0000000..67ab3c6
--- /dev/null
+++ b/Sln.Wcs.UI/Attribute/RegisterAsSingletonAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Sln.Wcs.UI.Attribute
+{
+ public class RegisterAsSingletonAttribute:System.Attribute
+ {
+ }
+}
diff --git a/Sln.Wcs.UI/Attribute/RegisterAsTransientAttribute.cs b/Sln.Wcs.UI/Attribute/RegisterAsTransientAttribute.cs
new file mode 100644
index 0000000..385d689
--- /dev/null
+++ b/Sln.Wcs.UI/Attribute/RegisterAsTransientAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Sln.Wcs.UI.Attribute
+{
+ public class RegisterAsTransientAttribute:System.Attribute
+ {
+ }
+}
diff --git a/Sln.Wcs.UI/Attribute/RequirePermissionAttribute.cs b/Sln.Wcs.UI/Attribute/RequirePermissionAttribute.cs
new file mode 100644
index 0000000..d443fc2
--- /dev/null
+++ b/Sln.Wcs.UI/Attribute/RequirePermissionAttribute.cs
@@ -0,0 +1,103 @@
+using Microsoft.Extensions.DependencyInjection;
+using Rougamo;
+using Rougamo.Context;
+using Sln.Wcs.UI.Page.Loading;
+using System.Windows;
+using System.Windows.Threading;
+
+#region << 版 本 注 释 >>
+/*--------------------------------------------------------------------
+* 版权所有 (c) 2024 WenJY 保留所有权利。
+* CLR版本:4.0.30319.42000
+* 机器名称:T14-GEN3-7895
+* 命名空间:SlnMesnac.WPF.Attribute
+* 唯一标识:fff40cb6-18aa-47e0-917c-1fa653e6f978
+*
+* 创建者:WenJY
+* 电子邮箱:
+* 创建时间:2024-12-30 10:19:41
+* 版本:V1.0.0
+* 描述:
+*
+*--------------------------------------------------------------------
+* 修改人:
+* 时间:
+* 修改说明:
+*
+* 版本:V1.0.0
+*--------------------------------------------------------------------*/
+#endregion << 版 本 注 释 >>
+namespace Sln.Wcs.UI.Attribute
+{
+ ///
+ /// 权限过滤
+ ///
+ public class RequirePermissionAttribute : MoAttribute
+ {
+ private LoadingWindow loadingWindow;
+ private string _permissionName;
+
+ public RequirePermissionAttribute(string permissionName)
+ {
+ _permissionName = permissionName;
+
+
+ }
+ public override void OnEntry(MethodContext context)
+ {
+ Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
+ newWindowThread.SetApartmentState(ApartmentState.STA); // 设置为 STA 模式
+ newWindowThread.IsBackground = true; // 设置为后台线程
+ newWindowThread.Start();
+
+ bool hasPermission = CheckPermission(_permissionName);
+
+ if (!hasPermission)
+ {
+ // 如果用户没有权限,抛出异常或采取其他措施
+ throw new UnauthorizedAccessException("User does not have the required permission.");
+ }
+
+ base.OnEntry(context);
+ }
+
+
+ public override void OnExit(MethodContext context)
+ {
+ Thread.Sleep(200);
+ if(loadingWindow != null)
+ {
+ loadingWindow.Dispatcher.Invoke(new Action(() =>
+ {
+ loadingWindow.Close(); // 关闭窗口
+ }));
+ }
+
+
+ base.OnExit(context);
+ }
+
+ ///
+ /// 判断权限
+ ///
+ ///
+ ///
+ private bool CheckPermission(string permissionName)
+ {
+ return true;
+ }
+
+ private void ThreadStartingPoint()
+ {
+ Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
+ {
+ loadingWindow = App.ServiceProvider.GetService();
+ loadingWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
+ loadingWindow.Topmost = true;
+ loadingWindow.Show();
+ }));
+
+ Dispatcher.Run();
+ }
+ }
+}
diff --git a/Sln.Wcs.UI/FodyWeavers.xml b/Sln.Wcs.UI/FodyWeavers.xml
new file mode 100644
index 0000000..a6a2edf
--- /dev/null
+++ b/Sln.Wcs.UI/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Sln.Wcs.UI/MainWindow.xaml b/Sln.Wcs.UI/MainWindow.xaml
new file mode 100644
index 0000000..9e7ab56
--- /dev/null
+++ b/Sln.Wcs.UI/MainWindow.xaml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/Sln.Wcs.UI/MainWindow.xaml.cs b/Sln.Wcs.UI/MainWindow.xaml.cs
new file mode 100644
index 0000000..1fa96a2
--- /dev/null
+++ b/Sln.Wcs.UI/MainWindow.xaml.cs
@@ -0,0 +1,24 @@
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Sln.Wcs.UI
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sln.Wcs.UI/Page/Loading/LoadingWindow.xaml b/Sln.Wcs.UI/Page/Loading/LoadingWindow.xaml
new file mode 100644
index 0000000..0eb20da
--- /dev/null
+++ b/Sln.Wcs.UI/Page/Loading/LoadingWindow.xaml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Sln.Wcs.UI/Page/Loading/LoadingWindow.xaml.cs b/Sln.Wcs.UI/Page/Loading/LoadingWindow.xaml.cs
new file mode 100644
index 0000000..b209975
--- /dev/null
+++ b/Sln.Wcs.UI/Page/Loading/LoadingWindow.xaml.cs
@@ -0,0 +1,26 @@
+using Sln.Wcs.UI.Attribute;
+using System;
+using System.Windows;
+using System.Windows.Threading;
+
+namespace Sln.Wcs.UI.Page.Loading
+{
+ ///
+ /// LoadingWindow.xaml 的交互逻辑
+ ///
+ [RegisterAsTransientAttribute]
+ public partial class LoadingWindow : Window
+ {
+ public LoadingWindow()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnClosed(EventArgs e)
+ {
+ base.OnClosed(e);
+ // 停止 Dispatcher 消息循环
+ Dispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
+ }
+ }
+}
diff --git a/Sln.Wcs.UI/Sln.Wcs.UI.csproj b/Sln.Wcs.UI/Sln.Wcs.UI.csproj
new file mode 100644
index 0000000..02fdd99
--- /dev/null
+++ b/Sln.Wcs.UI/Sln.Wcs.UI.csproj
@@ -0,0 +1,42 @@
+
+
+
+ WinExe
+ net8.0-windows
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sln.Wcs.UI/Templates/gif/loading.gif b/Sln.Wcs.UI/Templates/gif/loading.gif
new file mode 100644
index 0000000..ba81ff0
Binary files /dev/null and b/Sln.Wcs.UI/Templates/gif/loading.gif differ
diff --git a/Sln.Wcs.UI/Templates/icon/Icon.png b/Sln.Wcs.UI/Templates/icon/Icon.png
new file mode 100644
index 0000000..1560465
Binary files /dev/null and b/Sln.Wcs.UI/Templates/icon/Icon.png differ
diff --git a/Sln.Wcs.UI/Templates/image/background.jpg b/Sln.Wcs.UI/Templates/image/background.jpg
new file mode 100644
index 0000000..860c0b0
Binary files /dev/null and b/Sln.Wcs.UI/Templates/image/background.jpg differ
diff --git a/Sln.Wcs.UI/Templates/image/login-background.jpg b/Sln.Wcs.UI/Templates/image/login-background.jpg
new file mode 100644
index 0000000..96303ad
Binary files /dev/null and b/Sln.Wcs.UI/Templates/image/login-background.jpg differ
diff --git a/Sln.Wcs.UI/Templates/style/resourceStyle.xaml b/Sln.Wcs.UI/Templates/style/resourceStyle.xaml
new file mode 100644
index 0000000..e7155f2
--- /dev/null
+++ b/Sln.Wcs.UI/Templates/style/resourceStyle.xaml
@@ -0,0 +1,424 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Sln.Wcs.UI/ViewModel/Login/LoginViewModel.cs b/Sln.Wcs.UI/ViewModel/Login/LoginViewModel.cs
new file mode 100644
index 0000000..c2e9d9b
--- /dev/null
+++ b/Sln.Wcs.UI/ViewModel/Login/LoginViewModel.cs
@@ -0,0 +1,50 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using Microsoft.Extensions.DependencyInjection;
+using Sln.Wcs.UI;
+using Sln.Wcs.UI.Attribute;
+using System;
+using System.Windows;
+
+namespace Sln.Wcs.UI.ViewModel.Login
+{
+ [RegisterAsSingleton]
+ public partial class LoginViewModel: ObservableObject
+ {
+ [ObservableProperty]
+ public string systemTitle = string.Empty;
+
+ [ObservableProperty]
+ public string userName = string.Empty;
+
+ public LoginViewModel()
+ {
+ SystemTitle = "系统测试";
+ }
+
+
+ [RequirePermission("Login")]
+ public bool Login(string userName,string password)
+ {
+ bool res = true;
+ try
+ {
+ //res = _usersBusiness.Verify(userName, password);
+ if (res)
+ {
+ App.Current.Dispatcher.Invoke(() =>
+ {
+ MainWindow mainWindow = App.ServiceProvider.GetService();
+ App.Current.MainWindow = mainWindow;
+ mainWindow.Show();
+
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"登录失败:{ex.Message}");
+ }
+ return res;
+ }
+ }
+}
diff --git a/Sln.Wcs.UI/appsettings.json b/Sln.Wcs.UI/appsettings.json
new file mode 100644
index 0000000..d486625
--- /dev/null
+++ b/Sln.Wcs.UI/appsettings.json
@@ -0,0 +1,18 @@
+{
+ "exclude": [
+ "**/bin",
+ "**/bower_components",
+ "**/jspm_packages",
+ "**/node_modules",
+ "**/obj",
+ "**/platforms"
+ ],
+ "apollo": {
+ "AppId": "SlnWcs",
+ "Env": "DEV",
+ "MetaServer": "http://119.45.202.115:4320",
+ "ConfigServer": [
+ "http://119.45.202.115:4320"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Sln.Wcs.sln b/Sln.Wcs.sln
index ff73ae9..3874f83 100644
--- a/Sln.Wcs.sln
+++ b/Sln.Wcs.sln
@@ -10,17 +10,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Wcs.HikRoBotSdk", "Sln.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Wcs.HikRoBotApi", "Sln.Wcs.HikRoBotApi\Sln.Wcs.HikRoBotApi.csproj", "{9E3193CA-590C-4965-B2EF-02C2AE252095}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Wcs.Model", "Sln.Wcs.Model\Sln.Wcs.Model.csproj", "{18437437-F83E-4A3E-9759-8AF313C47D77}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Wcs.Model", "Sln.Wcs.Model\Sln.Wcs.Model.csproj", "{18437437-F83E-4A3E-9759-8AF313C47D77}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Wcs.Plc", "Sln.Wcs.Plc\Sln.Wcs.Plc.csproj", "{ECB2A29C-7A82-83D1-F9FD-5B8C41E55261}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Wcs.Plc", "Sln.Wcs.Plc\Sln.Wcs.Plc.csproj", "{ECB2A29C-7A82-83D1-F9FD-5B8C41E55261}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Wcs.ElevatorSdk", "SLn.Wcs.ElevatorSdk\Sln.Wcs.ElevatorSdk.csproj", "{504764BF-FD5F-4BE5-80C5-061C2EE9C79B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Wcs.ElevatorSdk", "SLn.Wcs.ElevatorSdk\Sln.Wcs.ElevatorSdk.csproj", "{504764BF-FD5F-4BE5-80C5-061C2EE9C79B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Wcs.Serilog", "Sln.Wcs.Serilog\Sln.Wcs.Serilog.csproj", "{5EF250AE-58B8-4C39-8F36-A579EA252A5C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Wcs.Repository", "Sln.Wcs.Repository\Sln.Wcs.Repository.csproj", "{549AF273-88BE-4316-88F8-CAD82BC5F1E7}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Wcs.Repository", "Sln.Wcs.Repository\Sln.Wcs.Repository.csproj", "{549AF273-88BE-4316-88F8-CAD82BC5F1E7}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Wcs.Cache", "Sln.Wcs.Cache\Sln.Wcs.Cache.csproj", "{97940311-1DE9-4282-8EE0-0174513BF245}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Wcs.Cache", "Sln.Wcs.Cache\Sln.Wcs.Cache.csproj", "{97940311-1DE9-4282-8EE0-0174513BF245}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Wcs.UI", "Sln.Wcs.UI\Sln.Wcs.UI.csproj", "{03325079-1FCE-4F30-828C-2E5260554961}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -68,6 +70,10 @@ Global
{97940311-1DE9-4282-8EE0-0174513BF245}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97940311-1DE9-4282-8EE0-0174513BF245}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97940311-1DE9-4282-8EE0-0174513BF245}.Release|Any CPU.Build.0 = Release|Any CPU
+ {03325079-1FCE-4F30-828C-2E5260554961}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {03325079-1FCE-4F30-828C-2E5260554961}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {03325079-1FCE-4F30-828C-2E5260554961}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {03325079-1FCE-4F30-828C-2E5260554961}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE