Compare commits

...

17 Commits

Author SHA1 Message Date
a4fc1b7c9c 增加功能:
1、增加可选是否上传至甲方数据库
2、增加AGV库位管理功能
2025-06-02 17:15:40 +08:00
zhangzhuo
88a65ffc61 BUG修改 2025-04-21 09:42:01 +08:00
anerx
41f5df88be 增加日志打印 2025-04-14 16:12:20 +08:00
anerx
6d221df494 更新BUG 2025-04-14 16:11:17 +08:00
anerx
2347c07d10 增加第三台打印机 2025-04-14 16:09:10 +08:00
zhangzhuo
1cbd295691 增加Code验证功能 2025-04-14 13:23:28 +08:00
zhangzhuo
c7e3c0fe81 增加共呢个 2025-04-14 13:17:51 +08:00
zhangzhuo
af40353527 增加入口2扫码枪 以及修改入库流程 2025-04-12 14:41:36 +08:00
anerx
e8194d006e 增加复制功能 2025-04-11 17:09:43 +08:00
anerx
2f0cc7d1ce 增加复制功能 2025-04-11 14:31:24 +08:00
zhangzhuo
83edcfa45e 修改BUG 2025-04-11 14:06:11 +08:00
zhangzhuo
5692f92c99 修改入库代码 2025-04-11 13:26:04 +08:00
anerx
6f7f0faf54 增加配置项 2025-04-10 16:29:19 +08:00
anerx
f014fc19da 使用Avalonia来绘制UI,看看是否可以解决性能问题 2025-04-10 16:20:00 +08:00
anerx
07e4c7a2d9 增加虚拟化以用来提高性能 2025-04-07 23:35:43 +08:00
zhangzhuo
3d81c7d4a1 修改BUG 2025-04-07 23:32:20 +08:00
anerx
fd0445a4d4 增加新版本的UI 2025-04-07 23:25:45 +08:00
98 changed files with 4062 additions and 294 deletions

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AvaloniaProject">
<option name="projectPerEditor">
<map>
<entry key="Seyounth.Hyosung.Ava/App.axaml" value="Seyounth.Hyosung.Ava/Seyounth.Hyosung.Ava.csproj" />
<entry key="Seyounth.Hyosung.Ava/Views/AgvBinManagerPage.axaml" value="Seyounth.Hyosung.Ava/Seyounth.Hyosung.Ava.csproj" />
<entry key="Seyounth.Hyosung.Ava/Views/HomePage.axaml" value="Seyounth.Hyosung.Ava/Seyounth.Hyosung.Ava.csproj" />
<entry key="Seyounth.Hyosung.Ava/Views/MainWindow.axaml" value="Seyounth.Hyosung.Ava/Seyounth.Hyosung.Ava.csproj" />
<entry key="Seyounth.Hyosung.Ava/Views/PalletManagerPage.axaml" value="Seyounth.Hyosung.Ava/Seyounth.Hyosung.Ava.csproj" />
<entry key="Seyounth.Hyosung.Ava/Views/VarietyManagerPage.axaml" value="Seyounth.Hyosung.Ava/Seyounth.Hyosung.Ava.csproj" />
</map>
</option>
</component>
</project>

View File

@ -8,5 +8,12 @@
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/Seyounth.Hyosung/bin/Debug/net8.0-windows/hyosung.test</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="hyosung.db" uuid="fc9f4212-d271-41ba-908e-c4274b657472">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:D:\RiderProjects\seyounth.hyosung.ty\Seyounth.Hyosung.Ava\bin\Debug\net8.0\hyosung.db</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@ -0,0 +1,17 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Seyounth.Hyosung.Ava.App"
xmlns:suki="clr-namespace:SukiUI;assembly=SukiUI"
xmlns:local="using:Seyounth.Hyosung.Ava"
RequestedThemeVariant="Light">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
<Application.DataTemplates>
<local:ViewLocator />
</Application.DataTemplates>
<Application.Styles>
<suki:SukiTheme Locale="zh-CN" ThemeColor="Blue" />
</Application.Styles>
</Application>

View File

@ -0,0 +1,66 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Styling;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using Seyounth.Hyosung.Ava.ViewModels;
using Seyounth.Hyosung.Ava.Views;
using Seyounth.Hyosung.Core;
using Seyounth.Hyosung.Core.Printer;
using Seyounth.Hyosung.Data;
using Seyounth.Hyosung.Runtime;
using SukiUI;
using SukiUI.Toasts;
namespace Seyounth.Hyosung.Ava;
public partial class App : Application
{
public static IHost _Host { get; private set; }
public override void Initialize()
{
var builder = Host
.CreateApplicationBuilder();
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddNLog("nlog.config");
builder.Configuration.AddJsonFile("PrintTemp.json", true, true);
builder.Configuration.AddJsonFile("appsettings.json", true, true);
builder.Services.Configure<PrintTemp>(builder.Configuration.GetSection("Print"));
builder.Services.AddSingleton<MainWindowViewModel>();
builder.Services.AddSingleton<MainWindow>();
builder.Services.AddSingleton<HomePage>();
builder.Services.AddSingleton<HomeViewModel>();
builder.Services.AddSingleton<VarietyManagerPage>();
builder.Services.AddSingleton<VarietyManagerViewModel>();
builder.Services.AddSingleton<PalletManagerPage>();
builder.Services.AddSingleton<PalletManagerViewModel>();
builder.Services.AddSingleton<ISukiToastManager, SukiToastManager>();
builder.Services.AddSingleton<AgvBinManagerPage>();
builder.Services.AddSingleton<AgvBinManagerViewModel>();
builder.Services.AddHyosung(builder.Configuration);
_Host = builder.Build();
_Host.Services.UseHyosung();
_Host.RunAsync();
AvaloniaXamlLoader.Load(this);
SukiTheme.GetInstance().ChangeBaseTheme(ThemeVariant.Dark);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = _Host.Services.GetRequiredService<MainWindow>();
}
base.OnFrameworkInitializationCompleted();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

View File

@ -0,0 +1,23 @@
using System;
using System.Windows.Markup;
using Avalonia.Markup.Xaml;
namespace Seyounth.Hyosung.UI.Helpers;
public class EnumBindingSourceExtension : MarkupExtension
{
public Type EnumType { get; private set; }
public EnumBindingSourceExtension(Type enumType)
{
if (enumType is null || !enumType.IsEnum)
throw new Exception("EnumType must be specified and be an Enum");
EnumType = enumType;
}
public override object? ProvideValue(IServiceProvider serviceProvider)
{
return Enum.GetValues(EnumType);
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using Avalonia.Data.Converters;
namespace Seyounth.Hyosung.UI.Helpers;
public class EnumDescriptionConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value == null) return string.Empty;
var field = value.GetType().GetField(value.ToString());
var attr = field?.GetCustomAttribute<DescriptionAttribute>();
return attr?.Description ?? value.ToString();
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@ -0,0 +1,9 @@
using System;
using Seyounth.Hyosung.Data.Models;
namespace Seyounth.Hyosung.UI.Helpers;
public static class PalletTypeExtensions
{
public static Array Values => Enum.GetValues(typeof(PalletType));
}

View File

@ -0,0 +1,9 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Material.Icons;
namespace Seyounth.Hyosung.Ava;
public partial class PageBase(string displayName, MaterialIconKind icon, int index = 0) : ObservableValidator
{
}

View File

@ -0,0 +1,23 @@
using Avalonia;
using Avalonia.ReactiveUI;
using System;
namespace Seyounth.Hyosung.Ava;
sealed class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace()
.UseReactiveUI();
}

View File

@ -0,0 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\**"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.2.6" />
<PackageReference Include="Avalonia.Controls.TreeDataGrid" Version="11.1.1" />
<PackageReference Include="Avalonia.Desktop" Version="11.2.6" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.6" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.6" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.2.6" />
<PackageReference Include="Avalonia.ReactiveUI" Version="11.2.6" />
<PackageReference Include="Material.Icons.Avalonia" Version="2.3.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.4.0" />
<PackageReference Include="SukiUI" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Seyounth.Hyosung.Core\Seyounth.Hyosung.Core.csproj" />
<ProjectReference Include="..\Seyounth.Hyosung.Runtime\Seyounth.Hyosung.Runtime.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,32 @@
using System;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Seyounth.Hyosung.Ava.ViewModels;
namespace Seyounth.Hyosung.Ava;
public class ViewLocator : IDataTemplate
{
public Control? Build(object? data)
{
if (data is null)
return null;
var name = data.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal);
var type = Type.GetType(name);
if (type != null)
{
var control = (Control)Activator.CreateInstance(type)!;
control.DataContext = data;
return control;
}
return new TextBlock { Text = "Not Found: " + name };
}
public bool Match(object? data)
{
return data is ViewModelBase;
}
}

View File

@ -0,0 +1,36 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using Seyounth.Hyosung.Data.Entities;
using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Services;
namespace Seyounth.Hyosung.Ava.ViewModels;
public partial class AgvBinManagerViewModel : ObservableObject
{
[ObservableProperty] private ObservableCollection<AgvBin> _bines;
private IAgvBinService _agvBinService;
public AgvBinManagerViewModel(IAgvBinService agvBinService)
{
_agvBinService = agvBinService;
NavigatedTo();
}
public void NavigatedTo()
{
Bines = new ObservableCollection<AgvBin>((_agvBinService.GetAllAsync().Result).Select(AgvBin.FromEntity));
foreach (var agvBin in Bines)
{
agvBin.OnDeletedChanged += AgvBinOnOnDeletedChanged;
}
}
private async Task AgvBinOnOnDeletedChanged(AgvBin arg1, bool arg2)
{
await _agvBinService.ChangeDeletedStatus(arg1.Id, arg2);
}
}

View File

@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Avalonia.Controls.Notifications;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Services;
using Seyounth.Hyosung.Runtime;
using SukiUI.Toasts;
namespace Seyounth.Hyosung.Ava.ViewModels;
public partial class HomeViewModel : ObservableObject
{
[ObservableProperty] private ObservableCollection<Variety> _varieties;
[ObservableProperty] private Variety _selectedVariety;
[ObservableProperty] private List<string> _yarnCarTypes;
[ObservableProperty] private List<string> _yarnCarSideType;
[ObservableProperty] private int _selectedYarnCarTypeIndex;
[ObservableProperty] private int _selectedYarnCarSideTypeIndex;
[ObservableProperty] private bool _isSendToErp;
private readonly IVarietyService _varietyService;
private readonly IHyosungRuntime _runtime;
private readonly ISukiToastManager _toastManager;
partial void OnIsSendToErpChanged(bool value)
{
if (_runtime is not null)
_runtime.SetIsSendToErp(value);
}
public HomeViewModel(IVarietyService varietyService, IHyosungRuntime runtime, ISukiToastManager toastManager)
{
IsSendToErp = runtime.GetIsSendToErp();
_varietyService = varietyService;
_runtime = runtime;
_toastManager = toastManager;
YarnCarTypes =
[
"A",
"B",
"C",
"D"
];
YarnCarSideType =
[
"正面",
"反面"
];
SelectedYarnCarTypeIndex = 0;
SelectedYarnCarSideTypeIndex = 0;
NavigatedTo();
}
public void NavigatedTo()
{
Varieties = new ObservableCollection<Variety>(_varietyService.GetAll());
}
[RelayCommand]
private void OnChangeVariety()
{
try
{
SelectedVariety.YarnCarType = SelectedYarnCarTypeIndex + 1;
SelectedVariety.YarnCarSide = SelectedYarnCarSideTypeIndex + 1;
_runtime.SendVarietyToPlcAsync(SelectedVariety);
_toastManager.CreateToast()
.WithTitle("发送成功")
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Success)
.Dismiss().ByClicking()
.Queue();
}
catch (Exception e)
{
_toastManager.CreateToast()
.WithTitle("发送失败")
.WithContent(e.Message)
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Error)
.Dismiss().ByClicking()
.Queue();
}
}
[RelayCommand]
private void OnChangeVarietyLastNo()
{
try
{
_varietyService.SetLastNo(SelectedVariety.Id, SelectedVariety.LastNo.Value);
_toastManager.CreateToast()
.WithTitle("更改控制号成功")
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Success)
.Dismiss().ByClicking()
.Queue();
}
catch (Exception e)
{
_toastManager.CreateToast()
.WithTitle("更改控制号失败")
.WithContent(e.Message)
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Error)
.Dismiss().ByClicking()
.Queue();
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reactive;
using Avalonia.Controls;
using Material.Icons;
using Microsoft.Extensions.DependencyInjection;
using ReactiveUI;
using Seyounth.Hyosung.Ava.Views;
using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Services;
using SukiUI.Controls;
using SukiUI.Toasts;
namespace Seyounth.Hyosung.Ava.ViewModels;
public class MainWindowViewModel : ViewModelBase
{
public ISukiToastManager ToastManager { get; }
public List<SukiSideMenuItem> ItemCollections { get; set; }
public MainWindowViewModel(IServiceProvider provider, ISukiToastManager toastManager)
{
ToastManager = toastManager;
ItemCollections =
[
new SukiSideMenuItem
{
Header = "首页",
PageContent = provider.GetService<HomePage>(),
Classes = { "Compact" }
},
new SukiSideMenuItem
{
Header = "品类管理",
PageContent = provider.GetService<VarietyManagerPage>(),
Classes = { "Compact" }
},
new SukiSideMenuItem
{
Header = "辅料管理",
PageContent = provider.GetService<PalletManagerPage>(),
Classes = { "Compact" }
},
new SukiSideMenuItem
{
Header = "库位管理",
PageContent = provider.GetService<AgvBinManagerPage>(),
Classes = { "Compact" }
}
];
}
}

View File

@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Avalonia.Controls.Notifications;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Services;
using Seyounth.Hyosung.Data.Services.Hyosung;
using SukiUI.Toasts;
namespace Seyounth.Hyosung.Ava.ViewModels;
public partial class PalletManagerViewModel : ObservableObject
{
public class SavePalletCompletedMessage;
public string Title => "辅料管理";
[ObservableProperty] private ObservableCollection<Pallet> _pallets;
private readonly ISukiToastManager _toastManager;
private readonly IPalletService _palletService;
public PalletManagerViewModel(IPalletService palletService, ISukiToastManager toastManager)
{
_toastManager = toastManager;
_palletService = palletService;
Pallets = new ObservableCollection<Pallet>(palletService.GetPallets());
}
[RelayCommand]
private void AddNewRow()
{
Pallets.Add(new Pallet());
}
[RelayCommand]
private void AddPallet()
{
var newPallet = new Pallet
{
/* 初始化默认值 */
};
Pallets.Add(newPallet);
}
[RelayCommand]
private void OnDeletePallet(object obj)
{
if (obj is Pallet pallet)
{
Pallets.Remove(pallet);
_palletService.DeletePalletAsync(pallet);
_toastManager.CreateToast()
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Success)
.Dismiss().ByClicking()
.Queue();
}
else
{
Console.Write("Object is not a Pallet");
}
}
[RelayCommand]
private async Task OnSavePallet(object obj)
{
if (obj is Pallet pallet)
{
if (pallet.Id == 0)
{
await _palletService.AddPalletAsync(pallet);
_toastManager.CreateToast()
.WithTitle("新增辅料成功")
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Success)
.Dismiss().ByClicking()
.Queue();
}
else
{
await _palletService.UpdatePalletAsync(pallet);
_toastManager.CreateToast()
.WithTitle("修改辅料成功")
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Success)
.Dismiss().ByClicking()
.Queue();
}
}
WeakReferenceMessenger.Default.Send(new SavePalletCompletedMessage());
}
}

View File

@ -0,0 +1,180 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Avalonia.Controls.Notifications;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Services;
using Seyounth.Hyosung.Data.Services.Hyosung;
using SukiUI.Toasts;
namespace Seyounth.Hyosung.Ava.ViewModels;
public partial class VarietyManagerViewModel : ObservableObject
{
[ObservableProperty] private ObservableCollection<Variety> _varieties;
[ObservableProperty] private ObservableCollection<Pallet> _pallets;
[ObservableProperty] private ObservableCollection<Pallet> _honeyPallets = new();
[ObservableProperty] private ObservableCollection<Pallet> _paperPallets = new();
[ObservableProperty] private ObservableCollection<Pallet> _trays = new();
private readonly ISukiToastManager _toastManager;
private readonly IVarietyService _varietyService;
private readonly IPalletService _palletService;
private readonly IHyosungWmsService _wmsService;
public void Reload()
{
Pallets = new ObservableCollection<Pallet>(_palletService.GetPallets());
HoneyPallets = new ObservableCollection<Pallet>(Pallets.Where(p => p.Type == PalletType.Honey));
var papers = Pallets.Where(p => p.Type == PalletType.Paper).ToList();
papers.Add(new Pallet());
papers = papers.OrderBy(p => p.Length).ToList();
PaperPallets = new ObservableCollection<Pallet>(papers);
Trays = new ObservableCollection<Pallet>(Pallets.Where(p =>
p.Type is PalletType.Plywood or PalletType.Wood));
var varieties = _varietyService.GetAll().Select(v =>
{
// 匹配相同ID的托盘对象
v.TopAndBottomPallet = HoneyPallets.FirstOrDefault(p => p.Id == v.TopAndBottomPallet.Id);
v.MiddlePallet = HoneyPallets.FirstOrDefault(p => p.Id == v.MiddlePallet.Id);
v.Tray = Trays.FirstOrDefault(p => p.Id == v.Tray.Id);
v.PaperTray = v.PaperTray is null
? PaperPallets.First()
: PaperPallets.FirstOrDefault(p =>
p.Id == v.PaperTray.Id);
return v;
});
Varieties = new ObservableCollection<Variety>(varieties);
}
public VarietyManagerViewModel(IVarietyService varietyService, ISukiToastManager toastManager,
IPalletService palletService,IHyosungWmsService wmsService)
{
_wmsService = wmsService;
_toastManager = toastManager;
_palletService = palletService;
_varietyService = varietyService;
Reload();
}
[RelayCommand]
private void AddNewRow()
{
Varieties.Add(new Variety());
}
[RelayCommand]
private void OnCopyNew(object obj)
{
if (obj is Variety variety)
{
var newVariety = new Variety
{
Id = variety.Id,
TopAndBottomPallet = variety.TopAndBottomPallet,
MiddlePallet = variety.MiddlePallet,
Tray = variety.Tray,
PaperTray = variety.PaperTray,
StackingLayers = variety.StackingLayers,
YarnCarType = variety.YarnCarType,
NeedAngleBeam = variety.NeedAngleBeam,
NeedFilmCoating = variety.NeedFilmCoating,
NeedFilmWrapping = variety.NeedFilmWrapping,
HasBox = variety.HasBox,
Specifications = variety.Specifications,
InnerDiameter = variety.InnerDiameter,
LastNo = variety.LastNo,
OuterDiameter = variety.OuterDiameter,
TotalCount = variety.TotalCount,
YarnDiameter = variety.YarnDiameter,
YarnThickness = variety.YarnThickness,
MasterLabelCount = variety.MasterLabelCount,
NeedPackStrap = variety.NeedPackStrap,
NeedTopBoard = variety.NeedTopBoard,
PaperTubeHeight = variety.PaperTubeHeight,
StackHeadCount = variety.StackHeadCount,
SubLabelCount = variety.SubLabelCount,
YarnCarSide = variety.YarnCarSide,
StackHeadSpec = variety.StackHeadSpec,
Code = variety.Code,
ControlNo = variety.ControlNo,
GrossWeight = variety.GrossWeight,
NetWeight = variety.NetWeight,
SingleWeight = variety.SingleWeight,
IsTurn = variety.IsTurn,
Lot = variety.Lot,
};
Varieties.Add(newVariety);
}
}
[RelayCommand]
private void OnDeletePallet(object obj)
{
if (obj is Variety variety)
{
Varieties.Remove(variety);
_varietyService.DeleteVarietyAsync(variety);
_toastManager.CreateToast()
.WithTitle("删除成功")
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Success)
.Dismiss().ByClicking()
.Queue();
}
else
{
Console.Write("Object is not a Pallet");
}
}
[RelayCommand]
private async Task OnSavePallet(object obj)
{
if (obj is Variety variety)
{
var mod = await _wmsService.GetItemInfoByItemCode(variety.Code);
if(mod is null)
{
_toastManager.CreateToast()
.WithTitle("保存失败")
.WithContent("无法从上游获取产品信息,请检查产品代码是否正确!")
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Error)
.Dismiss().ByClicking()
.Queue();
return;
}
if (variety.GrossWeight < variety.NetWeight)
{
_toastManager.CreateToast()
.WithTitle("保存失败")
.WithContent("毛重小于净重,请检查是否输入错误!")
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Error)
.Dismiss().ByClicking()
.Queue();
return;
}
await _varietyService.AddVarietyAsync(variety);
_toastManager.CreateToast()
.WithTitle("保存成功")
.Dismiss().After(TimeSpan.FromSeconds(3))
.OfType(NotificationType.Success)
.Dismiss().ByClicking()
.Queue();
//Pallets = new ObservableCollection<Pallet>(_palletService.GetPallets());
}
}
}

View File

@ -0,0 +1,7 @@
using ReactiveUI;
namespace Seyounth.Hyosung.Ava.ViewModels;
public class ViewModelBase : ReactiveObject
{
}

View File

@ -0,0 +1,28 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:suki="https://github.com/kikipoulet/SukiUI"
xmlns:viewModels="clr-namespace:Seyounth.Hyosung.Ava.ViewModels"
xmlns:views="clr-namespace:Seyounth.Hyosung.Ava.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="views:AgvBinManagerPage"
x:Name="PalletPage"
x:Class="Seyounth.Hyosung.Ava.Views.AgvBinManagerPage">
<suki:SukiStackPage>
<suki:SukiStackPage.Content>
<Grid x:Name="库位管理" RowDefinitions="Auto,*">
<DataGrid Grid.Row="1" GridLinesVisibility="All"
ItemsSource="{Binding ViewModel.Bines, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Columns>
<DataGridTextColumn IsReadOnly="True" Header="库位名称" Binding="{Binding BinCode}" />
<DataGridTextColumn IsReadOnly="True" Header="代码" Binding="{Binding CtnrCode}" />
<DataGridTextColumn Header="序号" Binding="{Binding Sort}" />
<DataGridCheckBoxColumn IsReadOnly="True" Header="是否空闲" Binding="{Binding IsFree}" />
<DataGridCheckBoxColumn Header="禁用" Binding="{Binding IsDeleted}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</suki:SukiStackPage.Content>
</suki:SukiStackPage>
</UserControl>

View File

@ -0,0 +1,24 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Seyounth.Hyosung.Ava.ViewModels;
namespace Seyounth.Hyosung.Ava.Views;
public partial class AgvBinManagerPage : UserControl
{
public AgvBinManagerViewModel ViewModel { get; }
public AgvBinManagerPage(AgvBinManagerViewModel viewModel)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
}
protected override void OnLoaded(RoutedEventArgs e)
{
ViewModel.NavigatedTo();
base.OnLoaded(e);
}
}

View File

@ -0,0 +1,72 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:suki="https://github.com/kikipoulet/SukiUI"
xmlns:views="clr-namespace:Seyounth.Hyosung.Ava.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="views:HomePage"
x:Class="Seyounth.Hyosung.Ava.Views.HomePage">
<suki:SukiStackPage>
<suki:SukiStackPage.Content>
<Grid x:Name="首页" RowDefinitions="Auto,*" ColumnDefinitions="*,*">
<suki:GlassCard>
<suki:GroupBox Header="入车设置">
<Grid RowDefinitions="*,*,*,*,*,*,*,*,*" ColumnDefinitions="*,*">
<TextBlock VerticalAlignment="Center" Text="产品类型" />
<ComboBox Grid.Row="0" Grid.Column="1"
SelectedValue="{Binding ViewModel.SelectedVariety, Mode=TwoWay}"
ItemsSource="{Binding ViewModel.Varieties}"
DisplayMemberBinding="{Binding Name}" />
<TextBlock Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" Text="纱车类型" />
<ComboBox Grid.Row="1" Grid.Column="1"
SelectedIndex="{Binding ViewModel.SelectedYarnCarTypeIndex, Mode=TwoWay}"
ItemsSource="{Binding ViewModel.YarnCarTypes}" />
<TextBlock Grid.Column="0" Grid.Row="2" VerticalAlignment="Center" Text="纱车正反面" />
<ComboBox Grid.Column="1" Grid.Row="2"
SelectedIndex="{Binding ViewModel.SelectedYarnCarSideTypeIndex, Mode=TwoWay}"
ItemsSource="{Binding ViewModel.YarnCarSideType}" />
<TextBlock Grid.Column="0" Grid.Row="3" VerticalAlignment="Center" Text="当前控制号" />
<StackPanel Grid.Column="1" Grid.Row="3" Orientation="Horizontal">
<TextBox Width="300" Text="{Binding ViewModel.SelectedVariety.LastNo,Mode=TwoWay}" />
<Button Margin="10,0,0,0" Classes="Outlined Accent" Content="修改"
Command="{Binding ViewModel.ChangeVarietyLastNoCommand }" />
</StackPanel>
<TextBlock Grid.Column="0" Grid.Row="4" VerticalAlignment="Center" Text="产品编码" />
<TextBox IsEnabled="False" Grid.Column="1" Grid.Row="4"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Text="{Binding ViewModel.SelectedVariety.Code}" />
<TextBlock Grid.Column="0" Grid.Row="5" VerticalAlignment="Center" Text="LOT" />
<TextBox IsEnabled="False" Grid.Column="1" Grid.Row="5"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Text="{Binding ViewModel.SelectedVariety.Lot}" />
<TextBlock Grid.Column="0" Grid.Row="6" VerticalAlignment="Center" Text="码垛层数" />
<TextBox IsEnabled="False" Grid.Column="1" Grid.Row="6"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Text="{Binding ViewModel.SelectedVariety.StackingLayers}" />
<TextBlock Grid.Column="0" Grid.Row="7" VerticalAlignment="Center" Text="总数" />
<TextBox IsEnabled="False" Grid.Column="1" Grid.Row="7"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Text="{Binding ViewModel.SelectedVariety.TotalCount}" />
<Button Grid.Row="8" Grid.Column="1" Content="切换"
Command="{Binding ViewModel.ChangeVarietyCommand }" Classes="Outlined" />
</Grid>
</suki:GroupBox>
</suki:GlassCard>
<suki:GlassCard Grid.Row="0" Grid.Column="1">
<suki:GroupBox Header="便捷设置">
<Grid RowDefinitions="*,*,*,*,*,*,*,*,*" ColumnDefinitions="*,*">
<TextBlock Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" Text="传送至ERP" />
<ToggleSwitch x:Name="IsSendToErp" HorizontalAlignment="Right" Grid.Column="1" Grid.Row="0"
IsChecked="{Binding ViewModel.IsSendToErp}" />
</Grid>
</suki:GroupBox>
</suki:GlassCard>
</Grid>
</suki:SukiStackPage.Content>
</suki:SukiStackPage>
</UserControl>

View File

@ -0,0 +1,26 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Seyounth.Hyosung.Ava.ViewModels;
namespace Seyounth.Hyosung.Ava.Views;
public partial class HomePage : UserControl
{
public HomeViewModel ViewModel { get; }
public HomePage(HomeViewModel viewModel)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
}
protected override void OnLoaded(RoutedEventArgs e)
{
ViewModel.NavigatedTo();
base.OnLoaded(e);
}
}

View File

@ -0,0 +1,44 @@
<suki:SukiWindow xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Seyounth.Hyosung.Ava.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:suki="https://github.com/kikipoulet/SukiUI"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Seyounth.Hyosung.Ava.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/avalonia-logo.ico"
Title="Seyounth.Hyosung.Ava">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainWindowViewModel />
</Design.DataContext>
<suki:SukiWindow.Hosts>
<suki:SukiToastHost Manager="{Binding ToastManager}"/>
</suki:SukiWindow.Hosts>
<suki:SukiSideMenu
ItemsSource="{Binding ItemCollections}">
<suki:SukiSideMenu.Styles>
<Style Selector="Image.AppIcon">
<Setter Property="Transitions">
<Transitions>
<DoubleTransition Property="Opacity" Duration="0.1" />
</Transitions>
</Setter>
<Style Selector="^:pointerover">
<Setter Property="Opacity" Value="0.5" />
</Style>
</Style>
</suki:SukiSideMenu.Styles>
<suki:SukiSideMenu.HeaderContent>
<!-- Header Content -->
</suki:SukiSideMenu.HeaderContent>
<suki:SukiSideMenu.FooterContent>
<!-- Footer Content -->
</suki:SukiSideMenu.FooterContent>
</suki:SukiSideMenu>
</suki:SukiWindow>

View File

@ -0,0 +1,14 @@
using Avalonia.Controls;
using Seyounth.Hyosung.Ava.ViewModels;
using SukiUI.Controls;
namespace Seyounth.Hyosung.Ava.Views;
public partial class MainWindow :SukiWindow
{
public MainWindow(MainWindowViewModel viewModel)
{
DataContext = viewModel;
InitializeComponent();
}
}

View File

@ -0,0 +1,77 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:viewModels="clr-namespace:Seyounth.Hyosung.Ava.ViewModels"
xmlns:views="clr-namespace:Seyounth.Hyosung.Ava.Views"
xmlns:models="clr-namespace:Seyounth.Hyosung.Data.Models;assembly=Seyounth.Hyosung.Data"
xmlns:helpers="clr-namespace:Seyounth.Hyosung.UI.Helpers"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:suki="https://github.com/kikipoulet/SukiUI"
x:DataType="viewModels:PalletManagerViewModel"
x:Name="PalletPage"
x:Class="Seyounth.Hyosung.Ava.Views.PalletManagerPage">
<UserControl.Resources>
<helpers:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />
</UserControl.Resources>
<suki:SukiStackPage>
<suki:SukiStackPage.Content>
<Grid x:Name="辅料管理" RowDefinitions="Auto,*">
<StackPanel Margin="20" Orientation="Horizontal">
<Button Content="新增" Classes="Outlined" Command="{Binding AddNewRowCommand }" />
</StackPanel>
<DataGrid Grid.Row="1" GridLinesVisibility="All"
ItemsSource="{Binding Pallets, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID"
IsReadOnly="True"
Binding="{Binding Id}" />
<DataGridTemplateColumn Header="辅料类型">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding Type, Mode=TwoWay}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models:PalletType}}}"
SelectionChanged="ComboBox_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="长度(Length)" Binding="{Binding Length}" />
<DataGridTextColumn Header="宽度(Width)" Binding="{Binding Width}" />
<DataGridTextColumn Header="高度(Height)" Binding="{Binding Height}" />
<DataGridCheckBoxColumn Header="大孔(BigHole)" Binding="{Binding IsBigHole}" />
<DataGridTextColumn Header="孔数(HoleCount)" Binding="{Binding HoleCount}" />
<DataGridTemplateColumn Header="操作">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button VerticalAlignment="Center" Margin="10,0,10,0"
Content="修改"
Classes="Outlined Accent"
Command="{Binding ElementName=PalletPage, Path=ViewModel.SavePalletCommand}"
CommandParameter="{Binding}"
IsVisible="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Path=IsEditing}" />
<!-- 删除按钮 -->
<Button VerticalAlignment="Center" Content="删除" Margin="10,0,10,0"
Command="{Binding ElementName=PalletPage, Path=ViewModel.DeletePalletCommand}"
CommandParameter="{Binding}" />
<!-- 保存按钮,根据 DataGridRow 的 IsEditing 属性控制可见性 -->
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</suki:SukiStackPage.Content>
</suki:SukiStackPage>
</UserControl>

View File

@ -0,0 +1,24 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Seyounth.Hyosung.Ava.ViewModels;
using SukiUI.Controls;
namespace Seyounth.Hyosung.Ava.Views;
public partial class PalletManagerPage :UserControl
{
public PalletManagerViewModel ViewModel { get; }
public PalletManagerPage(PalletManagerViewModel viewModel)
{
ViewModel = viewModel;
DataContext = ViewModel;
InitializeComponent();
}
private void ComboBox_SelectionChanged(object? sender, SelectionChangedEventArgs e)
{
}
}

View File

@ -0,0 +1,251 @@
<UserControl xmlns="https://github.com/avaloniaui"
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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:suki="https://github.com/kikipoulet/SukiUI"
xmlns:models1="clr-namespace:Seyounth.Hyosung.Data.Models;assembly=Seyounth.Hyosung.Data"
xmlns:views="clr-namespace:Seyounth.Hyosung.Ava.Views"
xmlns:helpers="clr-namespace:Seyounth.Hyosung.UI.Helpers"
x:DataType="views:VarietyManagerPage"
x:Name="VarietyPage"
x:Class="Seyounth.Hyosung.Ava.Views.VarietyManagerPage">
<UserControl.Resources>
<helpers:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />
</UserControl.Resources>
<suki:SukiStackPage>
<suki:SukiStackPage.Content>
<Grid x:Name="品类管理" RowDefinitions="Auto,*">
<StackPanel Margin="20" Orientation="Horizontal">
<Button Content="新增" Classes="Outlined" Command="{Binding ViewModel.AddNewRowCommand}" />
</StackPanel>
<DataGrid Grid.Row="1" GridLinesVisibility="All"
ItemsSource="{Binding ViewModel.Varieties,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="复制">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button VerticalAlignment="Center" Margin="10,0,10,0"
Content="复制"
Classes="Outlined Accent"
Command="{Binding ElementName=VarietyPage, Path=ViewModel.CopyNewCommand}"
CommandParameter="{Binding}"
IsVisible="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Path=IsEditing}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="编号"
Binding="{Binding Id}" />
<DataGridTextColumn MinWidth="200" Header="产品编码" Binding="{Binding Code}" />
<DataGridTextColumn Header="Lot" Binding="{Binding Lot}" />
<DataGridTextColumn Header="规格" Binding="{Binding Specifications}" />
<DataGridTextColumn
Binding="{Binding InnerDiameter }"
Header="内径(D1)"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding OuterDiameter }"
Header="外径(D2)"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding YarnDiameter }"
Header="直径(D3)"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding PaperTubeHeight }"
Header="纸管高(H1)"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding YarnThickness }"
Header="纱线厚(H2)"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding SingleWeight }"
Header="单筒重"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding StackingLayers }"
Header="码层数"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding TotalCount }"
Header="个/托"
Width="Auto" />
<DataGridTemplateColumn Width="180" Header="蜂窝板(中间)">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectedItem="{Binding MiddlePallet, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding ElementName=VarietyPage, Path=ViewModel.HoneyPallets}"
DisplayMemberBinding="{Binding Name}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="180" Header="蜂窝板(上下)">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectedItem="{Binding TopAndBottomPallet, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding ElementName=VarietyPage, Path=ViewModel.HoneyPallets}"
DisplayMemberBinding="{Binding Name}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="180" Header="底托">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectedItem="{Binding Tray, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding ElementName=VarietyPage, Path=ViewModel.Trays}"
DisplayMemberBinding="{Binding Name}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="180" Header="隔板">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectedItem="{Binding PaperTray, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding ElementName=VarietyPage, Path=ViewModel.PaperPallets}"
DisplayMemberBinding="{Binding Name}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
Binding="{Binding StackHeadSpec }"
Header="垛头尺寸" />
<DataGridTextColumn
Binding="{Binding StackHeadCount }"
Header="垛头数量" />
<DataGridCheckBoxColumn Header="套箱" Binding="{Binding HasBox}" />
<DataGridTemplateColumn Header="顶板">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectedItem="{Binding NeedTopBoard, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models1:NeedType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="护角">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectedItem="{Binding NeedAngleBeam, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models1:NeedType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="打带">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectedItem="{Binding NeedPackStrap, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models1:NeedType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="缠膜">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectedItem="{Binding NeedFilmWrapping, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models1:NeedType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="覆膜">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectedItem="{Binding NeedFilmCoating, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models1:NeedType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
Binding="{Binding MasterLabelCount }"
Header="主标签数量"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding SubLabelCount }"
Header="副标签数量"
Width="Auto" />
<DataGridTextColumn Header="毛重"
Binding="{Binding GrossWeight}" />
<DataGridTextColumn Header="净重"
Binding="{Binding NetWeight}" />
<DataGridTextColumn Header="控制号"
Binding="{Binding LastNo}" />
<DataGridTextColumn Header="主标签颜色"
Binding="{Binding LabelColor}" />
<DataGridTemplateColumn Header="操作">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button VerticalAlignment="Center" Margin="10,0,10,0"
Content="修改"
Classes="Outlined Accent"
Command="{Binding ElementName=VarietyPage, Path=ViewModel.SavePalletCommand}"
CommandParameter="{Binding}"
IsVisible="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Path=IsEditing}" />
<!-- 删除按钮 -->
<Button VerticalAlignment="Center" Content="删除" Margin="10,0,10,0"
Command="{Binding ElementName=VarietyPage, Path=ViewModel.DeletePalletCommand}"
CommandParameter="{Binding}" />
<!-- 保存按钮,根据 DataGridRow 的 IsEditing 属性控制可见性 -->
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</suki:SukiStackPage.Content>
</suki:SukiStackPage>
</UserControl>

View File

@ -0,0 +1,26 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Seyounth.Hyosung.Ava.ViewModels;
using SukiUI.Controls;
namespace Seyounth.Hyosung.Ava.Views;
public partial class VarietyManagerPage : UserControl
{
public VarietyManagerViewModel ViewModel { get; }
public VarietyManagerPage(VarietyManagerViewModel viewModel)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
}
protected override void OnLoaded(RoutedEventArgs e)
{
ViewModel.Reload();
base.OnLoaded(e);
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!-- This manifest is used on Windows only.
Don't remove it as it might cause problems with window transparency and embedded controls.
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
<assemblyIdentity version="1.0.0.0" name="Seyounth.Hyosung.Ava.Desktop"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on
and is designed to work with. Uncomment the appropriate elements
and Windows will automatically select the most compatible environment. -->
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
</assembly>

View File

@ -0,0 +1,5 @@
{
"ConnectionStrings": {
"DefaultConnection": "server=DESKTOP-AJ6K895;database=seyounth.hyosung;Trusted_Connection=SSPI;Encrypt=True;TrustServerCertificate=True;"
}
}

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Info"
internalLogFile="c:\temp\nlog-internal.log">
<!-- 定义目标,即日志输出的位置 -->
<targets>
<!-- 输出到控制台 -->
<target name="console" xsi:type="Console" />
<!-- 输出到文件 -->
<target name="file" xsi:type="File" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message} ${onexception:${exception:format=tostring} | ${stacktrace}}" />
</targets>
<!-- 定义规则,决定哪些日志应该输出到哪些目标 -->
<rules>
<!-- 记录所有级别的日志到控制台 -->
<logger name="*" minlevel="Trace" writeTo="console" />
<!-- 记录所有级别的日志到文件 -->
<logger name="*" minlevel="Trace" writeTo="file" />
</rules>
</nlog>

View File

@ -106,10 +106,10 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
await _writer.WriteShortsAsync(12120, ls.ToArray());
}
public async Task WritePrintLableOptionsAsync(int side, int slave)
public async Task WritePrintLabelOptionsAsync(int master, int slave, int color, bool isSendToErp)
{
short masterCount = 0;
switch (side)
switch (master)
{
case 0:
masterCount = 1;
@ -148,12 +148,23 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
break;
}
await _writer.WriteShortsAsync(13050, [1, 1, 1, 2]);
masterCount=isSendToErp ? masterCount : (short)2;
if (color == 1)
{
await _writer.WriteShortsAsync(13050, [1, 1, 1, masterCount]);
await _writer.WriteShortsAsync(13055, [1, 1]);
}
else
{
await _writer.WriteShortsAsync(13050, [1, 1, 1, 1]);
await _writer.WriteShortsAsync(13055, [1, masterCount]);
}
}
public async Task WritePrintLabelResultAsync(int index, bool result)
{
var address = index == 1 ? 13060 : 13061;
var address = 13059 + index;
await _writer.WriteShortsAsync(address, (short)(result ? 1 : 2));
}
@ -375,7 +386,7 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
private async Task QueryPrintLabel()
{
var requestPrintLabel = await _reader.ReadShortsAsync(13010, 3);
var requestPrintLabel = await _reader.ReadShortsAsync(13010, 4);
if (requestPrintLabel[0] == 1)
{
await _writer.WriteShortsAsync(13010, 0);
@ -389,5 +400,12 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
await _writer.WriteShortsAsync(13012, 0);
OnRequestPrintLabel?.Invoke(2, requestPrintLabel[2]);
}
if (requestPrintLabel[3] == 1)
{
await _writer.WriteShortsAsync(13013, 0);
await _writer.WriteShortsAsync(13012, 0);
OnRequestPrintLabel?.Invoke(3, requestPrintLabel[2]);
}
}
}

View File

@ -58,11 +58,11 @@ public interface IHyosungPlcService
Task WritePackLineOptionAsync(PackLineOption option);
Task WritePrintLableOptionsAsync(int side,int slaveCount);
Task WritePrintLabelOptionsAsync(int masterCount, int slaveCount, int color,bool isSendToErp);
Task WritePrintLabelResultAsync(int index, bool result);
Task WritePrintLabelResultAsync(int index, bool result);
Task WriteScanEntryResultAsync(int index, bool result);
/// <summary>
@ -101,6 +101,6 @@ public interface IHyosungPlcService
event Func<int, int, Task> OnRequestPrintLabel;
event Func<string, Task> OnRequestGetPrintLableOption;
event Func<int, Task> OnRequestScanEntry;
}

View File

@ -15,55 +15,58 @@ public class HyosungPrinter(
IHyosungWmsService hyosungWmsService,
IOptions<PrintTemp> options) : IHyosungPrinter
{
private readonly AveryPrinter _masterPrinter = new("192.168.3.61", 9100);
private readonly AveryPrinter _slavePrinter = new("192.168.3.60", 9100);
private readonly Dictionary<int, AveryPrinter> _printers = new Dictionary<int, AveryPrinter>()
{
{ 1001, new AveryPrinter("192.168.3.61", 9100) },
{ 2, new AveryPrinter("192.168.3.62", 9100) },
{ 1, new AveryPrinter("192.168.3.60", 9100) }
};
public async Task StartAsync(CancellationToken token)
{
List<Task> ls = new List<Task>();
ls.Add(_masterPrinter.ConnectAsync(token));
ls.Add(_slavePrinter.ConnectAsync(token));
foreach (var (_, printer) in _printers)
{
ls.Add(printer.ConnectAsync(token));
}
await Task.WhenAll(ls);
logger.LogInformation("printer connected");
}
public async Task StopAsync(CancellationToken token)
{
await _masterPrinter.CloseAsync(token);
await _slavePrinter.CloseAsync(token);
foreach (var (_, printer) in _printers)
{
printer.CloseAsync(token);
}
logger.LogInformation("printer disconnected");
}
public async Task PrintAsync(int index, string trayCode)
public async Task PrintMasterLabelAsync(int color, string trayCode)
{
var tray = await trayService.GetByCode(trayCode);
if (index == 1)
{
await PrintLabel1Async(tray);
}
else
{
await PrintLabel2Async(tray);
}
var content = await GetMasterLabelContent(tray);
await _printers[color].CleanContextAsync();
await _printers[color].SendContentAsync(content);
await _printers[color].PrintAsync();
}
private async Task PrintLabel1Async(Tray tray)
public async Task PrintSubLabelAsync(string trayCode)
{
await _masterPrinter.CleanContextAsync();
var content = await GetPrint1Content(tray);
await _masterPrinter.SendContentAsync(content);
await _masterPrinter.PrintAsync();
var tray = await trayService.GetByCode(trayCode);
var content = await GetSubLabelContentAsync(tray);
await _printers[1001].CleanContextAsync();
await _printers[1001].SendContentAsync(content);
await _printers[1001].PrintAsync();
}
private async Task PrintLabel2Async(Tray tray)
{
await _slavePrinter.CleanContextAsync();
var content = await GetPrint2Content(tray);
await _slavePrinter.SendContentAsync(content);
await _slavePrinter.PrintAsync();
}
private async Task<string> GetPrint1Content(Tray tray)
private async Task<string> GetSubLabelContentAsync(Tray tray)
{
var variety = await varietyService.GetById(tray.VarietyId);
var yarns = await yarnService.GetYarnsByTrayIdAsync(tray.Id);
@ -100,7 +103,7 @@ public class HyosungPrinter(
return temp;
}
private async Task<string> GetPrint2Content(Tray tray)
private async Task<string> GetMasterLabelContent(Tray tray)
{
var variety = await varietyService.GetById(tray.VarietyId);
@ -128,6 +131,7 @@ public class HyosungPrinter(
{
content = content.Replace(key, value);
}
logger.LogInformation($"print content: {content}");
return content;
}

View File

@ -6,10 +6,9 @@ public interface IHyosungPrinter
Task StopAsync(CancellationToken token);
/// <summary>
/// 打印指定垛的标签
/// </summary>
/// <param name="trayCode"></param>
/// <returns></returns>
Task PrintAsync(int index,string trayCode);
Task PrintMasterLabelAsync(int color, string trayCode);
Task PrintSubLabelAsync(string trayCode);
}

View File

@ -29,9 +29,9 @@ public class HyosungScannerService : IHyosungScannerService
_fixtureScanners.TryAdd(3, new HikScanner("192.168.3.33", 2001));
_fixtureScanners.TryAdd(4, new HikScanner("192.168.3.30", 2001));
_carScanners.Add(new HikScanner("192.168.30.46", 2001,5000));
//_carScanners.Add(new HikScanner("1920.168.3.48", 2001,5000));
_carScanners.Add(new HikScanner("1920.168.3.48", 2001,5000));
_varietyScanners.Add(new HikScanner("192.168.30.47", 2001,10000));
//_varietyScanners.Add(new HikScanner("192.168.3.49", 2001,10000));
_varietyScanners.Add(new HikScanner("192.168.3.49", 2001,10000));
_logger = logger;
lastCodes.Add("");
lastCodes.Add("");

View File

@ -1,3 +1,4 @@
using CommunityToolkit.Mvvm.ComponentModel;
using SqlSugar;
namespace Seyounth.Hyosung.Data.Entities;
@ -34,6 +35,6 @@ public class AgvBinEntity
[SugarColumn(IsNullable =true)]
public string HeightCode { get; set; }
public bool IsDeleted { get; set; }
}

View File

@ -6,7 +6,7 @@ namespace Seyounth.Hyosung.Data.Entities;
[SugarTable("system_variety", TableDescription = "品种表")]
public class VarietyEntity
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "主键")]
[SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")]
public int Id { get; set; }
[SugarColumn(ColumnDescription = "品种代码")]
@ -51,13 +51,13 @@ public class VarietyEntity
[SugarColumn(ColumnDescription = "托盘ID")]
public int TrayId { get; set; }
[SugarColumn(ColumnDescription = "垛头尺寸")]
[SugarColumn(ColumnDescription = "垛头尺寸", IsNullable = true)]
public string? StackHeadSpec { get; set; }
[SugarColumn(ColumnDescription = "垛头数量")]
public int? StackHeadCount { get; set; }
[SugarColumn(ColumnDescription = "纸托Id",IsNullable =true)]
[SugarColumn(ColumnDescription = "纸托Id", IsNullable = true)]
public int? PaperTrayId { get; set; }
[SugarColumn(ColumnDescription = "是否需要纸箱")]
@ -84,13 +84,12 @@ public class VarietyEntity
[SugarColumn(ColumnDescription = "副标签数量")]
public int SubLabelCount { get; set; }
[SugarColumn(IsNullable =true)]
public int? LastNo { get; set; }
[SugarColumn(IsNullable =true)]
public double? NetWeight { get; set; }
[SugarColumn(IsNullable =true)]
public double? GrossWeight { get; set; }
[SugarColumn(ColumnDescription = "标签颜色 1=红色 2=黑色")]
public int LabelColor { get; set; }
[SugarColumn(IsNullable = true)] public int? LastNo { get; set; }
[SugarColumn(IsNullable = true)] public double? NetWeight { get; set; }
[SugarColumn(IsNullable = true)] public double? GrossWeight { get; set; }
}

View File

@ -0,0 +1,38 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Seyounth.Hyosung.Data.Entities;
namespace Seyounth.Hyosung.Data.Models;
public partial class AgvBin : ObservableObject
{
public int Id { get; set; }
public string BinCode { get; set; }
public string CtnrCode { get; set; }
public bool IsFree { get; set; }
public int Sort { get; set; }
[ObservableProperty] private bool _isDeleted;
public event Func<AgvBin, bool, Task>? OnDeletedChanged;
partial void OnIsDeletedChanged(bool value)
{
// 触发视图模型的保存方法
OnDeletedChanged?.Invoke(this, value);
}
public static AgvBin FromEntity(AgvBinEntity entity)
{
return new AgvBin()
{
Id = entity.Id,
BinCode = entity.BinCode,
CtnrCode = entity.CtnrCode,
IsDeleted = entity.IsDeleted,
Sort = entity.Sort,
IsFree = entity.IsFree,
};
}
}

View File

@ -5,8 +5,24 @@ namespace Seyounth.Hyosung.Data.Models;
public class Pallet : PalletEntity
{
public string Name =>
$"{Type.GetDescription()}({Width}*{Height}*{Length})({HoleCount}|{(IsBigHole != null && IsBigHole.Value ? "" : "")})";
public string Name
{
get
{
if (Type == PalletType.Honey)
{
return
$"{Type.GetDescription()}({Width}*{Length}*{Height})({HoleCount}|{(IsBigHole != null && IsBigHole.Value ? "" : "")})";
}
else if (Length != 0)
{
return $"{Type.GetDescription()}({Width}*{Length}*{Height})";
}
else return "无";
}
}
public static Pallet FromEntity(PalletEntity p)
{

View File

@ -12,7 +12,7 @@ public enum PalletType
/// <summary>
/// 胶合板托盘
/// </summary>
[Description("胶合板")] Plywood = 1,
[Description("胶")] Plywood = 1,
/// <summary>
/// 木板托盘

View File

@ -70,6 +70,8 @@ public class Variety
public double? GrossWeight { get; set; }
public int LabelColor { get; set; }
public static Variety Create(VarietyEntity entity, List<PalletEntity> pallets)
{
var variety = new Variety()
@ -101,7 +103,8 @@ public class Variety
HasBox = entity.HasBox,
LastNo = entity.LastNo,
NetWeight = entity.NetWeight,
GrossWeight = entity.GrossWeight
GrossWeight = entity.GrossWeight,
LabelColor = entity.LabelColor,
};
if (entity.PaperTrayId != null && entity.PaperTrayId != 0)
variety.PaperTray = Pallet.FromEntity(pallets.First(x => x.Id == entity.PaperTrayId));
@ -141,7 +144,8 @@ public class Variety
HasBox = HasBox,
LastNo = LastNo,
NetWeight = NetWeight,
GrossWeight = GrossWeight
GrossWeight = GrossWeight,
LabelColor = LabelColor,
};
return entity;
}

View File

@ -18,21 +18,21 @@ public static class ServiceExtensions
{
//#if RELEASE
SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig()
{
DbType = DbType.SqlServer,
ConnectionString = connectionString,
IsAutoCloseConnection = true,
}
{
DbType = DbType.SqlServer,
ConnectionString = connectionString,
IsAutoCloseConnection = true,
}
);
//#elif DEBUG
//SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig()
// {
// DbType = DbType.Sqlite,
// ConnectionString = "Data Source=hyosung.db",
// IsAutoCloseConnection = true,
// InitKeyType = InitKeyType.Attribute
// }
//);
// SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig()
// {
// DbType = DbType.Sqlite,
// ConnectionString = "Data Source=hyosung.db",
// IsAutoCloseConnection = true,
// InitKeyType = InitKeyType.Attribute
// }
// );
//#endif
return sqlSugar;
});
@ -50,13 +50,13 @@ public static class ServiceExtensions
public static void UseHyosungData(this IServiceProvider provider)
{
//var db = provider.GetRequiredService<ISqlSugarClient>();
//db.DbMaintenance.CreateDatabase();
//db.CodeFirst.InitTables(typeof(VarietyEntity),
// typeof(PalletEntity),
// typeof(ScannedYarnEntity),
// typeof(TrayEntity),
// typeof(AgvBinEntity),
// typeof(DictEntity));
var db = provider.GetRequiredService<ISqlSugarClient>();
db.DbMaintenance.CreateDatabase();
db.CodeFirst.InitTables(typeof(VarietyEntity),
typeof(PalletEntity),
typeof(ScannedYarnEntity),
typeof(TrayEntity),
typeof(AgvBinEntity),
typeof(DictEntity));
}
}

View File

@ -6,29 +6,35 @@ namespace Seyounth.Hyosung.Data.Services;
public class AgvBinService : IAgvBinService
{
private readonly List<AgvBinEntity> _cache;
// private readonly List<AgvBinEntity> _cache;
private readonly IRepository<AgvBinEntity> _repository;
public AgvBinService(IServiceProvider provider)
{
_repository = provider.CreateScope().ServiceProvider.GetRequiredService<IRepository<AgvBinEntity>>();
_repository = provider.CreateScope().ServiceProvider.GetRequiredService<IRepository<AgvBinEntity>>();
//_repository = provider.GetService<IRepository<AgvBinEntity>>();
_cache = _repository.GetList();
// _cache = _repository.GetList();
}
public async Task<AgvBinEntity> GetAvailableBin(int height)
{
var bin = await _repository.CopyNew().AsQueryable()
.Where(x => x.IsFree && !x.IsDeleted).OrderBy(x => x.Sort).FirstAsync();
if (bin.BinCode == "B10")
var maxRackType1 = await _repository.CopyNew().AsQueryable()
.Where(x => x.RackType == 1)
.MaxAsync(r => r.Sort);
var maxRackType2 = await _repository.CopyNew().AsQueryable()
.Where(x => x.RackType == 2)
.MaxAsync(r => r.Sort);
if (bin.Sort == maxRackType1)
{
await _repository.CopyNew().AsUpdateable()
.Where(x => x.RackType == 2 && !x.IsDeleted)
.SetColumns(x => x.IsFree, true)
.ExecuteCommandAsync();
}
else if (bin.BinCode == "B33")
else if (bin.Sort == maxRackType2)
{
await _repository.CopyNew().AsUpdateable()
.Where(x => x.RackType == 1 && !x.IsDeleted)
@ -41,8 +47,22 @@ public class AgvBinService : IAgvBinService
public Task BindAsync(AgvBinEntity entity)
{
entity.IsFree = false;
_cache.First(e => e.Id == entity.Id).IsFree = false;
// entity.IsFree = false;
// _cache.First(e => e.Id == entity.Id).IsFree = false;
return _repository.CopyNew().UpdateAsync(entity);
}
public async Task<List<AgvBinEntity>> GetAllAsync()
{
var rs = await _repository.CopyNew().GetListAsync();
return rs;
}
public async Task ChangeDeletedStatus(int id, bool isDeleted)
{
await _repository.CopyNew().AsUpdateable()
.Where(x => x.Id == id)
.SetColumns(x => x.IsDeleted, isDeleted)
.ExecuteCommandAsync();
}
}

View File

@ -13,10 +13,10 @@ public class DictService : IDictService
public DictService(IServiceProvider provider)
{
_repository = provider.CreateScope()
.ServiceProvider.GetRequiredService<IRepository<DictEntity>>();
_repository = provider.CreateScope()
.ServiceProvider.GetRequiredService<IRepository<DictEntity>>();
//_repository = provider.GetService<IRepository<DictEntity>>();
_cache = _repository.GetList();
_cache = _repository.GetList();
}
@ -33,7 +33,8 @@ public class DictService : IDictService
public async Task SetValue(string type, string key, string value)
{
await _repository.CopyNew().AsUpdateable()
.Where(x => x.Type == type && x.Key == key).SetColumns(x => x.Value, value).ExecuteCommandAsync(); ;
.Where(x => x.Type == type && x.Key == key).SetColumns(x => x.Value, value).ExecuteCommandAsync();
;
}
public async Task<string> GetValue(string type, string key)
@ -41,4 +42,20 @@ public class DictService : IDictService
var dict = await _repository.CopyNew().GetFirstAsync(x => x.Type == type && x.Key == key);
return dict.Value;
}
public async Task<string> GetOrAddNewValue(string type, string key, string defaultValue = "")
{
var newRepo = _repository.CopyNew();
var dict = await newRepo.GetFirstAsync(x => x.Type == type && x.Key == key);
if (dict is null)
{
dict = new DictEntity();
dict.Type = type;
dict.Key = key;
dict.Value = defaultValue;
await newRepo.InsertAsync(dict);
}
return dict.Value;
}
}

View File

@ -33,7 +33,7 @@ public class LabelResult
public string COMMON_S3 { get; set; } = "";
public string COMMON_S4 { get; set; } = "";
public string COMMON_S5 { get; set; } = "";
public string COMMON_S5 { get; set; } = "0";
//public string COMMON_S4 { get; set; } = "";
//public string COMMON_S5 { get; set; } = "";
@ -43,9 +43,11 @@ public class LabelResult
public string CREATED_ON { get; set; } = DateTime.Now.ToString("yyyy-MM-dd");
public string MODIFIED_BY { get; set; } = "seyounth";
public string MODIFIED_ON { get; set; } = DateTime.Now.ToString("yyyy-MM-dd");
public double COMMON_N1 { get; set; } = 0;
public string TRI_INTERFACE_YN { get; set; } = "N";
public LabelResult(Tray tray, Variety variety)
{
LABEL_ID = tray.TrayCode;
@ -60,10 +62,10 @@ public class LabelResult
BOX_NO = $"{DateTime.Now.ToString("yyMMdd" + "J") + tray.ControlNo.ToString()?.PadLeft(3, '0')}";
CREATED_BY = "seyounth";
CREATED_ON = DateTime.Now.ToString("yyyy-MM-dd");
COMMON_S1 = tray.Type?? "";
COMMON_S1 = tray.Type ?? "";
COMMON_S2 = variety.TotalCount.ToString();
COMMON_S3=tray.DenFila?? "";
COMMON_S4 = tray.DtexFila?? "";
COMMON_S3 = tray.DenFila ?? "";
COMMON_S4 = tray.DtexFila ?? "";
COMMON_S5 = "0";
COMMON_N1 = (double)tray.ControlNo;
MODIFIED_BY = "seyounth";

View File

@ -0,0 +1,17 @@
namespace Seyounth.Hyosung.Data.Services.Hyosung.Entities;
[SqlSugar.SugarTable("PDA_PUTAWAY")]
public class PDA_PUTAWAY
{
public string BE_ID { get; set; }
public string BARCODE_TYPE { get; set; }
public string BAR_CODE { get; set; }
public DateTime SCAN_DATE { get; set; }
public string ISSUE_FLAG { get; set; }
public string SCAN_TYPE { get; set; }
public string PALLET_NO { get; set; }
public string LOCATION { get; set; }
public string PDA_USER_ID { get; set; }
public string CREATED_BY { get; set; }
public string STATUS { get; set; }
}

View File

@ -92,20 +92,40 @@ public class HyosungWmsService : IHyosungWmsService
try
{
var mst_item = await _db.Queryable<MST_ITEM>()
.FirstAsync(t => t.BE_ID == "2240"
&& t.ITEM_CODE == result.ITEM_CODE
&& t.ITEM_CODE_TYPE == "FERT");
.FirstAsync(t => t.BE_ID == "2240"
&& t.ITEM_CODE == result.ITEM_CODE
&& t.ITEM_CODE_TYPE == "FERT");
result.WMS_UOM = mst_item.WMS_UOM_ID;
result.ERP_UOM = mst_item.ERP_UOM_ID;
var workCenter = await _db.Queryable<MST_ITEM_VERSION>()
.FirstAsync(v => v.ITEM_CODE == result.ITEM_CODE);
result.MFG_LINE=(workCenter?.WORK_CENTER)??"TYJP11";
result.MFG_LINE = (workCenter?.WORK_CENTER) ?? "TYJP11";
await _db.Insertable(result).ExecuteCommandAsync();
}catch(Exception e)
{
}
catch (Exception e)
{
}
}
public async Task AddPdaPutawayRecord(string barcode)
{
await _db.Insertable(new PDA_PUTAWAY
{
BE_ID = "2240",
BARCODE_TYPE = "1111111",
BAR_CODE = barcode,
SCAN_DATE = DateTime.Now,
ISSUE_FLAG = "N",
SCAN_TYPE = "",
PALLET_NO = "",
LOCATION = "",
PDA_USER_ID = "TY_ACP",
CREATED_BY = "seyounth",
STATUS = "R"
}).ExecuteCommandAsync();
//await _db.Updateable<LabelResult>()
// .Where(x => x.BAR_CODE == barcode)
// .SetColumns(x => x.TRI_INTERFACE_YN, "Y").ExecuteCommandAsync();
}
}

View File

@ -14,4 +14,6 @@ public interface IHyosungWmsService
Task<LabelResult> GetLabelResult(string itemCode, string lot, int controlNo);
Task AddLabelResult(LabelResult result);
Task AddPdaPutawayRecord(string barcode);
}

View File

@ -18,4 +18,8 @@ public interface IAgvBinService
/// <param name="entity"></param>
/// <returns></returns>
Task BindAsync(AgvBinEntity entity);
Task<List<AgvBinEntity>> GetAllAsync();
Task ChangeDeletedStatus(int id,bool isDeleted);
}

View File

@ -11,4 +11,6 @@ public interface IDictService
Task SetValue(string type, string key,string value);
Task<string> GetValue(string type, string key);
Task<string> GetOrAddNewValue(string type, string key, string defaultValue = "");
}

View File

@ -19,10 +19,10 @@ public class VarietyService : IVarietyService
{
_varietyRepository =
provider.CreateScope().ServiceProvider.GetRequiredService<IRepository<VarietyEntity>>();
_palletRepository = provider.CreateScope().ServiceProvider.GetRequiredService<IRepository<PalletEntity>>();
_palletRepository = provider.CreateScope().ServiceProvider.GetRequiredService<IRepository<PalletEntity>>();
//_varietyRepository = provider.GetService<IRepository<VarietyEntity>>();
// _palletRepository = provider.GetService<IRepository<PalletEntity>>();
_varietiesCache = new List<VarietyEntity>(_varietyRepository.GetList());
// _palletRepository = provider.GetService<IRepository<PalletEntity>>();
_varietiesCache = new List<VarietyEntity>(_varietyRepository.GetList());
_palletsCache = new List<PalletEntity>(_palletRepository.GetList());
}
catch (Exception e)
@ -49,14 +49,23 @@ public class VarietyService : IVarietyService
{
try
{
var entity = await _varietyRepository.InsertReturnEntityAsync(variety.ToEntity());
_varietiesCache.Add(entity);
var entity = _varietiesCache.FirstOrDefault(p => p.Id == variety.Id);
if (entity == null)
{
entity = await _varietyRepository.InsertReturnEntityAsync(variety.ToEntity());
_varietiesCache.Add(entity);
}
else
{
entity = variety.ToEntity();
await _varietyRepository.UpdateAsync(entity);
_varietiesCache[_varietiesCache.IndexOf(entity)] = entity;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public async Task UpdateVarietyAsync(Variety variety)
@ -89,15 +98,20 @@ public class VarietyService : IVarietyService
public async Task<int?> GetLastNo(int varietyId)
{
var variety = await (_varietyRepository.CopyNew().GetFirstAsync(x=>x.Id==varietyId));
var variety = await (_varietyRepository.CopyNew().GetFirstAsync(x => x.Id == varietyId));
return variety.LastNo;
}
public async Task SetLastNo(int varietyId,int lastNo)
public async Task SetLastNo(int varietyId, int lastNo)
{
await _varietyRepository.CopyNew().AsUpdateable()
.Where(x => x.Id == varietyId)
.SetColumns(x => x.LastNo , lastNo)
.SetColumns(x => x.LastNo, lastNo)
.ExecuteCommandAsync();
var variety = _varietiesCache.FirstOrDefault(x => x.Id == varietyId);
if (variety != null)
{
variety.LastNo = lastNo;
}
}
}

View File

@ -36,6 +36,8 @@ public class HyosungRuntime(
private string currentPrintTrayCode = "";
private bool _isSendToErp = false;
public async Task StartAsync(CancellationToken token)
{
reportExportService.ExportNoExportAsync();
@ -52,6 +54,7 @@ public class HyosungRuntime(
hyosungPlcService.OnRequestPrintLabel += OnPlcRequestPrintLabel;
hyosungPlcService.OnRequestGetPrintLableOption += OnRequestGetPrintLabel;
hyosungPlcService.OnRequestScanEntry += OnPlcRequestScanEntry;
_isSendToErp = bool.Parse(dictService.GetOrAddNewValue("system", "IsSendToErp", "true").Result);
await hyosungPlcService.StartAsync(token);
}
@ -121,10 +124,20 @@ public class HyosungRuntime(
var trays = await trayService.GetTodayTrayAsync();
foreach (var tray in trays)
{
}
}
public bool GetIsSendToErp()
{
return _isSendToErp;
}
public async Task SetIsSendToErp(bool isSendToErp)
{
_isSendToErp = isSendToErp;
await dictService.SetValue("system", "IsSendToErp", isSendToErp.ToString());
}
/// <summary>
/// 处理PLC请求扫描治具事件
/// </summary>
@ -208,6 +221,9 @@ public class HyosungRuntime(
await hyosungAgvService.StorageAsync(info.TrayCode);
//标志下线已完成
await hyosungPlcService.LeaveCompletedAsync();
var tray = await trayService.GetByCode(info.TrayCode);
if (_isSendToErp)
await hyosungWmsService.AddPdaPutawayRecord(tray.Barcode);
logger.LogInformation($"plc leaving production line success");
}
catch (Exception e)
@ -372,28 +388,16 @@ public class HyosungRuntime(
var tray = await trayService.GetByCode(arg);
var variety = await varietyService.GetById(tray.VarietyId);
var mod = await hyosungWmsService.GetItemInfoByItemCode(variety.Code);
// var grade = "1";
// if (mod.GRADE != "AA") grade = mod.GRADE;
// int? controlNo;
// if (tray.ControlNo is null || tray.ControlNo == 0)
// {
// controlNo = await varietyService.GetLastNo(variety.Id);
// if (controlNo is null)
// controlNo = await hyosungWmsService.GetControlNo(variety, grade);
// else
// controlNo += 1;
//
// }
tray = await trayService.PrintTrayAsync(arg, mod, variety);
_ = await trayService.PrintTrayAsync(arg, mod, variety);
await dictService.SetValue("System", "CurrentPackingTrayCode", arg);
await hyosungPlcService.WritePrintLableOptionsAsync(variety.MasterLabelCount, variety.SubLabelCount);
await hyosungPlcService.WritePrintLabelOptionsAsync(variety.MasterLabelCount, variety.SubLabelCount,
variety.LabelColor, _isSendToErp);
logger.LogInformation("request print option succeed");
}
catch(Exception e)
catch (Exception e)
{
logger.LogError(e, "GetPrintOptionError");
}
}
/// <summary>
@ -415,19 +419,19 @@ public class HyosungRuntime(
{
if (arg1 == 1)
{
await printer.PrintAsync(1, tray.TrayCode);
await hyosungPlcService.WritePrintLabelResultAsync(arg1, true);
await printer.PrintSubLabelAsync(tray.TrayCode);
}
else
{
await printer.PrintAsync(2, tray.TrayCode);
await hyosungPlcService.WritePrintLabelResultAsync(arg1, true);
var version=await hyosungWmsService.GetItemInfoByItemCode(variety.Code);
// await varietyService.SetLastNo(variety.Id, tray.ControlNo.Value);
//await hyosungWmsService.UpdateControlNo(variety, tray.ControlNo.Value);
// await hyosungWmsService.AddLabelResult(new LabelResult(tray, variety));
//if (arg1 == 3)
// arg1 = 2;
await printer.PrintMasterLabelAsync(arg1 - 1, tray.TrayCode);
if (_isSendToErp)
await hyosungWmsService.AddLabelResult(new LabelResult(tray, variety));
}
await hyosungPlcService.WritePrintLabelResultAsync(arg1, true);
logger.LogInformation($"plc request print label success");
}
catch (Exception e)

View File

@ -38,4 +38,8 @@ public interface IHyosungRuntime
/// </summary>
/// <returns></returns>
Task GenerateReportAsync();
bool GetIsSendToErp();
Task SetIsSendToErp(bool isSendToErp);
}

View File

@ -0,0 +1,17 @@
<Application
x:Class="Seyounth.Hyosung.UI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
DispatcherUnhandledException="OnDispatcherUnhandledException"
Exit="OnExit"
Startup="OnStartup">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ThemesDictionary Theme="Light" />
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@ -0,0 +1,110 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Seyounth.Hyosung.UI.Services;
using Seyounth.Hyosung.UI.ViewModels.Pages;
using Seyounth.Hyosung.UI.ViewModels.Windows;
using Seyounth.Hyosung.UI.Views.Pages;
using Seyounth.Hyosung.UI.Views.Windows;
using System.IO;
using System.Reflection;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using Seyounth.Hyosung.Core.Printer;
using Seyounth.Hyosung.Runtime;
using Wpf.Ui;
namespace Seyounth.Hyosung.UI
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App
{
private static IHost _host;
public App()
{
var builder = Host
.CreateApplicationBuilder();
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddNLog("nlog.config");
builder.Configuration.AddJsonFile("PrintTemp.json", true, true);
builder.Configuration.AddJsonFile("appsettings.json", true, true);
builder.Services.Configure<PrintTemp>(builder.Configuration.GetSection("Print"));
builder.Services.AddHostedService<ApplicationHostService>();
// Page resolver service
builder.Services.AddSingleton<IPageService, PageService>();
builder.Services.AddSingleton<ISnackbarService, SnackbarService>();
// Theme manipulation
builder.Services.AddSingleton<IThemeService, ThemeService>();
// TaskBar manipulation
builder.Services.AddSingleton<ITaskBarService, TaskBarService>();
// Service containing navigation, same as INavigationWindow... but without window
builder.Services.AddSingleton<INavigationService, NavigationService>();
// Main window with navigation
builder.Services.AddSingleton<INavigationWindow, MainWindow>();
builder.Services.AddSingleton<MainWindowViewModel>();
builder.Services.AddSingleton<DashboardPage>();
builder.Services.AddSingleton<DashboardViewModel>();
builder.Services.AddSingleton<DataPage>();
builder.Services.AddSingleton<DataViewModel>();
builder.Services.AddSingleton<SettingsPage>();
builder.Services.AddSingleton<SettingsViewModel>();
builder.Services.AddSingleton<PalletManagementPage>();
builder.Services.AddSingleton<PalletManagementViewModel>();
builder.Services.AddSingleton<AgvBinPage>();
builder.Services.AddSingleton<AgvBinViewModel>();
builder.Services.AddHyosung(builder.Configuration);
_host = builder.Build();
}
/// <summary>
/// Gets registered service.
/// </summary>
/// <typeparam name="T">Type of the service to get.</typeparam>
/// <returns>Instance of the service or <see langword="null"/>.</returns>
public static T GetService<T>()
where T : class
{
return _host.Services.GetService(typeof(T)) as T;
}
/// <summary>
/// Occurs when the application is loading.
/// </summary>
private void OnStartup(object sender, StartupEventArgs e)
{
RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.Default;
_host.Services.UseHyosung();
_host.Start();
}
/// <summary>
/// Occurs when the application is closing.
/// </summary>
private async void OnExit(object sender, ExitEventArgs e)
{
await _host.StopAsync();
_host.Dispose();
}
/// <summary>
/// Occurs when an exception is thrown by an application but not handled.
/// </summary>
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
// For more info see https://docs.microsoft.com/en-us/dotnet/api/system.windows.application.dispatcherunhandledexception?view=windowsdesktop-6.0
}
}
}

View File

@ -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)
)]

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,21 @@
using System.Windows.Markup;
namespace Seyounth.Hyosung.UI.Helpers;
public class EnumBindingSourceExtension : MarkupExtension
{
public Type EnumType { get; private set; }
public EnumBindingSourceExtension(Type enumType)
{
if (enumType is null || !enumType.IsEnum)
throw new Exception("EnumType must be specified and be an Enum");
EnumType = enumType;
}
public override object? ProvideValue(IServiceProvider serviceProvider)
{
return Enum.GetValues(EnumType);
}
}

View File

@ -0,0 +1,23 @@
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Windows.Data;
namespace Seyounth.Hyosung.UI.Helpers;
public class EnumDescriptionConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value == null) return string.Empty;
var field = value.GetType().GetField(value.ToString());
var attr = field?.GetCustomAttribute<DescriptionAttribute>();
return attr?.Description ?? value.ToString();
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@ -0,0 +1,36 @@
using System.Globalization;
using System.Windows.Data;
using Wpf.Ui.Appearance;
namespace Seyounth.Hyosung.UI.Helpers
{
internal class EnumToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (parameter is not String enumString)
{
throw new ArgumentException("ExceptionEnumToBooleanConverterParameterMustBeAnEnumName");
}
if (!Enum.IsDefined(typeof(ApplicationTheme), value))
{
throw new ArgumentException("ExceptionEnumToBooleanConverterValueMustBeAnEnum");
}
var enumValue = Enum.Parse(typeof(ApplicationTheme), enumString);
return enumValue.Equals(value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (parameter is not String enumString)
{
throw new ArgumentException("ExceptionEnumToBooleanConverterParameterMustBeAnEnumName");
}
return Enum.Parse(typeof(ApplicationTheme), enumString);
}
}
}

View File

@ -0,0 +1,9 @@
namespace Seyounth.Hyosung.UI.Models
{
public class AppConfig
{
public string ConfigurationsFolder { get; set; }
public string AppPropertiesFileName { get; set; }
}
}

View File

@ -0,0 +1,9 @@
using System.Windows.Media;
namespace Seyounth.Hyosung.UI.Models
{
public struct DataColor
{
public Brush Color { get; set; }
}
}

View File

@ -0,0 +1,6 @@
namespace Seyounth.Hyosung.UI.Resources
{
public partial class Translations
{
}
}

View File

@ -0,0 +1,59 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Seyounth.Hyosung.UI.Views.Pages;
using Seyounth.Hyosung.UI.Views.Windows;
using Wpf.Ui;
namespace Seyounth.Hyosung.UI.Services
{
/// <summary>
/// Managed host of the application.
/// </summary>
public class ApplicationHostService : IHostedService
{
private readonly IServiceProvider _serviceProvider;
private INavigationWindow _navigationWindow;
public ApplicationHostService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
/// <summary>
/// Triggered when the application host is ready to start the service.
/// </summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
public async Task StartAsync(CancellationToken cancellationToken)
{
await HandleActivationAsync();
}
/// <summary>
/// Triggered when the application host is performing a graceful shutdown.
/// </summary>
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
public async Task StopAsync(CancellationToken cancellationToken)
{
await Task.CompletedTask;
}
/// <summary>
/// Creates main window during activation.
/// </summary>
private async Task HandleActivationAsync()
{
if (!Application.Current.Windows.OfType<MainWindow>().Any())
{
_navigationWindow = (
_serviceProvider.GetService(typeof(INavigationWindow)) as INavigationWindow
)!;
_navigationWindow!.ShowWindow();
_navigationWindow.Navigate(typeof(Views.Pages.DashboardPage));
}
await Task.CompletedTask;
}
}
}

View File

@ -0,0 +1,42 @@
using Wpf.Ui;
namespace Seyounth.Hyosung.UI.Services
{
/// <summary>
/// Service that provides pages for navigation.
/// </summary>
public class PageService : IPageService
{
/// <summary>
/// Service which provides the instances of pages.
/// </summary>
private readonly IServiceProvider _serviceProvider;
/// <summary>
/// Creates new instance and attaches the <see cref="IServiceProvider"/>.
/// </summary>
public PageService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
/// <inheritdoc />
public T? GetPage<T>()
where T : class
{
if (!typeof(FrameworkElement).IsAssignableFrom(typeof(T)))
throw new InvalidOperationException("The page should be a WPF control.");
return (T?)_serviceProvider.GetService(typeof(T));
}
/// <inheritdoc />
public FrameworkElement? GetPage(Type pageType)
{
if (!typeof(FrameworkElement).IsAssignableFrom(pageType))
throw new InvalidOperationException("The page should be a WPF control.");
return _serviceProvider.GetService(pageType) as FrameworkElement;
}
}
}

View File

@ -0,0 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ApplicationIcon>wpfui-icon.ico</ApplicationIcon>
<UseWPF>true</UseWPF>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Content Include="wpfui-icon.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NLog.Extensions.Logging" Version="5.4.0" />
<PackageReference Include="WPF-UI" Version="3.0.4" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
</ItemGroup>
<ItemGroup>
<None Remove="Assets\wpfui-icon-256.png" />
<None Remove="Assets\wpfui-icon-1024.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Assets\agv.png" />
<Resource Include="Assets\wpfui-icon-256.png" />
<Resource Include="Assets\wpfui-icon-1024.png" />
<None Remove="Resources\1744195034778.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Seyounth.Hyosung.Runtime\Seyounth.Hyosung.Runtime.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,4 @@
global using CommunityToolkit.Mvvm.ComponentModel;
global using CommunityToolkit.Mvvm.Input;
global using System;
global using System.Windows;

View File

@ -0,0 +1,14 @@
using Wpf.Ui.Controls;
namespace Seyounth.Hyosung.UI.ViewModels.Pages;
public partial class AgvBinViewModel : ObservableObject, INavigationAware
{
public void OnNavigatedTo()
{
}
public void OnNavigatedFrom()
{
}
}

View File

@ -0,0 +1,100 @@
using System.Collections.ObjectModel;
using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Services;
using Seyounth.Hyosung.Runtime;
using Wpf.Ui;
using Wpf.Ui.Controls;
namespace Seyounth.Hyosung.UI.ViewModels.Pages
{
public partial class DashboardViewModel : ObservableObject, INavigationAware
{
[ObservableProperty] private ObservableCollection<Variety> _varieties;
[ObservableProperty] private Variety _selectedVariety;
[ObservableProperty] private List<string> _yarnCarTypes;
[ObservableProperty] private List<string> _yarnCarSideType;
[ObservableProperty] private int _selectedYarnCarTypeIndex;
[ObservableProperty] private int _selectedYarnCarSideTypeIndex;
private readonly IVarietyService _varietyService;
private readonly IPalletService _palletService;
private readonly ISnackbarService _snackbarService;
private readonly IHyosungRuntime _runtime;
public DashboardViewModel(IVarietyService varietyService, ISnackbarService snackbarService,
IHyosungRuntime runtime)
{
_runtime = runtime;
SelectedYarnCarTypeIndex = 0;
SelectedYarnCarSideTypeIndex = 0;
_varietyService = varietyService;
_snackbarService = snackbarService;
Varieties = new ObservableCollection<Variety>(varietyService.GetAll());
YarnCarTypes =
[
"A",
"B",
"C",
"D"
];
YarnCarSideType =
[
"正面",
"反面"
];
}
public void OnNavigatedTo()
{
Varieties = new ObservableCollection<Variety>(_varietyService.GetAll());
}
public void OnNavigatedFrom()
{
}
[RelayCommand]
private void OnChangeVariety()
{
try
{
SelectedVariety.YarnCarType = SelectedYarnCarTypeIndex + 1;
SelectedVariety.YarnCarSide = SelectedYarnCarSideTypeIndex + 1;
_runtime.SendVarietyToPlcAsync(SelectedVariety);
_snackbarService.Show("切换成功", $"当前产品为: {SelectedVariety.Name}", ControlAppearance.Success,
new SymbolIcon(SymbolRegular.ArrowCircleUp24), TimeSpan.FromSeconds(5));
}
catch (Exception e)
{
_snackbarService.Show("切换异常", e.Message, ControlAppearance.Danger,
new SymbolIcon(SymbolRegular.ArrowCircleUp24), TimeSpan.FromSeconds(5));
}
}
[RelayCommand]
private void OnChangeVarietyLastNo()
{
if (SelectedVariety.LastNo != null)
{
_varietyService.SetLastNo(SelectedVariety.Id, SelectedVariety.LastNo.Value);
_snackbarService.Show("保存成功", "当前控制号保存成功", ControlAppearance.Success,
new SymbolIcon(SymbolRegular.Save24), TimeSpan.FromSeconds(5));
}
else
{
_snackbarService.Show("保存失败", "当前控制号为空", ControlAppearance.Danger,
new SymbolIcon(SymbolRegular.Save24), TimeSpan.FromSeconds(5));
}
}
}
}

View File

@ -0,0 +1,100 @@
using System.Collections.ObjectModel;
using Seyounth.Hyosung.UI.Models;
using System.Windows.Media;
using CommunityToolkit.Mvvm.Messaging;
using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Services;
using Wpf.Ui.Controls;
namespace Seyounth.Hyosung.UI.ViewModels.Pages
{
public partial class DataViewModel : ObservableObject, INavigationAware
{
public class SavePalletCompletedMessage;
[ObservableProperty] private ObservableCollection<Variety> _varieties;
[ObservableProperty] private ObservableCollection<Pallet> _pallets;
[ObservableProperty] private ObservableCollection<Pallet> _honeyPallets = new();
[ObservableProperty] private ObservableCollection<Pallet> _paperPallets = new();
[ObservableProperty] private ObservableCollection<Pallet> _trays = new();
private readonly IVarietyService _varietyService;
private readonly IPalletService _palletService;
public DataViewModel(IVarietyService varietyService, IPalletService palletService)
{
_varietyService = varietyService;
_palletService = palletService;
}
public void OnNavigatedTo()
{
Pallets = new ObservableCollection<Pallet>(_palletService.GetPallets());
HoneyPallets = new ObservableCollection<Pallet>(Pallets.Where(p => p.Type == PalletType.Honey));
var papers = Pallets.Where(p => p.Type == PalletType.Paper).ToList();
papers.Add(new Pallet());
papers = papers.OrderBy(p => p.Length).ToList();
PaperPallets = new ObservableCollection<Pallet>(papers);
Trays = new ObservableCollection<Pallet>(Pallets.Where(p =>
p.Type is PalletType.Plywood or PalletType.Wood));
var varieties = _varietyService.GetAll().Select(v =>
{
// 匹配相同ID的托盘对象
v.TopAndBottomPallet = HoneyPallets.FirstOrDefault(p => p.Id == v.TopAndBottomPallet.Id);
v.MiddlePallet = HoneyPallets.FirstOrDefault(p => p.Id == v.MiddlePallet.Id);
v.Tray = Trays.FirstOrDefault(p => p.Id == v.Tray.Id);
v.PaperTray = v.PaperTray is null
? PaperPallets.First()
: PaperPallets.FirstOrDefault(p =>
p.Id == v.PaperTray.Id);
return v;
});
Varieties = new ObservableCollection<Variety>(varieties);
}
public void OnNavigatedFrom()
{
}
[RelayCommand]
private void AddVariety()
{
var variety = new Variety
{
/* 初始化默认值 */
};
Varieties.Add(variety);
}
[RelayCommand]
private void OnDeleteVariety(object obj)
{
if (obj is Variety variety)
{
Varieties.Remove(variety);
_varietyService.DeleteVarietyAsync(variety);
}
else
{
Console.Write("Object is not a variety");
}
}
[RelayCommand]
private async Task OnSaveVariety(object obj)
{
if (obj is Variety variety)
{
await _varietyService.AddVarietyAsync(variety);
//Pallets = new ObservableCollection<Pallet>(_palletService.GetPallets());
}
WeakReferenceMessenger.Default.Send(new SavePalletCompletedMessage());
}
}
}

View File

@ -0,0 +1,72 @@
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.Messaging;
using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Services;
using Wpf.Ui.Controls;
namespace Seyounth.Hyosung.UI.ViewModels.Pages;
public partial class PalletManagementViewModel : ObservableObject, INavigationAware
{
public class SavePalletCompletedMessage;
[ObservableProperty] private ObservableCollection<Pallet> _pallets = [];
private readonly IPalletService _palletService;
/// <inheritdoc/>
public PalletManagementViewModel(IPalletService palletService)
{
_palletService = palletService;
Pallets = new ObservableCollection<Pallet>(_palletService.GetPallets());
}
public void OnNavigatedTo()
{
Pallets = new ObservableCollection<Pallet>(_palletService.GetPallets());
}
public void OnNavigatedFrom()
{
}
[RelayCommand]
private void AddPallet()
{
var newPallet = new Pallet
{
/* 初始化默认值 */
};
Pallets.Add(newPallet);
}
[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)
{
var id = _palletService.AddPalletAsync(pallet).Result;
//Pallets = new ObservableCollection<Pallet>(_palletService.GetPallets());
}
else
_palletService.UpdatePalletAsync(pallet);
}
WeakReferenceMessenger.Default.Send(new SavePalletCompletedMessage());
}
}

View File

@ -0,0 +1,63 @@
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
namespace Seyounth.Hyosung.UI.ViewModels.Pages
{
public partial class SettingsViewModel : ObservableObject, INavigationAware
{
private bool _isInitialized = false;
[ObservableProperty]
private string _appVersion = String.Empty;
[ObservableProperty]
private ApplicationTheme _currentTheme = ApplicationTheme.Unknown;
public void OnNavigatedTo()
{
if (!_isInitialized)
InitializeViewModel();
}
public void OnNavigatedFrom() { }
private void InitializeViewModel()
{
CurrentTheme = ApplicationThemeManager.GetAppTheme();
AppVersion = $"UiDesktopApp1 - {GetAssemblyVersion()}";
_isInitialized = true;
}
private string GetAssemblyVersion()
{
return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString()
?? String.Empty;
}
[RelayCommand]
private void OnChangeTheme(string parameter)
{
switch (parameter)
{
case "theme_light":
if (CurrentTheme == ApplicationTheme.Light)
break;
ApplicationThemeManager.Apply(ApplicationTheme.Light);
CurrentTheme = ApplicationTheme.Light;
break;
default:
if (CurrentTheme == ApplicationTheme.Dark)
break;
ApplicationThemeManager.Apply(ApplicationTheme.Dark);
CurrentTheme = ApplicationTheme.Dark;
break;
}
}
}
}

View File

@ -0,0 +1,65 @@
using System.Collections.ObjectModel;
using Wpf.Ui.Controls;
namespace Seyounth.Hyosung.UI.ViewModels.Windows
{
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty] private string _applicationTitle = "WPF UI - Seyounth.Hyosung.UI";
[ObservableProperty] private ObservableCollection<object> _menuItems = new()
{
new NavigationViewItem()
{
Content = "主页",
Icon = new SymbolIcon { Symbol = SymbolRegular.Home24 },
TargetPageType = typeof(Views.Pages.DashboardPage)
},
new NavigationViewItem()
{
Content = "产品管理",
Icon = new SymbolIcon { Symbol = SymbolRegular.Production24 },
TargetPageType = typeof(Views.Pages.DataPage)
},
new NavigationViewItem()
{
Content = "辅料管理",
Icon = new SymbolIcon { Symbol = SymbolRegular.Production24 },
TargetPageType = typeof(Views.Pages.PalletManagementPage)
},
new NavigationViewItem()
{
Content = "标签管理",
Icon = new SymbolIcon { Symbol = SymbolRegular.Print24 },
TargetPageType = typeof(Views.Pages.DataPage)
},
new NavigationViewItem()
{
Content = "入库管理",
Icon = new SymbolIcon { Symbol = SymbolRegular.DataHistogram24 },
TargetPageType = typeof(Views.Pages.DataPage)
},
new NavigationViewItem()
{
Content = "AGV库位管理",
Icon = new SymbolIcon { Symbol = SymbolRegular.DataHistogram24 },
TargetPageType = typeof(Views.Pages.AgvBinPage)
}
};
[ObservableProperty] private ObservableCollection<object> _footerMenuItems = new()
{
new NavigationViewItem()
{
Content = "Settings",
Icon = new SymbolIcon { Symbol = SymbolRegular.Settings24 },
TargetPageType = typeof(Views.Pages.SettingsPage)
}
};
[ObservableProperty] private ObservableCollection<MenuItem> _trayMenuItems = new()
{
new MenuItem { Header = "Home", Tag = "tray_home" }
};
}
}

View File

@ -0,0 +1,20 @@
<Page x:Class="Seyounth.Hyosung.UI.Views.Pages.AgvBinPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Seyounth.Hyosung.UI.Views.Pages"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
d:DataContext="{d:DesignInstance local:AgvBinPage,
IsDesignTimeCreatable=False}"
d:DesignHeight="800"
d:DesignWidth="1200"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
mc:Ignorable="d">
<!-- 更多线路 -->
<Page.Background>
<ImageBrush ImageSource="pack://application:,,,/Assets/agv.png"/>
</Page.Background>
</Page>

View File

@ -0,0 +1,16 @@
using System.Windows.Controls;
using Seyounth.Hyosung.UI.ViewModels.Pages;
namespace Seyounth.Hyosung.UI.Views.Pages;
public partial class AgvBinPage : Page
{
public AgvBinViewModel ViewModel { get; }
public AgvBinPage(AgvBinViewModel viewModel)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
}
}

View File

@ -0,0 +1,102 @@
<Page
x:Class="Seyounth.Hyosung.UI.Views.Pages.DashboardPage"
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:local="clr-namespace:Seyounth.Hyosung.UI.Views.Pages"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="生产看板"
d:DataContext="{d:DesignInstance local:DashboardPage,
IsDesignTimeCreatable=False}"
d:DesignHeight="800"
d:DesignWidth="1200"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
mc:Ignorable="d">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ui:CardControl Header="自动发行标签" Margin="0,20,10,20">
<ui:ToggleSwitch></ui:ToggleSwitch>
</ui:CardControl>
<ui:CardControl Grid.Column="1" Header="自动入库" Margin="10,20,10,20">
<ui:ToggleSwitch></ui:ToggleSwitch>
</ui:CardControl>
<ui:CardControl Grid.Column="2" Margin="10,20,0,20">
<ui:ToggleSwitch></ui:ToggleSwitch>
</ui:CardControl>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Vertical"
VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True">
<Border
Padding="16"
Background="{ui:ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ui:ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1,1,1,0"
CornerRadius="8,8,0,0">
<ui:TextBlock FontTypography="Subtitle" Text="产品设置" />
</Border>
<ui:CardControl CornerRadius="0,0,0,0" Header="产品ID">
<ComboBox Margin="0,0,10,0" Width="400"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.CanContentScroll="True"
ItemsSource="{Binding ViewModel.Varieties}"
SelectedItem="{Binding ViewModel.SelectedVariety, Mode=TwoWay}"
DisplayMemberPath="Name" />
</ui:CardControl>
<ui:CardControl CornerRadius="0,0,0,0" Header="纱车类型">
<ComboBox
SelectedIndex="{Binding ViewModel.SelectedYarnCarTypeIndex,Mode=TwoWay}"
ItemsSource="{Binding ViewModel.YarnCarTypes}" Margin="0,0,10,0" Width="400" />
</ui:CardControl>
<ui:CardControl CornerRadius="0,0,0,0" Header="纱车正反面">
<ComboBox
SelectedIndex="{Binding ViewModel.SelectedYarnCarSideTypeIndex,Mode=TwoWay}"
ItemsSource="{Binding ViewModel.YarnCarSideType}" Margin="0,0,10,0" Width="400" />
</ui:CardControl>
<ui:CardControl CornerRadius="0,0,0,0" Header="上一个的控制号">
<StackPanel Orientation="Horizontal">
<TextBox Margin="0,0,10,0" Width="348"
Text="{Binding ViewModel.SelectedVariety.LastNo,Mode=TwoWay}" />
<ui:Button Content="更改" Command="{Binding ViewModel.ChangeVarietyLastNoCommand}"></ui:Button>
</StackPanel>
</ui:CardControl>
<ui:CardControl CornerRadius="0,0,0,0" Header="产品编码">
<TextBlock Margin="0,0,10,0" Text="{Binding ViewModel.SelectedVariety.Code}" />
</ui:CardControl>
<ui:CardControl CornerRadius="0,0,0,0" Header="Lot">
<TextBlock Margin="0,0,10,0" Text="{Binding ViewModel.SelectedVariety.Lot}" />
</ui:CardControl>
<ui:CardControl CornerRadius="0,0,0,0" Header="码垛层数">
<TextBlock Margin="0,0,10,0" Text="{Binding ViewModel.SelectedVariety.StackingLayers}" />
</ui:CardControl>
<ui:CardControl CornerRadius="0,0,0,0" Header="总数">
<TextBlock Margin="0,0,10,0" Text="{Binding ViewModel.SelectedVariety.TotalCount}" />
</ui:CardControl>
<ui:CardControl CornerRadius="0,0,8,8" Header="切换">
<ui:Button Command="{Binding ViewModel.ChangeVarietyCommand}"
Appearance="Primary" Content="切换"
Margin="0,0,10,0" Width="80" />
</ui:CardControl>
</StackPanel>
</Grid>
</Grid>
</Page>

View File

@ -0,0 +1,19 @@
using Seyounth.Hyosung.UI.ViewModels.Pages;
using Wpf.Ui.Controls;
namespace Seyounth.Hyosung.UI.Views.Pages
{
public partial class DashboardPage : INavigableView<DashboardViewModel>
{
public DashboardViewModel ViewModel { get; }
public DashboardPage(DashboardViewModel viewModel)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
}
}
}

View File

@ -0,0 +1,262 @@
<Page
x:Class="Seyounth.Hyosung.UI.Views.Pages.DataPage"
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:local="clr-namespace:Seyounth.Hyosung.UI.Views.Pages"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:helpers="clr-namespace:Seyounth.Hyosung.UI.Helpers"
xmlns:models1="clr-namespace:Seyounth.Hyosung.Data.Models;assembly=Seyounth.Hyosung.Data"
x:Name="VarietyPage"
Title="DataPage"
d:DataContext="{d:DesignInstance local:DataPage,
IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
ScrollViewer.CanContentScroll="False"
mc:Ignorable="d">
<Page.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<helpers:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Menu Grid.Row="0">
<ui:MenuItem Header="新增" Command="{Binding ViewModel.AddVarietyCommand}" Icon="{ui:SymbolIcon Add24}" />
</Menu>
<ui:DataGrid x:Name="VarietyDataGrid" Margin="0,0,0,20" AutoGenerateColumns="False"
HeadersVisibility="All"
VerticalContentAlignment="Center"
CanUserAddRows="False"
EnableRowVirtualization="True"
EnableColumnVirtualization="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.CanContentScroll="True"
AddingNewItem="VarietyDataGrid_AddingNewItem"
CellEditEnding="VarietyDataGrid_CellEditEnding"
ItemsSource="{Binding ViewModel.Varieties, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="1">
<ui:DataGrid.Columns>
<DataGridTextColumn Header="编号"
Binding="{Binding Id}" />
<DataGridTextColumn Width="200" Header="产品编码" Binding="{Binding Code}" />
<DataGridTextColumn Width="60" Header="Lot" Binding="{Binding Lot}" />
<DataGridTextColumn Width="60" Header="规格" Binding="{Binding Specifications}" />
<DataGridTextColumn
Binding="{Binding InnerDiameter }"
Header="内径(D1)"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding OuterDiameter }"
Header="外径(D2)"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding YarnDiameter }"
Header="直径(D3)"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding PaperTubeHeight }"
Header="纸管高(H1)"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding YarnThickness }"
Header="纱线厚(H2)"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding SingleWeight }"
Header="单筒重"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding StackingLayers }"
Header="码层数"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding TotalCount }"
Header="个/托"
Width="Auto" />
<DataGridTemplateColumn Width="180" Header="蜂窝板(中间)">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectionChanged="ComboBox_SelectionChanged"
SelectedItem="{Binding MiddlePallet, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=ViewModel.HoneyPallets,RelativeSource={RelativeSource AncestorType={x:Type Page},Mode=FindAncestor}}"
DisplayMemberPath="Name">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="180" Header="蜂窝板(上下)">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectionChanged="ComboBox_SelectionChanged"
SelectedItem="{Binding TopAndBottomPallet, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=ViewModel.HoneyPallets,RelativeSource={RelativeSource AncestorType={x:Type Page},Mode=FindAncestor}}"
DisplayMemberPath="Name">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="180" Header="底托">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectionChanged="ComboBox_SelectionChanged"
SelectedItem="{Binding Tray, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=ViewModel.Trays,RelativeSource={RelativeSource AncestorType={x:Type Page},Mode=FindAncestor}}"
DisplayMemberPath="Name">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="180" Header="隔板">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectionChanged="ComboBox_SelectionChanged"
SelectedItem="{Binding PaperTray, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=ViewModel.PaperPallets,RelativeSource={RelativeSource AncestorType={x:Type Page},Mode=FindAncestor}}"
DisplayMemberPath="Name">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
Binding="{Binding StackHeadSpec }"
Header="垛头尺寸"
Width="120" />
<DataGridTextColumn
Binding="{Binding StackHeadCount }"
Header="垛头数量"
Width="80" />
<DataGridCheckBoxColumn Header="套箱" Binding="{Binding HasBox}" />
<DataGridTemplateColumn Width="120" Header="顶板">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectionChanged="ComboBox_SelectionChanged"
SelectedItem="{Binding NeedTopBoard, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models1:NeedType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="120" Header="护角">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectionChanged="ComboBox_SelectionChanged"
SelectedItem="{Binding NeedAngleBeam, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models1:NeedType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="120" Header="打带">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectionChanged="ComboBox_SelectionChanged"
SelectedItem="{Binding NeedPackStrap, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models1:NeedType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="120" Header="缠膜">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectionChanged="ComboBox_SelectionChanged"
SelectedItem="{Binding NeedFilmWrapping, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models1:NeedType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="120" Header="覆膜">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
SelectionChanged="ComboBox_SelectionChanged"
SelectedItem="{Binding NeedFilmCoating, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models1:NeedType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
Binding="{Binding MasterLabelCount }"
Header="主标签数量"
Width="Auto" />
<DataGridTextColumn
Binding="{Binding SubLabelCount }"
Header="副标签数量"
Width="Auto" />
<DataGridTextColumn Header="毛重"
Binding="{Binding GrossWeight}" />
<DataGridTextColumn Header="净重"
Binding="{Binding NetWeight}" />
<DataGridTextColumn Header="控制号"
Binding="{Binding LastNo}" />
<DataGridTemplateColumn Header="操作">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ui:Button Appearance="Primary" VerticalAlignment="Center" Margin="10,0,10,0"
Content="保存"
Command="{Binding ElementName=VarietyPage, Path=DataContext.ViewModel.SaveVarietyCommand}"
CommandParameter="{Binding}"
Visibility="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Path=IsEditing, Converter={StaticResource BooleanToVisibilityConverter}}" />
<!-- 删除按钮 -->
<ui:Button VerticalAlignment="Center" Content="删除" Margin="10,0,10,0"
Command="{Binding ElementName=VarietyPage, Path=DataContext.ViewModel.DeleteVarietyCommand}"
CommandParameter="{Binding}" />
<!-- 保存按钮,根据 DataGridRow 的 IsEditing 属性控制可见性 -->
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</ui:DataGrid.Columns>
</ui:DataGrid>
</Grid>
</Page>

View File

@ -0,0 +1,80 @@
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.Messaging;
using Seyounth.Hyosung.UI.ViewModels.Pages;
using Wpf.Ui.Controls;
using DataGrid = System.Windows.Controls.DataGrid;
using TextBox = System.Windows.Controls.TextBox;
namespace Seyounth.Hyosung.UI.Views.Pages
{
public partial class DataPage : INavigableView<DataViewModel>
{
public DataViewModel ViewModel { get; }
public DataPage(DataViewModel viewModel)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
WeakReferenceMessenger.Default.Register<PalletManagementViewModel.SavePalletCompletedMessage>(this, (r, m) =>
{
// 提交当前编辑并取消编辑模式
VarietyDataGrid.CommitEdit();
VarietyDataGrid.CancelEdit();
});
}
private void VarietyDataGrid_AddingNewItem(object? sender, AddingNewItemEventArgs e)
{
Dispatcher.BeginInvoke(new Action(() =>
{
if (VarietyDataGrid.Items.Count == 0) return;
var lastIndex = VarietyDataGrid.Items.Count - 1;
VarietyDataGrid.ScrollIntoView(VarietyDataGrid.Items[lastIndex]);
VarietyDataGrid.SelectedIndex = lastIndex;
if (VarietyDataGrid.ItemContainerGenerator.ContainerFromIndex(lastIndex) is not DataGridRow row) return;
row.Focus();
VarietyDataGrid.CurrentColumn = VarietyDataGrid.Columns[0];
VarietyDataGrid.BeginEdit();
}), DispatcherPriority.ContextIdle);
}
private void VarietyDataGrid_CellEditEnding(object? sender, DataGridCellEditEndingEventArgs e)
{
if (e.EditAction == DataGridEditAction.Commit)
{
var binding = e.EditingElement.GetBindingExpression(TextBox.TextProperty);
binding?.UpdateSource();
}
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is ComboBox comboBox)
{
// 获取所在DataGrid行
var dataGridRow = FindVisualParent<DataGridRow>(comboBox);
var dataGrid = FindVisualParent<DataGrid>(comboBox);
if (dataGrid != null && dataGridRow != null && !dataGridRow.IsEditing)
{
dataGrid.CurrentItem = dataGridRow.Item;
dataGrid.BeginEdit();
}
}
}
private static T FindVisualParent<T>(DependencyObject child) where T : DependencyObject
{
while (child != null && child is not T)
{
child = VisualTreeHelper.GetParent(child);
}
return child as T;
}
}
}

View File

@ -0,0 +1,87 @@
<Page x:Class="Seyounth.Hyosung.UI.Views.Pages.PalletManagementPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Seyounth.Hyosung.UI.Views.Pages"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:models="clr-namespace:Seyounth.Hyosung.Data.Models;assembly=Seyounth.Hyosung.Data"
xmlns:helpers="clr-namespace:Seyounth.Hyosung.UI.Helpers"
mc:Ignorable="d"
x:Name="PalletPage"
Title="PalletManagementPage"
d:DataContext="{d:DesignInstance local:PalletManagementPage,
IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
ScrollViewer.CanContentScroll="False">
<Page.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<helpers:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Menu>
<ui:MenuItem Command="{Binding ViewModel.AddPalletCommand }" Header="新增" Icon="{ui:SymbolIcon Add24}" />
</Menu>
<ui:DataGrid x:Name="PalletsDataGrid" Margin="0,0,0,20" AutoGenerateColumns="False"
HeadersVisibility="All"
VerticalContentAlignment="Center"
CanUserAddRows="False"
AddingNewItem="PalletsDataGrid_AddingNewItem"
CellEditEnding="PalletDataGrid_CellEditEnding"
ItemsSource="{Binding ViewModel.Pallets, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="1">
<ui:DataGrid.Columns>
<DataGridTextColumn IsReadOnly="True" Header="编号(Id)"
Binding="{Binding Id}" />
<DataGridTemplateColumn Width="120" Header="托盘类型(Type)">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding Type, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectionChanged="ComboBox_SelectionChanged"
ItemsSource="{Binding Source={helpers:EnumBindingSource {x:Type models:PalletType}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ., Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Width="120" Header="长度(Length)" Binding="{Binding Length}" />
<DataGridTextColumn Width="120" Header="宽度(Width)" Binding="{Binding Width}" />
<DataGridTextColumn Width="120" Header="高度(Height)" Binding="{Binding Height}" />
<DataGridCheckBoxColumn Header="大孔(BigHole)" Binding="{Binding IsBigHole}" />
<DataGridTextColumn Width="120" Header="孔数(HoleCount)" Binding="{Binding HoleCount}" />
<DataGridTemplateColumn Header="操作">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ui:Button Appearance="Primary" VerticalAlignment="Center" Margin="10,0,10,0"
Content="保存"
Command="{Binding ElementName=PalletPage, Path=DataContext.ViewModel.SavePalletCommand}"
CommandParameter="{Binding}"
Visibility="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Path=IsEditing, Converter={StaticResource BooleanToVisibilityConverter}}" />
<!-- 删除按钮 -->
<ui:Button VerticalAlignment="Center" Content="删除" Margin="10,0,10,0"
Command="{Binding ElementName=PalletPage, Path=DataContext.ViewModel.DeletePalletCommand}"
CommandParameter="{Binding}" />
<!-- 保存按钮,根据 DataGridRow 的 IsEditing 属性控制可见性 -->
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</ui:DataGrid.Columns>
</ui:DataGrid>
</Grid>
</Page>

View File

@ -0,0 +1,83 @@
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.Messaging;
using Seyounth.Hyosung.UI.ViewModels.Pages;
namespace Seyounth.Hyosung.UI.Views.Pages;
public partial class PalletManagementPage : Page
{
public PalletManagementViewModel ViewModel { get; }
public PalletManagementPage(PalletManagementViewModel viewModel)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
WeakReferenceMessenger.Default.Register<PalletManagementViewModel.SavePalletCompletedMessage>(this, (r, m) =>
{
// 提交当前编辑并取消编辑模式
PalletsDataGrid.CommitEdit();
PalletsDataGrid.CancelEdit();
});
}
private void PalletsDataGrid_AddingNewItem(object sender, AddingNewItemEventArgs e)
{
// 确保新项已添加到集合
Dispatcher.BeginInvoke(new Action(() =>
{
if (PalletsDataGrid.Items.Count == 0) return;
var lastIndex = PalletsDataGrid.Items.Count - 1;
PalletsDataGrid.ScrollIntoView(PalletsDataGrid.Items[lastIndex]);
PalletsDataGrid.SelectedIndex = lastIndex;
if (PalletsDataGrid.ItemContainerGenerator.ContainerFromIndex(lastIndex) is not DataGridRow row) return;
row.Focus();
PalletsDataGrid.CurrentColumn = PalletsDataGrid.Columns[0];
PalletsDataGrid.BeginEdit();
}), DispatcherPriority.ContextIdle);
}
// private void PalletDataGrid_RowEditEnding(object? sender, DataGridRowEditEndingEventArgs e)
// {
// if (e.EditAction != DataGridEditAction.Commit) return;
// var dataGrid = (DataGrid)sender;
// dataGrid.CommitEdit(DataGridEditingUnit.Row, true);
// }
private void PalletDataGrid_CellEditEnding(object? sender, DataGridCellEditEndingEventArgs e)
{
if (e.EditAction == DataGridEditAction.Commit)
{
var binding = e.EditingElement.GetBindingExpression(TextBox.TextProperty);
binding?.UpdateSource();
}
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is ComboBox comboBox)
{
// 获取所在DataGrid行
var dataGridRow = FindVisualParent<DataGridRow>(comboBox);
var dataGrid = FindVisualParent<DataGrid>(comboBox);
if (dataGrid != null && dataGridRow != null && !dataGridRow.IsEditing)
{
dataGrid.CurrentItem = dataGridRow.Item;
dataGrid.BeginEdit();
}
}
}
private static T FindVisualParent<T>(DependencyObject child) where T : DependencyObject
{
while (child != null && child is not T)
{
child = VisualTreeHelper.GetParent(child);
}
return child as T;
}
}

View File

@ -0,0 +1,51 @@
<Page
x:Class="Seyounth.Hyosung.UI.Views.Pages.SettingsPage"
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:helpers="clr-namespace:Seyounth.Hyosung.UI.Helpers"
xmlns:local="clr-namespace:Seyounth.Hyosung.UI.Views.Pages"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="SettingsPage"
d:DataContext="{d:DesignInstance local:SettingsPage,
IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
mc:Ignorable="d">
<Page.Resources>
<helpers:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</Page.Resources>
<StackPanel>
<TextBlock
FontSize="20"
FontWeight="Medium"
Text="Personalization" />
<TextBlock Margin="0,12,0,0" Text="Theme" />
<RadioButton
Margin="0,12,0,0"
Command="{Binding ViewModel.ChangeThemeCommand, Mode=OneWay}"
CommandParameter="theme_light"
Content="Light"
GroupName="themeSelect"
IsChecked="{Binding ViewModel.CurrentTheme, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Light, Mode=OneWay}" />
<RadioButton
Margin="0,8,0,0"
Command="{Binding ViewModel.ChangeThemeCommand, Mode=OneWay}"
CommandParameter="theme_dark"
Content="Dark"
GroupName="themeSelect"
IsChecked="{Binding ViewModel.CurrentTheme, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Dark, Mode=OneWay}" />
<TextBlock
Margin="0,24,0,0"
FontSize="20"
FontWeight="Medium"
Text="About Seyounth.Hyosung.UI" />
<TextBlock Margin="0,12,0,0" Text="{Binding ViewModel.AppVersion, Mode=OneWay}" />
</StackPanel>
</Page>

View File

@ -0,0 +1,18 @@
using Seyounth.Hyosung.UI.ViewModels.Pages;
using Wpf.Ui.Controls;
namespace Seyounth.Hyosung.UI.Views.Pages
{
public partial class SettingsPage : INavigableView<SettingsViewModel>
{
public SettingsViewModel ViewModel { get; }
public SettingsPage(SettingsViewModel viewModel)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
}
}
}

View File

@ -0,0 +1,13 @@
<ui:FluentWindow x:Class="Seyounth.Hyosung.UI.Views.Windows.AddOrUpdatePalletWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Seyounth.Hyosung.UI.Views.Windows"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
mc:Ignorable="d"
Title="" Height="450" Width="800">
<Grid>
</Grid>
</ui:FluentWindow>

View File

@ -0,0 +1,9 @@
namespace Seyounth.Hyosung.UI.Views.Windows;
public partial class AddOrUpdatePalletWindow
{
public AddOrUpdatePalletWindow()
{
InitializeComponent();
}
}

View File

@ -0,0 +1,65 @@
<ui:FluentWindow
x:Class="Seyounth.Hyosung.UI.Views.Windows.MainWindow"
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:local="clr-namespace:Seyounth.Hyosung.UI.Views.Windows"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="{Binding ViewModel.ApplicationTitle, Mode=OneWay}"
Width="1100"
Height="650"
d:DataContext="{d:DesignInstance local:MainWindow,
IsDesignTimeCreatable=True}"
d:DesignHeight="450"
d:DesignWidth="800"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
ExtendsContentIntoTitleBar="True"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
WindowBackdropType="Mica"
WindowCornerPreference="Round"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ui:NavigationView
x:Name="RootNavigation"
Grid.Row="1"
Padding="42,0,42,0"
BreadcrumbBar="{Binding ElementName=BreadcrumbBar}"
FooterMenuItemsSource="{Binding ViewModel.FooterMenuItems, Mode=OneWay}"
FrameMargin="0"
IsBackButtonVisible="Visible"
IsPaneToggleVisible="True"
MenuItemsSource="{Binding ViewModel.MenuItems, Mode=OneWay}"
PaneDisplayMode="Left">
<ui:NavigationView.Header>
<ui:BreadcrumbBar x:Name="BreadcrumbBar" Margin="42,32,42,20" />
</ui:NavigationView.Header>
<ui:NavigationView.ContentOverlay>
<Grid>
<ui:SnackbarPresenter x:Name="SnackbarPresenter" />
</Grid>
</ui:NavigationView.ContentOverlay>
</ui:NavigationView>
<ContentPresenter
x:Name="RootContentDialog"
Grid.Row="0"
Grid.RowSpan="2" />
<ui:TitleBar
x:Name="TitleBar"
Title="{Binding ViewModel.ApplicationTitle}"
Grid.Row="0"
CloseWindowByDoubleClickOnIcon="True">
<ui:TitleBar.Icon>
<ui:ImageIcon Source="pack://application:,,,/Assets/wpfui-icon-256.png" />
</ui:TitleBar.Icon>
</ui:TitleBar>
</Grid>
</ui:FluentWindow>

View File

@ -0,0 +1,65 @@
using Seyounth.Hyosung.UI.ViewModels.Windows;
using Wpf.Ui;
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
namespace Seyounth.Hyosung.UI.Views.Windows
{
public partial class MainWindow : INavigationWindow
{
public MainWindowViewModel ViewModel { get; }
public MainWindow(
MainWindowViewModel viewModel,
IPageService pageService,
ISnackbarService snackbarService,
INavigationService navigationService
)
{
ViewModel = viewModel;
DataContext = this;
SystemThemeWatcher.Watch(this);
InitializeComponent();
SetPageService(pageService);
snackbarService.SetSnackbarPresenter(SnackbarPresenter);
navigationService.SetNavigationControl(RootNavigation);
}
#region INavigationWindow methods
public INavigationView GetNavigation() => RootNavigation;
public bool Navigate(Type pageType) => RootNavigation.Navigate(pageType);
public void SetPageService(IPageService pageService) => RootNavigation.SetPageService(pageService);
public void ShowWindow() => Show();
public void CloseWindow() => Close();
#endregion INavigationWindow methods
/// <summary>
/// Raises the closed event.
/// </summary>
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
// Make sure that closing this window will begin the process of closing the application.
Application.Current.Shutdown();
}
INavigationView INavigationWindow.GetNavigation()
{
throw new NotImplementedException();
}
public void SetServiceProvider(IServiceProvider serviceProvider)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="Seyounth.Hyosung.UI.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel element will disable file and registry virtualization.
Remove this element if your application requires this virtualization for backwards
compatibility.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on
and is designed to work with. Uncomment the appropriate elements
and Windows will automatically select the most compatible environment. -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config.
Makes the application long-path aware. See https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*" />
</dependentAssembly>
</dependency>
</assembly>

View File

@ -0,0 +1,5 @@
{
"ConnectionStrings": {
"DefaultConnection": "server=DESKTOP-AJ6K895;database=seyounth.hyosung;Trusted_Connection=SSPI;Encrypt=True;TrustServerCertificate=True;"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,20 +1,27 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seyounth.Hyosung.Core", "Seyounth.Hyosung.Core\Seyounth.Hyosung.Core.csproj", "{B6FCBC79-2C82-4915-BE52-16F4F22F2650}"
# Visual Studio Version 17
VisualStudioVersion = 17.8.34316.72
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seyounth.Hyosung.Core", "Seyounth.Hyosung.Core\Seyounth.Hyosung.Core.csproj", "{B6FCBC79-2C82-4915-BE52-16F4F22F2650}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seyounth.Hyosung.Data", "Seyounth.Hyosung.Data\Seyounth.Hyosung.Data.csproj", "{BC51516E-38D1-482C-913B-CE8F514CF978}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seyounth.Hyosung.Data", "Seyounth.Hyosung.Data\Seyounth.Hyosung.Data.csproj", "{BC51516E-38D1-482C-913B-CE8F514CF978}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seyounth.Hyosung.Runtime", "Seyounth.Hyosung.Runtime\Seyounth.Hyosung.Runtime.csproj", "{CB32CBA4-8760-490A-8E48-91CB10AD3965}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seyounth.Hyosung.Runtime", "Seyounth.Hyosung.Runtime\Seyounth.Hyosung.Runtime.csproj", "{CB32CBA4-8760-490A-8E48-91CB10AD3965}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seyounth.Core", "Seyounth.Core\Seyounth.Core.csproj", "{BC139001-2C26-4E95-982F-DA90DC0CFB4A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seyounth.Core", "Seyounth.Core\Seyounth.Core.csproj", "{BC139001-2C26-4E95-982F-DA90DC0CFB4A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tester", "Tester", "{F94CF5F9-01E3-4159-BC91-1EC9D8112837}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HyosungDataTester", "HyosungDataTester\HyosungDataTester.csproj", "{6D6BC0D1-1460-42A7-8A47-81B22B2C7A07}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HyosungDataTester", "HyosungDataTester\HyosungDataTester.csproj", "{6D6BC0D1-1460-42A7-8A47-81B22B2C7A07}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HyosungTester", "HyosungTester\HyosungTester.csproj", "{95193F01-653D-4664-84F3-1956994703D6}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HyosungTester", "HyosungTester\HyosungTester.csproj", "{95193F01-653D-4664-84F3-1956994703D6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seyounth.Hyosung", "Seyounth.Hyosung\Seyounth.Hyosung.csproj", "{16C5CC9B-FEA9-4B1E-805F-C6DBF5865DC0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seyounth.Hyosung", "Seyounth.Hyosung\Seyounth.Hyosung.csproj", "{16C5CC9B-FEA9-4B1E-805F-C6DBF5865DC0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seyounth.Hyosung.UI", "Seyounth.Hyosung.UI\Seyounth.Hyosung.UI.csproj", "{C4C7C083-6AE5-4DFE-8798-70E1E62C558C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seyounth.Hyosung.Ava", "Seyounth.Hyosung.Ava\Seyounth.Hyosung.Ava.csproj", "{E09FBD1D-CFFD-4E60-94BD-87890AA199A8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -50,6 +57,17 @@ Global
{16C5CC9B-FEA9-4B1E-805F-C6DBF5865DC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16C5CC9B-FEA9-4B1E-805F-C6DBF5865DC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16C5CC9B-FEA9-4B1E-805F-C6DBF5865DC0}.Release|Any CPU.Build.0 = Release|Any CPU
{C4C7C083-6AE5-4DFE-8798-70E1E62C558C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4C7C083-6AE5-4DFE-8798-70E1E62C558C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4C7C083-6AE5-4DFE-8798-70E1E62C558C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4C7C083-6AE5-4DFE-8798-70E1E62C558C}.Release|Any CPU.Build.0 = Release|Any CPU
{E09FBD1D-CFFD-4E60-94BD-87890AA199A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E09FBD1D-CFFD-4E60-94BD-87890AA199A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E09FBD1D-CFFD-4E60-94BD-87890AA199A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E09FBD1D-CFFD-4E60-94BD-87890AA199A8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{6D6BC0D1-1460-42A7-8A47-81B22B2C7A07} = {F94CF5F9-01E3-4159-BC91-1EC9D8112837}

View File

@ -1,21 +1,134 @@
<Application x:Class="Seyounth.Hyosung.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Seyounth.Hyosung"
xmlns:ui="https://opensource.panuon.com/wpf-ui"
DispatcherUnhandledException="OnDispatcherUnhandledException"
Exit="OnExit"
Startup="OnStartup">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.dark.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
<ResourceDictionary>
<ui:MessageBoxXSettings x:Key="messageSetting">
<ui:MessageBoxXSettings.WindowXStyle>
<Style TargetType="ui:WindowX"
BasedOn="{StaticResource {x:Static ui:MessageBoxX.WindowXStyleKey}}">
<Setter Property="SizeToContent"
Value="Manual" />
<Setter Property="Width"
Value="400" />
<Setter Property="Height"
Value="200" />
<Setter Property="Background"
Value="{DynamicResource WindowBackground}" />
<Setter Property="Foreground"
Value="{DynamicResource BodyForeground}" />
</Style>
</ui:MessageBoxXSettings.WindowXStyle>
<ui:MessageBoxXSettings.ButtonStyle>
<Style TargetType="Button"
BasedOn="{StaticResource {x:Static ui:MessageBoxX.ButtonStyleKey}}">
<Setter Property="ui:ButtonHelper.CornerRadius"
Value="4" />
<Style.Triggers>
<Trigger Property="IsDefault"
Value="True">
<Setter Property="Foreground"
Value="#FFFFFF" />
<Setter Property="Background"
Value="#80BEE8" />
</Trigger>
</Style.Triggers>
</Style>
</ui:MessageBoxXSettings.ButtonStyle>
</ui:MessageBoxXSettings>
<ui:NoticeBoxSettings x:Key="noticeSetting"
Position="TopRight">
<ui:NoticeBoxSettings.NoticeBoxItemStyle>
<Style TargetType="ui:NoticeBoxItem"
BasedOn="{StaticResource {x:Static ui:NoticeBox.NoticeBoxItemStyleKey}}">
<Setter Property="Background"
Value="{DynamicResource WindowBackground}" />
<Setter Property="BorderBrush"
Value="#4E4E4E" />
<Setter Property="Foreground"
Value="{DynamicResource BodyForeground}" />
</Style>
</ui:NoticeBoxSettings.NoticeBoxItemStyle>
</ui:NoticeBoxSettings>
<ui:PendingBoxSettings x:Key="pendingSetting">
<ui:PendingBoxSettings.WindowStyle>
<Style BasedOn="{StaticResource {x:Static ui:PendingBox.WindowStyleKey}}"
TargetType="Window">
<Setter Property="SizeToContent"
Value="Manual" />
<Setter Property="Width"
Value="400" />
<Setter Property="Height"
Value="200" />
<Setter Property="Background"
Value="{DynamicResource WindowBackground}" />
<Setter Property="Foreground"
Value="{DynamicResource BodyForeground}" />
</Style>
</ui:PendingBoxSettings.WindowStyle>
<ui:PendingBoxSettings.SpinStyle>
<Style BasedOn="{StaticResource {x:Static ui:PendingBox.SpinStyleKey}}"
TargetType="ui:Spin">
<Setter Property="SpinStyle"
Value="Ring2" />
<Setter Property="GlyphBrush"
Value="#6CBCEA" />
</Style>
</ui:PendingBoxSettings.SpinStyle>
<ui:PendingBoxSettings.CancelButtonStyle>
<!--Attention : CancelButtonStyle in PendingBox does not support Helpers in PanuonUI-->
<Style BasedOn="{StaticResource {x:Static ui:PendingBox.CancelButtonStyleKey}}"
TargetType="Button">
<Setter Property="Background"
Value="#6CBCEA" />
<Setter Property="Foreground"
Value="White" />
<Setter Property="Height"
Value="30" />
<Style.Triggers>
<Trigger Property="IsPressed"
Value="True">
<Setter Property="Background"
Value="#6CABEA" />
</Trigger>
</Style.Triggers>
</Style>
</ui:PendingBoxSettings.CancelButtonStyle>
</ui:PendingBoxSettings>
<ui:ToastSettings x:Key="toastSetting"
Spacing="25">
<ui:ToastSettings.LabelStyle>
<Style TargetType="Label"
BasedOn="{StaticResource {x:Static ui:Toast.LabelStyleKey}}">
<Setter Property="Background"
Value="{DynamicResource ToastBackground}" />
<Setter Property="Foreground"
Value="{DynamicResource ToastForeground}" />
</Style>
</ui:ToastSettings.LabelStyle>
</ui:ToastSettings>
<ui:GlobalSettings x:Key="settings">
<ui:GlobalSettings.Themes>
<ui:ApplicationTheme Key="Light"
ResourceDictionary="/Samples;component/Themes/Light.xaml" />
<ui:ApplicationTheme Key="Dark"
ResourceDictionary="/Samples;component/Themes/Dark.xaml" />
</ui:GlobalSettings.Themes>
</ui:GlobalSettings>
</ResourceDictionary>
<ui:StyleDictionary Includes="All" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

View File

@ -10,9 +10,9 @@
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="MaterialDesignThemes" Version="4.9.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.4.0" />
<PackageReference Include="Panuon.WPF.UI" Version="1.3.0.2" />
</ItemGroup>
<ItemGroup>

View File

@ -1,129 +1,401 @@
<Window x:Class="Seyounth.Hyosung.Views.MainWindow"
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:Seyounth.Hyosung"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:views="clr-namespace:Seyounth.Hyosung.Views"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance views:MainWindow,
<ui:WindowX x:Class="Seyounth.Hyosung.Views.MainWindow"
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:Seyounth.Hyosung"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:views="clr-namespace:Seyounth.Hyosung.Views"
xmlns:ui="https://opensource.panuon.com/wpf-ui"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance views:MainWindow,
IsDesignTimeCreatable=True}"
Title="{Binding ViewModel.ApplicationTitle, Mode=OneWay}"
Height="1080" Width="1920"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
AllowsTransparency="True"
WindowState="Maximized"
Background="Transparent">
<Border Background="{DynamicResource MaterialDesignPaper}"
CornerRadius="4"
Margin="10"
materialDesign:ElevationAssist.Elevation="Dp2">
ui:WindowXCaption.Height="50"
ui:WindowXCaption.Foreground="#F1F1F1"
ui:WindowXCaption.Background="#C62F2F"
Title="{Binding ViewModel.ApplicationTitle, Mode=OneWay}"
Height="1080" Width="1920">
<ui:WindowX.Resources>
<Style x:Key="HeaderSolidIconButtonStyle"
TargetType="Button"
BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="ui:ButtonHelper.CornerRadius"
Value="3,0,0,3" />
<Setter Property="Height"
Value="25" />
<Setter Property="Width"
Value="30" />
<Setter Property="FontFamily"
Value="{StaticResource PanuonIconFont}" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderBrush"
Value="#B12323" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Foreground"
Value="#F1F1F1" />
<Setter Property="ui:ButtonHelper.HoverBackground"
Value="#1A3E3E3E" />
</Style>
<Style x:Key="HeaderLinkIconButtonStyle"
TargetType="Button"
BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="ui:ButtonHelper.CornerRadius"
Value="3,0,0,3" />
<Setter Property="FontFamily"
Value="{StaticResource PanuonIconFont}" />
<Setter Property="FontSize"
Value="16" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="#E8E8E8" />
<Setter Property="ui:ButtonHelper.HoverForeground"
Value="#E1E1E1" />
</Style>
<Style x:Key="SearchBoxStyle"
TargetType="ui:SearchBox">
<Setter Property="ui:ShadowHelper.Opacity"
Value="0.5" />
<Setter Property="ui:ShadowHelper.BlurRadius"
Value="25" />
<Setter Property="ui:DropDownHelper.ShadowColor"
Value="#C62F2F" />
<Setter Property="ui:DropDownHelper.BorderBrush"
Value="#C62F2F" />
<Setter Property="ui:DropDownHelper.Background"
Value="White" />
<Setter Property="ui:DropDownHelper.CornerRadius"
Value="4" />
<Setter Property="ui:WindowX.IsDragMoveArea"
Value="False" />
<Setter Property="FocusedShadowColor"
Value="#C62F2F" />
<Setter Property="CornerRadius"
Value="13" />
<Setter Property="Height"
Value="26" />
<Setter Property="Width"
Value="220" />
<Setter Property="FontSize"
Value="12" />
<Setter Property="Background"
Value="#B12323" />
<Setter Property="Foreground"
Value="#F1F1F1" />
<Setter Property="Padding"
Value="10,0,30,0" />
<Setter Property="Watermark"
Value="Search musics, vedios, radios" />
<Setter Property="ItemsBorderBrush"
Value="#C62F2F" />
<Setter Property="ItemsCornerRadius"
Value="4" />
<Setter Property="ItemsHeight"
Value="35" />
<Setter Property="ItemsForeground"
Value="#1E1E1E" />
<Setter Property="ItemsHoverBackground"
Value="{x:Null}" />
<Setter Property="ItemsHoverForeground"
Value="#C62F2F" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ui:SearchBoxItem">
<Setter Property="Height"
Value="50" />
</Style>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock FontSize="14"
Text="&#xe96d;"
FontFamily="{StaticResource PanuonIconFont}"
VerticalAlignment="Center" />
<TextBlock Grid.Column="1"
Margin="5,0,0,0"
Text="{Binding}"
VerticalAlignment="Center" />
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MainMenuTreeViewStyle"
TargetType="TreeView"
BasedOn="{StaticResource {x:Type TreeView}}">
<Setter Property="ui:IconHelper.FontFamily"
Value="{StaticResource PanuonIconFont}" />
<Setter Property="ui:IconHelper.FontSize"
Value="20" />
<Setter Property="ui:TreeViewHelper.ItemsBorderBrush"
Value="Transparent" />
<Setter Property="ui:TreeViewHelper.ItemsSelectedBorderBrush"
Value="#C62F2F" />
<Setter Property="ui:TreeViewHelper.ItemsSelectedBackground"
Value="#E8E8E8" />
<Setter Property="ui:TreeViewHelper.ItemsBorderThickness"
Value="3,0,0,0" />
<Setter Property="ui:TreeViewHelper.ItemsHeight"
Value="35" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="ui:TreeViewHelper.ToggleArrowToggleButtonStyle"
Value="{x:Null}" />
</Style>
<Style x:Key="SubMenuTabControlStyle"
TargetType="TabControl"
BasedOn="{StaticResource {x:Type TabControl}}">
<Setter Property="ui:TabControlHelper.HeaderPanelAlignment"
Value="Center" />
<Setter Property="ui:TabControlHelper.ItemsHeight"
Value="45" />
<Setter Property="ui:TabControlHelper.ItemsPadding"
Value="15,0" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="ui:TabControlHelper.ItemsHoverBackground"
Value="{x:Null}" />
<Setter Property="ui:TabControlHelper.ItemsRibbonLineVisibility"
Value="Visible" />
<Setter Property="ui:TabControlHelper.ItemsRibbonLinePlacement"
Value="Bottom" />
<Setter Property="ui:TabControlHelper.ItemsRibbonLineBrush"
Value="Transparent" />
<Setter Property="ui:TabControlHelper.ItemsHoverRibbonLineBrush"
Value="#C62F2F" />
<Setter Property="ui:TabControlHelper.ItemsHoverRibbonLineThickness"
Value="1" />
<Setter Property="ui:TabControlHelper.ItemsSelectedRibbonLineBrush"
Value="#C62F2F" />
<Setter Property="ui:TabControlHelper.ItemsSelectedRibbonLineThickness"
Value="3" />
<Setter Property="ui:TabControlHelper.ItemsSelectedBackground"
Value="{x:Null}" />
<Setter Property="ui:TabControlHelper.HeaderPanelBorderBrush"
Value="LightGray" />
<Setter Property="ui:TabControlHelper.HeaderPanelBorderThickness"
Value="0,0,0,1" />
</Style>
<Style x:Key="CarouselStyle"
TargetType="ui:Carousel">
<Setter Property="Animation"
Value="Flow,Fade" />
<Setter Property="AnimationEasing"
Value="CubicOut" />
<Setter Property="IndicatorVisibility"
Value="Visible" />
<Setter Property="IndicatorPaginationStyle">
<Setter.Value>
<Style TargetType="ui:Pagination"
BasedOn="{StaticResource {x:Static ui:Carousel.IndicatorPaginationStyleKey}}">
<Setter Property="ItemsWidth"
Value="NaN" />
<Setter Property="ItemsHeight"
Value="NaN" />
<Setter Property="ItemsBackground"
Value="Transparent" />
<Setter Property="ItemsForeground"
Value="#55000000" />
<Setter Property="ItemsSelectedBackground"
Value="{x:Null}" />
<Setter Property="ItemsSelectedForeground"
Value="#C62F2F" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ui:PaginationItem">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="&#xe954;"
FontFamily="{StaticResource PanuonIconFont}"
FontSize="16" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</ui:WindowX.Resources>
<ui:WindowXCaption.MinimizeButtonStyle>
<Style TargetType="Button"
BasedOn="{StaticResource {x:Static ui:WindowXCaption.MinimizeButtonStyleKey}}">
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="#E8E8E8" />
<Setter Property="ui:ButtonHelper.HoverForeground"
Value="#E1E1E1" />
<Setter Property="ui:ButtonHelper.HoverBackground"
Value="{x:Null}" />
</Style>
</ui:WindowXCaption.MinimizeButtonStyle>
<ui:WindowXCaption.MaximizeButtonStyle>
<Style TargetType="Button"
BasedOn="{StaticResource {x:Static ui:WindowXCaption.MaximizeButtonStyleKey}}">
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="#E8E8E8" />
<Setter Property="ui:ButtonHelper.HoverForeground"
Value="#E1E1E1" />
<Setter Property="ui:ButtonHelper.HoverBackground"
Value="{x:Null}" />
</Style>
</ui:WindowXCaption.MaximizeButtonStyle>
<ui:WindowXCaption.CloseButtonStyle>
<Style TargetType="Button"
BasedOn="{StaticResource {x:Static ui:WindowXCaption.CloseButtonStyleKey}}">
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="#E8E8E8" />
<Setter Property="ui:ButtonHelper.HoverForeground"
Value="#E1E1E1" />
<Setter Property="ui:ButtonHelper.HoverBackground"
Value="{x:Null}" />
</Style>
</ui:WindowXCaption.CloseButtonStyle>
<ui:WindowXCaption.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock FontSize="18"
FontWeight="Light"
VerticalAlignment="Center"
Margin="15,0,30,0"
Foreground="White"
Text="NETEASE MUSIC (SIM)" />
<StackPanel Grid.Column="1"
Orientation="Horizontal">
<Button ui:WindowX.IsDragMoveArea="False"
Style="{StaticResource HeaderSolidIconButtonStyle}"
Content="&#xe900;" />
<Button ui:WindowX.IsDragMoveArea="False"
Style="{StaticResource HeaderSolidIconButtonStyle}"
Content="&#xe902;" />
</StackPanel>
<Grid Grid.Column="2"
Margin="10,0,0,0">
<ui:SearchBox x:Name="SchBox"
Style="{StaticResource SearchBoxStyle}"
VerticalAlignment="Center">
</ui:SearchBox>
<Button ui:WindowX.IsDragMoveArea="False"
Style="{StaticResource HeaderLinkIconButtonStyle}"
HorizontalAlignment="Right"
Margin="0,0,7,0"
Content="&#xe928;" />
</Grid>
</Grid>
</DataTemplate>
</ui:WindowXCaption.HeaderTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<materialDesign:ColorZone Padding="16"
materialDesign:ElevationAssist.Elevation="Dp4"
DockPanel.Dock="Top"
Mode="PrimaryMid">
<DockPanel>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<Button x:Name="One" Margin="-20,-20,10,-20"
Content="_"
Command="{Binding ViewModel.MinimizeCommand}" />
<Button x:Name="Exit"
Content="X"
Command="{Binding ViewModel.ExitCommand}" />
</StackPanel>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="22"
Text="Hyosung -- Seyounth Auto" />
</DockPanel>
</materialDesign:ColorZone>
<materialDesign:Card Grid.Row="1">
<TabControl
x:Name="MenuTab"
materialDesign:ColorZoneAssist.Mode="Standard"
materialDesign:ElevationAssist.Elevation="Dp8"
Style="{StaticResource MaterialDesignNavigationRailTabControl}">
<TabItem x:Name="Home">
<TabItem.Header>
<StackPanel
Width="auto"
Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="Home" />
<TextBlock
HorizontalAlignment="Center"
Text="仪表盘" />
</StackPanel>
</TabItem.Header>
<Frame Padding="16" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" x:Name="HomeFrame" />
</TabItem>
<TabItem x:Name="VarietyTabItem">
<TabItem.Header>
<StackPanel
Width="auto"
Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="ListBox" />
<TextBlock
HorizontalAlignment="Center"
Text="产品信息" />
</StackPanel>
</TabItem.Header>
<Frame Padding="16" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" x:Name="VarietyFrame" />
</TabItem>
<TabItem>
<TabItem.Header>
<StackPanel
Width="auto"
Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="Info" />
<TextBlock
HorizontalAlignment="Center"
Text="运行状态" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem>
<TabItem.Header>
<StackPanel
Width="auto"
Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="Settings" />
<TextBlock
HorizontalAlignment="Center"
Text="系统设置" />
</StackPanel>
</TabItem.Header>
</TabItem>
</TabControl>
</materialDesign:Card>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Background="#F5F5F5">
<TreeView Grid.Row="1"
Style="{StaticResource MainMenuTreeViewStyle}">
<TreeViewItem Margin="0,10,0,10"
Padding="10,0,0,0"
ui:TreeViewItemHelper.IsStyleless="True"
Header="码垛管理" />
<TreeViewItem ui:TreeViewItemHelper.Icon="&#xe110;"
Header="生产看板"
IsSelected="True" />
<TreeViewItem ui:TreeViewItemHelper.Icon="&#xe939;"
Header="Perseonnel FM" />
<TreeViewItem ui:TreeViewItemHelper.Icon="&#xe95e;"
Header="Vedios" />
<TreeViewItem ui:TreeViewItemHelper.Icon="&#xe93b;"
Header="Friends" />
<TreeViewItem Margin="0,10,0,10"
Padding="10,0,0,0"
ui:TreeViewItemHelper.IsStyleless="True"
Header="Storage" />
<TreeViewItem ui:TreeViewItemHelper.Icon="&#xe991;"
Header="Local" />
<TreeViewItem ui:TreeViewItemHelper.Icon="&#xe90f;"
Header="Downloads" />
<TreeViewItem Margin="0,10,0,10"
Padding="10,0,0,0"
ui:TreeViewItemHelper.IsStyleless="True"
Header="My" />
<TreeViewItem ui:TreeViewItemHelper.Icon="&#xe952;"
Header="Favorites" />
</TreeView>
</Grid>
</Border>
</Window>
<ScrollViewer Grid.Column="1">
<StackPanel>
<ui:Carousel Style="{StaticResource CarouselStyle}"
AutoPlayDuration="0:0:2"
Height="300"
TextBlock.FontSize="40"
TextBlock.TextAlignment="Center">
<Border Background="#FAFAFA">
<TextBlock Text="Page 1"
VerticalAlignment="Center" />
</Border>
<Border Background="#FAFAFA">
<TextBlock Text="Page 2"
VerticalAlignment="Center" />
</Border>
<Border Background="#FAFAFA">
<TextBlock Text="Page 3"
VerticalAlignment="Center" />
</Border>
<Border Background="#FAFAFA">
<TextBlock Text="Page 4"
VerticalAlignment="Center" />
</Border>
<Border Background="#FAFAFA">
<TextBlock Text="Page 5"
VerticalAlignment="Center" />
</Border>
</ui:Carousel>
<TabControl Style="{StaticResource SubMenuTabControlStyle}">
<TabItem Header="Recommend" />
<TabItem Header="List" />
<TabItem Header="Radio" />
<TabItem Header="Charts" />
<TabItem Header="Singer" />
<TabItem Header="Newest" />
</TabControl>
</StackPanel>
</ScrollViewer>
</Grid>
</ui:WindowX>

View File

@ -1,8 +1,4 @@
using System.Windows;
using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Services;
using Seyounth.Hyosung.Runtime;
using Seyounth.Hyosung.ViewModels;
using Seyounth.Hyosung.ViewModels;
using Seyounth.Hyosung.Views.Pages;
namespace Seyounth.Hyosung.Views;