From 550d0b7308145596fe141602976e087f44715da2 Mon Sep 17 00:00:00 2001 From: anerx <512464164@qq.com> Date: Mon, 17 Mar 2025 22:17:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Plc/HyosungPlcService.cs | 1 - Seyounth.Hyosung.Core/Plc/McPlc.cs | 15 +- Seyounth.Hyosung.Data/Models/Pallet.cs | 11 +- Seyounth.Hyosung.Data/Models/PalletType.cs | 10 +- Seyounth.Hyosung.Data/ServiceExtensions.cs | 23 +- .../Services/IPalletService.cs | 14 + .../Services/PalletService.cs | 44 +++ Seyounth.Hyosung.Runtime/HyosungRuntime.cs | 3 +- Seyounth.Hyosung.Runtime/HyosungWorker.cs | 2 +- Seyounth.Hyosung/App.xaml.cs | 3 + Seyounth.Hyosung/Helpers/EnumDisplayHelper.cs | 12 + .../ViewConverter/EnumDescriptionConverter.cs | 24 ++ .../ViewConverter/PalletToStringConverter.cs | 40 ++ .../ViewModels/PalletManagerViewModel.cs | 55 +++ .../ViewModels/VarietyViewModel.cs | 14 +- .../Views/Controls/AddVarietyControl.xaml | 62 --- .../Views/Controls/AddVarietyControl.xaml.cs | 22 -- Seyounth.Hyosung/Views/Pages/VarietyPage.xaml | 357 +++++++++++------- .../Views/Pages/VarietyPage.xaml.cs | 24 +- .../Views/Windows/PalletManagerWindow.xaml | 106 ++++++ .../Views/Windows/PalletManagerWindow.xaml.cs | 39 ++ 21 files changed, 625 insertions(+), 256 deletions(-) create mode 100644 Seyounth.Hyosung.Data/Services/IPalletService.cs create mode 100644 Seyounth.Hyosung.Data/Services/PalletService.cs create mode 100644 Seyounth.Hyosung/Helpers/EnumDisplayHelper.cs create mode 100644 Seyounth.Hyosung/ViewConverter/EnumDescriptionConverter.cs create mode 100644 Seyounth.Hyosung/ViewConverter/PalletToStringConverter.cs create mode 100644 Seyounth.Hyosung/ViewModels/PalletManagerViewModel.cs delete mode 100644 Seyounth.Hyosung/Views/Controls/AddVarietyControl.xaml delete mode 100644 Seyounth.Hyosung/Views/Controls/AddVarietyControl.xaml.cs create mode 100644 Seyounth.Hyosung/Views/Windows/PalletManagerWindow.xaml create mode 100644 Seyounth.Hyosung/Views/Windows/PalletManagerWindow.xaml.cs diff --git a/Seyounth.Hyosung.Core/Plc/HyosungPlcService.cs b/Seyounth.Hyosung.Core/Plc/HyosungPlcService.cs index c4c9d2e..11d0064 100644 --- a/Seyounth.Hyosung.Core/Plc/HyosungPlcService.cs +++ b/Seyounth.Hyosung.Core/Plc/HyosungPlcService.cs @@ -15,7 +15,6 @@ public class HyosungPlcService(ILogger logger) : IHyosungPlcS public async Task StartAsync(CancellationToken token) { - token = token; List> ls = [ _reader.ConnectAsync(), diff --git a/Seyounth.Hyosung.Core/Plc/McPlc.cs b/Seyounth.Hyosung.Core/Plc/McPlc.cs index 96ddb77..b86f602 100644 --- a/Seyounth.Hyosung.Core/Plc/McPlc.cs +++ b/Seyounth.Hyosung.Core/Plc/McPlc.cs @@ -12,7 +12,20 @@ public class McPlc(string host, int port, Mitsubishi.McFrame type) _mc.HostName = host; _mc.PortNumber = port; _mc.CommandFrame = type; - return await _mc.Open(); + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1)); + var openTask = Task.Run(()=>_mc.Open(), cts.Token) ; + + var completedTask = await Task.WhenAny( + openTask, + Task.Delay(Timeout.Infinite, cts.Token) + ); + + if (completedTask != openTask) + { + throw new TimeoutException("PLC 连接超时 (1 秒未响应)"); + } + + return await openTask; } public Task CloseAsync() diff --git a/Seyounth.Hyosung.Data/Models/Pallet.cs b/Seyounth.Hyosung.Data/Models/Pallet.cs index 7a250bc..e061fdc 100644 --- a/Seyounth.Hyosung.Data/Models/Pallet.cs +++ b/Seyounth.Hyosung.Data/Models/Pallet.cs @@ -1,8 +1,13 @@ +using Seyounth.Core.Extensions; using Seyounth.Hyosung.Data.Entities; namespace Seyounth.Hyosung.Data.Models; -public class Pallet : PalletEntity { +public class Pallet : PalletEntity +{ + public string Name => + $"{Type.GetDescription()}({Width}*{Height}*{Length})({HoleCount}|{(IsBigHole != null && IsBigHole.Value ? "大" : "小")})"; + public static Pallet FromEntity(PalletEntity p) { return new Pallet() @@ -16,6 +21,4 @@ public class Pallet : PalletEntity { Type = p.Type }; } - - -} +} \ No newline at end of file diff --git a/Seyounth.Hyosung.Data/Models/PalletType.cs b/Seyounth.Hyosung.Data/Models/PalletType.cs index b8a80a8..e257c11 100644 --- a/Seyounth.Hyosung.Data/Models/PalletType.cs +++ b/Seyounth.Hyosung.Data/Models/PalletType.cs @@ -1,3 +1,5 @@ +using System.ComponentModel; + namespace Seyounth.Hyosung.Data.Models; public enum PalletType @@ -5,20 +7,20 @@ public enum PalletType /// /// 纸板托盘 /// - Paper=0, + [Description("纸板")] Paper = 0, /// /// 胶合板托盘 /// - Plywood = 1, + [Description("胶合板")] Plywood = 1, /// /// 木板托盘 /// - Wood = 2, + [Description("木托")] Wood = 2, /// /// 蜂窝板 /// - Honey=3 + [Description("蜂窝板")] Honey = 3 } \ No newline at end of file diff --git a/Seyounth.Hyosung.Data/ServiceExtensions.cs b/Seyounth.Hyosung.Data/ServiceExtensions.cs index 413c45f..218b491 100644 --- a/Seyounth.Hyosung.Data/ServiceExtensions.cs +++ b/Seyounth.Hyosung.Data/ServiceExtensions.cs @@ -17,22 +17,22 @@ public static class ServiceExtensions services.AddSingleton(s => { //#if RELEASE + // SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig() + // { + // DbType = DbType.SqlServer, + // ConnectionString = connectionString, + // IsAutoCloseConnection = true, + // } + // ); +//#elif DEBUG SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig() { - DbType = DbType.SqlServer, - ConnectionString = connectionString, + DbType = DbType.Sqlite, + ConnectionString = "Data Source=hyosung.db", IsAutoCloseConnection = true, + InitKeyType = InitKeyType.Attribute } ); -//#elif DEBUG - //SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig() - // { - // DbType = DbType.Sqlite, - // ConnectionString = "Data Source=hyosung.db", - // IsAutoCloseConnection = true, - // InitKeyType = InitKeyType.Attribute - // } - //); //#endif return sqlSugar; }); @@ -43,6 +43,7 @@ public static class ServiceExtensions services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); return services; } diff --git a/Seyounth.Hyosung.Data/Services/IPalletService.cs b/Seyounth.Hyosung.Data/Services/IPalletService.cs new file mode 100644 index 0000000..7d35918 --- /dev/null +++ b/Seyounth.Hyosung.Data/Services/IPalletService.cs @@ -0,0 +1,14 @@ +using Seyounth.Hyosung.Data.Models; + +namespace Seyounth.Hyosung.Data.Services; + +public interface IPalletService +{ + List GetPallets(); + + Task AddPalletAsync(Pallet pallet); + + Task DeletePalletAsync(Pallet pallet); + + Task UpdatePalletAsync(Pallet pallet); +} \ No newline at end of file diff --git a/Seyounth.Hyosung.Data/Services/PalletService.cs b/Seyounth.Hyosung.Data/Services/PalletService.cs new file mode 100644 index 0000000..4247f88 --- /dev/null +++ b/Seyounth.Hyosung.Data/Services/PalletService.cs @@ -0,0 +1,44 @@ +using Microsoft.Extensions.DependencyInjection; +using Seyounth.Hyosung.Data.Entities; +using Seyounth.Hyosung.Data.Models; +using Seyounth.Hyosung.Data.Repositories; + +namespace Seyounth.Hyosung.Data.Services; + +public class PalletService : IPalletService +{ + private readonly List _pallets; + public readonly IRepository _palletRepository; + + public PalletService(IServiceProvider serviceProvider) + { + _palletRepository = serviceProvider.CreateScope().ServiceProvider + .GetRequiredService>(); + _pallets = _palletRepository.GetList().Select(Pallet.FromEntity).ToList(); + } + + public List GetPallets() + { + return _pallets; + } + + public async Task AddPalletAsync(Pallet pallet) + { + var id = await _palletRepository.InsertReturnIdentityAsync(pallet); + pallet.Id = id; + _pallets.Add(pallet); + return id; + } + + public async Task DeletePalletAsync(Pallet pallet) + { + await _palletRepository.DeleteAsync(pallet); + _pallets.Remove(pallet); + } + + public async Task UpdatePalletAsync(Pallet pallet) + { + await _palletRepository.UpdateAsync(pallet); + _pallets[_pallets.IndexOf(pallet)] = pallet; + } +} \ No newline at end of file diff --git a/Seyounth.Hyosung.Runtime/HyosungRuntime.cs b/Seyounth.Hyosung.Runtime/HyosungRuntime.cs index 755a0c9..c26a477 100644 --- a/Seyounth.Hyosung.Runtime/HyosungRuntime.cs +++ b/Seyounth.Hyosung.Runtime/HyosungRuntime.cs @@ -32,6 +32,7 @@ public class HyosungRuntime( { //启动扫码服务 await hyosungScannerService.StartAsync(token); + await printer.StartAsync(token); //最后启动PLC服务 hyosungPlcService.OnPlcRequestScanProduct += OnPlcRequestScanProduct; hyosungPlcService.OnPlcRequestScanFixture += OnPlcRequestScanFixture; @@ -46,7 +47,7 @@ public class HyosungRuntime( public async Task StopAsync(CancellationToken token) { //先停止扫码服务 - // await hyosungScannerService.StopAsync(token); + await hyosungScannerService.StopAsync(token); await printer.StopAsync(token); //先停止PLC服务 //解绑相关事件 diff --git a/Seyounth.Hyosung.Runtime/HyosungWorker.cs b/Seyounth.Hyosung.Runtime/HyosungWorker.cs index c315f6c..a85c6fa 100644 --- a/Seyounth.Hyosung.Runtime/HyosungWorker.cs +++ b/Seyounth.Hyosung.Runtime/HyosungWorker.cs @@ -12,7 +12,7 @@ public class HyosungWorker(IHyosungRuntime runtime) : BackgroundService public override async Task StartAsync(CancellationToken cancellationToken) { - await runtime.StartAsync(cancellationToken); + runtime.StartAsync(cancellationToken); await base.StartAsync(cancellationToken); } diff --git a/Seyounth.Hyosung/App.xaml.cs b/Seyounth.Hyosung/App.xaml.cs index 41bef76..e947825 100644 --- a/Seyounth.Hyosung/App.xaml.cs +++ b/Seyounth.Hyosung/App.xaml.cs @@ -16,6 +16,7 @@ using Seyounth.Hyosung.Services; using Seyounth.Hyosung.ViewModels; using Seyounth.Hyosung.Views; using Seyounth.Hyosung.Views.Pages; +using Seyounth.Hyosung.Views.Windows; namespace Seyounth.Hyosung; @@ -40,6 +41,8 @@ public partial class App : Application builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); + builder.Services.AddTransient(); + builder.Services.AddSingleton(); builder.Services.AddHyosung(builder.Configuration); _host = builder.Build(); diff --git a/Seyounth.Hyosung/Helpers/EnumDisplayHelper.cs b/Seyounth.Hyosung/Helpers/EnumDisplayHelper.cs new file mode 100644 index 0000000..0bb2fad --- /dev/null +++ b/Seyounth.Hyosung/Helpers/EnumDisplayHelper.cs @@ -0,0 +1,12 @@ +using System.ComponentModel; +using System.Reflection; + +public class EnumDisplayHelper +{ + public static string DisplayName(object item) + { + if (item == null) return ""; + var field = item.GetType().GetField(item.ToString()); + return field?.GetCustomAttribute()?.Description ?? item.ToString(); + } +} \ No newline at end of file diff --git a/Seyounth.Hyosung/ViewConverter/EnumDescriptionConverter.cs b/Seyounth.Hyosung/ViewConverter/EnumDescriptionConverter.cs new file mode 100644 index 0000000..36b21da --- /dev/null +++ b/Seyounth.Hyosung/ViewConverter/EnumDescriptionConverter.cs @@ -0,0 +1,24 @@ +using System.ComponentModel; +using System.Globalization; +using System.Windows.Data; + +namespace Seyounth.Hyosung.ViewConverter; + +public class EnumDescriptionConverter : IValueConverter +{ + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value == null) return null; + + var field = value.GetType().GetField(value.ToString() ?? string.Empty); + if (field == null) return null; + + var attributes = field.GetCustomAttributes(typeof(DescriptionAttribute), false); + return attributes.Length == 0 ? value.ToString() : ((DescriptionAttribute)attributes[0]).Description; + } + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Seyounth.Hyosung/ViewConverter/PalletToStringConverter.cs b/Seyounth.Hyosung/ViewConverter/PalletToStringConverter.cs new file mode 100644 index 0000000..b5549fa --- /dev/null +++ b/Seyounth.Hyosung/ViewConverter/PalletToStringConverter.cs @@ -0,0 +1,40 @@ +using System.Globalization; +using System.Net.Mime; +using System.Windows; +using System.Windows.Data; +using Seyounth.Hyosung.Data.Models; +using Seyounth.Hyosung.ViewModels; + +namespace Seyounth.Hyosung.ViewConverter; + +public class PalletToStringConverter : IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Pallet pallet) + { + // 这里根据 Pallet 类的属性选择合适的字符串表示 + return pallet.Name; + } + + return null; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is string palletName) + { + // 这里需要根据实际情况实现反向转换逻辑 + // 例如,从名称查找对应的 Pallet 对象 + // 假设在 ViewModel 中有一个 Pallets 集合 + // 修正:获取正确的 ViewModel 引用 + var viewModel = Application.Current.MainWindow.DataContext as VarietyViewModel; + if (viewModel != null) + { + return viewModel.Pallets.FirstOrDefault(p => p.Name == palletName); + } + } + + return null; + } +} \ No newline at end of file diff --git a/Seyounth.Hyosung/ViewModels/PalletManagerViewModel.cs b/Seyounth.Hyosung/ViewModels/PalletManagerViewModel.cs new file mode 100644 index 0000000..aa3605d --- /dev/null +++ b/Seyounth.Hyosung/ViewModels/PalletManagerViewModel.cs @@ -0,0 +1,55 @@ +using System.Collections.ObjectModel; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.Messaging; +using Seyounth.Hyosung.Data.Models; +using Seyounth.Hyosung.Data.Services; + +namespace Seyounth.Hyosung.ViewModels; + +public partial class PalletManagerViewModel : ObservableObject +{ + [ObservableProperty] private ObservableCollection _pallets; + + private readonly IPalletService _palletService; + + public PalletManagerViewModel(IPalletService palletService) + { + Pallets = new ObservableCollection(palletService.GetPallets()); + _palletService = palletService; + } + + public class SavePalletCompletedMessage + { + } + + [RelayCommand] + private void OnDeletePallet(object obj) + { + if (obj is Pallet pallet) + { + Pallets.Remove(pallet); + _palletService.DeletePalletAsync(pallet); + } + else + { + Console.Write("Object is not a Pallet"); + } + } + + [RelayCommand] + private void OnSavePallet(object obj) + { + if (obj is Pallet pallet) + { + if (pallet.Id == 0) + { + _palletService.AddPalletAsync(pallet); + } + else + _palletService.UpdatePalletAsync(pallet); + } + + WeakReferenceMessenger.Default.Send(new SavePalletCompletedMessage()); + } +} \ No newline at end of file diff --git a/Seyounth.Hyosung/ViewModels/VarietyViewModel.cs b/Seyounth.Hyosung/ViewModels/VarietyViewModel.cs index 94ba22d..aac7dc3 100644 --- a/Seyounth.Hyosung/ViewModels/VarietyViewModel.cs +++ b/Seyounth.Hyosung/ViewModels/VarietyViewModel.cs @@ -1,3 +1,4 @@ +using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel; using Seyounth.Core.Extensions; using Seyounth.Hyosung.Data.Entities; @@ -7,12 +8,17 @@ namespace Seyounth.Hyosung.ViewModels; public partial class VarietyViewModel : ObservableObject { - [ObservableProperty] private List _varieties; + [ObservableProperty] private ObservableCollection _varieties; + + [ObservableProperty] private ObservableCollection _pallets; public IEnumerable NeedTypeItems { get; } - public VarietyViewModel() + + public VarietyViewModel(PalletManagerViewModel palletManagerViewModel) { - _varieties = new List(); + Pallets = new ObservableCollection(palletManagerViewModel.Pallets); + + _varieties = new ObservableCollection(); var needTypes = EnumHelper.GetValues(); NeedTypeItems = needTypes.Select(nt => new NeedTypeEnumItem { @@ -20,6 +26,4 @@ public partial class VarietyViewModel : ObservableObject Description = nt.GetDescription() }); } - - } \ No newline at end of file diff --git a/Seyounth.Hyosung/Views/Controls/AddVarietyControl.xaml b/Seyounth.Hyosung/Views/Controls/AddVarietyControl.xaml deleted file mode 100644 index c6b2c33..0000000 --- a/Seyounth.Hyosung/Views/Controls/AddVarietyControl.xaml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Seyounth.Hyosung/Views/Controls/AddVarietyControl.xaml.cs b/Seyounth.Hyosung/Views/Controls/AddVarietyControl.xaml.cs deleted file mode 100644 index 885dc10..0000000 --- a/Seyounth.Hyosung/Views/Controls/AddVarietyControl.xaml.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace Seyounth.Hyosung.Views.Controls; - -public partial class AddVarietyControl : UserControl -{ - public AddVarietyControl() - { - InitializeComponent(); - } - - private void CancelButton_Click(object sender, RoutedEventArgs e) - { - throw new NotImplementedException(); - } - - private void OkButton_Click(object sender, RoutedEventArgs e) - { - throw new NotImplementedException(); - } -} \ No newline at end of file diff --git a/Seyounth.Hyosung/Views/Pages/VarietyPage.xaml b/Seyounth.Hyosung/Views/Pages/VarietyPage.xaml index 2e67ae7..a068f9c 100644 --- a/Seyounth.Hyosung/Views/Pages/VarietyPage.xaml +++ b/Seyounth.Hyosung/Views/Pages/VarietyPage.xaml @@ -5,138 +5,237 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Seyounth.Hyosung.Views.Pages" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:viewConverter="clr-namespace:Seyounth.Hyosung.ViewConverter" + xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase" + xmlns:models="clr-namespace:Seyounth.Hyosung.Data.Models;assembly=Seyounth.Hyosung.Data" + xmlns:system="clr-namespace:System;assembly=System.Runtime" mc:Ignorable="d" + x:Name="VarietyRoot" Width="Auto" Height="Auto" d:DataContext="{d:DesignInstance local:VarietyPage, IsDesignTimeCreatable=True}"> - - - - - - - - -