change - 修改注入方式,添加登录页面、加载效果

dev
wenjy 3 weeks ago
parent 524c93f430
commit 3d58397c55

@ -1,150 +0,0 @@
using Autofac;
using SlnMesnac.Repository;
using SlnMesnac.Serilog;
using System.Reflection;
using TouchSocket.Sockets;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* LAPTOP-E0N2L34V
* SlnMesnac.Ioc
* 496f8d2b-70e3-4a05-ae18-a9b0fcd06b82
*
* WenJY
* wenjy@mesnac.com
* 2024-03-27 21:58:35
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Ioc
{
/// <summary>
/// Utility class for configuring dependency injection.
/// </summary>
public static class DependencyConfigurator
{
/// <summary>
/// Configures dependency injection for the application.
/// </summary>
/// <param name="builder">The Autofac container builder.</param>
public static void Configure(ContainerBuilder builder)
{
//注入Repository
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(Repository<>));
RegisterImplementations(builder, Assembly.LoadFrom("SlnMesnac.Repository.dll"));
//注入Plc
RegisterTypeTransient(builder, Assembly.LoadFrom("SlnMesnac.Plc.dll"));
//注入Rfid
RegisterTypeTransient(builder, Assembly.LoadFrom("SlnMesnac.Rfid.dll"));
//注入通用类
RegisterType(builder, Assembly.LoadFrom("SlnMesnac.Common.dll"));
//注入MQTT
RegisterType(builder, Assembly.LoadFrom("SlnMesnac.Mqtt.dll"));
//注入TouchSocket
builder.RegisterType(typeof(TcpService));
RegisterType(builder, Assembly.LoadFrom("SlnMesnac.TouchSocket.dll"));
//注入业务类
RegisterType(builder, Assembly.LoadFrom("SlnMesnac.Business.dll"));
//注入代码生成
RegisterType(builder, Assembly.LoadFrom("SlnMesnac.Generate.dll"));
//注入Serilog日志帮助类
builder.RegisterType(typeof(SerilogHelper)).SingleInstance();
}
/// <summary>
/// 自动注入接口实现
/// </summary>
/// <param name="builder"></param>
/// <param name="assembly"></param>
private static void RegisterImplementations(ContainerBuilder builder, Assembly assembly)
{
//自动注入仓储层的接口实现类
var types = assembly.GetTypes()
.Where(t => t.IsClass && !t.IsAbstract && !t.IsGenericType)
.ToList();
foreach (var type in types)
{
var interfaces = type.GetInterfaces();
foreach (var @interface in interfaces)
{
builder.RegisterType(type).As(@interface);
}
}
}
/// <summary>
/// 自动注入自定义类、抽象类,设置为单例
/// </summary>
/// <param name="builder"></param>
/// <param name="assembly"></param>
private static void RegisterType(ContainerBuilder builder, Assembly assembly)
{
var types = assembly.GetTypes()
.Where(t => t.IsClass && !t.IsAbstract && !t.IsGenericType)
.ToList();
foreach (var type in types)
{
var interfaces = type.GetInterfaces();
var baseType = type.BaseType;
#region 只注入抽象类 Delete By wenjy 2024-03-27
//if (baseType != null && baseType.IsAbstract && baseType == typeof(PlcAbsractFactory))
//{
// builder.RegisterType(type);
//}
#endregion
if (!typeof(Delegate).IsAssignableFrom(type)) //不注入委托事件
{
builder.RegisterType(type).SingleInstance();
}
}
}
/// <summary>
/// 自动注入自定义类,设置生命周期为每次解析返回新实例
/// </summary>
/// <param name="builder"></param>
/// <param name="assembly"></param>
private static void RegisterTypeTransient(ContainerBuilder builder, Assembly assembly)
{
var types = assembly.GetTypes()
.Where(t => t.IsClass && !t.IsAbstract && !t.IsGenericType)
.ToList();
foreach (var type in types)
{
var interfaces = type.GetInterfaces();
var baseType = type.BaseType;
if (!typeof(Delegate).IsAssignableFrom(type))
{
builder.RegisterType(type).AsSelf().InstancePerDependency();
}
}
}
}
}

@ -1,18 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SlnMesnac.Repository\SlnMesnac.Repository.csproj" />
<ProjectReference Include="..\SlnMesnac.TouchSocket\SlnMesnac.TouchSocket.csproj" />
</ItemGroup>
</Project>

@ -35,13 +35,10 @@ namespace SlnMesnac.Serilog
/// </summary>
public static class SerilogExtensions
{
public static IApplicationBuilder UseSerilogExtensions(this IApplicationBuilder app)
public static void UseSerilogExtensions(this IServiceProvider service)
{
//启用Serilog中间件
app.UseSerilogRequestLogging();
#region 通过配置文件读取日志存放位置
var appConfig = app.ApplicationServices.GetService<AppConfig>();
var appConfig = service.GetService<AppConfig>();
var logPath = $"{appConfig.logPath}/Logs/";
#endregion
@ -67,10 +64,6 @@ namespace SlnMesnac.Serilog
.Filter.ByIncludingOnly(logEvent => logEvent.Properties.ContainsKey("Module") && logEvent.Properties["Module"].ToString().Contains("Error"))
.WriteTo.File(Path.Combine($"{logPath}/Error/", "Error.log"), rollingInterval: RollingInterval.Day))
.CreateLogger();
app.UseSerilogRequestLogging();
return app;
}
}
}

@ -1,14 +1,36 @@
<Application x:Class="SlnMesnac.WPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SlnMesnac.WPF"
StartupUri="MainWindow.xaml">
xmlns:local="clr-namespace:SlnMesnac.WPF">
<Application.Resources>
<!--Button样式-->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Templates/style/resourceStyle.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign3.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.LightBlue.xaml" />
<!--<ResourceDictionary Source="Templates\Languages\StringResource.en-US.xaml" />
<ResourceDictionary Source="Templates\Languages\StringResource.zh-CN.xaml" />-->
</ResourceDictionary.MergedDictionaries>
<!--重写框架主体色-->
<SolidColorBrush x:Key="PrimaryHueLightBrush" Color="#3b76ee" />
<SolidColorBrush x:Key="PrimaryHueLightForegroundBrush" Color="#3b76ee" />
<SolidColorBrush x:Key="PrimaryHueMidBrush" Color="#3b76ee" />
<SolidColorBrush x:Key="PrimaryHueMidForegroundBrush" Color="#3b76ee" />
<SolidColorBrush x:Key="PrimaryHueDarkBrush" Color="#3b76ee" />
<SolidColorBrush x:Key="PrimaryHueDarkForegroundBrush" Color="#3b76ee" />
<!-- DataGrid列标题居中样式 -->
<Style x:Key="DataGridColumnHeaderStyle" TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
<!-- DataGrid单元格居中样式 -->
<Style x:Key="DataGridCellCenterStyle" TargetType="DataGridCell">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>

@ -1,15 +1,16 @@
using Lierda.WPFHelper;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using SlnMesnac.Config;
using System;
using System.Windows;
using Autofac.Extensions.DependencyInjection;
using SlnMesnac.Plc;
using System.Collections.Generic;
using SlnMesnac.Rfid;
using Microsoft.Extensions.Configuration;
using SlnMesnac.Extensions;
using SlnMesnac.Serilog;
using System.Reflection;
using TouchSocket.Sockets;
using SlnMesnac.WPF.Attribute;
using SlnMesnac.WPF.Page.Login;
namespace SlnMesnac.WPF
{
@ -22,9 +23,15 @@ namespace SlnMesnac.WPF
private LierdaCracker cracker = new LierdaCracker();
public static IServiceProvider? ServiceProvider = null;
public new static App Current => (App)Application.Current;
// Startup事件
protected override async void OnStartup(StartupEventArgs e)
{
this.DispatcherUnhandledException += App_DispatcherUnhandledException; //全局异常处理
#region 进程判断,避免重复开启
bool ret;
mutex = new System.Threading.Mutex(true, System.Diagnostics.Process.GetCurrentProcess().ProcessName, out ret);
if (!ret)
@ -32,35 +39,96 @@ namespace SlnMesnac.WPF
MessageBox.Show("应用程序已开启,禁止重复运行");
Environment.Exit(0);
}
#endregion
cracker.Cracker(100); //设置GC回收间隔
base.OnStartup(e);
var host = CreateHostBuilder(e.Args).Build();//生成宿主。
ServiceProvider = host.Services;
// 设置ServiceCollection
var services = new ServiceCollection();
ConfigureServices(services); // 配置服务
// 创建ServiceProvider
ServiceProvider = services.BuildServiceProvider();
await host.StartAsync();
// 配置Serilog和其他扩展
ServiceProvider.UseSerilogExtensions();
var appConfig = host.Services.GetService<AppConfig>();
var logPath = $"{appConfig.logPath}/Logs/{DateTime.UtcNow:yyyy-MM-dd}/";
Log.Information($"系统初始化完成,日志存放路径:{appConfig.logPath}");
var appConfig = ServiceProvider.GetService<AppConfig>();
Log.Information($"系统初始化完成,日志存放路径:{appConfig?.logPath}");
var loginWindow = ServiceProvider.GetRequiredService<LoginWindow>();
loginWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
loginWindow.Show();
}
/// <summary>
/// CreateHostBuilder
/// ConfigureServices
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
/// <param name="services"></param>
private void ConfigureServices(IServiceCollection services)
{
// 注册AppConfig
services.AddSingleton<AppConfig>(provider =>
{
var configurationBuilder = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
IConfiguration configuration = configurationBuilder.Build();
var ap = configuration.GetSection("AppConfig").Get<AppConfig>();
return ap;
});
services.AddSingleton(typeof(SerilogHelper));
Assembly[] assemblies = {
Assembly.LoadFrom("SlnMesnac.Repository.dll"),
Assembly.LoadFrom("SlnMesnac.Plc.dll"),
Assembly.LoadFrom("SlnMesnac.Rfid.dll"),
Assembly.LoadFrom("SlnMesnac.Common.dll"),
Assembly.LoadFrom("SlnMesnac.TouchSocket.dll"),
Assembly.LoadFrom("SlnMesnac.Business.dll"),
Assembly.LoadFrom("SlnMesnac.Generate.dll")
};
services.Scan(scan => scan.FromAssemblies(assemblies)
.AddClasses()
.AsImplementedInterfaces()
.AsSelf()
.WithTransientLifetime());
services.AddSingleton(typeof(TcpService));
services.AddLogging(x => x.AddSerilog());
services.Scan(scan => scan
.FromAssemblyOf<LoginWindow>()
.AddClasses(classes => classes.WithAttribute<RegisterAsSingletonAttribute>()).AsSelf().WithSingletonLifetime());
services.Scan(scan => scan
.FromAssemblyOf<LoginWindow>()
.AddClasses(classes => classes.WithAttribute<RegisterAsTransientAttribute>()).AsSelf().WithTransientLifetime());
// 注册ORM
services.AddSqlSugarSetup();
// 注册PLC工厂
//services.AddPlcFactorySetup();
//services.AddJob();
// 注册 EventBus 服务
//services.AddEventBus(builder =>
//{
// // 注册 ToDo 事件订阅者
// builder.AddSubscriber<ToDoEventSubscriber>();
//});
}
// Exit事件
protected override void OnExit(ExitEventArgs e)
@ -72,6 +140,17 @@ namespace SlnMesnac.WPF
// ...
}
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
// 处理异常
var info = e.Exception;
MessageBox.Show(e.Exception.Message);
Log.Error($"全局异常:{e.Exception.Message}", e.Exception);
// 防止默认的崩溃行为
e.Handled = true;
}
}
}

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.WPF.Attribute
{
public class RegisterAsSingletonAttribute:System.Attribute
{
}
}

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.WPF.Attribute
{
public class RegisterAsTransientAttribute:System.Attribute
{
}
}

@ -0,0 +1,109 @@
using Microsoft.Extensions.DependencyInjection;
using Rougamo;
using Rougamo.Context;
using SlnMesnac.WPF.Page.Loading;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.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 SlnMesnac.WPF.Attribute
{
/// <summary>
/// 权限过滤
/// </summary>
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);
}
/// <summary>
/// 判断权限
/// </summary>
/// <param name="permissionName"></param>
/// <returns></returns>
private bool CheckPermission(string permissionName)
{
return true;
}
private void ThreadStartingPoint()
{
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
loadingWindow = App.ServiceProvider.GetService<LoadingWindow>();
loadingWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
loadingWindow.Topmost = true;
loadingWindow.Show();
}));
Dispatcher.Run();
}
}
}

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Rougamo />
</Weavers>

@ -61,11 +61,11 @@
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Orientation="Horizontal">
<Button Content="首 页" x:Name="Index" Command="{Binding ControlOnClickCommand}" CommandParameter="{Binding Name,ElementName=Index}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="10,0,10,0"/>
<Button Content="代码生成" x:Name="Generate" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Generate}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>
<Button Content="键 盘" Command="{Binding OpenSystemKeyboardCommand}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>
<Button Content="最小化" x:Name="Minimized" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Minimized}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#FF9900" BorderBrush="#FF9900" Margin="0,0,10,0"/>
<Button Content="退 出" x:Name="Exit" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Exit}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#FF0033" BorderBrush="#FF0033" Margin="0,0,10,0"/>
<Button Content="首 页" x:Name="Index" Command="{Binding ControlOnClickCommand}" CommandParameter="{Binding Name,ElementName=Index}" Style="{StaticResource MaterialDesignFlatMidBgButton}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="10,0,10,0"/>
<Button Content="代码生成" x:Name="Generate" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Generate}" Style="{StaticResource MaterialDesignFlatMidBgButton}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>
<Button Content="键 盘" Command="{Binding OpenSystemKeyboardCommand}" Style="{StaticResource MaterialDesignFlatMidBgButton}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>
<Button Content="最小化" x:Name="Minimized" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Minimized}" Style="{StaticResource MaterialDesignFlatMidBgButton}" Width="100" Height="30" Background="#FF9900" BorderBrush="#FF9900" Margin="0,0,10,0"/>
<Button Content="退 出" x:Name="Exit" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Exit}" Style="{StaticResource MaterialDesignFlatMidBgButton}" Width="100" Height="30" Background="#FF0033" BorderBrush="#FF0033" Margin="0,0,10,0"/>
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal">

@ -1,4 +1,5 @@
using SlnMesnac.WPF.ViewModel;
using SlnMesnac.WPF.Attribute;
using SlnMesnac.WPF.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
@ -19,13 +20,14 @@ namespace SlnMesnac.WPF
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[RegisterAsSingletonAttribute]
public partial class MainWindow : Window
{
public MainWindow()
public MainWindow(MainWindowViewModel mainWindowViewModel)
{
InitializeComponent();
this.DataContext = new MainWindowViewModel();
this.DataContext = mainWindowViewModel;
}
}
}

@ -24,7 +24,7 @@
<TextBlock Text="表名:" FontSize="20" Foreground="White" VerticalAlignment="Center" Margin="30,0,10,0"/>
<TextBox x:Name="queryParam" Foreground="White" FontSize="18" Width="200" Height="35"/>
<Button Content="查 询" FontSize="16" Style="{StaticResource BUTTON_AGREE}" Width="120" Height="35" Background="#007DFA" BorderBrush="#007DFA" Margin="20,0,10,0" Command="{Binding QuerySearchCommand}" CommandParameter="{Binding Text, ElementName=queryParam}" />
<Button Content="查 询" FontSize="16" Width="120" Height="35" Background="#007DFA" BorderBrush="#007DFA" Margin="20,0,10,0" Command="{Binding QuerySearchCommand}" CommandParameter="{Binding Text, ElementName=queryParam}" />
</StackPanel>
</Border>

@ -1,4 +1,5 @@
using SlnMesnac.WPF.ViewModel.Generate;
using SlnMesnac.WPF.Attribute;
using SlnMesnac.WPF.ViewModel.Generate;
using System;
using System.Collections.Generic;
using System.Linq;
@ -19,12 +20,13 @@ namespace SlnMesnac.WPF.Page.Generate
/// <summary>
/// GenerateControl.xaml 的交互逻辑
/// </summary>
[RegisterAsSingletonAttribute]
public partial class GenerateControl : UserControl
{
public GenerateControl()
public GenerateControl(GenerateControlViewModel generateControlViewModel)
{
InitializeComponent();
this.DataContext = new GenerateControlViewModel();
this.DataContext = generateControlViewModel;
}
}
}

@ -0,0 +1,19 @@
<Window x:Class="SlnMesnac.WPF.Page.Loading.LoadingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SlnMesnac.WPF.Page.Loading"
xmlns:gif="http://wpfanimatedgif.codeplex.com"
mc:Ignorable="d"
Height="200" Width="400"
WindowStyle="None"
ResizeMode="NoResize"
Topmost="True"
AllowsTransparency="True"
Background="Transparent"
Opacity="0.8">
<Grid>
<Image gif:ImageBehavior.AnimatedSource="pack://application:,,,/Templates/gif/loading.gif" Height="180"/>
</Grid>
</Window>

@ -0,0 +1,26 @@
using SlnMesnac.WPF.Attribute;
using System;
using System.Windows;
using System.Windows.Threading;
namespace SlnMesnac.WPF.Page.Loading
{
/// <summary>
/// LoadingWindow.xaml 的交互逻辑
/// </summary>
[RegisterAsTransientAttribute]
public partial class LoadingWindow : Window
{
public LoadingWindow()
{
InitializeComponent();
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
// 停止 Dispatcher 消息循环
Dispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
}
}
}

@ -0,0 +1,58 @@
<Window x:Class="SlnMesnac.WPF.Page.Login.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SlnMesnac.WPF.Page.Login"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
Title="{Binding SystemTitle}" Height="600" Width="980">
<Window.Background>
<ImageBrush ImageSource="/Templates/image/login-background.jpg" />
</Window.Background>
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Background="Transparent" Height="50" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="50,50">
<Label Content="{Binding SystemTitle}" Foreground="#007DFA" FontSize="25"/>
</StackPanel>
<Border Grid.Column="1" Background="White" Height="300" CornerRadius="10" >
<Grid Cursor="">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Foreground="Gray" Text="用户登录" FontSize="20"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<!--<TextBlock Foreground="Gray" Text="账号:" FontSize="16" Margin="0,10,10,0"/>
<TextBox x:Name="UserNameStr" Foreground="Gray" FontSize="16" Width="150" Height="35"/>-->
<materialDesign:PackIcon Kind="AccountKeyOutline" VerticalAlignment="Bottom" Height="25" Width="25" Margin="0,0,10,0"/>
<TextBox x:Name="UserNameStr" Width="150" FontSize="16" VerticalAlignment="Center" materialDesign:HintAssist.Hint="请输入用户名" Style="{StaticResource MaterialDesignFloatingHintTextBox}" />
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<!--<TextBlock Foreground="Gray" Text="密码:" FontSize="16" Margin="0,10,10,0"/>-->
<!--<PasswordBox x:Name="PasswordStr" HorizontalAlignment="Left" VerticalContentAlignment="Center" Width="150" PasswordChar="*" />-->
<materialDesign:PackIcon Kind="AccountLockOutline" VerticalAlignment="Bottom" Height="25" Width="25" Margin="0,0,10,0"/>
<PasswordBox
x:Name="PasswordStr" Width="150" FontSize="16"
materialDesign:HintAssist.Foreground="Green"
materialDesign:HintAssist.Hint="请输入密码"
materialDesign:TextFieldAssist.UnderlineBrush="Green"
Style="{StaticResource MaterialDesignFloatingHintPasswordBox}" Cursor="Hand" />
</StackPanel>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="3">
<Button x:Name="LoginBtn" Content="登录" Background="#007DFA" ToolTip="MaterialDesignFlatMidButton" Margin="10,0,10,0" Style="{StaticResource MaterialDesignFlatMidBgButton}" Foreground="White" FontSize="16" Width="150" Height="30" Click="LoginBtn_Click"/>
</StackPanel>
</Grid>
</Border>
</Grid>
</Grid>
</Window>

@ -0,0 +1,54 @@
using SlnMesnac.WPF.Attribute;
using SlnMesnac.WPF.ViewModel.Login;
using System;
using System.Windows;
namespace SlnMesnac.WPF.Page.Login
{
/// <summary>
/// LoginWindow.xaml 的交互逻辑
/// </summary>
[RegisterAsSingletonAttribute]
public partial class LoginWindow : Window
{
private readonly LoginViewModel _loginViewModel;
public LoginWindow(LoginViewModel loginViewModel)
{
_loginViewModel = loginViewModel;
InitializeComponent();
this.DataContext = _loginViewModel;
}
private async void LoginBtn_Click(object sender, RoutedEventArgs e)
{
string userName = UserNameStr.Text.ToString();
string password = PasswordStr.Password;
//if (string.IsNullOrEmpty(userName))
//{
// MessageBox.Show("用户名不允许为空");
// return;
//}
//if (string.IsNullOrEmpty(password))
//{
// MessageBox.Show("密码不允许为空");
// return;
//}
bool res = _loginViewModel.Login(userName,password);
if (res)
{
this.Closing += MainWindow_Closing;
this.Close();
}
}
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
this.Closing -= MainWindow_Closing; // 防止多次绑定
e.Cancel = true;
this.Visibility = Visibility.Hidden; // 隐藏窗口
}
}
}

@ -1,15 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<None Remove="appsettings.json" />
<None Remove="Templates\gif\loading.gif" />
<None Remove="Templates\image\background.jpg" />
<None Remove="Templates\image\login-background.jpg" />
</ItemGroup>
<ItemGroup>
@ -36,15 +39,20 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Lierda.WPFHelper" Version="1.0.3" />
<PackageReference Include="NVelocity" Version="1.2.0" />
<PackageReference Include="MaterialDesignThemes" Version="5.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Rougamo.Fody" Version="5.0.0" />
<PackageReference Include="Scrutor" Version="6.0.1" />
<PackageReference Include="WindowsAPICodePack-Shell" Version="1.1.1" />
<PackageReference Include="WpfAnimatedGif" Version="2.0.2" />
</ItemGroup>
<ItemGroup>
<Resource Include="Templates\gif\loading.gif" />
<Resource Include="Templates\image\background.jpg" />
<Resource Include="Templates\image\login-background.jpg" />
</ItemGroup>
</Project>

@ -1,88 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SlnMesnac.Config;
using SlnMesnac.Repository;
using SlnMesnac.Serilog;
using System;
using Autofac;
using Microsoft.Extensions.Configuration;
using SlnMesnac.Rfid;
using SlnMesnac.Ioc;
using SlnMesnac.Plc;
using SlnMesnac.Extensions;
using SlnMesnac.TouchSocket;
namespace SlnMesnac.WPF
{
/// <summary>
///
/// </summary>
public class Startup
{
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services"></param>
[Obsolete]
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//注册AppConfig
services.AddSingleton<AppConfig>(provider =>
{
var configuration = provider.GetService<IConfiguration>();
return configuration.GetSection("AppConfig").Get<AppConfig>();
});
//注册ORM
services.AddSqlSugarSetup();
//注册PLC工厂
services.AddPlcFactorySetup();
//注册RFID工厂
services.AddRfidFactorySetup();
}
/// <summary>
/// AutoFac自动注入
/// </summary>
/// <param name="builder"></param>
public void ConfigureContainer(ContainerBuilder builder)
{
DependencyConfigurator.Configure(builder);
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//启用Serilog中间件
app.UseSerilogExtensions();
app.UseTouchSocketExtensions();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

@ -0,0 +1,59 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace SlnMesnac.WPF.ViewModel.Base
{
public class BaseViewModel : ObservableObject
{
public string EscapeUnicode(string input)
{
return Regex.Replace(input, "&#x([0-9a-fA-F]+);", match =>
{
string hexValue = match.Groups[1].Value;
return $"\\u{hexValue}";
});
}
/// <summary>
/// 获取当前类中的方法
/// </summary>
/// <returns></returns>
public Dictionary<string, IRelayCommand> GetRelayCommandsAsDictionary()
{
var commandDict = new Dictionary<string, IRelayCommand>();
var properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in properties)
{
if (property.PropertyType == typeof(IRelayCommand))
{
var command = property.GetValue(this) as IRelayCommand;
if (command != null)
{
commandDict[property.Name] = command;
}
}
}
var fields = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (var field in fields)
{
if (field.FieldType == typeof(IRelayCommand))
{
var command = field.GetValue(this) as IRelayCommand;
if (command != null)
{
commandDict[field.Name] = command;
}
}
}
return commandDict;
}
}
}

@ -0,0 +1,75 @@

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core;
namespace SlnMesnac.WPF.ViewModel.Base
{
/// <summary>
/// ViewModel抽象类分页
/// </summary>
public abstract partial class BaseViewModelAsPageQuery : ObservableObject
{
/// <summary>
/// 当前页码
/// </summary>
[ObservableProperty]
public int currentPage = 1;
/// <summary>
/// 每页显示的行数
/// </summary>
[ObservableProperty]
public int pageSize = 10;
/// <summary>
/// 总条数
/// </summary>
public int totalCount = 0;
/// <summary>
/// 总页数
/// </summary>
[ObservableProperty]
public int totalPages = 0;
/// <summary>
/// 首页
/// </summary>
[RelayCommand]
private void FirstPage() => ChangePage(1);
/// <summary>
/// 上一页
/// </summary>
[RelayCommand]
private void PreviousPage() => ChangePage(CurrentPage - 1);
/// <summary>
/// 下一页
/// </summary>
[RelayCommand]
private void NextPage() => ChangePage(CurrentPage + 1);
/// <summary>
/// 尾页
/// </summary>
[RelayCommand]
private void LastPage() => ChangePage(TotalPages);
private void ChangePage(int newPage)
{
if (newPage >= 1 && newPage <= TotalPages)
{
CurrentPage = newPage;
Query();
}
}
public abstract void Query();
}
}

@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.WindowsAPICodePack.Dialogs;
using SlnMesnac.Config;
using SlnMesnac.Generate;
using SlnMesnac.WPF.Attribute;
using SqlSugar;
using System;
using System.Collections.Generic;
@ -36,28 +37,31 @@ using System.Windows;
#endregion << 版 本 注 释 >>
namespace SlnMesnac.WPF.ViewModel.Generate
{
internal partial class GenerateControlViewModel : ObservableObject
[RegisterAsSingleton]
public class GenerateControlViewModel : ObservableObject
{
private readonly AppConfig _appConfig;
private readonly GenerateCode _generateCode;
public GenerateControlViewModel()
public GenerateControlViewModel(AppConfig appConfig, GenerateCode generateCode)
{
_appConfig = App.ServiceProvider.GetService<AppConfig>();
_appConfig = appConfig;
_generateCode = generateCode;
_generateCode = App.ServiceProvider.GetService<GenerateCode>();
var configIds = _appConfig.sqlConfig.Select(x=>x.configId).ToList();
var configIds = _appConfig.sqlConfig.Select(x => x.configId).ToList();
// 初始化选项列表
Options = new ObservableCollection<string>();
foreach(var configId in configIds)
foreach (var configId in configIds)
{
Options.Add(configId);
}
QuerySearchCommand = new RelayCommand<string>(Query);
CreateCodeCommand = new RelayCommand<string>(CreateCode);
}
#region 参数定义
@ -74,7 +78,7 @@ namespace SlnMesnac.WPF.ViewModel.Generate
get => _selectedOption;
set => SetProperty(ref _selectedOption, value);
}
private ObservableCollection<DbTableInfo> tablesDataGrid;
public ObservableCollection<DbTableInfo> TablesDataGrid
@ -85,13 +89,17 @@ namespace SlnMesnac.WPF.ViewModel.Generate
}
#endregion
#region 事件定义
public RelayCommand<string> QuerySearchCommand { get; set; }
public RelayCommand<string> CreateCodeCommand { get; set; }
#endregion
/// <summary>
/// 查询事件
/// </summary>
/// <param name="search"></param>
[RelayCommand]
private void QuerySearch(string search)
private void Query(string search)
{
var configId = _selectedOption;
@ -101,18 +109,17 @@ namespace SlnMesnac.WPF.ViewModel.Generate
var scope = db.AsTenant().GetConnectionScope(configId);
List<DbTableInfo> tables = scope.DbMaintenance.GetTableInfoList(false);
if(tables != null)
if (tables != null)
{
TablesDataGrid = new ObservableCollection<DbTableInfo>();
tables.ForEach(t => { TablesDataGrid.Add(t); });
}
}
}
[RelayCommand]
private void CreateCode(string tableName)
{
var info = tableName;
@ -137,7 +144,8 @@ namespace SlnMesnac.WPF.ViewModel.Generate
}
}
}
}catch(Exception ex)
}
catch (Exception ex)
{
MessageBox.Show($"{tableName}代码生成失败:{ex.Message}");
}

@ -0,0 +1,52 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Extensions.DependencyInjection;
using SlnMesnac.Config;
using SlnMesnac.WPF.Attribute;
using System;
using System.Windows;
namespace SlnMesnac.WPF.ViewModel.Login
{
[RegisterAsSingleton]
public partial class LoginViewModel: ObservableObject
{
private readonly AppConfig _appConfig;
[ObservableProperty]
public string systemTitle = string.Empty;
[ObservableProperty]
public string userName = string.Empty;
public LoginViewModel(AppConfig appConfig)
{
_appConfig = appConfig;
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<MainWindow>();
App.Current.MainWindow = mainWindow;
mainWindow.Show();
});
}
}
catch (Exception ex)
{
MessageBox.Show($"登录失败:{ex.Message}");
}
return res;
}
}
}

@ -3,71 +3,62 @@ using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.DependencyInjection;
using SlnMesnac.Serilog;
using SlnMesnac.WPF.Attribute;
using SlnMesnac.WPF.Page.Generate;
using SlnMesnac.WPF.ViewModel.Base;
using System;
using System.Windows;
namespace SlnMesnac.WPF.ViewModel
{
public partial class MainWindowViewModel: ObservableObject
[RegisterAsSingletonAttribute]
public partial class MainWindowViewModel : BaseViewModel
{
public readonly SerilogHelper _logger;
//代码生成
private readonly GenerateControl generateControl = new GenerateControl();
private readonly GenerateControl _generateControl;
#region 参数定义
/// <summary>
/// PLC设备状态
/// </summary>
private int _PlcStatus = 0;
public int PlcStatus
{
get => _PlcStatus;
set => SetProperty(ref _PlcStatus, value);
}
[ObservableProperty]
private int plcStatus = 0;
/// <summary>
/// 箱壳扫码器状态
/// 登录人员
/// </summary>
private int _ShellScannerStatus = 0;
public int ShellScannerStatus
{
get => _ShellScannerStatus;
set => SetProperty(ref _ShellScannerStatus, value);
}
[ObservableProperty]
private string otherInfo;
/// <summary>
/// 内胆扫码器状态
/// 系统标题
/// </summary>
private int _BoldScannerStatus = 0;
public int BoldScannerStatus
{
get => _BoldScannerStatus;
set => SetProperty(ref _BoldScannerStatus, value);
}
[ObservableProperty]
private string systemTitle = string.Empty;
public System.Windows.Controls.UserControl _content;
[ObservableProperty]
public System.Windows.Controls.UserControl userContent = new System.Windows.Controls.UserControl();
public System.Windows.Controls.UserControl UserContent
{
get => _content;
set => SetProperty(ref _content, value);
}
#endregion
/// <summary>
/// 箱壳扫码器状态
/// </summary>
[ObservableProperty]
private int _shellScannerStatus = 0;
#region 事件定义
/// <summary>
/// 打开系统键盘
/// 内胆扫码器状态
/// </summary>
public RelayCommand OpenSystemKeyboardCommand { get; set; }
[ObservableProperty]
private int _boldScannerStatus = 0;
#endregion
public MainWindowViewModel()
{
_logger = App.ServiceProvider.GetService<SerilogHelper>();
public MainWindowViewModel(SerilogHelper logger,GenerateControl generateControl)
{
_logger = logger;
_generateControl = generateControl;
}
@ -89,7 +80,7 @@ namespace SlnMesnac.WPF.ViewModel
Application.Current.Shutdown();
break;
case "Generate":
UserContent = generateControl;
UserContent = _generateControl;
break;
// 还原 或者 最大化当前窗口
case "Normal":

@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33502.453
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac", "SlnMesnac\SlnMesnac.csproj", "{19445879-B3F3-4C76-A670-EFAE9E25BAB4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Common", "SlnMesnac.Common\SlnMesnac.Common.csproj", "{BB71F26A-7007-423E-83E9-7A3BAC25E934}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Config", "SlnMesnac.Config\SlnMesnac.Config.csproj", "{6EF7F087-7149-4689-885C-E0D05E1A9AA8}"
@ -29,13 +27,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Mqtt", "SlnMesnac
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Rfid", "SlnMesnac.Rfid\SlnMesnac.Rfid.csproj", "{40D23A4B-8372-4145-936C-08AE63C6D1F9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Ioc", "SlnMesnac.Ioc\SlnMesnac.Ioc.csproj", "{30A3F86B-774E-4153-9A00-FD3173C710EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Generate", "SlnMesnac.Generate\SlnMesnac.Generate.csproj", "{00FC9358-2381-4C1B-BD45-6D31DD1DB7D3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Extensions", "SlnMesnac.Extensions\SlnMesnac.Extensions.csproj", "{6D929802-24AA-42A7-92C5-303C3D59A990}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Extensions", "SlnMesnac.Extensions\SlnMesnac.Extensions.csproj", "{6D929802-24AA-42A7-92C5-303C3D59A990}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Redis", "SlnMesnac.Redis\SlnMesnac.Redis.csproj", "{0E041719-E755-43CD-8A0E-DF62E0B2E463}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Redis", "SlnMesnac.Redis\SlnMesnac.Redis.csproj", "{0E041719-E755-43CD-8A0E-DF62E0B2E463}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -43,10 +39,6 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{19445879-B3F3-4C76-A670-EFAE9E25BAB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19445879-B3F3-4C76-A670-EFAE9E25BAB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19445879-B3F3-4C76-A670-EFAE9E25BAB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19445879-B3F3-4C76-A670-EFAE9E25BAB4}.Release|Any CPU.Build.0 = Release|Any CPU
{BB71F26A-7007-423E-83E9-7A3BAC25E934}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BB71F26A-7007-423E-83E9-7A3BAC25E934}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BB71F26A-7007-423E-83E9-7A3BAC25E934}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -95,10 +87,6 @@ Global
{40D23A4B-8372-4145-936C-08AE63C6D1F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40D23A4B-8372-4145-936C-08AE63C6D1F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40D23A4B-8372-4145-936C-08AE63C6D1F9}.Release|Any CPU.Build.0 = Release|Any CPU
{30A3F86B-774E-4153-9A00-FD3173C710EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30A3F86B-774E-4153-9A00-FD3173C710EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30A3F86B-774E-4153-9A00-FD3173C710EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30A3F86B-774E-4153-9A00-FD3173C710EB}.Release|Any CPU.Build.0 = Release|Any CPU
{00FC9358-2381-4C1B-BD45-6D31DD1DB7D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{00FC9358-2381-4C1B-BD45-6D31DD1DB7D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00FC9358-2381-4C1B-BD45-6D31DD1DB7D3}.Release|Any CPU.ActiveCfg = Release|Any CPU

@ -1,91 +0,0 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service;
using SlnMesnac.Serilog;
namespace SlnMesnac.Controllers
{
/// <summary>
/// 物料信息
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class BaseMaterialInfoController
{
public readonly SerilogHelper _logger;
private IBaseMaterialService _service;
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
/// <param name="service"></param>
public BaseMaterialInfoController(SerilogHelper logger, IBaseMaterialService service)
{
_logger = logger;
_service = service;
}
/// <summary>
/// 获取物料信息
/// </summary>
/// <returns></returns>
[HttpGet]
public IEnumerable<BaseMaterialInfo> Get()
{
IEnumerable<BaseMaterialInfo> materialInfos = null;
try
{
materialInfos = _service.GetMaterialInfos();
}
catch (Exception ex)
{
_logger.Error($"获取物料信息接口调用异常:{ex.Message}");
}
return materialInfos;
}
/// <summary>
/// 根据物料编号获取物料信息
/// </summary>
/// <param name="materialCode">物料编号</param>
/// <returns></returns>
[HttpGet("Get/{materialCode}")]
public BaseMaterialInfo GetMaterialInfoByMaterialCode(string materialCode)
{
BaseMaterialInfo materialInfo = null;
try
{
materialInfo = _service.GetMaterialInfoByMaterialCode(materialCode);
}
catch (Exception ex)
{
_logger.Error($"根据物料编号获取物料信息接口调用异常:{ex.Message}");
}
return materialInfo;
}
/// <summary>
/// 通过物料类别获取物料信息
/// </summary>
/// <param name="majorTypeId">物料大类</param>
/// <param name="minorTypeId">物料细类</param>
/// <returns></returns>
[HttpGet("Get/{majorTypeId}/{minorTypeId}")]
public IEnumerable<BaseMaterialInfo> GetMaterialInfosByMaterialType(int majorTypeId, string minorTypeId)
{
IEnumerable<BaseMaterialInfo> materialInfos = null;
try
{
materialInfos = _service.GetMaterialInfosByMaterialType(majorTypeId, minorTypeId);
}
catch (Exception ex)
{
_logger.Error($"通过物料类别获取物料信息接口调用异常:{ex.Message}");
}
return materialInfos;
}
}
}

@ -1,82 +0,0 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SlnMesnac.Model.domain;
using SlnMesnac.Plc;
using SlnMesnac.Repository.service;
using SlnMesnac.Serilog;
namespace SlnMesnac.Controllers
{
/// <summary>
/// 人员基础信息
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class BaseUserController : ControllerBase
{
public readonly SerilogHelper _logger;
private readonly IBaseUserService _service;
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
/// <param name="service"></param>
public BaseUserController(SerilogHelper logger, IBaseUserService service)
{
_logger = logger;
_service = service;
}
/// <summary>
/// 获取人员基础信息
/// </summary>
/// <returns></returns>
[HttpGet]
public IEnumerable<BaseUser> Get()
{
IEnumerable<BaseUser> users = null;
try
{
users = _service.GetUsers();
}
catch (Exception ex)
{
_logger.Error($"获取用户信息接口调用异常:{ex.Message}");
}
return users;
}
/// <summary>
/// 通过用户名称获取指定用户信息
/// </summary>
/// <param name="userName">用户名称</param>
/// <returns></returns>
[HttpGet("Gets/{userName}")]
public IEnumerable<BaseUser> GetUserByUserName(string userName)
{
IEnumerable<BaseUser> users = null;
try
{
users = _service.GetUsers();
}
catch (Exception ex)
{
_logger.Error($"获取用户信息接口调用异常:{ex.Message}");
}
return users;
}
/// <summary>
/// 添加用户信息
/// </summary>
/// <param name="users">用户列表</param>
/// <returns></returns>
[HttpPut]
public bool InsertUserInfo(List<BaseUser> users)
{
return _service.InsertUsers(users);
}
}
}

@ -1,61 +0,0 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Quartz;
namespace SlnMesnac.Controllers
{
/// <summary>
/// 任务调度
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class JobController
{
private readonly IScheduler _scheduler;
/// <summary>
///
/// </summary>
/// <param name="scheduler"></param>
public JobController(IScheduler scheduler)
{
_scheduler = scheduler;
}
/// <summary>
/// 启动任务
/// </summary>
/// <param name="jobName">任务名称</param>
/// <param name="groupName">任务分组</param>
/// <returns></returns>
[HttpPost("start")]
public async Task<string> StartJob(string jobName, string groupName)
{
// 检查调度器是否已经启动
if (!_scheduler.IsStarted)
{
await _scheduler.Start();
}
var myJobKey = new JobKey(jobName, groupName);
await _scheduler.ResumeJob(myJobKey);
return "Job started successfully.";
}
/// <summary>
/// 停止任务
/// </summary>
/// <param name="jobName">任务名称</param>
/// <param name="groupName">任务分组</param>
/// <returns></returns>
[HttpPost("stop")]
public async Task<string> StopJob(string jobName, string groupName)
{
var myJobKey = new JobKey(jobName, groupName);
await _scheduler.PauseJob(myJobKey);
return "Job stopped successfully.";
}
}
}

@ -1,32 +0,0 @@
using Serilog;
namespace SlnMesnac
{
/// <summary>
/// Æô¶¯Àà
/// </summary>
public class Program
{
/// <summary>
/// Main·½·¨
/// </summary>
/// <param name="args"></param>
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
/// <summary>
/// CreateHostBuilder
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

@ -1,30 +0,0 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:32147",
"sslPort": 44302
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
//"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"SlnMesnac": {
"commandName": "Project",
"launchBrowser": true,
//"launchUrl": "swagger",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

@ -1,24 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SlnMesnac.Config\SlnMesnac.Config.csproj" />
<ProjectReference Include="..\SlnMesnac.Extensions\SlnMesnac.Extensions.csproj" />
<ProjectReference Include="..\SlnMesnac.Model\SlnMesnac.Model.csproj" />
<ProjectReference Include="..\SlnMesnac.Plc\SlnMesnac.Plc.csproj" />
<ProjectReference Include="..\SlnMesnac.Quartz\SlnMesnac.Quartz.csproj" />
<ProjectReference Include="..\SlnMesnac.Repository\SlnMesnac.Repository.csproj" />
<ProjectReference Include="..\SlnMesnac.Serilog\SlnMesnac.Serilog.csproj" />
</ItemGroup>
</Project>

@ -1,121 +0,0 @@
using Microsoft.OpenApi.Models;
using SlnMesnac.Config;
using SlnMesnac.Quartz;
using SlnMesnac.Serilog;
using SlnMesnac.Extensions;
using System.Runtime.Serialization;
namespace SlnMesnac
{
/// <summary>
///
/// </summary>
public class Startup
{
/// <summary>
///
/// </summary>
/// <param name="configuration"></param>
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
/// <summary>
///
/// </summary>
public IConfiguration Configuration { get; }
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services"></param>
[Obsolete]
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//配置Swagger
services.AddSwaggerGen(swagger =>
{
//自定义接口信息
swagger.SwaggerDoc("V1.0", new OpenApiInfo
{
Title = "MES Web Api",
Version = "V1.0",
Description = $"API版本V1.0",
Contact = new OpenApiContact
{
Name = "MES Web Api",
Email = "wenjy@mesnac.com"
}
});
//自定义实体别名
swagger.CustomSchemaIds(type => type.GetCustomAttributes(typeof(DataContractAttribute), true)
.Cast<DataContractAttribute>()
.FirstOrDefault()?.Name);
//配置Action名称
var path = Path.Combine(AppContext.BaseDirectory, "SlnMesnac.xml");
swagger.IncludeXmlComments(path, true); // true : 显示控制器层注释
swagger.OrderActionsBy(o => o.RelativePath); // 对action的名称进行排序如果有多个就可以看见效果了。
});
//注册配置类
services.AddSingleton<AppConfig>(provider =>
{
var configuration = provider.GetService<IConfiguration>();
return configuration.GetSection("AppConfig").Get<AppConfig>();
});
//注册SqlSugar
services.AddSqlSugarSetup();
//注册服务
//services.AddServices();
//注册任务调度
services.AddQuartzSetUp();
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//启用Swagger中间件
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/V1.0/swagger.json", "MES Web Api V1.0");
c.RoutePrefix = "";
});
//启用Serilog中间件
app.UseSerilogExtensions();
//app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

@ -1,15 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"AppConfig": {
"logPath": "E:\\桌面\\日常代码\\SlnMesnac\\SlnMesnac\\bin\\Debug\\net6.0",
"mesConnStr": "server=.;uid=sa;pwd=123456;database=JiangYinMENS",
"mcsConnStr": "Data Source=175.27.215.92/helowin;User ID=aucma_scada;Password=aucma"
}
}
Loading…
Cancel
Save