@@ -12,6 +12,7 @@ | |||||
<section name="StockInfo5" type="System.Configuration.NameValueSectionHandler"/> | <section name="StockInfo5" type="System.Configuration.NameValueSectionHandler"/> | ||||
<section name="StockInfo6" type="System.Configuration.NameValueSectionHandler"/> | <section name="StockInfo6" type="System.Configuration.NameValueSectionHandler"/> | ||||
<section name="Services" type="System.Configuration.NameValueSectionHandler"/> | <section name="Services" type="System.Configuration.NameValueSectionHandler"/> | ||||
<section name="MQTTParam" type="System.Configuration.NameValueSectionHandler"/> | |||||
</sectionGroup> | </sectionGroup> | ||||
</configSections> | </configSections> | ||||
<FlexBatchSystem> | <FlexBatchSystem> | ||||
@@ -59,5 +60,11 @@ | |||||
<add key="Service4" value="CancelRecipeService"/> | <add key="Service4" value="CancelRecipeService"/> | ||||
</Services> | </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> | </FlexBatchSystem> | ||||
</configuration> | </configuration> |
@@ -4,6 +4,8 @@ using BPASmartClient.CustomResource.Pages.Model; | |||||
using BPASmartClient.CustomResource.Pages.View; | using BPASmartClient.CustomResource.Pages.View; | ||||
using BPASmartClient.CustomResource.Pages.ViewModel; | using BPASmartClient.CustomResource.Pages.ViewModel; | ||||
using BPASmartClient.DosingSystem.Model; | using BPASmartClient.DosingSystem.Model; | ||||
using BPASmartClient.DosingSystem.Model.MQTT; | |||||
using BPASmartClient.DosingSystem.Service; | |||||
using System; | using System; | ||||
using System.Collections.ObjectModel; | using System.Collections.ObjectModel; | ||||
using System.Collections.Specialized; | using System.Collections.Specialized; | ||||
@@ -58,6 +60,7 @@ namespace BPASmartClient.DosingSystem | |||||
await Task.Run(() => { excute = ExcuteControl.GetInstance; }); | await Task.Run(() => { excute = ExcuteControl.GetInstance; }); | ||||
MenuInit(); | MenuInit(); | ||||
//SiemensTest.GetInstance.Init(); | //SiemensTest.GetInstance.Init(); | ||||
DeviceInquire.GetInstance.Init();//配料机设备上线监听,设备列表初始化 | DeviceInquire.GetInstance.Init();//配料机设备上线监听,设备列表初始化 | ||||
MainView mv = new MainView(); | MainView mv = new MainView(); | ||||
@@ -92,6 +95,8 @@ namespace BPASmartClient.DosingSystem | |||||
} | } | ||||
else | else | ||||
mv.Close(); | mv.Close(); | ||||
ServerFactory.GetInstance.Set(new APIServer()); | |||||
MqttServer.GetInstance.Init(); | |||||
MainWindow = mv; | MainWindow = mv; | ||||
} | } | ||||
@@ -280,7 +285,7 @@ namespace BPASmartClient.DosingSystem | |||||
ToggleWindowPath = "View.DeviceListView" | ToggleWindowPath = "View.DeviceListView" | ||||
}); | }); | ||||
//2023/6/29修改 | //2023/6/29修改 | ||||
if ((ConveryType)Enum.Parse(typeof(ConveryType), Json<DevicePar>.Data.BaseParModel.ConveryType) == ConveryType.U型) | |||||
if (!String.IsNullOrWhiteSpace(Json<DevicePar>.Data.BaseParModel.ConveryType) && (ConveryType)Enum.Parse(typeof(ConveryType), Json<DevicePar>.Data.BaseParModel.ConveryType) == ConveryType.U型) | |||||
{ | { | ||||
DeviceMonitor.Add(new SubMenumodel() | DeviceMonitor.Add(new SubMenumodel() | ||||
{ | { | ||||
@@ -29,6 +29,8 @@ using static Microsoft.EntityFrameworkCore.DbLoggerCategory; | |||||
using System.Windows.Navigation; | using System.Windows.Navigation; | ||||
using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||
using static System.Resources.ResXFileRef; | using static System.Resources.ResXFileRef; | ||||
using BPASmartClient.DosingSystem.Model.Dto; | |||||
using BPASmartClient.DosingSystem.Model.MQTT; | |||||
namespace BPASmartClient.DosingSystem | namespace BPASmartClient.DosingSystem | ||||
{ | { | ||||
@@ -102,8 +104,8 @@ namespace BPASmartClient.DosingSystem | |||||
RecipeRun(); | RecipeRun(); | ||||
BusinessExcute(); | BusinessExcute(); | ||||
ConveyerPropertyReport(); | ConveyerPropertyReport(); | ||||
#if Debug | |||||
ThreadTaskInit(); | |||||
#if Debug | |||||
Task.Run(() => { | Task.Run(() => { | ||||
while (true) | while (true) | ||||
{ | { | ||||
@@ -749,8 +751,58 @@ namespace BPASmartClient.DosingSystem | |||||
/// <summary> | |||||
/// 多线程接收工单配方数据。 | |||||
/// </summary> | |||||
private void ThreadTaskInit() | |||||
{ | |||||
TaskManage.GetInstance.StartLong(new Action(() => | |||||
{ | |||||
while (MqttServer.GetInstance.WorkOrders.Count > 0) | |||||
{ | |||||
if (MqttServer.GetInstance.WorkOrders.TryDequeue(out WorkOrderPusht wod)) | |||||
{ | |||||
App.Current?.Dispatcher?.Invoke(new Action(() => | |||||
{ | |||||
//TODO:工单数据处理,直接新建配方。 | |||||
foreach (var recipe in wod.ProductList) | |||||
{ | |||||
var tempRecipe = new RecipeModel(); | |||||
var tempMaterials = new ObservableCollection<RawMaterialModel>(); | |||||
if (Json<LocalRecipe>.Data.Recipes.Any(p => p.RecipCode == recipe.Id)) | |||||
{ | |||||
continue; | |||||
} | |||||
else | |||||
{ | |||||
tempRecipe.RecipCode = recipe.Id; | |||||
} | |||||
tempRecipe.RecipeName = recipe.Name; | |||||
foreach (var material in recipe.BOMEntryList) | |||||
{ | |||||
tempMaterials.Add(new RawMaterialModel() | |||||
{ | |||||
RawMaterialName = material.MaterialName, | |||||
DeviceIp="", | |||||
Loc=1, | |||||
RawMaterialWeight=(uint)material.BomQty, | |||||
RawMaterialSource=0, | |||||
RawMaterialId=material.MaterialId, | |||||
}); | |||||
} | |||||
tempRecipe.RawMaterials = tempMaterials; | |||||
Json<LocalRecipe>.Data.Recipes.Add(tempRecipe); | |||||
} | |||||
})); | |||||
} | |||||
} | |||||
Thread.Sleep(500); | |||||
}), "工单信息监听"); | |||||
} | |||||
@@ -0,0 +1,83 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Model.Dto | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
public class BOMEntryOutput | |||||
{ | |||||
/// <summary> | |||||
/// 主键 | |||||
/// </summary> | |||||
public string Id { get; set; } | |||||
/// <summary> | |||||
/// 工单id | |||||
/// </summary> | |||||
public string WorkOrderId { get; set; } | |||||
/// <summary> | |||||
/// 工单id | |||||
/// </summary> | |||||
public string WorkOrderName { get; set; } | |||||
/// <summary> | |||||
/// 配方单位 | |||||
/// </summary> | |||||
public string UnitId { get; set; } | |||||
/// <summary> | |||||
/// 配方单位名称 | |||||
/// </summary> | |||||
public string UnitName { get; set; } | |||||
/// <summary> | |||||
/// 上误差值 | |||||
/// </summary> | |||||
public string UpErrorValue { get; set; } | |||||
/// <summary> | |||||
/// 下误差值 | |||||
/// </summary> | |||||
public string DownErrorValue { get; set; } | |||||
/// <summary> | |||||
/// 物料id | |||||
/// </summary> | |||||
public string MaterialId { get; set; } | |||||
/// <summary> | |||||
/// 物料名称 | |||||
/// </summary> | |||||
public string MaterialName { get; set; } | |||||
/// <summary> | |||||
/// 产品Id | |||||
/// </summary> | |||||
public string ProductId { get; set; } | |||||
/// <summary> | |||||
/// 产品名称 | |||||
/// </summary> | |||||
public string ProductName { get; set; } | |||||
/// <summary> | |||||
/// 配方用量 | |||||
/// </summary> | |||||
public decimal BomQty { get; set; } | |||||
/// <summary> | |||||
/// 产量 | |||||
/// </summary> | |||||
public string Yield { get; set; } | |||||
/// <summary> | |||||
/// 配方id | |||||
/// </summary> | |||||
public string BomId { get; set; } | |||||
/// <summary> | |||||
/// 1主料配方0 辅料配方 | |||||
/// </summary> | |||||
public bool IsMain { get; set; } | |||||
/// <summary> | |||||
/// 计划完成时间 | |||||
/// </summary> | |||||
public string PlantEndTime { get; set; } | |||||
/// <summary> | |||||
/// 计划开始时间 | |||||
/// </summary> | |||||
public string PlantStartTime { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,30 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Model.Dto | |||||
{ | |||||
public class BOMOutput | |||||
{ | |||||
/// <summary> | |||||
/// 主键 | |||||
/// </summary> | |||||
public string Id { get; set; } | |||||
/// <summary> | |||||
/// 配方名称 | |||||
/// </summary> | |||||
public string Name { get; set; } | |||||
/// <summary> | |||||
/// 1主料配方0 辅料配方 | |||||
/// </summary> | |||||
public bool IsMain { get; set; } | |||||
/// <summary> | |||||
/// 配方明细 | |||||
/// </summary> | |||||
public List<BOMEntryOutput> BOMEntryList { get; set; } = new(); | |||||
} | |||||
} |
@@ -0,0 +1,37 @@ | |||||
using BPASmartClient.DosingSystem.Model.MQTT.Messages; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Model.Dto | |||||
{ | |||||
public class WorkOrderPusht : IMessage | |||||
{ | |||||
/// <summary> | |||||
/// 主键 | |||||
/// </summary> | |||||
public string Id { get; set; } | |||||
/// <summary> | |||||
/// 工单名称 | |||||
/// </summary> | |||||
public string Name { get; set; } | |||||
/// <summary> | |||||
/// 计划完成时间 | |||||
/// </summary> | |||||
public string PlantEndTime { get; set; } | |||||
/// <summary> | |||||
/// 产量 | |||||
/// </summary> | |||||
public string Yield { get; set; } | |||||
/// <summary> | |||||
/// 计划开始时间 | |||||
/// </summary> | |||||
public string PlantStartTime { get; set; } | |||||
/// <summary> | |||||
/// 配方信息 | |||||
/// </summary> | |||||
public List<BOMOutput> ProductList { get; set; } = new(); | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Model.MQTT | |||||
{ | |||||
public interface IServer | |||||
{ | |||||
Task Init(params object[] pars); | |||||
void Dispose(); | |||||
} | |||||
} |
@@ -0,0 +1,12 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Model.MQTT.Messages | |||||
{ | |||||
public interface IMessage | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,13 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
namespace BPASmartClient.DosingSystem.Model.MQTT.Messages | |||||
{ | |||||
public class MessageDefine | |||||
{ | |||||
public static readonly Dictionary<int, Type> MSG = new Dictionary<int, Type>() | |||||
{ | |||||
{ MessageID.WorkOrderIssued,typeof(WorkOrderPublishOutput)}, | |||||
}; | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
namespace BPASmartClient.DosingSystem.Model.MQTT.Messages | |||||
{ | |||||
public class MessageID | |||||
{ | |||||
public const int DevcieControl = 1;//出入库命令控制ID | |||||
public const int WorkOrderIssued = 2;//工单下发ID | |||||
public const int StatusChange = 3;//配料流程修改ID | |||||
public const int MakeDown = 4;//工单配方下发ID | |||||
public const int DeviceDataUpdate = 5;//设备数据更新ID | |||||
public const int HandControlComm = 6;//手动控制命令 | |||||
public const int DataActualTimeUpdate = 7;//设备数据实时更新 | |||||
public const int UiChangeNotify = 8;//UI操作更新 | |||||
public const int StoreStockTaking = 9;//库存盘点 | |||||
public const int LogInfoNotify = 10;//业务服务日志消息通知 | |||||
} | |||||
} |
@@ -0,0 +1,8 @@ | |||||
namespace BPASmartClient.DosingSystem.Model.MQTT.Messages | |||||
{ | |||||
public class MqttBaseModel : IMessage | |||||
{ | |||||
/// <summary>客户端唯一ID,客户端区分</summary> | |||||
public short ClientId { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,86 @@ | |||||
using BPA.Helper; | |||||
using Newtonsoft.Json; | |||||
using Newtonsoft.Json.Linq; | |||||
using System; | |||||
using System.Linq; | |||||
namespace BPASmartClient.DosingSystem.Model.MQTT.Messages | |||||
{ | |||||
public static class MsgPackExtensionMethod | |||||
{ | |||||
public static MsgPackage Deserialize(this string msg) | |||||
{ | |||||
if (msg != null) | |||||
{ | |||||
if (msg.Iskey("MessageId") && msg.Iskey("Message") && msg.Iskey("MessageLen")) | |||||
{ | |||||
var obj = msg.FromJSON<MsgPackage>(); | |||||
if (obj != null) | |||||
return obj; | |||||
} | |||||
else | |||||
{ | |||||
var id = msg.ToLower().GetJsonObjValue("messageid"); | |||||
if (int.TryParse(id, out int tempId)) | |||||
{ | |||||
if (MessageDefine.MSG.ContainsKey(tempId)) | |||||
{ | |||||
MsgPackage package = new MsgPackage(); | |||||
package.MessageId = tempId; | |||||
if (int.TryParse(msg.ToLower().GetJsonObjValue("messagelen"), out int tempLen)) | |||||
package.MessageLen = tempLen; | |||||
var res = msg.ToLower().GetJsonObjValue("message"); | |||||
if (res != null) | |||||
{ | |||||
package.Message = (IMessage)JsonConvert.DeserializeObject(res, MessageDefine.MSG[tempId]); | |||||
} | |||||
return package; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return new MsgPackage(); | |||||
} | |||||
public static string Serialize(this IMessage mes) | |||||
{ | |||||
MsgPackage msg = new MsgPackage(); | |||||
var res = MessageDefine.MSG.FirstOrDefault(p => p.Value == mes.GetType()); | |||||
msg.MessageId = res.Key; | |||||
msg.MessageLen = JsonConvert.SerializeObject(mes).Length; | |||||
msg.Message = mes; | |||||
return JsonConvert.SerializeObject(msg); | |||||
} | |||||
public static string GetJsonObjValue(this string input, string key) | |||||
{ | |||||
try | |||||
{ | |||||
JObject jo = (JObject)JsonConvert.DeserializeObject(input); | |||||
if (jo != null && jo.ContainsKey(key)) | |||||
return jo[key].ToString(); | |||||
else | |||||
return string.Empty; | |||||
} | |||||
catch (Exception EX) | |||||
{ | |||||
MessageLog.GetInstance.ShowEx(EX.ToString()); | |||||
return string.Empty; | |||||
} | |||||
} | |||||
public static bool Iskey(this string input, string key) | |||||
{ | |||||
try | |||||
{ | |||||
JObject jo = (JObject)JsonConvert.DeserializeObject(input); | |||||
return jo != null && jo.ContainsKey(key); | |||||
} | |||||
catch (Exception EX) | |||||
{ | |||||
MessageLog.GetInstance.ShowEx(EX.ToString()); | |||||
return false; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,17 @@ | |||||
using Newtonsoft.Json; | |||||
namespace BPASmartClient.DosingSystem.Model.MQTT.Messages | |||||
{ | |||||
public class MsgPackage | |||||
{ | |||||
/// <summary>消息ID</summary> | |||||
public int MessageId { get; set; } | |||||
/// <summary>消息内容</summary> | |||||
[JsonProperty(TypeNameHandling = TypeNameHandling.Auto)] | |||||
public IMessage Message { get; set; } | |||||
/// <summary>消息长度</summary> | |||||
public int MessageLen { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,19 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Model.MQTT.Messages | |||||
{ | |||||
/// <summary> | |||||
/// 下发数据 | |||||
/// </summary> | |||||
public class WorkOrderPublishOutput : IMessage | |||||
{ | |||||
/// <summary> | |||||
/// 工单Id | |||||
/// </summary> | |||||
public string WorkOrderId { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,120 @@ | |||||
using Aop.Api.Domain; | |||||
using BPA.Communication; | |||||
using BPA.Communication.Base; | |||||
using BPA.Helper; | |||||
using BPASmartClient.DosingSystem.Model.Dto; | |||||
using BPASmartClient.DosingSystem.Model.MQTT.Messages; | |||||
using BPASmartClient.DosingSystem.Service; | |||||
using BPASmartClient.Model; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using System; | |||||
using System.Collections.Concurrent; | |||||
using System.Collections.Generic; | |||||
using System.Collections.Specialized; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Model.MQTT | |||||
{ | |||||
public class MqttServer : IServer | |||||
{ | |||||
private volatile static MqttServer _Instance; | |||||
public static MqttServer GetInstance => _Instance ?? (_Instance = new MqttServer()); | |||||
private MqttServer() { } | |||||
/// <summary> | |||||
/// MQTT 消息 | |||||
/// </summary> | |||||
ConcurrentQueue<string> msg= new ConcurrentQueue<string>(); | |||||
MqttHelper mqttHelper = new MqttHelper(); | |||||
NameValueCollection mqttParam; | |||||
/// <summary> | |||||
/// 工单信息 | |||||
/// </summary> | |||||
public ConcurrentQueue<WorkOrderPusht> WorkOrders { get; set; } = new ConcurrentQueue<WorkOrderPusht>(); | |||||
public Task Init(params object[] pars) | |||||
{ | |||||
return Task.Factory.StartNew(() => | |||||
{ | |||||
mqttParam = (NameValueCollection)System.Configuration.ConfigurationManager.GetSection("FlexBatchSystem/MQTTParam"); | |||||
//mqttHelper.IsVerifyNetwork = false; | |||||
mqttHelper.MessageRecive = new Action<string>( | |||||
s => { | |||||
msg.Enqueue(s); }); | |||||
mqttHelper.Connected = new Action(() => | |||||
{ | |||||
if (pars.Length > 0) | |||||
{ | |||||
pars.ToList().ForEach(item => { mqttHelper.Subscrib(item?.ToString()); }); | |||||
} | |||||
else | |||||
{ | |||||
//mqttHelper.Subscrib(Topics.MakeDown); | |||||
//mqttHelper.Subscrib(Topics.StatusChange); | |||||
mqttHelper.Subscrib(Topics.WorkOrderDown); | |||||
//mqttHelper.Subscrib(Topics.DataActualTimeUpdate); | |||||
} | |||||
TaskManage.GetInstance.StartLong(new Action(() => | |||||
{ | |||||
while (msg.Count > 0) | |||||
{ | |||||
try | |||||
{ | |||||
if (msg.TryDequeue(out string str)) | |||||
{ | |||||
var res = str.Deserialize(); | |||||
if (res?.Message is WorkOrderPublishOutput wod) | |||||
WorkOrderPublish(wod); | |||||
} | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
MessageLog.GetInstance.ShowEx(ex.ToString()); | |||||
} | |||||
} | |||||
Thread.Sleep(10); | |||||
}), "MCS工单信息接收", true); | |||||
}); | |||||
//mqttHelper.Connect(Json<ConnectConfig>.Data.MqttUser, Json<ConnectConfig>.Data.MqttPas, Json<ConnectConfig>.Data.MqttIp, Json<ConnectConfig>.Data.MqttPort, $"WCS系统,{Guid.NewGuid()}"); | |||||
mqttHelper.Connect(new ConfigurationOptions() | |||||
{ | |||||
UserName = mqttParam?.Get("UserName")?? "admin", | |||||
Password = mqttParam?.Get("Password")?? "admin8765490789", | |||||
IpAddress =mqttParam?.Get("IpAddress")?? "111.9.47.105", | |||||
Port =int.TryParse( mqttParam?.Get("Port"),out int port)?port:18883, | |||||
ClientId = $"WCS系统业务消息,{Guid.NewGuid()}" | |||||
}); | |||||
}); | |||||
} | |||||
private void WorkOrderPublish(WorkOrderPublishOutput wod) | |||||
{ | |||||
Task.Factory.StartNew(new Action(() => | |||||
{ | |||||
var x = ServerFactory.GetInstance.Get().GetWorkOrder(wod.WorkOrderId); | |||||
if (x.IsSuccess && x.Content.Count > 0) | |||||
{ | |||||
var wop = x.Content.ElementAt(0); | |||||
wop.ProductList = wop.ProductList.OrderBy(p => p.Name).ToList(); | |||||
WorkOrders.Enqueue(wop); | |||||
} | |||||
})); | |||||
} | |||||
public void Dispose() | |||||
{ | |||||
mqttHelper.Dispose(); | |||||
} | |||||
public static void Dis() => _Instance = null; | |||||
} | |||||
} |
@@ -0,0 +1,61 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Model.MQTT | |||||
{ | |||||
public class Topics | |||||
{ | |||||
/// <summary> | |||||
/// 工单下发 | |||||
/// </summary> | |||||
public const string WorkOrderDown = "WMS/WCS/WorkOrderDown"; | |||||
/// <summary> | |||||
/// 工单配方下发 | |||||
/// </summary> | |||||
public const string MakeDown = "WCSClient/WCSServer/MakeDown"; | |||||
/// <summary> | |||||
/// 控制命令,出入库操作 | |||||
/// </summary> | |||||
public const string ControlComm = "WCSClient/WCSServer/ControlComm"; | |||||
/// <summary> | |||||
/// 配料状态更改 | |||||
/// </summary> | |||||
public const string StatusChange = "WCSServer/WCSClient/StatusChange"; | |||||
/// <summary> | |||||
/// 称重设备数据更新 | |||||
/// </summary> | |||||
public const string DeviceDataUpdate = "WCSServer/WCSClient/DataUpdate"; | |||||
/// <summary> | |||||
/// 手动控制命令下发 | |||||
/// </summary> | |||||
public const string HandControlComm = "WCSClient/WCSServer/HandControlComm"; | |||||
/// <summary> | |||||
/// 设备数据实时更新 | |||||
/// </summary> | |||||
public const string DataActualTimeUpdate = "WCSServer/WCSClient/DataActualTimeUpdate"; | |||||
/// <summary> | |||||
/// UI操作修改数据时触发更新其它UI | |||||
/// </summary> | |||||
public const string UIDataChange = "WCSClient/WCSClient/UIDataChange"; | |||||
/// <summary> | |||||
/// 盘库消息+库房ID | |||||
/// </summary> | |||||
public static string StoreStockTaking = "WMS/WCSClient/StoreStockTaking"; | |||||
/// <summary> | |||||
/// 日志消息通知 | |||||
/// </summary> | |||||
public static string LogInfoNotify = "WCSBusines/WCS/LoginfoNotify"; | |||||
} | |||||
} |
@@ -0,0 +1,24 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Service | |||||
{ | |||||
public class APIResult<T> | |||||
{ | |||||
public T Content { get; set; } | |||||
public string ErrorMesg { get; set; } = string.Empty; | |||||
public bool IsSuccess { get; set; } | |||||
} | |||||
public class APIResult | |||||
{ | |||||
public string ErrorMesg { get; set; } = string.Empty; | |||||
public bool IsSuccess { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,35 @@ | |||||
using BPA.Helper; | |||||
using BPA.Message; | |||||
using BPASmartClient.DosingSystem.Model.Dto; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Service | |||||
{ | |||||
public class APIServer : IAPIServer | |||||
{ | |||||
/// <summary> | |||||
/// 设置业务插件状态 | |||||
/// </summary> | |||||
/// <param name="state"></param> | |||||
/// <returns></returns> | |||||
public APIResult<bool> PlugInstatusSet(bool state) | |||||
{ | |||||
var data = new { state = state }; | |||||
var res = APIHelper.GetInstance.PostRequest($"{ApiRoute.SetStatus}{state}", data.ToJson()); | |||||
return new FromT<bool>(res).Result; | |||||
} | |||||
public APIResult<List<WorkOrderPusht>> GetWorkOrder(string workOrderId) | |||||
{ | |||||
var data = new { workOrderId = workOrderId, startTime = "", endTime = "" }; | |||||
var res = APIHelper.GetInstance.PostRequest(ApiRoute.WorkOrderData, data.ToJson()); | |||||
return new FromT<List<WorkOrderPusht>>(res).Result; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,87 @@ | |||||
using BPA.Helper; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Service | |||||
{ | |||||
public class ApiRoute | |||||
{ | |||||
private static string APIAddress => "http://111.9.47.105:18090"; | |||||
//private static string APIAddress => "https://localhost:44342"; | |||||
/// <summary> | |||||
/// 货架路由 | |||||
/// </summary> | |||||
public static string StoreShelves => $"{APIAddress}/StoreShelves/List"; | |||||
/// <summary> | |||||
/// 库位路由 | |||||
/// </summary> | |||||
public static string StorePlace => $"{APIAddress}/StorePlace/MaterialStorePlaceList"; | |||||
/// <summary> | |||||
/// 库位数据更新(库位坐标更新) | |||||
/// </summary> | |||||
public static string StorePlaceUpdate => $"{APIAddress}/StorePlace/Update"; | |||||
/// <summary> | |||||
/// 获取物料信息 | |||||
/// </summary> | |||||
public static string GetMaterialInfo => $"{APIAddress}/Material/GetMaterialList"; | |||||
/// <summary> | |||||
/// 获取电子标签 | |||||
/// </summary> | |||||
public static string GetCaseTagList => $"{APIAddress}/CaseTag/List"; | |||||
/// <summary> | |||||
/// 出入库管理 | |||||
/// </summary> | |||||
public static string StockFlowManager => $"{APIAddress}/StockFlow/Add"; | |||||
/// <summary> | |||||
/// 库位解绑 | |||||
/// </summary> | |||||
public static string StockUnBind => $"{APIAddress}/MaterialStock/UnBind"; | |||||
/// <summary> | |||||
/// 绑定标签 | |||||
/// </summary> | |||||
public static string BindTag => $"{APIAddress}/StorePlace/BindCaseTag"; | |||||
/// <summary> | |||||
/// 库位坐标批量更新 | |||||
/// </summary> | |||||
public static string BatchUpdate => $"{APIAddress}/StorePlace/BatchUpdate"; | |||||
/// <summary> | |||||
/// 出入库流水记录添加(更新库位余量数据) | |||||
/// </summary> | |||||
public static string MaterialStockUpdate => $"{APIAddress}/StockFlow/Add"; | |||||
/// <summary> | |||||
/// 库存盘点数据 | |||||
/// </summary> | |||||
public static string StoreStockTakingInfo => $"{APIAddress}/StoreStockTakingInfo/Add"; | |||||
/// <summary> | |||||
/// 工单下发数据 | |||||
/// </summary> | |||||
public static string WorkOrderData => $"{APIAddress}/WorkOrder/WorkOrderData"; | |||||
/// <summary> | |||||
/// 业务插件唯一性状态设置 | |||||
/// </summary> | |||||
public static string SetStatus => $"{APIAddress}/Basic/PlugInstatusSet?state="; | |||||
/// <summary> | |||||
/// 获取库房信息 | |||||
/// </summary> | |||||
public static string GetStoreHouseInfo => $"{APIAddress}/StoreHouse/List"; | |||||
} | |||||
} |
@@ -0,0 +1,41 @@ | |||||
using BPA.Helper; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Service | |||||
{ | |||||
public class FromT<T> | |||||
{ | |||||
public APIResult<T> Result { get; set; } = new APIResult<T>(); | |||||
public FromT(string msg) | |||||
{ | |||||
if (string.IsNullOrEmpty(msg)) | |||||
return; | |||||
//Result.Content = msg.ToJson("content").FromJSON<T>(); | |||||
if (msg.ToJson("content").TryFromJSON(out T temp)) | |||||
Result.Content = temp; | |||||
else | |||||
{ | |||||
Result.Content = (T)Convert.ChangeType(msg.ToJson("content"), typeof(T)); | |||||
} | |||||
Result.ErrorMesg = msg.ToJson("message"); | |||||
Result.IsSuccess = msg.ToJson("isSuccess").ToLower().FromJSON<bool>(); | |||||
} | |||||
} | |||||
public class FromT | |||||
{ | |||||
public APIResult Result { get; set; } = new APIResult(); | |||||
public FromT(string msg) | |||||
{ | |||||
if (string.IsNullOrEmpty(msg)) | |||||
return; | |||||
Result.ErrorMesg = msg.ToJson("message"); | |||||
Result.IsSuccess = msg.ToJson("isSuccess").ToLower().FromJSON<bool>(); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,116 @@ | |||||
using BPA.Message; | |||||
using BPA.Models; | |||||
using BPASmartClient.DosingSystem.Model.Dto; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Service | |||||
{ | |||||
public interface IAPIServer | |||||
{ | |||||
/// <summary> | |||||
/// 获取货架信息 | |||||
/// </summary> | |||||
/// <param name="id"></param> | |||||
/// <param name="houseId">创库ID</param> | |||||
/// <returns></returns> | |||||
//APIResult<List<StoreShelvesEntity>> GetStoreShelvesInfo(string id, string houseId); | |||||
/// <summary> | |||||
/// 获取库位信息 | |||||
/// </summary> | |||||
/// <param name="id"></param> | |||||
/// <param name="houseId">仓库ID</param> | |||||
/// <param name="shelvesId">货架ID</param> | |||||
/// <returns></returns> | |||||
//APIResult<List<MaterialStorePlaceOutput>> GetStorePlace(string id, string houseId, string shelvesId); | |||||
/// <summary> | |||||
/// 批量更新库位坐标 | |||||
/// </summary> | |||||
/// <param name="stores"></param> | |||||
/// <returns></returns> | |||||
//APIResult BatchUpdate(List<StorePlaceParModel> stores); | |||||
/// <summary> | |||||
/// 更新库位坐标 | |||||
/// </summary> | |||||
/// <param name="store"></param> | |||||
/// <returns></returns> | |||||
// APIResult StorePlaceUpdate(StorePlaceParModel store); | |||||
/// <summary> | |||||
/// 获取物料信息 | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
// APIResult<List<MaterialOutput>> GetMaterialInfo(); | |||||
/// <summary> | |||||
/// 获取电子标签 | |||||
/// </summary> | |||||
//APIResult<List<CaseTagOutput>> GetCaseTagList(); | |||||
/// <summary> | |||||
/// 出入库流水管理 | |||||
/// </summary> | |||||
/// <param name="sfm"></param> | |||||
/// <returns></returns> | |||||
// APIResult StockFlowManager(StockFlowManagerModel sfm); | |||||
/// <summary> | |||||
/// 库位解绑 | |||||
/// </summary> | |||||
/// <param name="MaterialId">物料ID</param> | |||||
/// <param name="PlaceId">库位ID</param> | |||||
/// <returns></returns> | |||||
//APIResult StockUnBind(string MaterialId, string PlaceId); | |||||
/// <summary> | |||||
/// 库位绑定标签 | |||||
/// </summary> | |||||
/// <param name="PlaceId">库位ID</param> | |||||
/// <param name="TagId">标签ID</param> | |||||
/// <returns></returns> | |||||
// APIResult BindTag(string PlaceId, string TagId); | |||||
/// <summary> | |||||
/// 库位数据更新 | |||||
/// </summary> | |||||
/// <param name="materialId">物料ID</param> | |||||
/// <param name="placeId">库位ID</param> | |||||
/// <param name="qty">数量</param> | |||||
/// <param name="id">主键ID</param> | |||||
/// <returns></returns> | |||||
//APIResult MaterialStockUpdate(string materialId, string placeId, double qty, string id); | |||||
/// <summary> | |||||
/// 盘库操作 | |||||
/// </summary> | |||||
/// <param name="sstie">库位信息</param> | |||||
/// <returns></returns> | |||||
//APIResult StoreStockTakingInfoService(List<StoreStockTakingInfoEntity> sstie); | |||||
/// <summary> | |||||
/// 设置业务插件状态 | |||||
/// </summary> | |||||
/// <param name="state"></param> | |||||
/// <returns></returns> | |||||
APIResult<bool> PlugInstatusSet(bool state); | |||||
/// <summary> | |||||
/// 获取工单信息 | |||||
/// </summary> | |||||
/// <param name="workOrderId"></param> | |||||
/// <returns></returns> | |||||
APIResult<List<WorkOrderPusht>> GetWorkOrder(string workOrderId); | |||||
/// <summary> | |||||
/// 获取库房信息 | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
//APIResult<List<StoreHouseOutput>> GetStoreHouseInfo(); | |||||
} | |||||
} |
@@ -0,0 +1,43 @@ | |||||
using System; | |||||
using System.Collections.Concurrent; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DosingSystem.Service | |||||
{ | |||||
public class ServerFactory | |||||
{ | |||||
private volatile static ServerFactory _Instance; | |||||
public static ServerFactory GetInstance => _Instance ?? (_Instance = new ServerFactory()); | |||||
private ServerFactory() { } | |||||
ConcurrentDictionary<string, IAPIServer> servers = new ConcurrentDictionary<string, IAPIServer>(); | |||||
public void Set<T>(T server) where T : IAPIServer | |||||
{ | |||||
string name = server.GetType().Name; | |||||
if (!servers.ContainsKey(name)) | |||||
{ | |||||
servers.TryAdd(name, server); | |||||
} | |||||
} | |||||
public IAPIServer Get() | |||||
{ | |||||
if (servers.Count > 0) | |||||
return servers.ElementAt(0).Value; | |||||
return default; | |||||
} | |||||
public IAPIServer Get<TServer>(TServer server) where TServer : IAPIServer | |||||
{ | |||||
var name = server.GetType().Name; | |||||
if (servers.ContainsKey(name)) | |||||
return servers[name]; | |||||
return default; | |||||
} | |||||
} | |||||
} |