Browse Source

研究院项目框架搭建

reconfiguration
pry 3 months ago
parent
commit
408eda9c08
41 changed files with 4569 additions and 327 deletions
  1. +70
    -0
      BPASmartClient.Academy/App.config
  2. +42
    -0
      BPASmartClient.Academy/App.xaml
  3. +229
    -0
      BPASmartClient.Academy/App.xaml.cs
  4. +10
    -0
      BPASmartClient.Academy/AssemblyInfo.cs
  5. +24
    -0
      BPASmartClient.Academy/BPASmartClient.Academy.csproj
  6. +27
    -0
      BPASmartClient.Academy/Converter/DataTableRedundantConverter.cs
  7. +64
    -0
      BPASmartClient.Academy/Converter/RunStatusConvert.cs
  8. +16
    -0
      BPASmartClient.Academy/GlobalUsing.cs
  9. +12
    -0
      BPASmartClient.Academy/MainWindow.xaml
  10. +24
    -0
      BPASmartClient.Academy/MainWindow.xaml.cs
  11. +43
    -0
      BPASmartClient.Academy/Model/AlarmInfo.cs
  12. +142
    -0
      BPASmartClient.Academy/Model/Expand.cs
  13. +29
    -0
      BPASmartClient.Academy/Model/OutletInfoModel.cs
  14. +100
    -0
      BPASmartClient.Academy/Model/RawMaterialDeviceStatus.cs
  15. +46
    -0
      BPASmartClient.Academy/Model/RecipeModel.cs
  16. +15
    -0
      BPASmartClient.Academy/Model/RecipeProcess.cs
  17. +56
    -0
      BPASmartClient.Academy/Model/StockStatusModel.cs
  18. +20
    -0
      BPASmartClient.Academy/Model/ViewModelBase.cs
  19. +109
    -0
      BPASmartClient.Academy/Model/par/BasePar.cs
  20. +19
    -0
      BPASmartClient.Academy/Model/par/DevicePar.cs
  21. +70
    -0
      BPASmartClient.Academy/Model/par/DeviceParModel.cs
  22. +11
    -0
      BPASmartClient.Academy/Model/par/LocaPar.cs
  23. +11
    -0
      BPASmartClient.Academy/Model/par/LocalRecipe.cs
  24. +12
    -0
      BPASmartClient.Academy/View/DeviceMotionView.xaml
  25. +28
    -0
      BPASmartClient.Academy/View/DeviceMotionView.xaml.cs
  26. +267
    -0
      BPASmartClient.Academy/View/NewMaterialView.xaml
  27. +23
    -0
      BPASmartClient.Academy/View/NewMaterialView.xaml.cs
  28. +370
    -0
      BPASmartClient.Academy/View/NewRecipeView.xaml
  29. +33
    -0
      BPASmartClient.Academy/View/NewRecipeView.xaml.cs
  30. +1063
    -0
      BPASmartClient.Academy/View/RecipeControlView.xaml
  31. +50
    -0
      BPASmartClient.Academy/View/RecipeControlView.xaml.cs
  32. +319
    -0
      BPASmartClient.Academy/View/RecipeSettingsView.xaml
  33. +41
    -0
      BPASmartClient.Academy/View/RecipeSettingsView.xaml.cs
  34. +16
    -0
      BPASmartClient.Academy/ViewModel/DeviceMotionViewModel.cs
  35. +52
    -0
      BPASmartClient.Academy/ViewModel/NewMaterialViewModel.cs
  36. +160
    -0
      BPASmartClient.Academy/ViewModel/NewRecipeViewModel.cs
  37. +42
    -0
      BPASmartClient.Academy/ViewModel/RecipeControlViewModel.cs
  38. +87
    -0
      BPASmartClient.Academy/ViewModel/RecipeSettingsViewModel.cs
  39. BIN
     
  40. +793
    -326
      BPASmartClient.CustomResource/Pages/View/UserConfigView.xaml
  41. +24
    -1
      SmartClient.sln

+ 70
- 0
BPASmartClient.Academy/App.config View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="FlexBatchSystem">
<section name="ProductInfo" type="System.Configuration.NameValueSectionHandler"/>
<section name="MqttInfo" type="System.Configuration.NameValueSectionHandler"/>
<section name="ConveyerInfo" type="System.Configuration.NameValueSectionHandler"/>
<section name="StockInfo1" type="System.Configuration.NameValueSectionHandler"/>
<section name="StockInfo2" type="System.Configuration.NameValueSectionHandler"/>
<section name="StockInfo3" type="System.Configuration.NameValueSectionHandler"/>
<section name="StockInfo4" type="System.Configuration.NameValueSectionHandler"/>
<section name="StockInfo5" type="System.Configuration.NameValueSectionHandler"/>
<section name="StockInfo6" type="System.Configuration.NameValueSectionHandler"/>
<section name="Services" type="System.Configuration.NameValueSectionHandler"/>
<section name="MQTTParam" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
</configSections>
<FlexBatchSystem>
<ProductInfo>
<add key="ProductKey" value="j090GlJPJNv"/>
<add key="ProductSecret" value="OVTPKMuGlBLZRBFt"/>
<add key="Stock" value="StockModel"/>
<add key="Conveyer" value="ConveyerModel"/>
</ProductInfo>
<MqttInfo>
<add key="mqttHostUrl" value="iot-06z00carjduqaue.mqtt.iothub.aliyuncs.com"/>
</MqttInfo>
<ConveyerInfo>
<add key="DeviceName" value="Conveyer"/>
<add key="DeviceSecret" value="b3df8aaa82de59f478dffb172acf78cd"/>
</ConveyerInfo>
<StockInfo1>
<add key="DeviceName" value="Stock1"/>
<add key="DeviceSecret" value="b0928d8f6e36aabd94f0fce3f9b02536"/>
</StockInfo1>
<StockInfo2>
<add key="DeviceName" value="Stock2"/>
<add key="DeviceSecret" value="8373c57ddc6cd134b19cd89fad564157"/>
</StockInfo2>
<StockInfo3>
<add key="DeviceName" value="Stock3"/>
<add key="DeviceSecret" value="83f1457dbbb3c155d512c7a632d4c033"/>
</StockInfo3>
<StockInfo4>
<add key="DeviceName" value="Stock4"/>
<add key="DeviceSecret" value="9f9d37bebfc94900613890a294f1302d"/>
</StockInfo4>
<StockInfo5>
<add key="DeviceName" value="Stock5"/>
<add key="DeviceSecret" value="7ce871f33f86e9b71d30bdaa39899169"/>
</StockInfo5>
<StockInfo6>
<add key="DeviceName" value="Stock6"/>
<add key="DeviceSecret" value="f18b9d31180c7b7e32508b255c418d07"/>
</StockInfo6>
<Services>
<add key="Service1" value="RunControlService"/>
<add key="Service2" value="StockAirControlService"/>
<add key="Service3" value="RecipeSendService"/>
<add key="Service4" value="CancelRecipeService"/>

</Services>
<MQTTParam>
<add key="UserName" value="admin"/>
<add key="Password" value="admin8765490789"/>
<add key="IpAddress" value="111.9.47.105"/>
<add key="Port" value="18883"/>
</MQTTParam>
</FlexBatchSystem>
</configuration>

+ 42
- 0
BPASmartClient.Academy/App.xaml View File

@@ -0,0 +1,42 @@
<Application
x:Class="BPASmartClient.Academy.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:con="clr-namespace:BPASmartClient.CustomResource.Converters;assembly=BPASmartClient.CustomResource"
xmlns:local="clr-namespace:BPASmartClient.Academy">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>

<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/RecCheckBox.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/RecTitleBarButton.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/GlobalStyle.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/RecComboBox.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/RecIcoButtonStyle.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/RecToggleButton.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/BeveledRadioButtonStyle.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/DatePickeerDictionary.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/RecButtonStyle.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/RecDictionarys/TextBoxStyle.xaml" />

<ResourceDictionary>
<con:ColorConverter x:Key="ColorConverter" />
<con:TextConverter x:Key="TextConverter" />
<con:VisibleTypeConverter x:Key="VisibleTypeConverter" />
<con:StatusConverter x:Key="StatusConverter" />
<con:StringToIconConverter x:Key="StringToIconConverter" />
<con:BoolToVisibilityConvert x:Key="BoolToVisibilityConvert" />
<con:CountIsVisiableConvert x:Key="CountIsVisiableConvert" />
<con:BoolToFillColorConverter x:Key="BoolToFillColorConverter" />
<con:RecipeStatusConvert x:Key="RecipeStatusConvert" />
</ResourceDictionary>

<ResourceDictionary>
<ImageBrush x:Key="hbl" ImageSource="/BPASmartClient.CustomResource;component/Image/HBL.png" />
<ImageBrush x:Key="dbxt" ImageSource="/BPASmartClient.CustomResource;component/Image/顶部线条.png" />
</ResourceDictionary>

</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

+ 229
- 0
BPASmartClient.Academy/App.xaml.cs View File

@@ -0,0 +1,229 @@
using System.Configuration;
using System.Data;
using System.Windows;

namespace BPASmartClient.Academy
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{

public static Window MainWindow;

public EventWaitHandle ProgramStarted { get; set; }
protected override async void OnStartup(StartupEventArgs e)
{
bool createNew;

MessageLog.GetInstance.NotifyShow = new Action<string>(o =>
{
DebugLogViewModel.MessageModels.Add(new MessageModel()
{
LogInfo = o,
Forground = System.Windows.Media.Brushes.DeepSkyBlue
});
});
MessageLog.GetInstance.NotifyShowEx = new Action<string>(o =>
{
DebugLogViewModel.MessageModels.Add(new MessageModel()
{
LogInfo = o,
Forground = System.Windows.Media.Brushes.Red
});
});
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, "Academy", out createNew);
if (!createNew)
{
MessageBox.Show("程序已启动");
App.Current.Shutdown();
Environment.Exit(0);
}
base.OnStartup(e);
SystemHelper.GetInstance.CreateDesktopShortcut();
DataInit();
MenuInit();
MainView mv = new MainView();
mv.TitleName = $"反应釜焖制系统 V1.0.1";
LoginView lv = new LoginView();
var res = lv.ShowDialog();
if (res != null && res == true)
{
#region 更新测试
//string directory = $"{AppDomain.CurrentDomain.BaseDirectory}AccessFile\\JSON\\UpdateModel.json";
//if (File.Exists(directory))
// mv.TitleName = $"味魔方管理系统软件[简称:味魔方] {Json<UpdateModel>.Data.UpgradeVersion}";
//else
//{
// mv.TitleName = $"味魔方管理系统软件[简称:味魔方] V1.0.1";
// Task.Run(() =>
// {
// Thread.Sleep(3000);
// var tt = MessageNotify.GetInstance.ShowDialog("检测到新版本,请问是否现在更新?", DialogType.Information);
// if (tt)
// {
// string directory = AppDomain.CurrentDomain.BaseDirectory;
// Process.Start($"{directory}BPASmartClient.Update.exe");
// App.Current.Dispatcher.Invoke(() => { mv.Close(); });
// }
// });
//}
#endregion

BPASmartClient.CustomResource.Pages.Model.MessageNotify.GetInstance.ShowUserLog("用户登录");
mv.Show();
}
else
mv.Close();
MainWindow = mv;
}

protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
Json<LocalRecipe>.Save();
Json<DevicePar>.Save();
Json<LocaMaterial>.Save();
BPASmartClient.CustomResource.Pages.Model.MessageNotify.GetInstance.LogSave();
TaskManage.GetInstance.Dispose();
//Process.GetCurrentProcess().Kill();
}

private void MenuInit()
{
#region 配方管理菜单
ObservableCollection<SubMenumodel> RecipeManage = new ObservableCollection<SubMenumodel>();
RecipeManage.Add(new SubMenumodel()
{
SubMenuName = "配方管理",
SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
AssemblyName = "BPASmartClient.Academy",
ToggleWindowPath = "View.RecipeSettingsView"
});

RecipeManage.Add(new SubMenumodel()
{
SubMenuName = "配方下发",
SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
AssemblyName = "BPASmartClient.Academy",
ToggleWindowPath = "View.RecipeControlView"
});

MenuManage.GetInstance.menuModels.Add(new MenuModel()
{
MainMenuIcon = "&#xe683;",
MainMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
MainMenuName = "配方管理",
Alias = "Recipe Management",
subMenumodels = RecipeManage,
});
#endregion

#region 消息日志
ObservableCollection<SubMenumodel> InfoLog = new ObservableCollection<SubMenumodel>();
InfoLog.Add(new SubMenumodel()
{
SubMenuName = "操作日志",
SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
AssemblyName = "BPASmartClient.CustomResource",
ToggleWindowPath = "Pages.View.UserLogView"
});

InfoLog.Add(new SubMenumodel()
{
SubMenuName = "运行日志",
SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
AssemblyName = "BPASmartClient.CustomResource",
ToggleWindowPath = "Pages.View.RunLogView"
});

InfoLog.Add(new SubMenumodel()
{
SubMenuName = "报警记录",
SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
AssemblyName = "BPASmartClient.CustomResource",
ToggleWindowPath = "Pages.View.AlarmView"
});

InfoLog.Add(new SubMenumodel()
{
SubMenuName = "调试日志",
SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
AssemblyName = "BPASmartClient.CustomResource",
ToggleWindowPath = "Pages.View.DebugLogView"
});
MenuManage.GetInstance.menuModels.Add(new MenuModel()
{
MainMenuIcon = "&#xe668;",
MainMenuName = "消息日志",
MainMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
Alias = "Message Log",
subMenumodels = InfoLog,
});
#endregion

#region 硬件设备监控
ObservableCollection<SubMenumodel> DeviceMonitor = new ObservableCollection<SubMenumodel>();
DeviceMonitor.Add(new SubMenumodel()
{
SubMenuName = "设备状态",
SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
AssemblyName = "BPASmartClient.Academy",
ToggleWindowPath = "View.DeviceMotionView"
});
MenuManage.GetInstance.menuModels.Add(new MenuModel()
{
MainMenuIcon = "&#xe603;",
MainMenuName = "设备监控",
MainMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
Alias = "Device Monitor",
subMenumodels = DeviceMonitor,
});
#endregion

#region 用户管理
ObservableCollection<SubMenumodel> UserManager = new ObservableCollection<SubMenumodel>();
UserManager.Add(new SubMenumodel()
{
SubMenuName = "用户登录",
SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
AssemblyName = "BPASmartClient.CustomResource",
ToggleWindowPath = "Pages.View.SubPagLoginView"
});

UserManager.Add(new SubMenumodel()
{
SubMenuName = "密码修改",
SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
AssemblyName = "BPASmartClient.CustomResource",
ToggleWindowPath = "Pages.View.PasswordChangeView"
});
UserManager.Add(new SubMenumodel()
{
SubMenuName = "用户管理",
SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
AssemblyName = "BPASmartClient.CustomResource",
ToggleWindowPath = "Pages.View.UserManagerView"
});
MenuManage.GetInstance.menuModels.Add(new MenuModel()
{
MainMenuIcon = "&#xe66d;",
MainMenuName = "用户管理",
MainMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.观察员, Permission.技术员 },
Alias = "User Management",
subMenumodels = UserManager,
});
#endregion
}

private void DataInit()
{
Json<LocalRecipe>.Read();
Json<DevicePar>.Read();
Json<LocaMaterial>.Read();
}

}

}

+ 10
- 0
BPASmartClient.Academy/AssemblyInfo.cs 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)
)]

+ 24
- 0
BPASmartClient.Academy/BPASmartClient.Academy.csproj View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>

<ItemGroup>
<None Remove="hbl.ico" />
</ItemGroup>

<ItemGroup>
<Content Include="hbl.ico" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\BPASmartClient.CustomResource\BPASmartClient.CustomResource.csproj" />
<ProjectReference Include="..\BPASmartClient.Update\BPASmartClient.Update.csproj" />
</ItemGroup>

</Project>

+ 27
- 0
BPASmartClient.Academy/Converter/DataTableRedundantConverter.cs View File

@@ -0,0 +1,27 @@
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;

namespace BPASmartClient.Academy.Converter
{
public class DataTableRedundantConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && value is bool bit)
{
if (bit)
return new SolidColorBrush(Color.FromArgb(255, 245, 63, 98));
else
return new SolidColorBrush(Color.FromArgb(255, 42, 178, 231));
}
return default;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

+ 64
- 0
BPASmartClient.Academy/Converter/RunStatusConvert.cs View File

@@ -0,0 +1,64 @@
using System;
using System.Globalization;
using System.Windows.Data;

namespace BPASmartClient.Academy.Converter
{
public class RunStatusConvert : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is ushort tempValue)
{
if (tempValue == 1) return "等待配料";
if (tempValue == 2) return "配料中";
if (tempValue == 3) return "配料完成";
}
return "等待配料";
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

public class EnbleConvert : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is ushort tempValue)
{
if (tempValue == 0) return true;
if (tempValue == 1) return false;

}
return true;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

public class IntToSourceConvert : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is ushort tempValue)
{
if (tempValue == 0) return "本地原料";
if (tempValue == 1) return "设备原料";

}
return "未知";
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

}

+ 16
- 0
BPASmartClient.Academy/GlobalUsing.cs View File

@@ -0,0 +1,16 @@
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Text;
global using System.Threading.Tasks;
global using BPA.Helper;
global using System.Collections.Concurrent;
global using System.Collections.ObjectModel;
global using BPASmartClient.Academy.Converter;
global using BPASmartClient.Academy.Model;
global using BPASmartClient.Academy.View;
global using BPASmartClient.Academy.ViewModel;
global using BPASmartClient.CustomResource.Pages.ViewModel;
global using BPASmartClient.CustomResource.Pages.View;
global using BPASmartClient.CustomResource.Pages.Model;
global using BPASmartClient.CustomResource.Pages.Enums;

+ 12
- 0
BPASmartClient.Academy/MainWindow.xaml View File

@@ -0,0 +1,12 @@
<Window x:Class="BPASmartClient.Academy.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:BPASmartClient.Academy"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>

</Grid>
</Window>

+ 24
- 0
BPASmartClient.Academy/MainWindow.xaml.cs View File

@@ -0,0 +1,24 @@
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BPASmartClient.Academy
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}

+ 43
- 0
BPASmartClient.Academy/Model/AlarmInfo.cs View File

@@ -0,0 +1,43 @@


namespace BPASmartClient.Academy
{
public class AlarmInfo
{
/// <summary>
/// 1#急停
/// </summary>
[Alarm("1#急停")]
public bool EStop1 { get; set; }

/// <summary>
/// 伺服故障
/// </summary>
[Alarm("伺服故障")]
public bool Servo { get; set; }

/// <summary>
/// 变频器故障
/// </summary>
[Alarm("变频器故障")]
public bool Inverter { get; set; }

/// <summary>
/// 2#急停
/// </summary>
[Alarm("2#急停")]
public bool EStop2 { get; set; }

/// <summary>
/// 料仓上限
/// </summary>
[Alarm("料仓上限")]
public bool SiloUpperLimit { get; set; }

/// <summary>
/// 料仓下限
/// </summary>
[Alarm("料仓下限")]
public bool SiloLowerLimit { get; set; }
}
}

+ 142
- 0
BPASmartClient.Academy/Model/Expand.cs View File

@@ -0,0 +1,142 @@
using System;

namespace BPASmartClient.Academy.Model
{
public static class Expand
{
/// <summary>
/// 获取 M 区 和 VW 区的Modbus的地址
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public static string ToAdd(this string address)
{
if (address == null) return "";
if (address.Length > 0)
{
address = address.Trim();
if (address.ToUpper().Contains("GM") && address.Length >= 3)
{
var res = address.Remove(0, 2);
if (res != null && res.Length > 0)
{
return (int.Parse(res) + 4096).ToString();
}
}
else if (address.ToUpper().Contains("M") && address.Length >= 4)
{
var res = address.Substring(1).Split('.');
if (res != null && res.Length == 2)
{
if (int.TryParse(res[0], out int firstAddress) && int.TryParse(res[1], out int ExitAddress))
{
if (ExitAddress >= 0 && ExitAddress <= 7)
{
return ((firstAddress * 8) + 320 + ExitAddress).ToString();
}
}
}
}

else if (address.ToUpper().Contains("I") && address.Length >= 2)
{
var res = address.Substring(1).Split('.');
if (res != null && res.Length == 2)
{
if (int.TryParse(res[0], out int firstAddress) && int.TryParse(res[1], out int ExitAddress))
{
if (ExitAddress >= 0 && ExitAddress <= 7)
{
return ((firstAddress * 8) + ExitAddress).ToString();
}
}
}
}
else if (address.ToUpper().Contains("GI") && address.Length >= 3)
{
var res = address.Remove(0, 2);
if (res != null && res.Length > 0)
{
return (int.Parse(res)).ToString();
}
}
else if (address.ToUpper().Contains("LB") && address.Length >= 3)
{
var res = address.Substring(2);
if (res != null && res.Length > 0)
{
if (int.TryParse(res, out int firstAddress))
{
return firstAddress.ToString();
}
}
}

else if ((address.ToUpper().Contains("VW") || address.ToUpper().Contains("VD")) && address.Length >= 3)
{
var res = address.Substring(2);
if (res != null && int.TryParse(res, out int tempAddress))
{
return ((tempAddress / 2) + 100).ToString();
}
}
else if (address.ToUpper().Contains("LW") && address.Length >= 3)
{
var res = address.Substring(2);
if (res != null && int.TryParse(res, out int LwAddress))
{
return LwAddress.ToString();
}
}
else if (address.ToUpper().Contains("D") && address.Length == 5)
{
try
{
//D1001
string head = (System.Convert.ToInt32(address.Substring(1, 1))).ToString();
int num = System.Convert.ToInt32(address.Substring(2, 3));
int len = num.ToString().Length;
string tail = string.Empty;
switch (len)
{

case 1:
if ((System.Convert.ToInt32(address.Substring(4, 1))).ToString().Length > 1)
{
tail = "0" + (System.Convert.ToInt32(address.Substring(4, 1))).ToString();
}
else
{
tail = "00" + (System.Convert.ToInt32(address.Substring(4, 1))).ToString();
}
break;
case 2:
if ((System.Convert.ToInt32(address.Substring(3, 2))).ToString().Length > 2)
{
tail = (System.Convert.ToInt32(address.Substring(3, 2))).ToString();
}
else
{
tail = "0" + (System.Convert.ToInt32(address.Substring(3, 2))).ToString();
}
break;
case 3:
tail = (System.Convert.ToInt32(address.Substring(2, 3))).ToString();
break;
}

address = head + tail;
return address;
}
catch (Exception)
{
//打印日志

}

}
}
return "";
}
}
}

+ 29
- 0
BPASmartClient.Academy/Model/OutletInfoModel.cs View File

@@ -0,0 +1,29 @@
using BPA.Helper;
using System.Collections.ObjectModel;

namespace BPASmartClient.Academy
{
/// <summary>
/// 出料口信息
/// </summary>
public class OutletInfoModel : NotifyBase
{
/// <summary>
/// 出料口名称
/// </summary>
public string OutletName { get { return _mOutletName; } set { _mOutletName = value; OnPropertyChanged(); } }
private string _mOutletName;

/// <summary>
/// 出料口位置
/// </summary>
public int OutletLoc { get { return _mOutletLoc; } set { _mOutletLoc = value; OnPropertyChanged(); } }
private int _mOutletLoc;

/// <summary>
/// 出料口对应的料仓信息
/// </summary>
public ObservableCollection<string> SiloInfos { get; set; } = new ObservableCollection<string>();

}
}

+ 100
- 0
BPASmartClient.Academy/Model/RawMaterialDeviceStatus.cs View File

@@ -0,0 +1,100 @@
namespace BPASmartClient.Academy
{
public class RawMaterialDeviceStatus
{

/// <summary>
/// 原料类型
/// 1:膏体
/// 2:液体
/// 3:粉体
/// </summary>
public ushort RawMaterialType { get; set; }

/// <summary>
/// 料仓重量反馈
/// </summary>
public float WeightFeedback { get; set; }

/// <summary>
/// 当前出料重量反馈
/// </summary>
public float NowWeightFeedback { get; set; }

/// <summary>
/// 上限反馈
/// </summary>
public bool UpLimitFeedback { get; set; }

/// <summary>
/// 下限反馈
/// </summary>
public bool DownLimitFeedback { get; set; }

/// <summary>
/// 下料重量反馈
/// </summary>
public float CutWeightFeedback { get; set; }

/// <summary>
/// 设备运行状态
/// 0:未知
/// 1:等待配料
/// 2:配料中
/// 3:配料完成
/// </summary>
public ushort RunStatus { get; set; }

/// <summary>
/// 设备故障编码
/// </summary>
public ushort DeviceAlarmCode { get; set; }

/// <summary>
/// 设备料仓编号
/// </summary>
public ushort DeviceNum { get; set; }

/// <summary>
/// 原料名称
/// </summary>
public string DeviceName { get; set; }
/// <summary>
/// 工作模式0:手动 1:自动
/// </summary>
public bool WorkModel { get; set; }
/// <summary>
/// 慢加重量
/// </summary>
public float SlowAddWeight { get; set; }
/// <summary>
/// 提前关阀重量
/// </summary>
public float PreCloseValueWeight { get; set; }

/// <summary>
/// 快加速度
/// </summary>
public uint RapidAcceleration { get; set; }
/// <summary>
/// 慢加速度
/// </summary>
public uint SlowAcceleration { get; set; }
/// <summary>
/// 伺服手动速度
/// </summary>
public uint ServoManualSpeed { get; set; }
/// <summary>
/// 料仓上限重量
/// </summary>
public uint SiloUpperLimitWeight { get; set; }
/// <summary>
/// 料仓下限重量
/// </summary>
public uint SiloLowerLimitWeight { get; set; }
/// <summary>
/// 搅拌速度
/// </summary>
public uint StirringSpeed { get; set; }
}
}

+ 46
- 0
BPASmartClient.Academy/Model/RecipeModel.cs View File

@@ -0,0 +1,46 @@
using BPA.Helper;
using BPASmartClient.Model;
using System.Collections.ObjectModel;
using System.Threading;

namespace BPASmartClient.Academy
{
/// <summary>
/// 配方模块
/// </summary>
public class RecipeModel : NotifyBase
{
[Newtonsoft.Json.JsonIgnore]
public bool IsEnable { get { return _mIsEnable; } set { _mIsEnable = value; OnPropertyChanged(); } }
private bool _mIsEnable = true;

/// <summary>
/// 序号
/// </summary>
public int SerialNum { get { return _mSerialNum; } set { _mSerialNum = value; OnPropertyChanged(); } }
private int _mSerialNum;

/// <summary>
/// 配方名称
/// </summary>
public string RecipeName { get { return _mRecipeName; } set { _mRecipeName = value; OnPropertyChanged(); } }
private string _mRecipeName;

/// <summary>
/// 配方编码
/// </summary>
public string RecipCode { get { return _mRecipCode; } set { _mRecipCode = value; OnPropertyChanged(); } }
private string _mRecipCode;


[Newtonsoft.Json.JsonIgnore]
public string RecipStatus { get { return _mRecipStatus; } set { _mRecipStatus = value; OnPropertyChanged(); } }
private string _mRecipStatus;

/// <summary>
/// 原料集合
/// </summary>
public ObservableCollection<RawMaterialModel> RawMaterials { get; set; } = new ObservableCollection<RawMaterialModel>();

}
}

+ 15
- 0
BPASmartClient.Academy/Model/RecipeProcess.cs View File

@@ -0,0 +1,15 @@
using BPA.Helper;

namespace BPASmartClient.Academy
{
public class RecipeProcess : NotifyBase
{
public string RawMaterialName { get { return _mRawMaterialName; } set { _mRawMaterialName = value; OnPropertyChanged(); } }
private string _mRawMaterialName;


public int RawMaterialStatus { get { return _mRawMaterialStatus; } set { _mRawMaterialStatus = value; OnPropertyChanged(); } }
private int _mRawMaterialStatus;

}
}

+ 56
- 0
BPASmartClient.Academy/Model/StockStatusModel.cs View File

@@ -0,0 +1,56 @@
using BPA.Helper;

namespace BPASmartClient.Academy
{
public class StockStatusModel : NotifyBase
{
/// <summary>
/// 料仓物料重量
/// </summary>
public double MaterialWeight { get { return _materialWeight; } set { _materialWeight = value; OnPropertyChanged(); } }
private double _materialWeight;

/// <summary>
/// 料仓物料名称
/// </summary>
public string MaterialName { get { return _materialName; } set { _materialName = value; OnPropertyChanged(); } }
private string _materialName;

/// <summary>
/// 是否真在运行
/// </summary>
public bool IsRunning { get { return _isRunning; } set { _isRunning = value; OnPropertyChanged(); } }
private bool _isRunning;

/// <summary>
/// 是否正在下料
/// </summary>
public bool IsLayOff { get { return _isLayOff; } set { _isLayOff = value; OnPropertyChanged(); } }
private bool _isLayOff;

/// <summary>
/// 是否开盖
/// </summary>
public bool IsOpen { get { return _mIsOpen; } set { _mIsOpen = value; OnPropertyChanged(); } }
private bool _mIsOpen;

/// <summary>
/// 是否故障报警
/// </summary>
public bool IsFault { get { return _isFault; } set { _isFault = value; OnPropertyChanged(); } }
private bool _isFault;

/// <summary>
/// 下料状态 0:未出料 1:出料指令下发 2:出料完成
/// </summary>
public int IssueStatus { get { return _isIssueStatus; } set { _isIssueStatus = value; OnPropertyChanged(); } }
private int _isIssueStatus;

/// <summary>
/// 下料重量
/// </summary>
public double IssueWeight { get { return _IssueWeight; } set { _IssueWeight = value; OnPropertyChanged(); } }
private double _IssueWeight;

}
}

+ 20
- 0
BPASmartClient.Academy/Model/ViewModelBase.cs View File

@@ -0,0 +1,20 @@
using BPA.Helper;

namespace BPASmartClient.Academy
{
public class ViewModelBase : NotifyBase
{
public int Index { get; set; } = -1;
public BPARelayCommand AddCommand { get; set; }//添加
public BPARelayCommand CancelCommand { get; set; }//取消
public BPARelayCommand SaveCommand { get; set; }//保存
public BPARelayCommand<object> RemoveCommand { get; set; }//移除
public BPARelayCommand<object> DetailsCommand { get; set; }//编辑

/// <summary>
/// 错误信息
/// </summary>
public string ErrorInfo { get { return _mErrorInfo; } set { _mErrorInfo = value; OnPropertyChanged(); } }
private string _mErrorInfo = string.Empty;
}
}

+ 109
- 0
BPASmartClient.Academy/Model/par/BasePar.cs View File

@@ -0,0 +1,109 @@
using BPA.Helper;
using System.Collections.Generic;

namespace BPASmartClient.Academy
{
/// <summary>
/// 基础参数
/// </summary>
public class BasePar : NotifyBase
{
/// <summary>
/// 设备扫描网段
/// </summary>
public string NetworkSegAddress { get { return _mNetworkSegAddress; } set { _mNetworkSegAddress = value; OnPropertyChanged(); } }
private string _mNetworkSegAddress = "192.168.0.";

/// <summary>
/// 输送带设备 PLC IP 地址
/// </summary>
public string DeviceAddress { get { return _mDeviceAddress; } set { _mDeviceAddress = value; OnPropertyChanged(); } }
private string _mDeviceAddress = "192.168.0.15";


/// <summary>
/// 料仓数量
/// </summary>
public int StockCount { get { return _stockCount; } set { _stockCount = value; OnPropertyChanged(); } }
private int _stockCount = 0;


/// <summary>
/// 当前使用的输送线类型
/// </summary>
public string ConveryType { get { return _converyType; } set { _converyType = value; OnPropertyChanged(); } }
private string _converyType;
/// <summary>
/// 输送线类型集合
/// </summary>
private List<string> _converyTypeList = new List<string>();
public List<string> ConveryTypeList
{
get { return _converyTypeList; }

set
{
foreach (var item in value)
{
if (_converyTypeList.Contains(item))
{
continue;
}
_converyTypeList.Add(item);
}

OnPropertyChanged();
}
}
/// <summary>
/// 输送带数量
/// </summary>
public int ConveyerBeltCount
{
get { return _mConveyerBeltCount; }
set
{
_mConveyerBeltCount = value;
//var temp = ConveyerBeltModels;
//App.Current.Dispatcher.Invoke(() => { ConveyerBeltModels.Clear(); });
//for (int i = 0; i < value; i++)
//{
// App.Current.Dispatcher.Invoke(() =>
// {
// ConveyerBeltModels.Add(new ConveyerBeltModel()
// {
// Name = $"输送带{i + 1}速度",
// Num = i + 1,
// Speed = (i >= 0 && i < temp.Count) ? temp.ElementAt(i).Speed : 0
// });
// });
//}
OnPropertyChanged();
}
}
private int _mConveyerBeltCount = 0;



/// <summary>
/// 升降气缸数量
/// </summary>
public int LiftCylinderCount { get { return _mLiftCylinderCount; } set { _mLiftCylinderCount = value; OnPropertyChanged(); } }
private int _mLiftCylinderCount = 0;

/// <summary>
/// 阻挡气缸数量
/// </summary>
public int BlockCylinderCount { get { return _mBlockCylinderCount; } set { _mBlockCylinderCount = value; OnPropertyChanged(); } }
private int _mBlockCylinderCount = 0;

/// <summary>
/// 托盘气缸数量
/// </summary>
public int PalletCylinderCount { get { return _mPalletCylinderCount; } set { _mPalletCylinderCount = value; OnPropertyChanged(); } }
private int _mPalletCylinderCount = 0;

//public ObservableCollection<ConveyerBeltModel> ConveyerBeltModels { get; set; } = new ObservableCollection<ConveyerBeltModel>();

}
}

+ 19
- 0
BPASmartClient.Academy/Model/par/DevicePar.cs View File

@@ -0,0 +1,19 @@
using BPA.Helper;
using System.Collections.ObjectModel;

namespace BPASmartClient.Academy
{
public class DevicePar : NotifyBase
{
/// <summary>
/// 配料设备参数
/// </summary>
public ObservableCollection<DeviceParModel> deviceParModels { get; set; } = new ObservableCollection<DeviceParModel>();

public ObservableCollection<OutletInfoModel> OutletInfoModels { get; set; } = new ObservableCollection<OutletInfoModel>();

public BasePar BaseParModel { get { return _mBaseParModel; } set { _mBaseParModel = value; OnPropertyChanged(); } }
private BasePar _mBaseParModel = new BasePar();

}
}

+ 70
- 0
BPASmartClient.Academy/Model/par/DeviceParModel.cs View File

@@ -0,0 +1,70 @@
using BPA.Helper;

namespace BPASmartClient.Academy
{
public class DeviceParModel : NotifyBase
{
/// <summary>
/// 原料名称
/// </summary>
public string MaterialName { get { return _mMaterialName; } set { _mMaterialName = value; OnPropertyChanged(); } }
private string _mMaterialName = string.Empty;

/// <summary>
/// 慢加重量
/// </summary>
public float SlowlyAddWeight { get { return _mSlowlyAddWeight; } set { _mSlowlyAddWeight = value; OnPropertyChanged(); } }
private float _mSlowlyAddWeight;

/// <summary>
/// 提前关阀重量
/// </summary>
public float PreCloseValveWeight { get { return _mPreCloseValveWeight; } set { _mPreCloseValveWeight = value; OnPropertyChanged(); } }
private float _mPreCloseValveWeight;

/// <summary>
/// 快加速度
/// </summary>
public int RapidAcceleration { get { return _mRapidAcceleration; } set { _mRapidAcceleration = value; OnPropertyChanged(); } }
private int _mRapidAcceleration;

/// <summary>
/// 慢加速度
/// </summary>
public int SlowAcceleration { get { return _mSlowAcceleration; } set { _mSlowAcceleration = value; OnPropertyChanged(); } }
private int _mSlowAcceleration;

/// <summary>
/// 伺服手动速度
/// </summary>
public int ServoManualSpeed { get { return _mServoManualSpeed; } set { _mServoManualSpeed = value; OnPropertyChanged(); } }
private int _mServoManualSpeed;

/// <summary>
/// 料仓上限重量
/// </summary>
public int SiloUpperLimitWeight { get { return _mSiloUpperLimitWeight; } set { _mSiloUpperLimitWeight = value; OnPropertyChanged(); } }
private int _mSiloUpperLimitWeight;

/// <summary>
/// 料仓下限重量
/// </summary>
public int LowerLimitWeightOfSilo { get { return _mLowerLimitWeightOfSilo; } set { _mLowerLimitWeightOfSilo = value; OnPropertyChanged(); } }
private int _mLowerLimitWeightOfSilo;

/// <summary>
/// 搅拌速度
/// </summary>
public int StirringSpeed { get { return _mStirringSpeed; } set { _mStirringSpeed = value; OnPropertyChanged(); } }
private int _mStirringSpeed;

/// <summary>
/// 是否重复
/// </summary>
[Newtonsoft.Json.JsonIgnore]
public bool IsRedundant { get { return _mIsRedundant; } set { _mIsRedundant = value; OnPropertyChanged(); } }
private bool _mIsRedundant;


}
}

+ 11
- 0
BPASmartClient.Academy/Model/par/LocaPar.cs View File

@@ -0,0 +1,11 @@
using System.Collections.ObjectModel;

namespace BPASmartClient.Academy
{
public class LocaPar
{
public ObservableCollection<RecipeModel> Recipes { get; set; } = new ObservableCollection<RecipeModel>();


}
}

+ 11
- 0
BPASmartClient.Academy/Model/par/LocalRecipe.cs View File

@@ -0,0 +1,11 @@
using System.Collections.ObjectModel;

namespace BPASmartClient.Academy
{
public class LocalRecipe
{
public ObservableCollection<RecipeModel> Recipes { get; set; } = new ObservableCollection<RecipeModel>();


}
}

+ 12
- 0
BPASmartClient.Academy/View/DeviceMotionView.xaml View File

@@ -0,0 +1,12 @@
<UserControl x:Class="BPASmartClient.Academy.View.DeviceMotionView"
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:BPASmartClient.Academy.View"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
</Grid>
</UserControl>

+ 28
- 0
BPASmartClient.Academy/View/DeviceMotionView.xaml.cs View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BPASmartClient.Academy.View
{
/// <summary>
/// DeviceMotionView.xaml 的交互逻辑
/// </summary>
public partial class DeviceMotionView : UserControl
{
public DeviceMotionView()
{
InitializeComponent();
}
}
}

+ 267
- 0
BPASmartClient.Academy/View/NewMaterialView.xaml View File

@@ -0,0 +1,267 @@
<Window
x:Class="BPASmartClient.Academy.View.NewMaterialView"
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:BPASmartClient.Academy.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:BPASmartClient.Academy.ViewModel"
Title="NewMateritalView"
Width="600"
Height="350"
AllowsTransparency="True"
Background="{x:Null}"
Topmost="True"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
mc:Ignorable="d">
<Window.DataContext>
<vm:NewMaterialViewModel />
</Window.DataContext>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/Themes/GenricStyle.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/Themes/MyStyle.xaml" />

<ResourceDictionary>

<SolidColorBrush x:Key="tabColor" Color="#FF2AB2E7" />
<!--<SolidColorBrush x:Key="bordColor" Color="#33ffffff" />-->
<SolidColorBrush x:Key="bordColor" Color="#332AB2E7" />

<Style x:Key="ControlButtonStyle" TargetType="Button">
<Setter Property="Margin" Value="0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="Foreground" Value="#FFF53F62" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="FontFamily" Value="楷体" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
Name="TitleBarBr"
BorderBrush="#00c2f4"
BorderThickness="0"
CornerRadius="0"
Opacity="0.8">

<ContentPresenter
Margin="{TemplateBinding Margin}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
<Border.Background>
<ImageBrush
ImageSource="/BPASmartClient.CustomResource;component/Image/组合边框1.1.png"
Opacity="0.8"
Stretch="Fill" />
</Border.Background>

</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="TitleBarBr" Property="Opacity" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style x:Key="TitleTextblockStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="16" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Foreground" Value="{StaticResource tabColor}" />
<Setter Property="FontFamily" Value="楷体" />
<Setter Property="FontWeight" Value="SemiBold" />
</Style>

<!--#region ListBox样式-->
<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="20" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="border" CornerRadius="8">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion-->
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>

<Border Name="br" BorderThickness="1">
<Border.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/容器边框.png" />
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="55" />
<RowDefinition Height="20" />
<RowDefinition Height="40" />
<RowDefinition />
</Grid.RowDefinitions>

<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="25"
Foreground="#FF2AB2E7"
Text="本地原料创建" />

<Grid Grid.Row="2" Margin="10,0">

<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>

<TextBlock
HorizontalAlignment="Left"
Background="Transparent"
FontSize="20"
Foreground="#FF2AB2E7"
Text="请输入原料名称:" />

<TextBox
Grid.Column="1"
Height="30"
FontSize="16"
Text="{Binding MaterialName}" />

</Grid>

<StackPanel Grid.Column="1" Orientation="Horizontal">
<Button
Width="80"
Height="30"
Margin="5,0"
Command="{Binding SaveCommand}"
Content="添加"
Cursor="Hand" />

<Button
Name="btClose"
Width="70"
Height="30"
Click="btClose_Click"
Content="取消" />
</StackPanel>


</Grid>
<TextBlock
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="Transparent"
FontSize="16"
Foreground="Red"
Text="{Binding ErrorInfo}" />

<Grid Grid.Row="4" Margin="10,0">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<Grid Margin="0,10,0,0" Background="#ff0C255F">

<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>

<TextBlock
Grid.Column="0"
Style="{StaticResource TitleTextblockStyle}"
Text="原料名称" />

<Grid Grid.Column="1">
<TextBlock Style="{StaticResource TitleTextblockStyle}" Text="功能操作" />
<Border
BorderBrush="{StaticResource bordColor}"
BorderThickness="1,0,1,0"
Cursor="SizeWE" />
</Grid>

<Border
Grid.ColumnSpan="2"
BorderBrush="{StaticResource bordColor}"
BorderThickness="1,0,1,0" />

</Grid>

<ScrollViewer
Grid.Row="1"
BorderBrush="#FF2AB2E7"
BorderThickness="1"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden">
<ItemsControl ItemsSource="{Binding Materials}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Name="gr" Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>

<TextBlock
Grid.Column="0"
Margin="10,0,0,0"
VerticalAlignment="Center"
Foreground="{StaticResource TitleBorderColor}"
Text="{Binding RawMaterialName}" />

<Grid Grid.Column="1">
<Button
Command="{Binding DataContext.RemoveCommand, RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}}"
CommandParameter="{Binding RawMaterialId}"
Content="删除"
FontSize="16"
Style="{StaticResource ControlButtonStyle}" />
<Border BorderBrush="{StaticResource bordColor}" BorderThickness="1,0,1,0" />
</Grid>

<Border
Grid.ColumnSpan="2"
BorderBrush="{StaticResource bordColor}"
BorderThickness="1,0,1,1" />

</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="gr" Property="Background" Value="#112AB2E7" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<!--</Border>-->
</Grid>

</Grid>

</Border>
</Window>

+ 23
- 0
BPASmartClient.Academy/View/NewMaterialView.xaml.cs View File

@@ -0,0 +1,23 @@
using System.Windows;
using System.Windows.Input;

namespace BPASmartClient.Academy.View
{
/// <summary>
/// NewMateritalView.xaml 的交互逻辑
/// </summary>
public partial class NewMaterialView : Window
{
public NewMaterialView()
{
InitializeComponent();
this.btClose.Click += (o, e) => { this.Close(); };
this.br.MouseLeftButtonDown += (o, e) => { if (e.LeftButton == MouseButtonState.Pressed) this.DragMove(); };
}

private void btClose_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
}

+ 370
- 0
BPASmartClient.Academy/View/NewRecipeView.xaml View File

@@ -0,0 +1,370 @@
<Window
x:Class="BPASmartClient.Academy.View.NewRecipeView"
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:BPASmartClient.Academy.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:BPASmartClient.Academy.ViewModel"
Title="NewRecipeView"
Width="550"
Height="600"
AllowsTransparency="True"
Background="{x:Null}"
Topmost="True"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
mc:Ignorable="d">

<Window.DataContext>
<vm:NewRecipeViewModel />
</Window.DataContext>

<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/Themes/GenricStyle.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/Themes/MyStyle.xaml" />

<ResourceDictionary>
<!--#region ListBox样式-->
<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="20" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="border" CornerRadius="8">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion-->

<Style x:Key="closeBtn" TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Name="gr">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="/BPASmartClient.CustomResource;component/Fonts/#iconfont"
FontSize="30"
Foreground="White"
Text="&#xe8e7;" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="gr" Property="Background" Value="#22009DFF" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style x:Key="btn" TargetType="Button">
<Setter Property="Background" Value="#064d87" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
Name="gr"
Background="{TemplateBinding Background}"
CornerRadius="5"
Opacity="0.8">
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="gr" Property="Opacity" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>

<Border
Name="br"
Background="Transparent"
BorderBrush="#064d87"
BorderThickness="2">
<Grid Background="#061c43">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition />
</Grid.RowDefinitions>

<Border BorderBrush="#064d87" BorderThickness="0,0,0,2">
<Border.Background>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#064d87" />
<GradientStop Offset="1" Color="#99064d87" />
</LinearGradientBrush>
</Border.Background>
<TextBlock
Margin="10,0,0,0"
Foreground="White"
Text="新建配方" />
</Border>

<Button
Width="40"
HorizontalAlignment="Right"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Click="btClose_Click"
Style="{StaticResource closeBtn}" />

<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="30" />
<RowDefinition />
<RowDefinition Height="40" />
</Grid.RowDefinitions>

<Grid Grid.Row="0" Margin="5,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
<ColumnDefinition Width="118" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>

<TextBlock
Background="Transparent"
FontSize="20"
Foreground="#FF2AB2E7"
Text="请输入配方名称:" />

<TextBox
Grid.Column="1"
Grid.ColumnSpan="2"
Height="30"
Margin="0,0,7,0"
BorderThickness="2"
CaretBrush="DeepSkyBlue"
FontSize="16"
Text="{Binding RecipeName}" />

<TextBlock
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
HorizontalAlignment="Left"
Background="Transparent"
FontSize="16"
Foreground="Red"
Text="{Binding ErrorInfo}" />

<Button
Grid.Row="1"
Grid.Column="2"
Width="118"
Height="30"
Command="{Binding AddCommand}"
Content="添加原料"
Cursor="Hand"
Style="{StaticResource btn}" />

</Grid>

<!--#region 表格标题栏设置-->
<Grid
Grid.Row="1"
Margin="5,0"
Background="#ff0C255F">

<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.7*" />
</Grid.ColumnDefinitions>

<TextBlock
Grid.Column="0"
Grid.ColumnSpan="2"
Style="{StaticResource TitleTextblockStyle}"
Text="原料名称" />
<Border
Grid.ColumnSpan="2"
BorderBrush="{StaticResource bordColor}"
BorderThickness="1,0,1,0"
Cursor="SizeWE" />

<!--<Grid Grid.Column="1">
<TextBlock Style="{StaticResource TitleTextblockStyle}" Text="桶号" />
<Border
BorderBrush="{StaticResource bordColor}"
BorderThickness="1,0,1,0"
Cursor="SizeWE" />
</Grid>-->

<TextBlock
Grid.Column="2"
Style="{StaticResource TitleTextblockStyle}"
Text="重量" />

<Grid Grid.Column="3">
<TextBlock Style="{StaticResource TitleTextblockStyle}" Text="删除" />
<Border
BorderBrush="{StaticResource bordColor}"
BorderThickness="1,0,1,0"
Cursor="SizeWE" />
</Grid>

<Border
Grid.ColumnSpan="10"
BorderBrush="{StaticResource bordColor}"
BorderThickness="0,1,0,1" />

</Grid>
<!--#endregion-->

<ScrollViewer
Grid.Row="2"
Margin="5,0"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden">
<ItemsControl ItemsSource="{Binding RawMaterials}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton GroupName="all">
<RadioButton.Template>
<ControlTemplate TargetType="RadioButton">
<Grid Name="gr" Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.7*" />
</Grid.ColumnDefinitions>

<!--<TextBox
Grid.Column="0"
Grid.ColumnSpan="2"
Height="{Binding ElementName=gr, Path=ActualHeight}"
VerticalAlignment="Center"
BorderBrush="#FF074B92"
BorderThickness="1"
FontFamily="楷体"
FontSize="20"
Foreground="#FF2AB2E7"
Style="{StaticResource InputTextboxStyle}"
Text="{Binding RawMaterialName}" />-->

<TextBox
Name="cb"
Grid.Column="0"
Grid.ColumnSpan="2"
Height="{Binding ElementName=gr, Path=ActualHeight}"
VerticalAlignment="Center"
CaretBrush="DeepSkyBlue"
FontSize="20"
Foreground="#FF2AB2E7"
Text="{Binding RawMaterialName}" />

<!--<TextBox
Grid.Column="1"
Height="{Binding ElementName=gr, Path=ActualHeight}"
VerticalAlignment="Center"
FontSize="20"
Foreground="#FF2AB2E7"
Text="{Binding Loc}" />-->

<TextBox
Name="tb"
Grid.Column="2"
Height="{Binding ElementName=gr, Path=ActualHeight}"
VerticalAlignment="Center"
CaretBrush="DeepSkyBlue"
FontSize="20"
Foreground="#FF2AB2E7"
Text="{Binding RawMaterialWeight}" />

<TextBlock
Grid.Column="2"
Margin="0,0,8,4"
HorizontalAlignment="Right"
VerticalAlignment="Center"
FontSize="20"
Foreground="#FF2AB2E7"
Text="g" />

<Button
Grid.Column="3"
Command="{Binding DataContext.RemoveCommand, RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}}"
CommandParameter="{Binding RawMaterialId}"
Content="删除"
FontSize="16"
Style="{StaticResource ControlButtonStyle}" />

</Grid>


</ControlTemplate>
</RadioButton.Template>
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>

<Border
Grid.Row="3"
BorderBrush="#064d87"
BorderThickness="0,1,0,0">
<StackPanel
Margin="0,0,10,0"
HorizontalAlignment="Right"
Orientation="Horizontal">

<Button
Width="80"
Height="30"
Command="{Binding SaveCommand}"
Content="确认"
Style="{StaticResource btn}" />

<Button
Name="btClose"
Width="80"
Height="30"
Margin="7,0,0,0"
Click="btClose_Click"
Content="取消"
Style="{StaticResource btn}" />

</StackPanel>
</Border>


</Grid>

</Grid>
</Border>
</Window>

+ 33
- 0
BPASmartClient.Academy/View/NewRecipeView.xaml.cs View File

@@ -0,0 +1,33 @@
using BPA.Helper;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace BPASmartClient.Academy.View
{
/// <summary>
/// NewRecipeView.xaml 的交互逻辑
/// </summary>
public partial class NewRecipeView : Window
{
public NewRecipeView()
{
InitializeComponent();
//this.btClose.Click += (o, e) => { this.Close(); };
this.br.MouseLeftButtonDown += (o, e) => { if (e.LeftButton == MouseButtonState.Pressed) this.DragMove(); };
ActionManage.GetInstance.Register(new Action(() => { this.Close(); }), "CloseNewRecipeView", true);
this.Unloaded += (o, s) => { Json<LocalRecipe>.Save(); };
}

private void cb_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//ActionManage.GetInstance.SendAsync("原料选择修改", (sender as ComboBox).SelectedValue);
}

private void btClose_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
}

+ 1063
- 0
BPASmartClient.Academy/View/RecipeControlView.xaml
File diff suppressed because it is too large
View File


+ 50
- 0
BPASmartClient.Academy/View/RecipeControlView.xaml.cs View File

@@ -0,0 +1,50 @@
using BPASmartClient.Academy.ViewModel;
using System.Windows;
using System.Windows.Controls;

namespace BPASmartClient.Academy.View
{
/// <summary>
/// RecipeControlView.xaml 的交互逻辑
/// </summary>
public partial class RecipeControlView : UserControl
{
public RecipeControlView()
{
InitializeComponent();
RadioButtonWait_Click(null, null);
}

private void RadioButtonCompelete_Click(object sender, RoutedEventArgs e)
{
//repiceList.ItemsSource = RecipeControlViewModel.UserTreeCompelete;
//repiceList.Visibility = Visibility.Visible;
//repiceListMaking.Visibility = Visibility.Hidden;
//this.Wait.ItemsSource = ExcuteControl.GetInstance.UserTreeCompelete;
CookingGrid.Visibility = Visibility.Collapsed;
WaitOrCompleteGrid.Visibility = Visibility.Visible;
this.Wait.Visibility = Visibility.Visible;
}

private void RadioButtonWait_Click(object sender, RoutedEventArgs e)
{
//repiceList.ItemsSource = RecipeControlViewModel.UserTreeWait;
//repiceList.Visibility = Visibility.Visible;
//repiceListMaking.Visibility = Visibility.Hidden;
//this.Wait.ItemsSource = ExcuteControl.GetInstance.UserTreeWait;
CookingGrid.Visibility = Visibility.Collapsed;
WaitOrCompleteGrid.Visibility = Visibility.Visible;
this.Wait.Visibility = Visibility.Visible;

}

private void RadioButtonMaking_Click(object sender, RoutedEventArgs e)
{
//repiceListMaking.Visibility = Visibility.Visible;
//repiceList.Visibility = Visibility.Hidden;
WaitOrCompleteGrid.Visibility = Visibility.Collapsed;
this.Wait.Visibility = Visibility.Collapsed;
CookingGrid.Visibility = Visibility.Visible;
}
}
}

+ 319
- 0
BPASmartClient.Academy/View/RecipeSettingsView.xaml View File

@@ -0,0 +1,319 @@
<UserControl
x:Class="BPASmartClient.Academy.View.RecipeSettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:control="clr-namespace:BPASmartClient.CustomResource.UserControls;assembly=BPASmartClient.CustomResource"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BPASmartClient.Academy.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pry="clr-namespace:BPASmartClient.CustomResource.UserControls;assembly=BPASmartClient.CustomResource"
xmlns:vm="clr-namespace:BPASmartClient.Academy.ViewModel"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">

<UserControl.Resources>
<SolidColorBrush x:Key="BorderSolid" Color="#5523CACA" />
<SolidColorBrush x:Key="FontColor" Color="#FF2AB2E7" />
<SolidColorBrush x:Key="TitleFontColor" Color="#ddd" />
<SolidColorBrush x:Key="CursorColor" Color="Aqua" />
<SolidColorBrush x:Key="TitleBorderColor" Color="#FF2AB2E7" />
<SolidColorBrush x:Key="TextBlockForeground" Color="#9934F7F7" />

<Style x:Key="TextBlockStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="楷体" />
<Setter Property="FontSize" Value="20" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>

<Style x:Key="buttonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Foreground" Value="Aqua" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="BorderThickness" Value="0" />
</Style>

<!--<Style x:Key="ListViewStyle" TargetType="ListView" />-->

</UserControl.Resources>

<UserControl.DataContext>
<vm:RecipeSettingsViewModel />
</UserControl.DataContext>

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="30" />
<RowDefinition />
</Grid.RowDefinitions>

<!--#region 操作按钮-->
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<!--<pry:IcoButton
Grid.Column="3"
Width="140"
Margin="10"
HorizontalAlignment="Left"
Command="{Binding NewMaterital}"
Content="新建原料"
FontSize="16"
Foreground="Aqua"
IcoText="&#xe626;"
Style="{StaticResource IcoButtonStyle}" />-->

<!--<Button
Width="140"
Height="30"
Margin="10 0"
Command="{Binding NewMaterital}"
Content="新建原料"
FontSize="16"
Style="{StaticResource ImageButtonStyle}" />-->

<Button
Width="140"
Height="30"
Margin="10 0"
Command="{Binding NewRecipe}"
Content="新建配方"
FontSize="16"
Style="{StaticResource ImageButtonStyle}" />

<Button
Width="140"
Height="30"
Margin="10 0"
Command="{Binding SaveRecipe}"
Content="保存配方"
FontSize="16"
Style="{StaticResource ImageButtonStyle}" />

<!--<pry:IcoButton
Grid.Column="3"
Width="140"
Margin="10"
HorizontalAlignment="Left"
Command="{Binding NewRecipe}"
Content="新建配方"
FontSize="16"
Foreground="Aqua"
IcoText="&#xe626;"
Style="{StaticResource IcoButtonStyle}" />-->

<!--<pry:IcoButton
Grid.Column="3"
Width="140"
Margin="10"
HorizontalAlignment="Left"
Command="{Binding SaveRecipe}"
Content="保存配方"
FontSize="17"
Foreground="Aqua"
IcoText="&#xe635;"
IsEnabled="True"
Style="{StaticResource IcoButtonStyle}" />-->
</StackPanel>
<!--#endregion-->

<ListBox
Grid.Row="2"
Margin="5"
VerticalAlignment="Top"
Background="Transparent"
BorderThickness="0"
ItemsSource="{Binding Recipes}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<!--<UniformGrid
HorizontalAlignment="Left"
VerticalAlignment="Top"
Columns="8" />-->
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>

<ListBox.ItemTemplate>
<DataTemplate>

<Grid
Name="tt"
Width="180"
Height="220"
Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="20" />
<RowDefinition Height="128" />
<RowDefinition Height="2" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>

<Image
Grid.RowSpan="5"
Source="/BPASmartClient.CustomResource;component/Image/配方背景/竖背景框.png"
Stretch="Fill" />

<TextBlock
Grid.Row="0"
Margin="2,5,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Top"
FontSize="18"
Foreground="#FF2AB2E7"
Text="{Binding RecipeName}" />

<TextBlock
Grid.Row="1"
Margin="5,0,0,0"
VerticalAlignment="Top"
Foreground="#FF2AB2E7"
Text="配方信息:" />

<ScrollViewer
Grid.Row="2"
VerticalAlignment="Top"
Background="Transparent"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>

<ItemsControl ItemsSource="{Binding RawMaterials}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock
Grid.Row="1"
Margin="5,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Foreground="#aa2AB2E7"
Text="{Binding RawMaterialName}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

<ItemsControl Grid.Column="1" ItemsSource="{Binding RawMaterials}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">

<TextBlock
Margin="5,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#aa2AB2E7"
Text=":" />

<TextBlock
Margin="5,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#aa2AB2E7"
Text="{Binding RawMaterialWeight}" />

<TextBlock
Margin="5,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#aa2AB2E7"
Text="g" />

</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

</Grid>

</ScrollViewer>

<!--<Grid
Grid.Row="3"
Height="2"
VerticalAlignment="Bottom">
<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/直线.png" Stretch="Fill" />
</Grid.Background>
</Grid>-->

<Image
Grid.Row="3"
Width="{Binding ElementName=tt, Path=ActualWidth}"
Height="2"
VerticalAlignment="Bottom"
Source="/BPASmartClient.CustomResource;component/Image/直线.png"
Stretch="Fill" />

<Grid
Name="gr"
Grid.Row="4"
Height="30"
Margin="0,0,0,10"
VerticalAlignment="Bottom"
Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>

<Image
Grid.ColumnSpan="2"
Width="{Binding ElementName=gr, Path=ActualWidth}"
Height="2"
VerticalAlignment="Top"
Source="/BPASmartClient.CustomResource;component/Image/直线.png" />

<pry:IcoButton
Width="{Binding ElementName=gr, Path=ActualWidth}"
Height="{Binding ElementName=gr, Path=ActualHeight}"
Margin="4,4,3,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="#11F53F62"
BorderThickness="0"
Command="{Binding DataContext.RemoveCommand, RelativeSource={RelativeSource AncestorType=ListBox, Mode=FindAncestor}}"
CommandParameter="{Binding RecipeName}"
Content="删除"
EnterBackground="#22F53F62"
FontStyle="Normal"
Foreground="#FFF53F62"
IcoText="&#xe68e;"
Style="{StaticResource IcoButtonStyle}" />

<pry:IcoButton
Grid.Column="1"
Width="{Binding ElementName=gr, Path=ActualWidth}"
Height="{Binding ElementName=gr, Path=ActualHeight}"
Margin="3,4,4,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="#112AB2E7"
BorderThickness="0"
Command="{Binding DataContext.DetailsCommand, RelativeSource={RelativeSource AncestorType=ListBox, Mode=FindAncestor}}"
CommandParameter="{Binding RecipeName}"
Content="编辑"
EnterBackground="#222AB2E7"
Foreground="#FF2AB2E7"
IcoText="&#xe636;"
Style="{StaticResource IcoButtonStyle}" />

</Grid>
<!--</StackPanel>-->
</Grid>

</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

</Grid>
</UserControl>

+ 41
- 0
BPASmartClient.Academy/View/RecipeSettingsView.xaml.cs View File

@@ -0,0 +1,41 @@
using BPA.Helper;
using System.Windows;
using System.Windows.Controls;

namespace BPASmartClient.Academy.View
{
/// <summary>
/// RecipeSettingsView.xaml 的交互逻辑
/// </summary>
public partial class RecipeSettingsView : UserControl
{
public RecipeSettingsView()
{
InitializeComponent();
this.Unloaded += RecipeSettingsView_Unloaded;
}

private void RecipeSettingsView_Unloaded(object sender, RoutedEventArgs e)
{
Json<LocalRecipe>.Save();
}

//public static void SetAlignment()
//{
// //获取系统是以Left-handed(true)还是Right-handed(false)
// var ifLeft = SystemParameters.MenuDropAlignment;

// if (ifLeft)
// {
// Console.WriteLine($"系统为左撇子,转换为右撇子。");

// // change to false
// var t = typeof(SystemParameters);
// var field = t.GetField("_menuDropAlignment", BindingFlags.NonPublic | BindingFlags.Static);
// field.SetValue(null, false);

// ifLeft = SystemParameters.MenuDropAlignment;
// }
//}
}
}

+ 16
- 0
BPASmartClient.Academy/ViewModel/DeviceMotionViewModel.cs View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.Academy.ViewModel
{
public class DeviceMotionViewModel : NotifyBase
{
public DeviceMotionViewModel()
{

}
}
}

+ 52
- 0
BPASmartClient.Academy/ViewModel/NewMaterialViewModel.cs View File

@@ -0,0 +1,52 @@
using BPA.Helper;
using BPASmartClient.CustomResource.Pages.Model;
using BPASmartClient.Model;
using System;
using System.Collections.ObjectModel;
using System.Linq;

namespace BPASmartClient.Academy.ViewModel;

public class NewMaterialViewModel : ViewModelBase
{
public ObservableCollection<RawMaterialModel> Materials { get; set; } = Json<LocaMaterial>.Data.LocalMaterails;

public string MaterialName { get { return _materialName; } set { _materialName = value; OnPropertyChanged(); } }
private string _materialName = string.Empty;

//public string ErrorInfo { get { return _mErrorInfo; } set { _mErrorInfo = value; OnPropertyChanged(); } }
//private string _mErrorInfo;

//public BPARelayCommand<object> RemoveCommand { get; set; }

//public BPARelayCommand SaveCommand { get; set; }



private void Remove(object o)
{
if (o == null) return;
if (o is string id)
{
var res = Materials.FirstOrDefault(p => p.RawMaterialId == id);
Materials.Remove(res);
Json<LocaMaterial>.Save();
MessageNotify.GetInstance.ShowUserLog($"删除原料--{res.RawMaterialName}");
}
}

public NewMaterialViewModel()
{
RemoveCommand = new BPARelayCommand<object>(Remove);

SaveCommand = new BPARelayCommand(() =>
{
if (MaterialName == String.Empty) { ErrorInfo = "原料名称不能为空"; return; }
if (Global.DeviceRawMaterials.FirstOrDefault(p => p.RawMaterialName == MaterialName) != null) { ErrorInfo = "设备中已存在该原料名称"; return; }
if (Json<LocaMaterial>.Data.LocalMaterails.FirstOrDefault(p => p.RawMaterialName == MaterialName) != null) { ErrorInfo = "本地原料名称重复"; return; }
Json<LocaMaterial>.Data.LocalMaterails.Add(new RawMaterialModel { RawMaterialName = MaterialName, RawMaterialId = Guid.NewGuid().ToString() });
Json<LocaMaterial>.Save();
MessageNotify.GetInstance.ShowUserLog($"添加原料--{MaterialName}");
});
}
}

+ 160
- 0
BPASmartClient.Academy/ViewModel/NewRecipeViewModel.cs View File

@@ -0,0 +1,160 @@
using BPA.Helper;
using BPASmartClient.CustomResource.Pages.Model;
using BPASmartClient.CustomResource.UserControls;
using BPASmartClient.CustomResource.UserControls.MessageShow;
using BPASmartClient.Academy.Model;
using BPASmartClient.Model;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

namespace BPASmartClient.Academy.ViewModel
{
public class NewRecipeViewModel : ViewModelBase
{
public NewRecipeViewModel()
{

ActionManage.GetInstance.Register(new Action<object>((o) =>
{
if (o != null && o is RecipeModel rm)
{
RecipeName = rm.RecipeName;
foreach (var item in rm.RawMaterials)
{
item.SelectIndex = Array.FindIndex(RawMaterialNames.ToArray(), p => p == item.RawMaterialName);
RawMaterials.Add(item);
}
RecipCode = rm.RecipCode;
Index = Array.FindIndex(Json<LocalRecipe>.Data.Recipes.ToArray(), p => p.RecipeName == RecipeName);
}
}), "Details", true);

AddCommand = new BPARelayCommand(() =>
{
p:
string guid = Guid.NewGuid().ToString();
if (RawMaterials.FirstOrDefault(p => p.RawMaterialId == guid) == null)
{
int index = RawMaterials.Count;
RawMaterials.Add(new RawMaterialModel()
{
RawMaterialId = guid,
SelectIndex = index
});
}
else goto p;
});

RemoveCommand = new BPARelayCommand<object>((obj) =>
{
if (obj is string rm)
{
var res = RawMaterials.FirstOrDefault(p => p.RawMaterialId == rm);
if (res != null) RawMaterials.Remove(res);
}
});

SaveCommand = new BPARelayCommand(() =>
{
if (string.IsNullOrEmpty(RecipeName)) { MessageNotify.GetInstance.ShowDialog("请输入配方名称!", DialogType.Warning); ErrorInfo = "请输入配方名称"; return; }
var tempRes = RawMaterials.GroupBy(p => p.RawMaterialName);

//编辑配方
if (Index >= 0 && Index < Json<LocalRecipe>.Data.Recipes.Count)
{
var res = Array.FindIndex(Json<LocalRecipe>.Data.Recipes.ToArray(), p => p.RecipeName == RecipeName);
if (res >= 0 && res != Index)
{
ErrorInfo = "配方名称已经存在!";
MessageNotify.GetInstance.ShowDialog("配方名称已经存在!", DialogType.Warning);
return;
}
Json<LocalRecipe>.Data.Recipes.ElementAt(Index).RecipeName = RecipeName;
Json<LocalRecipe>.Data.Recipes.ElementAt(Index).RawMaterials.Clear();
RawMaterials.ToList()?.ForEach(item =>
{
Json<LocalRecipe>.Data.Recipes.ElementAt(Index).RawMaterials.Add(item);
});
Json<LocalRecipe>.Save();
NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"{RecipeName} 配方编辑完成");
}
else //新建配方
{
if (Json<LocalRecipe>.Data.Recipes.FirstOrDefault(p => p.RecipeName == RecipeName) != null)
{
ErrorInfo = "配方名称已存在!";
MessageNotify.GetInstance.ShowDialog("配方名称已经存在!", DialogType.Warning);
return;
}
ObservableCollection<RawMaterialModel> TempRawMaterials = new ObservableCollection<RawMaterialModel>();
RawMaterials.ToList()?.ForEach(item =>
{
TempRawMaterials.Add(item);
});
Json<LocalRecipe>.Data.Recipes.Add(new RecipeModel()
{
RecipeName = RecipeName,
RawMaterials = TempRawMaterials,
});
Json<LocalRecipe>.Save();
NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"新建配方成功!");
}
ActionManage.GetInstance.Send("CloseNewRecipeView");
});

if (Global.userInfo.permission == CustomResource.Pages.Enums.Permission.管理员)
{
foreach (var item in Global.DeviceRawMaterials)
{
RawMaterialNames.Add(item.RawMaterialName);

}
foreach (var item in Json<LocaMaterial>.Data.LocalMaterails)
{
RawMaterialNames.Add(item.RawMaterialName);
}
}
else
{
foreach (var item in Global.DeviceRawMaterials)
{
if (Global.userInfo.devRawMaterials.FirstOrDefault(p => p.RawMaterialName == item.RawMaterialName) != null) RawMaterialNames.Add(item.RawMaterialName);

}
foreach (var item in Json<LocaMaterial>.Data.LocalMaterails)
{
if (Global.userInfo.locaRawMaterials.FirstOrDefault(p => p.RawMaterialName == item.RawMaterialName) != null) RawMaterialNames.Add(item.RawMaterialName);
}
}

}

private void AddRecipes()
{
string date = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
var dates = date.Split("-").ToList();
StringBuilder sb = new StringBuilder();
dates?.ForEach((item) => { sb.Append(item); });
Json<LocalRecipe>.Data.Recipes.Add(new RecipeModel()
{
SerialNum = Json<LocalRecipe>.Data.Recipes.Count + 1,
RawMaterials = RawMaterials,
RecipCode = sb.ToString(),
RecipeName = RecipeName,
});
}


private string RecipCode = string.Empty;

public string RecipeName { get { return _mRecipeName; } set { _mRecipeName = value; OnPropertyChanged(); } }
private string _mRecipeName = string.Empty;

public ObservableCollection<RawMaterialModel> RawMaterials { get; set; } = new ObservableCollection<RawMaterialModel>();


public ObservableCollection<string> RawMaterialNames { get; set; } = new ObservableCollection<string>();
}
}

+ 42
- 0
BPASmartClient.Academy/ViewModel/RecipeControlViewModel.cs View File

@@ -0,0 +1,42 @@
using BPA.Helper;
using BPASmartClient.CustomResource.Pages.Model;
using BPASmartClient.CustomResource.UserControls;
using BPASmartClient.CustomResource.UserControls.MessageShow;
using BPASmartClient.Model;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace BPASmartClient.Academy.ViewModel
{
public class RecipeControlViewModel : NotifyBase
{
public RecipeControlViewModel()
{
StartCommand = new BPARelayCommand<object>(new Action<object>((o) =>
{
if (o != null && o is string recipeName)
{
ActionManage.GetInstance.Send("配方下发", recipeName);
}
}));
CancelRecipeCommand = new BPARelayCommand<object>(new Action<object>((ob) =>
{
if (ob != null && ob is RecipeModel recipe)
{
ActionManage.GetInstance.Send("取消配方", recipe.RecipeName);
}
}));
}
public BPARelayCommand<object> StartCommand { get; set; }

public BPARelayCommand<object> CancelRecipeCommand { get; set; }
}


}

+ 87
- 0
BPASmartClient.Academy/ViewModel/RecipeSettingsViewModel.cs View File

@@ -0,0 +1,87 @@
using BPA.Helper;
using BPASmartClient.CustomResource.Pages.Model;
using BPASmartClient.CustomResource.UserControls;
using BPASmartClient.CustomResource.UserControls.MessageShow;
using BPASmartClient.Academy.Model;
using BPASmartClient.Academy.View;
using System.Collections.ObjectModel;
using System.Linq;

namespace BPASmartClient.Academy.ViewModel
{
public class RecipeSettingsViewModel : NotifyBase
{
public RecipeSettingsViewModel()
{
Recipes = Json<LocalRecipe>.Data.Recipes;

NewMaterital = new BPARelayCommand(() =>
{
NewMaterialView newMateritalView = new NewMaterialView();
newMateritalView.ShowDialog();
});
NewRecipe = new BPARelayCommand(() =>
{
NewRecipeView nrv = new NewRecipeView();
nrv.ShowDialog();
MessageNotify.GetInstance.ShowUserLog("新建配方");
});
SaveRecipe = new BPARelayCommand(() =>
{
Json<LocalRecipe>.Save();
MessageNotify.GetInstance.ShowUserLog("保存配方");
NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方保存成功!");
});
RemoveCommand = new BPARelayCommand<object>((o) =>
{
if (!string.IsNullOrEmpty(o?.ToString()))
{
if (MessageNotify.GetInstance.ShowDialog($"是否删除【{o.ToString()}】配方,删除后数据将永久丢失!无法找回", DialogType.Warning))
{
var res = Json<LocalRecipe>.Data.Recipes.FirstOrDefault(p => p.RecipeName == o.ToString());
if (res.IsEnable)
{
if (res != null) Json<LocalRecipe>.Data.Recipes.Remove(res);
Json<LocalRecipe>.Save();
NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方删除成功!");
MessageNotify.GetInstance.ShowUserLog($"删除配方 {res.RecipeName}");
}
else
{
NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, App.MainWindow, "提示", $"删除【{o.ToString()}】配方失败,配方正在使用!");
}
}
}
});

DetailsCommand = new BPARelayCommand<object>((o) =>
{
if (!string.IsNullOrEmpty(o?.ToString()))
{
var res = Json<LocalRecipe>.Data.Recipes.FirstOrDefault(p => p.RecipeName == o.ToString());
if (res != null)
{
NewRecipeView nrv = new NewRecipeView();
//ActionManage.GetInstance.Send("Details", res);
nrv.ShowDialog();
}
}
});

}

public BPARelayCommand NewMaterital { get; set; }

public BPARelayCommand NewRecipe { get; set; }

public BPARelayCommand SaveRecipe { get; set; }

public BPARelayCommand<object> EditCommand { get; set; }

public BPARelayCommand<object> DetailsCommand { get; set; }

public BPARelayCommand<object> RemoveCommand { get; set; }

public ObservableCollection<RecipeModel> Recipes { get; set; }
}
}

BIN
View File


+ 793
- 326
BPASmartClient.CustomResource/Pages/View/UserConfigView.xaml
File diff suppressed because it is too large
View File


+ 24
- 1
SmartClient.sln View File

@@ -170,7 +170,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "阿里云IOT平台测试",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.AliyunIot", "BPASmartClient.AliyunIot\BPASmartClient.AliyunIot.csproj", "{75CD8585-6D44-4291-9524-0B6CE22D3C74}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkSVer3", "BPASmartClient.MorkSWithNoodleMachine\BPASmartClient.MorkSVer3.csproj", "{B042F069-B71A-40AA-81F3-BA8AFF7F075F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkSVer3", "BPASmartClient.MorkSWithNoodleMachine\BPASmartClient.MorkSVer3.csproj", "{B042F069-B71A-40AA-81F3-BA8AFF7F075F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Academy", "BPASmartClient.Academy\BPASmartClient.Academy.csproj", "{B7644117-360F-4ECD-AB25-F1895B973B7D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1626,6 +1628,26 @@ Global
{B042F069-B71A-40AA-81F3-BA8AFF7F075F}.Release|x64.Build.0 = Release|Any CPU
{B042F069-B71A-40AA-81F3-BA8AFF7F075F}.Release|x86.ActiveCfg = Release|Any CPU
{B042F069-B71A-40AA-81F3-BA8AFF7F075F}.Release|x86.Build.0 = Release|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Debug|ARM.Build.0 = Debug|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Debug|ARM64.Build.0 = Debug|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Debug|x64.ActiveCfg = Debug|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Debug|x64.Build.0 = Debug|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Debug|x86.ActiveCfg = Debug|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Debug|x86.Build.0 = Debug|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Release|Any CPU.Build.0 = Release|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Release|ARM.ActiveCfg = Release|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Release|ARM.Build.0 = Release|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Release|ARM64.ActiveCfg = Release|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Release|ARM64.Build.0 = Release|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Release|x64.ActiveCfg = Release|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Release|x64.Build.0 = Release|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Release|x86.ActiveCfg = Release|Any CPU
{B7644117-360F-4ECD-AB25-F1895B973B7D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1705,6 +1727,7 @@ Global
{36E8EDC4-DD22-4968-B43A-984A5DDE5D78} = {8712125E-14CD-4E1B-A1CE-4BDE03805942}
{75CD8585-6D44-4291-9524-0B6CE22D3C74} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625}
{B042F069-B71A-40AA-81F3-BA8AFF7F075F} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F}
{B7644117-360F-4ECD-AB25-F1895B973B7D} = {8712125E-14CD-4E1B-A1CE-4BDE03805942}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC}


Loading…
Cancel
Save