using Admin.Core.Common.Helper;
using Admin.Core.IService;
using Admin.Core.Model;
using Admin.Core.Model.Model_New;
using Admin.Core.Service;
using Admin.Core.Socket;
using Aucma.Core.HwPLc;
using Aucma.Core.Palletiz.config;
using Aucma.Core.Palletiz.ViewModels;
using log4net;
using Microsoft.Extensions.DependencyInjection;
using NPOI.SS.Formula.UDF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Interop;
using TouchSocket.Sockets;
namespace Aucma.Core.Palletiz.Business
{
internal class InStoreBusiness
{
private static readonly log4net.ILog _logger = LogManager.GetLogger(typeof(InStoreBusiness));
private readonly IProductOffLineServices _offlineService;
private readonly IBaseSpaceInfoServices _spaceinfoService;
private readonly AppConfig _appConfig;
#region 委托事件
///
/// 扫码信息刷新
///
public delegate void RefreshProductInfo(string productCode, string productModel, string orderCode);
public static event RefreshProductInfo? RefreshProductInfoEvent;
///
/// 提示信息刷新
///
public delegate void RefreshMsg(string msg);
public static event RefreshMsg? RefreshMsgEvent;
#endregion
// private const string BarcodeRef = "6933973114570;1621240AP0098E3D3497";
private PlcModel plcCon = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("InStoreAPlc"));
public InStoreBusiness()
{
_appConfig = new AppConfig();
_spaceinfoService = App.ServiceProvider.GetService();
_offlineService = App.ServiceProvider.GetService();
// string AA = ExtractNumber("FD01_012");
}
public void Init()
{
TouchSocketService.ReceivedClientBufferEvent += ReceivedBuffer;
}
///
/// Buffer缓冲
///
///
private void ReceivedBuffer(SocketClient client, byte[] buffer)
{
try
{
//_logger.LogInformation($"接收客户端:{client.Id};原始报文:{_stringChange.bytesToHexStr(buffer, buffer.Length)}");
do
{
string asciiStr = Encoding.ASCII.GetString(buffer);
if (asciiStr.Contains("heartbeat"))
{
_logger.Info($"收到客户端:{client.Id};心跳指令:{asciiStr}");
continue;
}
if (asciiStr.Contains("NoRead"))
{
NoReadHandle(client.Id);
continue;
}
_logger.Info($"收到客户端:{client.Id}条码信息:{asciiStr}");
InStore(client.Id, asciiStr);
} while (false);
}
catch (Exception e)
{
_logger.Error($"Buffer缓冲异常:{e.Message}");
}
}
///
/// 入库申请
///
/// 货道区域
///
private void InStore(string spaceArea, string asciiStr)
{
String msg = string.Empty;
try
{
if (string.IsNullOrEmpty(asciiStr))
{
throw new ArgumentException($"入库申请处理异常:条码信息为空");
}
if (string.IsNullOrEmpty(spaceArea))
{
throw new ArgumentException($"入库申请处理异常:货道区域为空");
}
//if (asciiStr.Contains(";") && asciiStr.Length == BarcodeRef.Length)
//{
// string[] splitStr = asciiStr.Split(";");
// if (splitStr.Length > 1)
// {
// asciiStr = splitStr[1];
// }
//}
_offlineService.GetProductInfosBySnCode(asciiStr, out ProductOffline prodInfo);
if (prodInfo == null)
{
throw new ArgumentException($"入库申请处理异常:根据成品码获取成品信息为空");
}
RefreshProductInfoEvent?.Invoke(asciiStr,prodInfo.ProductModel,prodInfo.ProductOrderNo);
GetSpaceInfoByMaterialType(spaceArea, prodInfo, out BaseSpaceInfo laseSpaceinfo,
out BaseSpaceInfo spaceinfo);
bool result = false;
SendInStoreTask(asciiStr,spaceinfo, ref result,Convert.ToInt32(prodInfo.ProductMasterModel),ref msg);
if (!result)
{
msg = msg + "放行失败";
RefreshMsgEvent?.Invoke(msg);
throw new ArgumentException($"入库申请处理异常:入库任务下发至PLC失败");
}
else
{
msg = msg + "放行成功";
RefreshMsgEvent?.Invoke(msg);
List spaceinfos = new List();
if (laseSpaceinfo != null)
{
laseSpaceinfo.InStoreFlag = 1;
spaceinfos.Add(laseSpaceinfo);
}
spaceinfo.InStoreFlag = 3;
spaceinfos.Add(spaceinfo);
_spaceinfoService.UpdateSpaceInfo(spaceinfos);
}
}
catch (Exception e)
{
msg =$"入库逻辑处理异常:{e.Message}";
RefreshMsgEvent?.Invoke(msg);
}
}
///
/// 通过物料型号获取货道信息
///
///
///
///
///
///
///
private void GetSpaceInfoByMaterialType(string spaceArea, ProductOffline prodInfo, out BaseSpaceInfo laseSpaceinfo, out BaseSpaceInfo spaceinfo, bool isBig = false)
{
List spaceinfos = null;
if (isBig)
{
_spaceinfoService.GetSpaceInfosByExpression(out spaceinfos, x => x.StoreCode == _appConfig.storeCode && x.SpaceArea == spaceArea && x.MaterialType == prodInfo.ProductCode && x.SpaceType == 2);
}
else
{
_spaceinfoService.GetSpaceInfosByExpression(out spaceinfos, x => x.StoreCode == _appConfig.storeCode && x.SpaceArea == spaceArea && x.MaterialType == prodInfo.ProductCode);
}
if (spaceinfos == null)
{
throw new ArgumentException($"通过物料型号获取货道信息异常:根据成品信息获取货道信息为空");
}
spaceinfos = spaceinfos.OrderBy(x => x.ObjId).ToList();
MatchSpaceInfoByPlc(ref spaceinfos);
if (spaceinfos == null)
{
throw new ArgumentException($"通过物料型号获取货道信息异常:通过PLC匹配可用货道信息为空");
}
FiltrateSpaceInfo(spaceinfos, out laseSpaceinfo, out spaceinfo);
if (spaceinfo == null)
{
throw new ArgumentException($"通过物料型号获取货道信息异常:未获取到匹配的货道信息");
}
}
///
/// 通过PLC匹配获取,去除已满的货道
///
///
private void MatchSpaceInfoByPlc(ref List spaceinfos)
{
if (plcCon == null)
{
Task.Delay(1000 * 5).Wait();
plcCon = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("InStoreAPlc"));
if(plcCon == null)
{
throw new ArgumentException($"通过PLC匹配获取货道信息异常:Plc连接为空");
}
}
var _plc = plcCon.plc;
foreach (var item in spaceinfos)
{
item.SpaceCode = ExtractNumber(item.SpaceName);
var plcAddress = _appConfig.plcAddr.Where(x => x.spaceCode.ToString() == item.SpaceCode && x.spaceArea == item.SpaceArea).First();
int isFlag = _plc.ReadInt16(plcAddress.address);
if (isFlag == 1)
{
item.SpaceStatus = 3;
}
}
spaceinfos = spaceinfos.Where(x => x.SpaceStatus != 3).ToList();
}
///
/// 筛选货道信息
///
///
///
///
private void FiltrateSpaceInfo(List spaceinfos, out BaseSpaceInfo laseSpaceinfo, out BaseSpaceInfo spaceinfo)
{
if (spaceinfos == null)
{
throw new ArgumentException($"筛选货道信息异常:传入货道信息参数为空");
}
int count = spaceinfos.Where(x => x.InStoreFlag == 3).ToList().Count;
if (count > 0)
{
int index = spaceinfos.FindIndex(entity => entity.InStoreFlag == 3);
laseSpaceinfo = spaceinfos[index];
int nextIndex = (index + 1) % spaceinfos.Count;
spaceinfo = spaceinfos[nextIndex];
}
else
{
laseSpaceinfo = null;
spaceinfo = spaceinfos.First();
}
}
///
/// 下发入库任务至PLC
///
///
///
///
private void SendInStoreTask(string asciiStr, BaseSpaceInfo spaceinfo, ref bool result,int prodWeight,ref string msg)
{
if (plcCon == null)
{
throw new ArgumentException($"下发入库任务至PLC逻辑异常:Plc连接为空");
}
var _plc = plcCon.plc;
bool isFlag = true;
int spaceCode = StringChange.ParseToInt(spaceinfo.SpaceCode);
int spinFlag = 3; // 转180度发1,不转发3
if (prodWeight < 140)
{
if (spaceCode % 2 != 0) //偶数 转180°
{
spinFlag = 1; //4
}
}
else if (prodWeight >= 140)
{
if (spaceCode % 2 == 0) //偶数 转180°
{
spinFlag = 1; //4
}
}
msg = $"成品码:{asciiStr},仓库区域:{spaceinfo.SpaceArea},匹配货道:{spaceinfo.SpaceCode};旋转:{(spinFlag == 3 ? "0°" : "180°")};下发plc放行信号";
RefreshMsgEvent?.Invoke(msg);
while (isFlag)
{
bool answerFlag = _plc.ReadBool("B1000");
if (answerFlag)
{
isFlag = false;
}
Task.Delay(1000 * 2).Wait();
}
if (spaceinfo.SpaceArea == "A")
{
if (!_plc.WriteInt16("D2", spinFlag.ToString()))
{
throw new ArgumentException($"旋转角度下发至PLC失败");
}
if (!_plc.WriteInt16("D29", spaceCode.ToString()))
{
throw new ArgumentException($"货道号下发至PLC失败");
}
_plc.WriteInt16("B1001", "1");//发送完成信号
result = true;
}
else if (spaceinfo.SpaceArea == "B")
{
result = false;
}
}
///
/// 提取货道号
///
///
///
private static string ExtractNumber(string input)
{
string pattern = @"\d+";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
return match.Value.TrimStart('0');
}
else
{
return null; // 或者返回默认值,如"0"
}
}
///
/// 读取失败处理
///
///
private void NoReadHandle(string client)
{
_logger.Error($"客户端:{client};读取失败!!!!!!");
}
///
/// 获取成品库指定区域的货道信息
///
///
///
public List GetBaseSpaceinfos(string spaceArea)
{
_spaceinfoService.GetSpaceInfosByExpression(out List spaceinfos, x => x.StoreCode == _appConfig.storeCode && x.SpaceArea == spaceArea);
return spaceinfos;
}
///
/// 获取货道信息
///
///
///
public BaseSpaceInfo GetSpaceinfosById(int id)
{
BaseSpaceInfo spaceInfo = _spaceinfoService.FirstAsync(x=>x.ObjId==id).Result;
return spaceInfo;
}
}
}