Files
tnb.server/WarehouseMgr/Tnb.WarehouseMgr/BaseWareHouseService.cs

617 lines
22 KiB
C#

using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Claims;
using System.Text;
using JNPF;
using JNPF.Common.Contracts;
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.DataEncryption;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.EventBus;
using JNPF.Extras.CollectiveOAuth.Enums;
using JNPF.VisualDev;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using SqlSugar;
using Tnb.BasicData.Entities;
using Tnb.Common.Core.EventBus.Constants;
using Tnb.Common.Core.EventBus.Sources;
using Tnb.WarehouseMgr.Entities;
using Tnb.WarehouseMgr.Entities.Attributes;
using Tnb.WarehouseMgr.Entities.Dto;
using Tnb.WarehouseMgr.Entities.Dto.Outputs;
using Tnb.WarehouseMgr.Interfaces;
using Tnb.WarehouseMgr.Print;
namespace Tnb.WarehouseMgr
{
[ApiDescriptionSettings(Tag = ModuleConsts.Tag, Area = ModuleConsts.Area, Order = 700)]
[Route("api/[area]/[controller]/[action]")]
public class BaseWareHouseService : IOverideVisualDevService, IDynamicApiController, ITransient
{
private static readonly Lazy<Dictionary<string, IWHStorageService>> _stroageMapLazy;
private static readonly Dictionary<LogLevel, string> s_logLevelMap = new()
{
[LogLevel.Debug] = "DBG",
[LogLevel.Information] = "INF",
[LogLevel.Warning] = "WRN",
[LogLevel.Error] = "ERR",
};
public OverideVisualDevFunc OverideFuncs { get; } = new OverideVisualDevFunc();
public static SemaphoreSlim s_taskExecuteSemaphore = new(1);
public static SemaphoreSlim s_elevatorStatusSemaphore = new(1);
protected static Dictionary<string, int> _s_eleUseStatusDic;
protected IEventPublisher? EventPublisher { set; get; }
protected static string _LoggerFileName = "";
protected static ILogger _Logger;
protected ILogger Logger
{
get
{
string newFileName = $"{AppContext.BaseDirectory}/logs/custom{DateTime.Now:yyyyMMdd}.log";
if (_LoggerFileName != newFileName)
{
ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddFile(newFileName, cfgOpts =>
{
//cfgOpts.DateFormat = "yyyy-MM-dd HH:mm:ss.fff";
cfgOpts.MessageFormat = (logMsg) =>
{
var logLevel = s_logLevelMap[logMsg.LogLevel];
var sb = new StringBuilder();
_ = sb.Append($"[{logLevel}] ");
_ = sb.Append($"{logMsg.LogName} ");
_ = sb.Append($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} ");
_ = sb.Append($"#{logMsg.EventId.Id} ");
_ = sb.Append(logMsg.Message + " ");
_ = sb.Append(logMsg.Exception?.ToString());
return sb.ToString();
};
}));
_Logger = loggerFactory.CreateLogger(this.GetType());
_LoggerFileName = newFileName;
}
return _Logger;
}
}
static BaseWareHouseService()
{
_stroageMapLazy = new Lazy<Dictionary<string, IWHStorageService>>(() =>
{
Dictionary<string, IWHStorageService> map = new();
List<Type> serviceTypes = App.EffectiveTypes.Where(u => u.IsClass && !u.IsInterface && !u.IsAbstract && typeof(IWHStorageService).IsAssignableFrom(u)).ToList();
foreach (Type? serviceType in serviceTypes)
{
string callerName = serviceType.GetCustomAttribute<CallerAttribute>()?.Name ?? string.Empty;
if (!callerName.IsNullOrEmpty())
{
if (Activator.CreateInstance(serviceType) is not IWHStorageService obj)
{
continue;
}
map[callerName] = obj;
}
}
return map;
});
}
protected Task<ClaimsPrincipal> GetUserIdentity(string? asscessToken = null)
{
asscessToken = asscessToken?.Replace("Bearer ", "").Replace("bearer ", "");
string at = asscessToken ?? UserManager.AsscessToken;
IEnumerable<Claim>? claims = JWTEncryption.ReadJwtToken(at)?.Claims;
ClaimsIdentity toKen = new();
foreach (Claim item in claims)
{
toKen.AddClaim(item);
}
ClaimsPrincipal curUser = new(toKen);
return Task.FromResult(curUser);
}
protected Task SetUserEntity(IUserManager userManager, ClaimsPrincipal principal)
{
return Task.Run(() =>
{
FieldInfo fieldInfo = userManager.GetType().GetField("_user", BindingFlags.NonPublic | BindingFlags.Instance);
fieldInfo?.SetValue(userManager, principal);
});
}
protected Task InvokeGenPretaskExcute()
{
IWareHouseService wareHouseSvc = App.GetRequiredService<IWareHouseService>();
return wareHouseSvc.GenTaskExecute();
}
/// <summary>
/// 判断最终目标库位是否可以放置当前载具
/// </summary>
/// <param name="carry">当前载具</param>
/// <param name="locDest">目标库位</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
[NonAction]
protected Task<bool> IsCarryAndLocationMatchByCarryStd(WmsCarryH carry, BasLocation locDest)
{
bool isMatch = false;
if (carry == null)
{
throw new ArgumentNullException(nameof(carry));
}
if (locDest == null)
{
throw new ArgumentNullException(nameof(locDest));
}
if (!carry.carrystd_id.IsNullOrEmpty() && !locDest.carrystd_id.IsNullOrEmpty())
{
JArray? jsonArr = null;
try
{
jsonArr = JArray.Parse(locDest.carrystd_id);
string?[] locCarryStdArr = jsonArr.Select(x => x.ToObject<string>()).ToArray();
isMatch = locCarryStdArr.Contains(carry.carrystd_id);
}
catch (Exception ex) when (ex is JsonException jex)
{
isMatch = carry.carrystd_id.Equals(locDest.carrystd_id, StringComparison.OrdinalIgnoreCase);
}
}
return Task.FromResult(isMatch);
}
/// <summary>
/// 根据当前目标楼层获取,电梯接口真正的楼层
/// </summary>
/// <param name="floor"></param>
/// <returns></returns>
[NonAction]
protected Task<int> GetRealFloor(int floor)
{
int realFloor = 0;
if (floor == 4)
{
realFloor = 5;
}
else if (floor == 3)
{
realFloor = 4;
}
else if (floor == 2)
{
realFloor = 3;
}
else if(floor == 1)
{
realFloor = 1;
}
return Task.FromResult(realFloor);
}
/// <summary>
/// 发布消息
/// </summary>
/// <param name="taskName"></param>
/// <returns></returns>
[NonAction]
protected async Task Publish(string taskName)
{
await EventPublisher.PublishAsync(new TaskStatusChangeSource(EventSubscribeEventConsts.TASKSTATUSCHANGE_EVENTID, taskName));
}
[NonAction]
protected async Task DoUpdate(WareHouseUpInput input)
{
if (_stroageMapLazy.Value.ContainsKey(input.loginType))
{
await _stroageMapLazy.Value[input.loginType].Do(input);
}
}
[NonAction]
public virtual Task ModifyAsync(WareHouseUpInput input)
{
return Task.CompletedTask;
}
/// <summary>
/// 条码打印
/// </summary>
/// <param name="barCodes">条码</param>
/// <param name="copies">打印份数</param>
/// <returns></returns>
[NonAction]
protected void BarCodePrint(List<string> barCodes,int copies,string ip)
{
TaskCompletionSource tcs = new();
// open port.
try
{
int nLen, ret, sw;
byte[] pbuf = new byte[128];
string strmsg;
IntPtr ver;
System.Text.Encoding encAscII = System.Text.Encoding.ASCII;
System.Text.Encoding encUnicode = System.Text.Encoding.Unicode;
// dll version.
ver = PPLBUtility.B_Get_DLL_Version(0);
// search port.
nLen = PPLBUtility.B_GetUSBBufferLen() + 1;
strmsg = "DLL ";
strmsg += Marshal.PtrToStringAnsi(ver);
strmsg += "\r\n";
if (nLen > 1)
{
byte[] buf1, buf2;
int len1 = 128, len2 = 128;
buf1 = new byte[len1];
buf2 = new byte[len2];
_ = PPLBUtility.B_EnumUSB(pbuf);
_ = PPLBUtility.B_GetUSBDeviceInfo(1, buf1, out len1, buf2, out len2);
sw = 1;
if (1 == sw)
{
ret = PPLBUtility.B_CreatePrn(12, encAscII.GetString(buf2, 0, len2));// open usb.
}
else
{
ret = PPLBUtility.B_CreateUSBPort(1);// must call B_GetUSBBufferLen() function fisrt.
}
if (0 != ret)
{
strmsg += "Open USB fail!";
}
else
{
strmsg += "Open USB:\r\nDevice name: ";
strmsg += encAscII.GetString(buf1, 0, len1);
strmsg += "\r\nDevice path: ";
strmsg += encAscII.GetString(buf2, 0, len2);
//sw = 2;
if (2 == sw)
{
//Immediate Error Report.
_ = PPLBUtility.B_WriteData(1, encAscII.GetBytes("^ee\r\n"), 5);//^ee
ret = PPLBUtility.B_ReadData(pbuf, 4, 1000);
}
}
}
else
{
ret = PPLBUtility.B_CreatePrn(13, ip);
}
/* else
{
_ = System.IO.Directory.CreateDirectory(PPLBUtility.szSavePath);
ret = PPLBUtility.B_CreatePrn(0, PPLBUtility.szSaveFile);// open file.
strmsg += "Open ";
strmsg += PPLBUtility.szSaveFile;
if (0 != ret)
{
strmsg += " file fail!";
}
else
{
strmsg += " file succeed!";
}
}*/
if (0 != ret)
{
return;
}
// sample setting.
_ = PPLBUtility.B_Set_Originpoint(0, 0);
_ = PPLBUtility.B_Select_Option(2);
_ = PPLBUtility.B_Set_Darkness(8);
_ = PPLBUtility.B_Del_Pcx("*");// delete all picture.
//PPLBUtility.B_Set_LabelForSmartPrint(254 * 3, 30);//label information: length= 3 * 25.4 mm, gap= 3 mm. 254 * 3, 30
_ = PPLBUtility.B_Set_Labwidth(80 * 8);
//var labelWidth = 640; //254 * 3; // 标签宽度
//var barcodeWidth = 320; // 条码宽度
//var barcodeX = (labelWidth - barcodeWidth) / 2;
//B_Prn_Barcode(barcodeX, 100, 0, "QRcode", 1, 0, 2, 2, "YourBarcodeData"); 8
foreach (string code in barCodes)
{
for (int i = 0; i < copies; i++)
{
// _ = PPLBUtility.B_Prn_Text(50, 90, 0, 2, 2, 2, 'N', code);
// _ = PPLBUtility.B_Prn_Barcode(50, 270, 0, "1", 3, 5, 70, 'N', code);
_ = PPLBUtility.B_Prn_Text(50, 100, 0, 2, 2, 2, 'N', code);
_ = PPLBUtility.B_Prn_Barcode(50, 150, 0, "1", 3, 5, 100, 'N', code);
_ = PPLBUtility.B_Prn_Text(50, 305, 0, 2, 2, 2, 'N', code);
_ = PPLBUtility.B_Print_Out(1);
}
}
}
catch (Exception ex)
{
tcs.SetException(ex);
throw ex;
Logger.Error("条码打印时出现错误", ex);
}
finally
{
// close port.
PPLBUtility.B_ClosePrn();
}
}
/// <summary>
/// 载具条码打印
/// </summary>
/// <param name="barCodes">条码</param>
/// <param name="copies">打印份数</param>
/// <returns></returns>
[NonAction]
protected void CarryPrint(List<string> barCodes, int copies, string ip)
{
TaskCompletionSource tcs = new();
// open port.
try
{
int nLen, ret, sw;
byte[] pbuf = new byte[128];
string strmsg;
IntPtr ver;
System.Text.Encoding encAscII = System.Text.Encoding.ASCII;
System.Text.Encoding encUnicode = System.Text.Encoding.Unicode;
// dll version.
ver = PPLBUtility.B_Get_DLL_Version(0);
// search port.
nLen = PPLBUtility.B_GetUSBBufferLen() + 1;
strmsg = "DLL ";
strmsg += Marshal.PtrToStringAnsi(ver);
strmsg += "\r\n";
if (nLen > 1)
{
byte[] buf1, buf2;
int len1 = 128, len2 = 128;
buf1 = new byte[len1];
buf2 = new byte[len2];
_ = PPLBUtility.B_EnumUSB(pbuf);
_ = PPLBUtility.B_GetUSBDeviceInfo(1, buf1, out len1, buf2, out len2);
sw = 1;
if (1 == sw)
{
ret = PPLBUtility.B_CreatePrn(12, encAscII.GetString(buf2, 0, len2));// open usb.
}
else
{
ret = PPLBUtility.B_CreateUSBPort(1);// must call B_GetUSBBufferLen() function fisrt.
}
if (0 != ret)
{
strmsg += "Open USB fail!";
}
else
{
strmsg += "Open USB:\r\nDevice name: ";
strmsg += encAscII.GetString(buf1, 0, len1);
strmsg += "\r\nDevice path: ";
strmsg += encAscII.GetString(buf2, 0, len2);
//sw = 2;
if (2 == sw)
{
//Immediate Error Report.
_ = PPLBUtility.B_WriteData(1, encAscII.GetBytes("^ee\r\n"), 5);//^ee
ret = PPLBUtility.B_ReadData(pbuf, 4, 1000);
}
}
}
else
{
ret = PPLBUtility.B_CreatePrn(13, ip);
}
/* else
{
_ = System.IO.Directory.CreateDirectory(PPLBUtility.szSavePath);
ret = PPLBUtility.B_CreatePrn(0, PPLBUtility.szSaveFile);// open file.
strmsg += "Open ";
strmsg += PPLBUtility.szSaveFile;
if (0 != ret)
{
strmsg += " file fail!";
}
else
{
strmsg += " file succeed!";
}
}*/
if (0 != ret)
{
return;
}
// sample setting.
_ = PPLBUtility.B_Set_Originpoint(0, 0);
_ = PPLBUtility.B_Select_Option(2);
_ = PPLBUtility.B_Set_Darkness(8);
_ = PPLBUtility.B_Del_Pcx("*");// delete all picture.
//PPLBUtility.B_Set_LabelForSmartPrint(254 * 3, 30);//label information: length= 3 * 25.4 mm, gap= 3 mm. 254 * 3, 30
_ = PPLBUtility.B_Set_Labwidth(80 * 8);
//var labelWidth = 640; //254 * 3; // 标签宽度
//var barcodeWidth = 320; // 条码宽度
//var barcodeX = (labelWidth - barcodeWidth) / 2;
//B_Prn_Barcode(barcodeX, 100, 0, "QRcode", 1, 0, 2, 2, "YourBarcodeData"); 8
foreach (string code in barCodes)
{
for (int i = 0; i < copies; i++)
{
// _ = PPLBUtility.B_Prn_Text(50, 90, 0, 2, 2, 2, 'N', code);
// _ = PPLBUtility.B_Prn_Barcode(50, 270, 0, "1", 3, 5, 70, 'N', code);
//_ = PPLBUtility.B_Prn_Text(50, 100, 0, 2, 2, 2, 'N', code);
//_ = PPLBUtility.B_Prn_Barcode(50, 150, 0, "1", 3, 5, 100, 'N', code);
_ = PPLBUtility.B_Prn_Text(50, 100, 0, 2, 2, 2, 'N', code);
_ = PPLBUtility.B_Prn_Barcode(50, 150, 0, "1", 3, 5, 90, 'N', code);
//_ = PPLBUtility.B_Prn_Text(50, 305, 0, 2, 2, 2, 'N', code);
_ = PPLBUtility.B_Print_Out(1);
}
}
}
catch (Exception ex)
{
tcs.SetException(ex);
throw ex;
Logger.Error("条码打印时出现错误", ex);
}
finally
{
// close port.
PPLBUtility.B_ClosePrn();
}
}
#region
/// <summary>
/// 打印
/// </summary>
/// <param name="zplStr"></param>
/// <returns></returns>
//[NonAction]
//protected async Task Print(string zplStr)
//{
// var zpl_string = @$"^XA
// ^XA^LH0,0^LL100^PW580
// ^FX 文本
// ^FO 80,100^BCN,100,10^FDQA,Hello world^FS
// ^FO 150,200^A0N 80,50^FD Hello world^FS
// ^XZ";
// List<DiscoveredPrinter> printerList = await GetUSBPrinters();
// if (printerList?.Count > 0)
// {
// // in this case, we arbitrarily are printing to the first found printer
// DiscoveredPrinter discoveredPrinter = printerList[0];
// Connection connection = discoveredPrinter.GetConnection();
// connection.Open();
// connection.Write(Encoding.UTF8.GetBytes(zplStr));
// }
//}
//private Task<List<DiscoveredPrinter>> GetUSBPrinters()
//{
// var tcs = new TaskCompletionSource<List<DiscoveredPrinter>>();
// List<DiscoveredPrinter> printerList = new();
// try
// {
// foreach (DiscoveredUsbPrinter usbPrinter in UsbDiscoverer.GetZebraUsbPrinters())
// {
// printerList.Add(usbPrinter);
// Console.WriteLine(usbPrinter);
// }
// }
// catch (ConnectionException e)
// {
// JNPF.Logging.Log.Error("获取本地打印机时出错", e);
// tcs.SetException(e);
// }
// Console.WriteLine("Done discovering local printers.");
// tcs.SetResult(printerList);
// return tcs.Task;
//}
#endregion
/// <summary>
/// Api响应结果
/// </summary>
/// <returns></returns>
[NonAction]
protected Task<Result> ToApiResult()
{
Result result = new();
return Task.FromResult(result);
}
/// <summary>
/// Api响应结果
/// </summary>
/// <returns></returns>
[NonAction]
protected Task<Result> ToApiResult(HttpStatusCode statusCode, object data)
{
Result result = new()
{
code = statusCode,
data = data
};
return Task.FromResult(result);
}
/// <summary>
/// Api响应结果
/// </summary>
/// <returns></returns>
[NonAction]
protected Task<Result> ToApiResult(object data)
{
Result result = new()
{
data = data
};
return Task.FromResult(result);
}
/// <summary>
/// Api响应结果
/// </summary>
/// <returns></returns>
[NonAction]
protected Task<Result> ToApiResult(HttpStatusCode statusCode, string msg)
{
Result result = new()
{
code = statusCode,
msg = msg
};
return Task.FromResult(result);
}
/// <summary>
/// Api响应结果
/// </summary>
/// <returns></returns>
[NonAction]
protected Task<Result> ToApiResult(HttpStatusCode statusCode, string msg, object data)
{
Result result = new()
{
code = statusCode,
msg = msg,
data = data
};
return Task.FromResult(result);
}
}
}