first commit
This commit is contained in:
+8
@@ -0,0 +1,8 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=enumerations/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=interfaces/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=transferservice/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=transferservice_005Cdownload/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=transferservice_005Cexceptions/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=transferservice_005Cupload/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
@@ -0,0 +1,155 @@
|
||||
using JSMachine.WMS.Infrastructure.Enums;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.AppConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// WMS 运行时配置模型,由配置文件和环境变量绑定生成。
|
||||
/// </summary>
|
||||
public class AppSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据库连接字符串
|
||||
/// </summary>
|
||||
public string DataBaseCon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// /删除前多少天之前的log
|
||||
/// </summary>
|
||||
public int DelLogDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Erp配置
|
||||
/// </summary>
|
||||
public ErpConfig ErpConfig { get; set; }
|
||||
/// <summary>
|
||||
/// Rcs配置
|
||||
/// </summary>
|
||||
public RcsConfig RcsConfig { get; set; }
|
||||
/// <summary>
|
||||
/// 提升机配置
|
||||
/// </summary>
|
||||
public ElevatorConfig[] ElevatorConfig { get; set; }
|
||||
/// <summary>
|
||||
/// 放置模式(0-完全不混放 1-混合模式,优先同批次放一列,没有空库位再混放 2-完全混放模式,不用批次货物放一起)
|
||||
/// </summary>
|
||||
public int PlcaementMod { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Erp配置,此配置项做了冗余,不同的Erp按需配置
|
||||
/// </summary>
|
||||
public class ErpConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Erp类型
|
||||
/// </summary>
|
||||
public ErpType ErpType { get; set; }
|
||||
/// <summary>
|
||||
/// Erp地址
|
||||
/// </summary>
|
||||
public string ErpUrl { get; set; }
|
||||
/// <summary>
|
||||
/// Erp服务器IP
|
||||
/// </summary>
|
||||
public string ErpIP { get; set; }
|
||||
/// <summary>
|
||||
/// 回传Erp前几天数据
|
||||
/// </summary>
|
||||
public int ErpUploadBefore { get; set; }
|
||||
/// <summary>
|
||||
/// 上传数据,重试次数
|
||||
/// </summary>
|
||||
public int RetryNum { get; set; }
|
||||
/// <summary>
|
||||
/// 获取原纸信息接口地址
|
||||
/// </summary>
|
||||
public string QueryByPaperLabelUrl { get; set; }
|
||||
/// <summary>
|
||||
/// 获取原纸信息接口地址(通过幅宽、纸质编码)
|
||||
/// </summary>
|
||||
public string QueryByPaperWidthAndCodeUrl { get; set; }
|
||||
/// <summary>
|
||||
/// 原纸出库接口地址
|
||||
/// </summary>
|
||||
public string PaperStockOutUrl { get; set; }
|
||||
/// <summary>
|
||||
/// 残卷回库接口地址
|
||||
/// </summary>
|
||||
public string RePaperStockInUrl { get; set; }
|
||||
/// <summary>
|
||||
/// AppId
|
||||
/// </summary>
|
||||
public string AppId { get; set; }
|
||||
/// <summary>
|
||||
/// AppKey
|
||||
/// </summary>
|
||||
public string AppKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PDA扫合格证码获取物料信息
|
||||
/// </summary>
|
||||
public string QueryMateriaInforUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生产入库
|
||||
/// </summary>
|
||||
public string ProduceInUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生产退库
|
||||
/// </summary>
|
||||
public string ProduceOutUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 销售出库接口
|
||||
/// </summary>
|
||||
public string SaleOutUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户编号
|
||||
/// </summary>
|
||||
public string Userkey { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rcs系统配置
|
||||
/// </summary>
|
||||
public class RcsConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// RCS 服务基础地址。
|
||||
/// </summary>
|
||||
public string RcsUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建任务Url
|
||||
/// </summary>
|
||||
public string CreateTaskUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 取消任务Url
|
||||
/// </summary>
|
||||
public string CancelTaskUrl { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提升机PLC配置
|
||||
/// </summary>
|
||||
public class ElevatorConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 提升机序号(1,2)
|
||||
/// </summary>
|
||||
public int ElevatorNo { get; set; }
|
||||
/// <summary>
|
||||
/// 提升机PLC的IP
|
||||
/// </summary>
|
||||
public string IP { get; set; }
|
||||
/// <summary>
|
||||
/// 提升机PLC的端口
|
||||
/// </summary>
|
||||
public int Port { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using JSMachine.WMS.Infrastructure.Enums;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ErpTypeAttribute : Attribute
|
||||
{
|
||||
public ErpType ErpType { get; set; }
|
||||
public ErpTypeAttribute(ErpType erpType)
|
||||
{
|
||||
ErpType = erpType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Rougamo;
|
||||
using Rougamo.Context;
|
||||
using System.Threading;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// 注意,任何使用该标记的项目中均需要安装Rougamo.Fody包,否则属性标记锁将失效
|
||||
/// </summary>
|
||||
public class MethodLockedAttribute : MoAttribute
|
||||
{
|
||||
private static readonly SemaphoreSlim SemaphoreSlim = new(1);
|
||||
|
||||
public override void OnEntry(MethodContext context)
|
||||
{
|
||||
SemaphoreSlim.Wait();
|
||||
|
||||
}
|
||||
|
||||
public override void OnExit(MethodContext context)
|
||||
{
|
||||
SemaphoreSlim.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using JSMachine.WMS.Infrastructure.Enums;
|
||||
using System;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class PmsTypeAttribute : Attribute
|
||||
{
|
||||
public PmsType PmsType { get; set; }
|
||||
public PmsTypeAttribute(PmsType pmsType)
|
||||
{
|
||||
PmsType = pmsType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Erp类型
|
||||
/// </summary>
|
||||
public enum ErpType
|
||||
{
|
||||
/// <summary>
|
||||
/// 企望ERP
|
||||
/// </summary>
|
||||
Wantit = 0,
|
||||
/// <summary>
|
||||
/// 自有IBS
|
||||
/// </summary>
|
||||
IBS = 1,
|
||||
/// <summary>
|
||||
/// 辰龙Erp
|
||||
/// </summary>
|
||||
ChenLong = 2,
|
||||
/// <summary>
|
||||
/// 新荣Erp
|
||||
/// </summary>
|
||||
XinRong = 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Enums
|
||||
{
|
||||
public enum PmsType
|
||||
{
|
||||
/// <summary>
|
||||
/// DCS生管
|
||||
/// </summary>
|
||||
DCS = 0,
|
||||
/// <summary>
|
||||
/// ACS生管
|
||||
/// </summary>
|
||||
ACS = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace JSMachine.WMS.Infrastructure.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// 扫码场景
|
||||
/// </summary>
|
||||
public enum ScannerScene
|
||||
{
|
||||
/// <summary>
|
||||
/// 江苏弘晟
|
||||
/// </summary>
|
||||
JiangSuHongShen = 0,
|
||||
/// <summary>
|
||||
/// 南阳联络
|
||||
/// </summary>
|
||||
NanYangLianLuo = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Extensions
|
||||
{
|
||||
public static class DateTimeExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当日零点
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <returns></returns>
|
||||
public static DateTime GetTodayBegin(this DateTime dateTime)
|
||||
{
|
||||
DateTime timeNow = DateTime.Now;
|
||||
|
||||
return new DateTime(timeNow.Year, timeNow.Month, timeNow.Day, 0, 0, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当日23点59分59秒
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <returns></returns>
|
||||
public static DateTime GetTodayEnd(this DateTime dateTime)
|
||||
{
|
||||
DateTime timeNow = DateTime.Now;
|
||||
|
||||
return new DateTime(timeNow.Year, timeNow.Month, timeNow.Day, 23, 59, 59);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将秒数转化为时分秒
|
||||
/// </summary>
|
||||
/// <param name="duration"></param>
|
||||
/// <returns></returns>
|
||||
public static string Sec_to_hms(int duration)
|
||||
{
|
||||
TimeSpan ts = new(0, 0, duration);
|
||||
string str = "";
|
||||
if (ts.Hours > 0)
|
||||
{
|
||||
str = string.Format("{0:00}", ts.Hours) + ":" + string.Format("{0:00}", ts.Minutes) + ":" + string.Format("{0:00}", ts.Seconds);
|
||||
}
|
||||
if (ts.Hours == 0 && ts.Minutes > 0)
|
||||
{
|
||||
str = "00:" + string.Format("{0:00}", ts.Minutes) + ":" + string.Format("{0:00}", ts.Seconds);
|
||||
}
|
||||
if (ts.Hours == 0 && ts.Minutes == 0)
|
||||
{
|
||||
str = "00:00:" + string.Format("{0:00}", ts.Seconds);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将秒数转换为分秒
|
||||
/// </summary>
|
||||
/// <param name="duration"></param>
|
||||
/// <returns></returns>
|
||||
public static string Sec_to_ms(int duration)
|
||||
{
|
||||
TimeSpan ts = new(0, 0, duration);
|
||||
string str = "";
|
||||
|
||||
if (ts.Hours == 0 && ts.Minutes > 0)
|
||||
{
|
||||
str = string.Format("{0:00}", ts.Minutes) + ":" + string.Format("{0:00}", ts.Seconds);
|
||||
}
|
||||
if (ts.Hours == 0 && ts.Minutes == 0)
|
||||
{
|
||||
str = "00:" + string.Format("{0:00}", ts.Seconds);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure
|
||||
{
|
||||
public static class EnumExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取枚举描述属性值
|
||||
/// </summary>
|
||||
/// <param name="enum"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetDescription(this Enum @enum)
|
||||
{
|
||||
Type type = @enum.GetType();
|
||||
string name = Enum.GetName(type, @enum);
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
return @enum.ToString();
|
||||
|
||||
FieldInfo field = type.GetField(name);
|
||||
DescriptionAttribute des = field?.GetCustomAttribute<DescriptionAttribute>();
|
||||
if (des == null)
|
||||
return @enum.ToString();
|
||||
|
||||
return des.Description;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Linq;
|
||||
using JSMachine.DCS.Infrastructure;
|
||||
using JSMachine.WMS.Infrastructure;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace System.Collections.Generic
|
||||
{
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
public static void ForEach<T>(this IEnumerable<T> @this, Action<T> callback, bool immutable = false)
|
||||
{
|
||||
Guards.ThrowIfNull(@this, callback);
|
||||
|
||||
var collection = immutable ? @this.ToArray() : @this;
|
||||
|
||||
foreach (T item in collection)
|
||||
{
|
||||
callback(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<T> Do<T>(this IEnumerable<T> @this, Action<T> callback)
|
||||
{
|
||||
Guards.ThrowIfNull(@this, callback);
|
||||
|
||||
foreach (var item in @this)
|
||||
{
|
||||
callback?.Invoke(item);
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
//public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
|
||||
//{
|
||||
// return source == null || source.Count() == 0;
|
||||
//}
|
||||
|
||||
public static bool IsNullOrEmpty(this IList source)
|
||||
{
|
||||
return source == null || source.Count == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure
|
||||
{
|
||||
public static class GlobalServericeProvidor
|
||||
{
|
||||
public static IServiceProvider IServiceProvider { get; private set; }
|
||||
|
||||
public static void UseGlobalServiceProvider(this IApplicationBuilder builder)
|
||||
{
|
||||
IServiceProvider = builder.ApplicationServices;
|
||||
}
|
||||
|
||||
public static T GetService<T>()
|
||||
{
|
||||
|
||||
return IServiceProvider.GetService<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using JSMachine.DCS.Infrastructure;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace System
|
||||
{
|
||||
public static class JsonExtensions
|
||||
{
|
||||
public static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
|
||||
public static readonly JsonSerializerSettings JsonDeserializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
|
||||
public static readonly FileLocatorConverter FileLocatorConverter = new FileLocatorConverter();
|
||||
|
||||
static JsonExtensions()
|
||||
{
|
||||
JsonSerializerSettings.Converters.Add(FileLocatorConverter);
|
||||
}
|
||||
|
||||
public static string ToJson<T>(this T @object, Formatting formatting = Formatting.None, bool specifyRootType = true)
|
||||
{
|
||||
var type = @object.GetType();
|
||||
|
||||
return typeof(T) != type && specifyRootType
|
||||
? JsonConvert.SerializeObject(@object, typeof(T), formatting, JsonSerializerSettings)
|
||||
: JsonConvert.SerializeObject(@object, formatting, JsonSerializerSettings);
|
||||
}
|
||||
|
||||
public static T ToObject<T>(this string json)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(json)
|
||||
? JsonConvert.DeserializeObject<T>(json, JsonDeserializerSettings)
|
||||
: default;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class FileLocatorConverter : JsonConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
var fileLocator = (FileLocator)value;
|
||||
writer.WriteValue(fileLocator.FullPath);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType) => objectType == typeof(FileLocator);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Prism.Logging
|
||||
{
|
||||
public static class LoggerFacadeExtensions
|
||||
{
|
||||
public static void Error(this ILoggerFacade logger, string message, Exception e = null)
|
||||
{
|
||||
logger.Log(GetMessage(message, e), Category.Exception, Priority.High);
|
||||
}
|
||||
|
||||
public static void Warning(this ILoggerFacade logger, string message, Exception e = null)
|
||||
{
|
||||
logger.Log(GetMessage(message, e), Category.Warn, Priority.Medium);
|
||||
}
|
||||
|
||||
public static void Info(this ILoggerFacade logger, string message, Exception e = null)
|
||||
{
|
||||
logger.Log(GetMessage(message, e), Category.Info, Priority.Low);
|
||||
}
|
||||
|
||||
public static void Debug(this ILoggerFacade logger, string message, Exception e = null)
|
||||
{
|
||||
logger.Log(GetMessage(message, e), Category.Debug, Priority.Low);
|
||||
}
|
||||
|
||||
private static string GetMessage(string message, Exception e)
|
||||
{
|
||||
message = $"{message}{Environment.NewLine}";
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
message = $"{message}{e.Message}{Environment.NewLine}" +
|
||||
$"{e.StackTrace}{Environment.NewLine}";
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace System
|
||||
{
|
||||
public static class ObjectExtensions
|
||||
{
|
||||
private const double Tolerance = 1e-6;
|
||||
|
||||
public static T CastTo<T>(this object value)
|
||||
{
|
||||
return typeof(T).IsValueType && value != null
|
||||
? (T)Convert.ChangeType(value, typeof(T))
|
||||
: value is T typeValue ? typeValue : default;
|
||||
}
|
||||
|
||||
public static bool EqualsWithinTolerance(this double @this, double other)
|
||||
{
|
||||
return Math.Abs(@this - other) < Tolerance;
|
||||
}
|
||||
|
||||
public static bool GreaterOrEqual(this double @this, double other)
|
||||
{
|
||||
return @this > other || @this.EqualsWithinTolerance(other);
|
||||
}
|
||||
|
||||
public static bool LessOrEqual(this double @this, double other)
|
||||
{
|
||||
return @this < other || @this.EqualsWithinTolerance(other);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace System
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
public static class SecureStringExtensions
|
||||
{
|
||||
public static string AsString(this SecureString @this)
|
||||
{
|
||||
if (@this == null || @this.Length == 0)
|
||||
return string.Empty;
|
||||
|
||||
IntPtr bstr = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
bstr = Marshal.SecureStringToBSTR(@this);
|
||||
return Marshal.PtrToStringBSTR(bstr);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (bstr != IntPtr.Zero)
|
||||
Marshal.ZeroFreeBSTR(bstr);
|
||||
}
|
||||
}
|
||||
|
||||
public static SecureString AsSecureString(this string @this)
|
||||
{
|
||||
if (string.IsNullOrEmpty(@this))
|
||||
return new SecureString();
|
||||
|
||||
var secureString = new SecureString();
|
||||
Array.ForEach(@this.ToCharArray(), secureString.AppendChar);
|
||||
|
||||
return secureString;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using JSMachine.DCS.Infrastructure;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace System
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static string RandomString(int length)
|
||||
{
|
||||
var b = new byte[4];
|
||||
new RNGCryptoServiceProvider().GetBytes(b);
|
||||
var r = new Random(BitConverter.ToInt32(b, 0));
|
||||
var ret = string.Empty;
|
||||
const string str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
for (var i = 0; i < length; i++)
|
||||
ret += str.Substring(r.Next(0, str.Length - 1), 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string LogId => RandomString(48);
|
||||
|
||||
public static string GetMatch(this string text, string p1, string p2)
|
||||
{
|
||||
var rg = new Regex("(?<=(" + p1 + "))[.\\s\\S]*?(?=(" + p2 + "))",
|
||||
RegexOptions.Multiline | RegexOptions.Singleline);
|
||||
return rg.Match(text).Value;
|
||||
}
|
||||
|
||||
public static bool IsEmailAddress(this string @this)
|
||||
{
|
||||
return !string.IsNullOrEmpty(@this) && !string.IsNullOrWhiteSpace(@this); // TODO
|
||||
}
|
||||
|
||||
public static string TrimMiddle(this string @this, int limitLength, string omitPlaceholder = null)
|
||||
{
|
||||
const string defaultOmitPlaceholder = "...";
|
||||
|
||||
if (omitPlaceholder == null) omitPlaceholder = defaultOmitPlaceholder;
|
||||
Guards.ThrowIfNot(limitLength >= omitPlaceholder.Length);
|
||||
|
||||
if (string.IsNullOrEmpty(@this) || @this.Length <= limitLength) return @this;
|
||||
|
||||
if (limitLength == omitPlaceholder.Length) return omitPlaceholder;
|
||||
|
||||
var halfLength = (limitLength - omitPlaceholder.Length) / 2;
|
||||
var bias = (limitLength - omitPlaceholder.Length) % 2;
|
||||
|
||||
var firstHalfString = @this.Substring(0, halfLength + bias);
|
||||
var secondHalfString = @this.Substring(@this.Length - halfLength);
|
||||
|
||||
return $"{firstHalfString}{omitPlaceholder}{secondHalfString}";
|
||||
}
|
||||
|
||||
public static string UpperCamelCaseToDelimiterSeparated(this string upperCamelCase)
|
||||
{
|
||||
var stringBuilder = new StringBuilder(upperCamelCase.Length, upperCamelCase.Length * 2);
|
||||
|
||||
for (int i = 0; i < upperCamelCase.Length; i++)
|
||||
{
|
||||
var @char = upperCamelCase[i];
|
||||
if (char.IsUpper(@char))
|
||||
{
|
||||
if (i != 0) stringBuilder.Append('-');
|
||||
stringBuilder.Append(char.ToLower(@char));
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.Append(@char);
|
||||
}
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace JSMachine.DCS.Infrastructure
|
||||
{
|
||||
[DebuggerDisplay("{" + nameof(FullPath) + "}")]
|
||||
public class FileLocator : IEquatable<FileLocator>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a regular expression for splitting the file full path string.
|
||||
/// In the right case, the group will have four elements:
|
||||
/// [0]: FullPath
|
||||
/// [1]: FolderName
|
||||
/// [2]: FileName
|
||||
/// [3]: FileExtension
|
||||
/// </summary>
|
||||
private static readonly Regex RegexFileLocation = new Regex(@"^([\\/]?(?:\w:)?(?:[^\\/]+?[\\/])*?)([^\\/]+?(?:\.(\w+?))?)?$", RegexOptions.Compiled);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representing the full path of the file.
|
||||
/// </summary>
|
||||
public string FullPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representing the folder where the file is located.
|
||||
/// </summary>
|
||||
public string FolderPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representing the file name.
|
||||
/// </summary>
|
||||
public string FileName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representing the file extension.
|
||||
/// </summary>
|
||||
public string FileExtension { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a instance of <see cref="FileLocator"/> with specified file full path.
|
||||
/// </summary>
|
||||
/// <param name="fileFullPath">A string representing the full path of the file. </param>
|
||||
public FileLocator(string fileFullPath)
|
||||
{
|
||||
var matchResult = RegexFileLocation.Match(fileFullPath);
|
||||
|
||||
if (matchResult.Groups == null || matchResult.Groups.Count != 4)
|
||||
throw new ArgumentException($"The file path is not valid: {fileFullPath}", fileFullPath);
|
||||
|
||||
FullPath = matchResult.Groups[0].Value;
|
||||
var temp = matchResult.Groups[1].Value;
|
||||
if (!string.IsNullOrEmpty(temp)) FolderPath = temp.Remove(temp.Length - 1); // Remove the "\" or "/" at the end.
|
||||
FileName = matchResult.Groups[2].Value;
|
||||
FileExtension = matchResult.Groups[3].Value.ToLower();
|
||||
}
|
||||
|
||||
public override string ToString() => FullPath;
|
||||
|
||||
#region Implements Equals
|
||||
|
||||
public bool Equals(FileLocator other) => !Equals(other, null) && string.Equals(FullPath, other.FullPath);
|
||||
|
||||
public override bool Equals(object obj) => ReferenceEquals(this, obj) || Equals(obj as FileLocator);
|
||||
|
||||
public static bool operator ==(FileLocator left, FileLocator right)
|
||||
{
|
||||
if ((object)left == null || (object)right == null)
|
||||
return Equals(left, right);
|
||||
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(FileLocator left, FileLocator right) => !(left == right);
|
||||
|
||||
public override int GetHashCode() => FullPath != null ? FullPath.GetHashCode() : 0;
|
||||
|
||||
#endregion
|
||||
|
||||
public static implicit operator FileLocator(string filePath) => string.IsNullOrEmpty(filePath) ? null : new FileLocator(filePath);
|
||||
|
||||
public static implicit operator string(FileLocator fileLocation) => fileLocation?.FullPath;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<Rougamo />
|
||||
</Weavers>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="Rougamo" minOccurs="0" maxOccurs="1" type="xs:anyType" />
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.FullTextSearch
|
||||
{
|
||||
/// <summary>
|
||||
/// 全文检索忽略字段标记
|
||||
/// </summary>
|
||||
public class FullTextSearchIgnoreAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using JSMachine.WMS.Infrastructure.LambdaHelp;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.FullTextSearch
|
||||
{
|
||||
/// <summary>
|
||||
/// 全文检索表达式目录树辅助类
|
||||
/// </summary>
|
||||
public static class FulleTextSearchHelper<T> where T : class, new()
|
||||
{
|
||||
private static PropertyInfo[] Properties = typeof(T).GetProperties();
|
||||
|
||||
/// <summary>
|
||||
/// 构建全文检索表达式目录树(精确匹配)
|
||||
/// </summary>
|
||||
public static Expression<Func<T, bool>> BuildFullTextSearchEqualExpression(object keyWords)
|
||||
{
|
||||
if (keyWords == null || string.IsNullOrEmpty(keyWords.ToString()))
|
||||
{
|
||||
return ExpressionTreeHelper<T>.True();
|
||||
}
|
||||
|
||||
|
||||
Expression<Func<T, bool>> initTree = ExpressionTreeHelper<T>.False();
|
||||
|
||||
foreach (PropertyInfo propertyInfo in Properties)
|
||||
{
|
||||
FullTextSearchIgnoreAttribute ignoreAttrbute = propertyInfo
|
||||
.GetCustomAttributes()
|
||||
.FirstOrDefault(attribute => attribute is FullTextSearchIgnoreAttribute)
|
||||
as FullTextSearchIgnoreAttribute;
|
||||
|
||||
if (ignoreAttrbute == null)
|
||||
{
|
||||
Expression<Func<T, bool>> express = ExpressionTreeHelper<T>.CreateEqual(propertyInfo.Name, keyWords);
|
||||
initTree = initTree.Or(express);
|
||||
}
|
||||
}
|
||||
|
||||
return initTree;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建全文检索表达式目录树(模糊匹配)
|
||||
/// </summary>
|
||||
public static Expression<Func<T, bool>> BuildFullTextSearchLikeExpression(object keyWords)
|
||||
{
|
||||
if (keyWords == null || string.IsNullOrEmpty(keyWords.ToString()))
|
||||
{
|
||||
return ExpressionTreeHelper<T>.True();
|
||||
}
|
||||
|
||||
Expression<Func<T, bool>> initTree = ExpressionTreeHelper<T>.False();
|
||||
|
||||
foreach (PropertyInfo propertyInfo in Properties)
|
||||
{
|
||||
FullTextSearchIgnoreAttribute ignoreAttrbute = propertyInfo
|
||||
.GetCustomAttributes()
|
||||
.FirstOrDefault(attribute => attribute is FullTextSearchIgnoreAttribute)
|
||||
as FullTextSearchIgnoreAttribute;
|
||||
|
||||
if (ignoreAttrbute == null)
|
||||
{
|
||||
//值类型
|
||||
Type[] valueTypes = new Type[5] ;
|
||||
|
||||
//如果是可空类型
|
||||
if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
|
||||
{
|
||||
valueTypes = new Type[5] { typeof(int?), typeof(byte?), typeof(double?), typeof(float?), typeof(DateTime?) };
|
||||
Expression<Func<T, bool>> express = ExpressionTreeHelper<T>.CreateEqual(propertyInfo.Name, keyWords);
|
||||
initTree = initTree.Or(express);
|
||||
}
|
||||
//值类型只能精准匹配
|
||||
else if (valueTypes.Contains(propertyInfo.PropertyType))
|
||||
{
|
||||
valueTypes = new Type[5] { typeof(int), typeof(byte), typeof(double), typeof(float), typeof(DateTime) };
|
||||
Expression<Func<T, bool>> express = ExpressionTreeHelper<T>.CreateEqual(propertyInfo.Name, keyWords);
|
||||
initTree = initTree.Or(express);
|
||||
}
|
||||
else if(propertyInfo.PropertyType==typeof(string))
|
||||
{
|
||||
Expression<Func<T, bool>> express = ExpressionTreeHelper<T>.GetContains(propertyInfo.Name, keyWords);
|
||||
initTree = initTree.Or(express);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return initTree;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure
|
||||
{
|
||||
public interface IGenericInterface
|
||||
{
|
||||
Type Type { get; }
|
||||
|
||||
Type[] GenericArguments { get; }
|
||||
|
||||
TDelegate GetMethod<TDelegate>(string methodName, params Type[] argTypes);
|
||||
}
|
||||
|
||||
public static class GenericInterfaceExtensions
|
||||
{
|
||||
public static IGenericInterface AsGenericInterface(this object @this, Type type)
|
||||
{
|
||||
var interfaceType = (
|
||||
from @interface in @this.GetType().GetInterfaces()
|
||||
where @interface.IsGenericType
|
||||
let definition = @interface.GetGenericTypeDefinition()
|
||||
where definition == type
|
||||
select @interface
|
||||
)
|
||||
.SingleOrDefault();
|
||||
|
||||
return interfaceType != null
|
||||
? new GenericInterfaceImpl(@this, interfaceType)
|
||||
: null;
|
||||
}
|
||||
|
||||
private class GenericInterfaceImpl : IGenericInterface
|
||||
{
|
||||
private static readonly Regex ActionDelegateRegex = new Regex(@"^System\.Action(`\d{1,2})?", RegexOptions.Compiled);
|
||||
private static readonly Regex FuncDelegateRegex = new Regex(@"^System\.Func`(\d{1,2})", RegexOptions.Compiled);
|
||||
|
||||
private readonly object _instance;
|
||||
|
||||
public Type Type { get; }
|
||||
|
||||
public Type[] GenericArguments => Type.GetGenericArguments();
|
||||
|
||||
public GenericInterfaceImpl(object instance, Type interfaceType)
|
||||
{
|
||||
_instance = instance;
|
||||
Type = interfaceType;
|
||||
}
|
||||
|
||||
public TDelegate GetMethod<TDelegate>(string methodName, params Type[] argTypes)
|
||||
{
|
||||
switch (GetDelegateType<TDelegate>())
|
||||
{
|
||||
case DelegateType.Action:
|
||||
return GetAction<TDelegate>(methodName);
|
||||
case DelegateType.ActionWithParams:
|
||||
return GetActionWithParams<TDelegate>(methodName, argTypes);
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private TDelegate GetActionWithParams<TDelegate>(string methodName, params Type[] argTypes)
|
||||
{
|
||||
var methodInfo = Type.GetMethod(methodName) ?? throw new ArgumentException(nameof(methodName));
|
||||
var argTypeList = argTypes.Any() ? argTypes : typeof(TDelegate).GetGenericArguments();
|
||||
(ParameterExpression expression, Type type)[] argObjectParameters = argTypeList
|
||||
.Select(item => (Expression.Parameter(typeof(object)), item))
|
||||
.ToArray();
|
||||
|
||||
var method = Expression.Lambda<TDelegate>(
|
||||
Expression.Call(
|
||||
Expression.Constant(_instance),
|
||||
methodInfo,
|
||||
argObjectParameters.Select(item => Expression.Convert(item.expression, item.type))),
|
||||
argObjectParameters.Select(item => item.expression))
|
||||
.Compile();
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
private TDelegate GetAction<TDelegate>(string methodName)
|
||||
{
|
||||
var methodInfo = Type.GetMethod(methodName) ?? throw new ArgumentException(nameof(methodName));
|
||||
var method = Expression.Lambda<TDelegate>(
|
||||
Expression.Call(
|
||||
Expression.Constant(_instance),
|
||||
methodInfo))
|
||||
.Compile();
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
private static DelegateType GetDelegateType<TDelegate>()
|
||||
{
|
||||
var actionMatch = ActionDelegateRegex.Match(typeof(TDelegate).FullName ?? throw new InvalidOperationException());
|
||||
if (actionMatch.Success)
|
||||
{
|
||||
return actionMatch.Groups.Count > 1 ? DelegateType.ActionWithParams : DelegateType.Action;
|
||||
}
|
||||
|
||||
var funcMatch = FuncDelegateRegex.Match(typeof(TDelegate).FullName ?? throw new InvalidOperationException());
|
||||
if (funcMatch.Success)
|
||||
{
|
||||
return int.Parse(actionMatch.Groups[1].Value) > 1 ? DelegateType.FuncWithParams : DelegateType.Func;
|
||||
}
|
||||
|
||||
return DelegateType.NotSupported;
|
||||
}
|
||||
|
||||
private enum DelegateType
|
||||
{
|
||||
NotSupported,
|
||||
Action,
|
||||
Func,
|
||||
ActionWithParams,
|
||||
FuncWithParams
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using JSMachine.WMS.Infrastructure.AppConfiguration;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
|
||||
namespace JSMachine.WMS.Common
|
||||
{
|
||||
public static class Global
|
||||
{
|
||||
public static AppSettings AppSettings { get; set; } = new AppSettings();
|
||||
|
||||
static Global()
|
||||
{
|
||||
string filePath = $@"{AppDomain.CurrentDomain.BaseDirectory}\appSettingsWebhost.json";
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
string json = File.ReadAllText(filePath);
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
{
|
||||
JObject jobject = JObject.Parse(json);
|
||||
string appSettings = jobject["AppSettings"].ToString();
|
||||
|
||||
AppSettings = JsonConvert.DeserializeObject<AppSettings>(appSettings);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LogHelper.Error("配置文件读取错误!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace JSMachine.DCS.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础参数守卫工具,在进入业务流程前校验空值、路径和条件状态。
|
||||
/// </summary>
|
||||
public static class Guards
|
||||
{
|
||||
/// <summary>当任意参数为空时抛出参数异常。</summary>
|
||||
/// <param name="parameters">待检查的参数集合。</param>
|
||||
public static void ThrowIfNull(params object[] parameters)
|
||||
{
|
||||
if (parameters.Any(item => item == null))
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
/// <summary>当任意字符串为空或空字符串时抛出参数异常。</summary>
|
||||
/// <param name="strings">待检查的字符串集合。</param>
|
||||
public static void ThrowIfNullOrEmpty(params string[] strings)
|
||||
{
|
||||
if (strings.Any(string.IsNullOrEmpty))
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
/// <summary>检查字符串序列及其中的每一项是否为空。</summary>
|
||||
/// <param name="strings">待检查的字符串序列。</param>
|
||||
public static void ThrowIfNullOrEmpty(IEnumerable<string> strings)
|
||||
{
|
||||
ThrowIfNull(strings);
|
||||
ThrowIfNullOrEmpty(strings.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>当指定文件不存在时抛出文件未找到异常。</summary>
|
||||
/// <param name="path">文件路径。</param>
|
||||
public static void ThrowIfFileNotFound(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
throw new FileNotFoundException("Can not found the specified file path. ", path);
|
||||
}
|
||||
|
||||
/// <summary>当指定目录不存在时抛出目录未找到异常。</summary>
|
||||
/// <param name="path">目录路径。</param>
|
||||
public static void ThrowIfFolderNotFount(string path)
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
throw new DirectoryNotFoundException($"Can not found the specified path {path}. ");
|
||||
}
|
||||
|
||||
/// <summary>当路径既不是文件也不是目录时抛出目录异常。</summary>
|
||||
/// <param name="path">待检查的路径。</param>
|
||||
public static void ThrowIfInvalidPath(string path)
|
||||
{
|
||||
if (!File.Exists(path) && !Directory.Exists(path))
|
||||
throw new DirectoryNotFoundException($"The specified path is not a valid file or directory. ({path})");
|
||||
}
|
||||
|
||||
/// <summary>当条件不成立时抛出无效操作异常。</summary>
|
||||
/// <param name="condition">必须成立的条件。</param>
|
||||
public static void ThrowIfNot(bool condition)
|
||||
{
|
||||
if (!condition)
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
/// <summary>计算条件并在结果不成立时抛出无效操作异常。</summary>
|
||||
/// <param name="condition">返回校验结果的委托。</param>
|
||||
public static void ThrowIfNot(Func<bool> condition)
|
||||
{
|
||||
ThrowIfNull(condition);
|
||||
ThrowIfNot(condition());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
using JSMachine.DCS.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using RestSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Helper
|
||||
{
|
||||
public static class HttpRequestHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 字典方式请求,支持表单数据
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="dic"></param>
|
||||
/// <param name="postFileParam"></param>
|
||||
/// <param name="timeOut"></param>
|
||||
/// <returns></returns>
|
||||
public async static Task<string> RequestByDic(string url,
|
||||
Method method,
|
||||
Dictionary<string, object> dic = null,
|
||||
List<PostFileParam> postFileParam = null,
|
||||
int timeOut = 5000)
|
||||
{
|
||||
|
||||
RestClient client = new(url)
|
||||
{
|
||||
Timeout = timeOut
|
||||
};
|
||||
|
||||
RestRequest request = new(method);
|
||||
|
||||
dic?.Select(p => p.Key)
|
||||
.ToList()
|
||||
.ForEach(key => request.AddParameter(key, dic[key]));
|
||||
|
||||
postFileParam?.ForEach(p =>
|
||||
{
|
||||
request.AddFile(p.RemoteParamName, p.FileBytes, p.FileName);
|
||||
});
|
||||
|
||||
IRestResponse response = await client.ExecuteAsync(request);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK && response.ErrorException == null)
|
||||
return response.Content;
|
||||
|
||||
if (response.ErrorException != null)
|
||||
{
|
||||
LogHelper.Error($"HttpRequstHandling.PostFile--{response.ErrorException.Message}");
|
||||
LogHelper.Error("当前请求url:" + url);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// JSON参数请求
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="json"></param>
|
||||
/// <param name="timeOut"></param>
|
||||
/// <returns></returns>
|
||||
public async static Task<string> RequestByJson(string url, Method method, string json, int timeOut = 5000)
|
||||
{
|
||||
RestClient client = new(url)
|
||||
{
|
||||
Timeout = timeOut
|
||||
};
|
||||
RestRequest request = new(method);
|
||||
|
||||
request.AddHeader("Content-Type", "application/json");
|
||||
request.AddParameter("application/json", json, ParameterType.RequestBody);
|
||||
IRestResponse response = client.Execute(request);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK && response.ErrorException == null)
|
||||
return response.Content;
|
||||
|
||||
if (response.ErrorException != null)
|
||||
{
|
||||
LogHelper.Error($"HttpRequstHandling.PostFile--{response.ErrorException.Message}");
|
||||
LogHelper.Error("当前请求url:" + url);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// JSON参数请求
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="json"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="timeOut"></param>
|
||||
/// <returns></returns>
|
||||
public async static Task<string> RequestByJson(string url, Method method, string json, string token, int timeOut = 5000)
|
||||
{
|
||||
|
||||
RestClient client = new(url)
|
||||
{
|
||||
Timeout = timeOut
|
||||
};
|
||||
RestRequest request = new(method);
|
||||
|
||||
request.AddHeader("Authorization", $"Bearer {token}");
|
||||
request.AddHeader("Content-Type", "application/json");
|
||||
|
||||
request.AddHeader("Content-Type", "application/json");
|
||||
request.AddParameter("application/json", json, ParameterType.RequestBody);
|
||||
IRestResponse response = await client.ExecuteAsync(request);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK && response.ErrorException == null)
|
||||
return response.Content;
|
||||
|
||||
if (response.ErrorException != null)
|
||||
{
|
||||
LogHelper.Error($"HttpRequstHandling.PostFile--{response.ErrorException.Message}");
|
||||
LogHelper.Error("当前请求url:" + url);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 无参请求返回二进制(用于下载文件)
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="timeOut"></param>
|
||||
/// <returns></returns>
|
||||
public async static Task<byte[]> RequestRturnRawAsync(string url, Method method, int timeOut = 5000)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
return null;
|
||||
|
||||
RestClient client = new(url)
|
||||
{
|
||||
Timeout = timeOut
|
||||
};
|
||||
|
||||
RestRequest request = new(method);
|
||||
request.AlwaysMultipartFormData = true;
|
||||
|
||||
|
||||
IRestResponse response = await client.ExecuteAsync(request);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK && response.ErrorException == null)
|
||||
return response.RawBytes;
|
||||
|
||||
if (response.ErrorException != null)
|
||||
{
|
||||
LogHelper.Error($"HttpRequstHandling.PostFile--{response.ErrorException.Message}");
|
||||
LogHelper.Error("当前请求url:" + url);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 无参请求返回二进制(用于下载文件)
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="timeOut"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] RequestRturnRaw(string url, Method method, int timeOut = 5000)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
return null;
|
||||
|
||||
RestClient client = new(url)
|
||||
{
|
||||
Timeout = timeOut
|
||||
};
|
||||
|
||||
RestRequest request = new(method);
|
||||
request.AlwaysMultipartFormData = true;
|
||||
|
||||
IRestResponse response = client.Execute(request);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK && response.ErrorException == null)
|
||||
return response.RawBytes;
|
||||
|
||||
if (response.ErrorException != null)
|
||||
{
|
||||
LogHelper.Error($"HttpRequstHandling.PostFile--{response.ErrorException.Message}");
|
||||
LogHelper.Error("当前请求url:" + url);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取请求的数据
|
||||
/// </summary>
|
||||
private static string GetResponseString(WebResponse webResponse)
|
||||
{
|
||||
using (var stream = webResponse.GetResponseStream())
|
||||
{
|
||||
if (stream == null) return string.Empty;
|
||||
using (var reader = new StreamReader(stream, Encoding.UTF8))
|
||||
{
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以GET方式请求HTTP地址并获取返回
|
||||
/// </summary>
|
||||
public async static Task<string> Get(string url, Dictionary<string, string> headers = null,
|
||||
CookieCollection cookies = null)
|
||||
{
|
||||
HttpWebRequest request = null;
|
||||
WebResponse response = null;
|
||||
try
|
||||
{
|
||||
ServicePointManager.DefaultConnectionLimit = 200;
|
||||
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//对服务端证书进行有效性校验
|
||||
ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
|
||||
}
|
||||
request = (HttpWebRequest)WebRequest.Create(url);
|
||||
request.Method = "GET";
|
||||
|
||||
if (headers != null && headers.Count > 0)
|
||||
{
|
||||
foreach (var header in headers)
|
||||
{
|
||||
request.Headers.Add(header.Key, header.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (cookies != null)
|
||||
{
|
||||
request.CookieContainer = new CookieContainer();
|
||||
request.CookieContainer.Add(cookies);
|
||||
}
|
||||
response = request.GetResponse();
|
||||
return GetResponseString(response);
|
||||
}
|
||||
catch (System.Threading.ThreadAbortException e)
|
||||
{
|
||||
System.Threading.Thread.ResetAbort();
|
||||
throw new Exception(e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
request?.Abort();
|
||||
response?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以POST方式请求HTTP地址并获取返回
|
||||
/// </summary>
|
||||
/// <param name="url">HTTP地址</param>
|
||||
/// <param name="parameters">POST的键值对参数</param>
|
||||
/// <param name="headers"></param>
|
||||
/// <param name="cookies"></param>
|
||||
/// <returns></returns>
|
||||
public async static Task<string> Post(string url, Dictionary<string, string> parameters,
|
||||
Dictionary<string, string> headers = null, CookieCollection cookies = null)
|
||||
{
|
||||
return await Post(url, GetPostData(parameters), null, headers, cookies);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以POST方式请求HTTP地址并获取返回
|
||||
/// </summary>
|
||||
/// <param name="url">HTTP地址</param>
|
||||
/// <param name="content">POST的内容</param>
|
||||
/// <param name="contentType"></param>
|
||||
/// <param name="headers"></param>
|
||||
/// <param name="cookies"></param>
|
||||
/// <returns></returns>
|
||||
public async static Task<string> Post(string url, string content, string contentType = null,
|
||||
Dictionary<string, string> headers = null, CookieCollection cookies = null)
|
||||
{
|
||||
HttpWebRequest request = null;
|
||||
HttpWebResponse response = null;
|
||||
|
||||
try
|
||||
{
|
||||
ServicePointManager.DefaultConnectionLimit = 200;
|
||||
//如果是发送HTTPS请求
|
||||
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//对服务端证书进行有效性校验
|
||||
ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
|
||||
}
|
||||
request = (HttpWebRequest)WebRequest.Create(url);
|
||||
request.Method = "POST";
|
||||
request.Timeout = 30000;
|
||||
request.ContentType = contentType ?? "application/x-www-form-urlencoded";
|
||||
|
||||
if (headers != null && headers.Count > 0)
|
||||
{
|
||||
foreach (var header in headers)
|
||||
{
|
||||
request.Headers.Add(header.Key, header.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (cookies != null)
|
||||
{
|
||||
request.CookieContainer = new CookieContainer();
|
||||
request.CookieContainer.Add(cookies);
|
||||
}
|
||||
//发送POST数据
|
||||
var data = Encoding.UTF8.GetBytes(content ?? string.Empty);
|
||||
request.ContentLength = data.Length;
|
||||
using (var stream = request.GetRequestStream())
|
||||
{
|
||||
stream.Write(data, 0, data.Length);
|
||||
}
|
||||
|
||||
response = (HttpWebResponse)request.GetResponse();
|
||||
return GetResponseString(response);
|
||||
}
|
||||
catch (System.Threading.ThreadAbortException e)
|
||||
{
|
||||
System.Threading.Thread.ResetAbort();
|
||||
throw new Exception(e.Message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception(e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
request?.Abort();
|
||||
response?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字典转化为post数据
|
||||
/// </summary>
|
||||
/// <param name="dictionary"></param>
|
||||
/// <returns></returns>
|
||||
private static string GetPostData(Dictionary<string, string> dictionary)
|
||||
{
|
||||
if (dictionary == null || dictionary.Count == 0) return string.Empty;
|
||||
var sb = new StringBuilder();
|
||||
var keys = dictionary.Keys.ToList();
|
||||
for (var i = 0; i < keys.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
sb.Append("&");
|
||||
}
|
||||
sb.AppendFormat("{0}={1}", keys[i], HttpUtility.UrlEncode(dictionary[keys[i]]));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证证书
|
||||
/// </summary>
|
||||
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain,
|
||||
SslPolicyErrors errors)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class PostFileParam
|
||||
{
|
||||
public string RemoteParamName { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public byte[] FileBytes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
using NLog;
|
||||
using NLog.Web;
|
||||
using System;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Helper
|
||||
{
|
||||
public static class LogHelper
|
||||
{
|
||||
private static ILogger logger = GetLogger();
|
||||
private static ILogger GetLogger()
|
||||
{
|
||||
ILogger logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
|
||||
return logger;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 调试
|
||||
/// </summary>
|
||||
/// <param name="debug"></param>
|
||||
public static void Debug(string debug)
|
||||
{
|
||||
logger.Debug(debug);
|
||||
}
|
||||
public static void Debug(Exception ex)
|
||||
{
|
||||
logger.Debug(ex);
|
||||
}
|
||||
public static void Debug(string debug,Exception ex)
|
||||
{
|
||||
logger.Debug(ex,debug);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 信息
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
public static void Info(string info)
|
||||
{
|
||||
logger.Info(info);
|
||||
}
|
||||
public static void Info(Exception ex)
|
||||
{
|
||||
logger.Info(ex);
|
||||
}
|
||||
public static void Info(string info,Exception ex)
|
||||
{
|
||||
logger.Info(ex,info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 警告
|
||||
/// </summary>
|
||||
/// <param name="warn"></param>
|
||||
public static void Warn(string warn)
|
||||
{
|
||||
logger.Warn(warn);
|
||||
}
|
||||
public static void Warn(Exception ex)
|
||||
{
|
||||
logger.Warn(ex);
|
||||
}
|
||||
public static void Warn(string warn,Exception ex)
|
||||
{
|
||||
logger.Warn(ex,warn);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误
|
||||
/// </summary>
|
||||
/// <param name="error"></param>
|
||||
public static void Error(string error)
|
||||
{
|
||||
logger.Error(error);
|
||||
}
|
||||
public static void Error(Exception error)
|
||||
{
|
||||
logger.Error(error);
|
||||
}
|
||||
public static void Error(string error, Exception ex)
|
||||
{
|
||||
logger.Error(ex, error);
|
||||
}
|
||||
/// <summary>
|
||||
/// 严重错误
|
||||
/// </summary>
|
||||
/// <param name="fatale"></param>
|
||||
public static void Fatal(string fatal)
|
||||
{
|
||||
logger.Fatal(fatal);
|
||||
}
|
||||
public static void Fatal(Exception ex)
|
||||
{
|
||||
logger.Fatal(ex);
|
||||
}
|
||||
public static void Fatal(string fatal,Exception ex)
|
||||
{
|
||||
logger.Fatal(ex,fatal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 跟踪
|
||||
/// </summary>
|
||||
/// <param name="trace"></param>
|
||||
public static void Trace(string trace)
|
||||
{
|
||||
logger.Trace(trace);
|
||||
}
|
||||
public static void Trace(Exception ex)
|
||||
{
|
||||
logger.Trace(ex);
|
||||
}
|
||||
public static void Trace(string trace,Exception ex)
|
||||
{
|
||||
logger.Trace(ex,trace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Org.BouncyCastle.Crypto.Digests;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// Md5加密辅助类
|
||||
/// </summary>
|
||||
public static class Md5EncryptionHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 16位MD5加密
|
||||
/// </summary>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
public static string MD5Encrypt16(string str)
|
||||
{
|
||||
MD5 md5 = MD5.Create();
|
||||
string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(str)), 4, 8);
|
||||
t2 = t2.Replace("-", "");
|
||||
return t2;
|
||||
}
|
||||
/// <summary>
|
||||
/// 32位MD5加密
|
||||
/// </summary>
|
||||
/// <param name="password"></param>
|
||||
/// <param name="lower">是否小写输出</param>
|
||||
/// <returns></returns>
|
||||
public static string MD5Encrypt32(string str, bool lower)
|
||||
{
|
||||
string cl = str;
|
||||
string pwd = string.Empty;
|
||||
MD5 md5 = MD5.Create(); //实例化一个md5对像
|
||||
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
|
||||
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
|
||||
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
|
||||
pwd = lower ? pwd + s[i].ToString("x").PadLeft(2, '0') : pwd + s[i].ToString("X").PadLeft(2, '0');
|
||||
}
|
||||
return pwd;
|
||||
}
|
||||
|
||||
public static string MD5Encrypt64(string str)
|
||||
{
|
||||
string cl = str;
|
||||
//string pwd = "";
|
||||
MD5 md5 = MD5.Create(); //实例化一个md5对像
|
||||
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
|
||||
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
|
||||
return Convert.ToBase64String(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象拷贝帮助类
|
||||
/// </summary>
|
||||
public static class ObjectCloneHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 深拷贝
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public static T DeepClone<T>(T t) where T : class
|
||||
{
|
||||
if (t == null)
|
||||
return null;
|
||||
|
||||
string json = JsonConvert.SerializeObject(t);
|
||||
return JsonConvert.DeserializeObject<T>(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using JSMachine.DCS.Infrastructure;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Helper
|
||||
{
|
||||
public static class ProcessHelper
|
||||
{
|
||||
//调用浏览器打开指定的网址
|
||||
public static bool OpenBrowserUrl(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
//优先用IE,不行再尝试用谷歌
|
||||
if (OpenIe(url))
|
||||
return true;
|
||||
|
||||
// 64位注册表路径
|
||||
string openKey = @"SOFTWARE\Wow6432Node\Google\Chrome";
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
// 32位注册表路径
|
||||
openKey = @"SOFTWARE\Google\Chrome";
|
||||
}
|
||||
RegistryKey appPath = Registry.LocalMachine.OpenSubKey(openKey);
|
||||
// 谷歌浏览器就用谷歌打开,没找到就用系统默认的浏览器
|
||||
// 谷歌卸载了,注册表还没有清空,程序会返回一个"系统找不到指定的文件。"的bug
|
||||
if (appPath != null)
|
||||
{
|
||||
Process result = Process.Start("chrome.exe", url);
|
||||
return result != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Process result = Process.Start("chrome.exe", url);
|
||||
return result != null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error(ex.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// 用IE打开浏览器
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
public static bool OpenIe(string url)
|
||||
{
|
||||
Process process = new();
|
||||
process.StartInfo.FileName = "iexplore.exe"; //IE浏览器,可以更换
|
||||
process.StartInfo.Arguments = url;
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error($"使用IE打开网址错误:{ex.Message}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using BeetleX.BNR;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// 序列号生成帮助类
|
||||
/// </summary>
|
||||
public static class SerialNumHelper
|
||||
{
|
||||
public async static Task<string> GenerateSerialNum()
|
||||
{
|
||||
return await BNRFactory.Default.Create("[CN:WH][D:yyyyMMdd][N:[D:yyyyMMdd]/000000]");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace SuperDogTest
|
||||
{
|
||||
/// <summary>
|
||||
/// 超级狗辅助类
|
||||
/// </summary>
|
||||
public static class SuperDogHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 加载dll
|
||||
/// </summary>
|
||||
/// <param name="DllName"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("kernel32.dll")]
|
||||
public extern static IntPtr LoadLibrary(string DllName);
|
||||
/// <summary>
|
||||
/// 释放dll
|
||||
/// </summary>
|
||||
/// <param name="hModule"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
[DllImport("kernel32")]
|
||||
public extern static bool FreeLibrary(IntPtr hModule);
|
||||
/// <summary>
|
||||
/// 获取dll中的方法句柄
|
||||
/// </summary>
|
||||
/// <param name="hModule"></param>
|
||||
/// <param name="ProcName"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public extern static IntPtr GetProcAddress(IntPtr hModule, string ProcName);
|
||||
|
||||
/// <summary>
|
||||
/// 查找加密狗委托
|
||||
/// </summary>
|
||||
/// <param name="Count"></param>
|
||||
/// <returns></returns>
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
public delegate int VikeyFindType(ref int Count);
|
||||
|
||||
/// <summary>
|
||||
/// 读取加密狗数据委托
|
||||
/// </summary>
|
||||
/// <param name="Index"></param>
|
||||
/// <param name="Addr"></param>
|
||||
/// <param name="Length"></param>
|
||||
/// <param name="buffer"></param>
|
||||
/// <returns></returns>
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
public delegate int VikeyReadDataType(int Index, int Addr, int Length, StringBuilder buffer);
|
||||
|
||||
/// <summary>
|
||||
/// 管理员登录加密狗委托
|
||||
/// </summary>
|
||||
/// <param name="Index"></param>
|
||||
/// <param name="AdminPassword"></param>
|
||||
/// <returns></returns>
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
public delegate int VikeyAdminLoginType(int Index, string AdminPassword);
|
||||
|
||||
/// <summary>
|
||||
/// 加密狗句柄
|
||||
/// </summary>
|
||||
private static IntPtr VikeyHandle;
|
||||
/// <summary>
|
||||
/// 查找加密狗
|
||||
/// </summary>
|
||||
public static VikeyFindType VikeyFind { get; private set; }
|
||||
/// <summary>
|
||||
/// 加密狗管理员登录
|
||||
/// </summary>
|
||||
public static VikeyAdminLoginType VikeyAdminLogin { get; private set; }
|
||||
/// <summary>
|
||||
/// 加密狗读取数据
|
||||
/// </summary>
|
||||
public static VikeyReadDataType VikeyReadData { get; private set; }
|
||||
static SuperDogHelper()
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
VikeyHandle = LoadLibrary("ViKey32.dll");
|
||||
}
|
||||
else if (IntPtr.Size == 8)
|
||||
{
|
||||
VikeyHandle = LoadLibrary("ViKey64.dll");
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
VikeyFind = Marshal.GetDelegateForFunctionPointer<VikeyFindType>(GetProcAddress(VikeyHandle, "VikeyFind"));
|
||||
VikeyAdminLogin = Marshal.GetDelegateForFunctionPointer<VikeyAdminLoginType>(GetProcAddress(VikeyHandle, "VikeyAdminLogin"));
|
||||
VikeyReadData = Marshal.GetDelegateForFunctionPointer<VikeyReadDataType>(GetProcAddress(VikeyHandle, "VikeyReadData"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// 值转换服务类
|
||||
/// </summary>
|
||||
public static class ValueConvertHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 将一个int32类型转换为一个ushort数组,高位在前面
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static ushort[] IntToUshorts(int value)
|
||||
{
|
||||
string str = Convert.ToString(value, 2).PadLeft(32, '0');
|
||||
string high = str.Substring(0, 16);
|
||||
string low = str.Substring(16);
|
||||
|
||||
return new ushort[2] { Convert.ToUInt16(high, 2), Convert.ToUInt16(low, 2) };
|
||||
}
|
||||
|
||||
public static short[] IntToShorts(int value)
|
||||
{
|
||||
string str = Convert.ToString(value, 2).PadLeft(32, '0');
|
||||
string high = str.Substring(0, 16);
|
||||
string low = str.Substring(16);
|
||||
|
||||
return new short[2] { Convert.ToInt16(high, 2), Convert.ToInt16(low, 2) };
|
||||
}
|
||||
/// <summary>
|
||||
/// 将两个ushort转换为一个int,高位在前
|
||||
/// </summary>
|
||||
/// <param name="values"></param>
|
||||
/// <returns></returns>
|
||||
public static int UshortsToInt(ushort[] values)
|
||||
{
|
||||
return values.First() << 16 | values.Last();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将两个short转换为一个int,高位在前
|
||||
/// </summary>
|
||||
/// <param name="values"></param>
|
||||
/// <returns></returns>
|
||||
public static int ShortsToInt(short[] values)
|
||||
{
|
||||
return values.First() << 16 | values.Last();
|
||||
}
|
||||
/// <summary>
|
||||
/// 调整值的后一位强制转换成无符号
|
||||
/// </summary>
|
||||
/// <param name="values"></param>
|
||||
/// <returns></returns>
|
||||
public static int adjShortsToInt(short[] values)
|
||||
{
|
||||
ushort value = (ushort)(values.Last());
|
||||
return values.First() << 16 | value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Helper
|
||||
{
|
||||
public static class XmlHelper
|
||||
{
|
||||
public static T XmlToModel<T>(string xml) where T : class, new()
|
||||
{
|
||||
try
|
||||
{
|
||||
xml = Regex.Replace(xml, @"<\?xml*.*?>", "", RegexOptions.IgnoreCase);
|
||||
XmlSerializer xmlSer = new(typeof(T));
|
||||
using (StringReader xmlReader = new(xml))
|
||||
{
|
||||
return (T)xmlSer.Deserialize(xmlReader);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return null;
|
||||
//throw new Exception("将XML字符串转换为实体异常", ex); ;
|
||||
}
|
||||
}
|
||||
|
||||
public static string ModelToXml<T>(T obj) where T : class, new()
|
||||
{
|
||||
try
|
||||
{
|
||||
MemoryStream stream = new();
|
||||
XmlSerializer xmlSer = new(typeof(T));
|
||||
xmlSer.Serialize(stream, obj);
|
||||
|
||||
stream.Position = 0;
|
||||
StreamReader sr = new(stream);
|
||||
return sr.ReadToEnd();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return null;
|
||||
//throw new Exception("将实体对象转换成XML异常", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AssemblyTitle>Accelerider.Windows.Infrastructure</AssemblyTitle>
|
||||
<Product>Accelerider.Windows.Infrastructure</Product>
|
||||
<OutputPath>..\Build\$(Configuration)\</OutputPath>
|
||||
<OutputType>Library</OutputType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<!--<UseWPF>true</UseWPF>-->
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="Extensions\LoggerFacadeExtensions.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Accelerider.Windows.Infrastructure.csproj.DotSettings" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="11.0.1" />
|
||||
<PackageReference Include="BeetleX.BNR" Version="1.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client.Core" Version="6.0.5" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
<PackageReference Include="NLog" Version="5.0.1" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.0.0" />
|
||||
<PackageReference Include="NPOI" Version="2.5.5" />
|
||||
<PackageReference Include="Prism.Core" Version="8.1.97" />
|
||||
<PackageReference Include="RestSharp" Version="106.15.0" />
|
||||
<PackageReference Include="Rougamo.Fody" Version="1.4.1" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.3.49" />
|
||||
<PackageReference Include="System.Management" Version="6.0.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="Logo.bmp">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="NLog.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="ViKey32.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="ViKey64.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ShowAllFiles>false</ShowAllFiles>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Json基本设置
|
||||
/// </summary>
|
||||
public static class JsonSetting
|
||||
{
|
||||
public class DateTimeJsonConverter : JsonConverter<DateTime>
|
||||
{
|
||||
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.String)
|
||||
{
|
||||
if (DateTime.TryParse(reader.GetString(), out DateTime datetime))
|
||||
{
|
||||
return datetime;
|
||||
}
|
||||
}
|
||||
|
||||
return reader.GetDateTime();
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 公共Json序列化反序列化设置-忽略大小写,解决解决时间格式反序列化报错
|
||||
/// </summary>
|
||||
public static JsonSerializerOptions CommonJsonSerializerOptions = new()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
static JsonSetting()
|
||||
{
|
||||
CommonJsonSerializerOptions.Converters.Add(new DateTimeJsonConverter());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.LambdaHelp
|
||||
{
|
||||
public static class ExpressionExtension
|
||||
{
|
||||
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
|
||||
{
|
||||
if (expr1 == null)
|
||||
return expr2;
|
||||
else if (expr2 == null)
|
||||
return expr1;
|
||||
|
||||
//return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, expr2.Body), expr1.Parameters);
|
||||
ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
|
||||
NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);
|
||||
|
||||
var left = visitor.Replace(expr1.Body);
|
||||
var right = visitor.Replace(expr2.Body);
|
||||
var body = Expression.And(left, right);
|
||||
return Expression.Lambda<Func<T, bool>>(body, newParameter);
|
||||
}
|
||||
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
|
||||
{
|
||||
if (expr1 == null)
|
||||
return expr2;
|
||||
else if (expr2 == null)
|
||||
return expr1;
|
||||
|
||||
ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
|
||||
NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);
|
||||
|
||||
var left = visitor.Replace(expr1.Body);
|
||||
var right = visitor.Replace(expr2.Body);
|
||||
var body = Expression.Or(left, right);
|
||||
return Expression.Lambda<Func<T, bool>>(body, newParameter);
|
||||
}
|
||||
|
||||
//与拼接
|
||||
public static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b)
|
||||
{
|
||||
var p = Expression.Parameter(typeof(T), "p");
|
||||
var bd = Expression.AndAlso(
|
||||
Expression.Invoke(a, p),
|
||||
Expression.Invoke(b, p));
|
||||
var ld = Expression.Lambda<Func<T, bool>>(bd, p);
|
||||
return ld;
|
||||
}
|
||||
|
||||
//或拼接
|
||||
public static Expression<Func<T, bool>> Orelse<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b)
|
||||
{
|
||||
var p = Expression.Parameter(typeof(T), "p");
|
||||
var bd = Expression.OrElse(
|
||||
Expression.Invoke(a, p),
|
||||
Expression.Invoke(b, p));
|
||||
var ld = Expression.Lambda<Func<T, bool>>(bd, p);
|
||||
return ld;
|
||||
}
|
||||
}
|
||||
|
||||
internal class NewExpressionVisitor : ExpressionVisitor
|
||||
{
|
||||
public ParameterExpression _NewParameter { get; private set; }
|
||||
public NewExpressionVisitor(ParameterExpression param)
|
||||
{
|
||||
this._NewParameter = param;
|
||||
}
|
||||
public Expression Replace(Expression exp)
|
||||
{
|
||||
return this.Visit(exp);
|
||||
}
|
||||
protected override Expression VisitParameter(ParameterExpression node)
|
||||
{
|
||||
return this._NewParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,438 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.LambdaHelp
|
||||
{
|
||||
public static class ExpressionTreeHelper<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p == null
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> Null(string propertyName)
|
||||
{
|
||||
return p => p.GetType().GetProperty(propertyName).GetValue(p) == null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>true
|
||||
/// </summary>p != null
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>zhangsansss
|
||||
public static Expression<Func<T, bool>> NotNull(string propertyName)
|
||||
{
|
||||
return p => p.GetType().GetProperty(propertyName).GetValue(p) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>true
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> True()
|
||||
{
|
||||
return p => true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>false
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> False()
|
||||
{
|
||||
return p => false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <param name="sort"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, TKey>> GetOrderExpression<TKey>(string propertyName)
|
||||
{
|
||||
ParameterExpression param = Expression.Parameter(typeof(T), "t");
|
||||
|
||||
return Expression.Lambda<Func<T, TKey>>
|
||||
(
|
||||
Expression.Convert(Expression.Property(param, propertyName),
|
||||
typeof(object)),
|
||||
param
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName == propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateEqual(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
Type type = typeof(T).GetProperty(propertyName).PropertyType;
|
||||
|
||||
if (!UnifyParamType(type, ref propertyValue))
|
||||
{
|
||||
return False();
|
||||
}
|
||||
|
||||
////Type type = typeof(T).GetProperty(propertyName).PropertyType;
|
||||
////propertyValue = propertyValue.ToString();
|
||||
////propertyValue = Convert.ChangeType(propertyValue, type);
|
||||
|
||||
//ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
//MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
//ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
|
||||
//return MyEqual(member, constant, parameter);
|
||||
|
||||
//propertyValue = propertyValue.ToString();
|
||||
//propertyValue = Convert.ChangeType(propertyValue, type);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
//return Expression.Lambda<Func<T, bool>>(Expression.Equal(member, constant), parameter);
|
||||
|
||||
return MyEqual(member,constant,parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName != propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="propertyValue"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateNotEqual(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
Type type = typeof(T).GetProperty(propertyName).PropertyType;
|
||||
propertyValue = Convert.ChangeType(propertyValue, type);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.NotEqual(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式: p=>propertyValue.Contains(p.propertyName) 目前仅支持 List<string>类型,后期完善
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="propertyValue"></param>
|
||||
/// <returns></returns>
|
||||
internal static Expression<Func<T, bool>> GetIn(string propertyName, object propertyValue)
|
||||
{
|
||||
//目前仅支持 List<string>类型,后期完善
|
||||
try
|
||||
{
|
||||
//使用Newtonsoft的ToObject方法将JArray转换成List<string>类型
|
||||
List<string> lst = ((dynamic)propertyValue).ToObject<List<string>>();
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
|
||||
MethodInfo method = typeof(List<string>).GetMethod("Contains", new[] { typeof(string) });
|
||||
ConstantExpression constant = Expression.Constant(lst, typeof(List<string>));
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Call(constant, method, member), parameter);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("查询的参数不合法,无法解析成表达式目录树");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName > propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateGreaterThan(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
|
||||
return MyGreaterThan(member, constant, parameter);
|
||||
|
||||
//return Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName < propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateLessThan(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
|
||||
return MyLessThan(member, constant, parameter);
|
||||
|
||||
//return Expression.Lambda<Func<T, bool>>(Expression.LessThan(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName >= propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateGreaterThanOrEqual(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
|
||||
return MyGreaterThanOrEqual(member, constant, parameter);
|
||||
|
||||
//return Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName <= propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateLessThanOrEqual(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
|
||||
return MyLessThanOrEqual(member, constant, parameter);
|
||||
//return Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName.Contains(propertyValue)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> GetContains(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
Type type = typeof(T).GetProperty(propertyName).PropertyType;
|
||||
|
||||
if (!UnifyParamType(type, ref propertyValue))
|
||||
{
|
||||
return False();
|
||||
}
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
|
||||
ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Call(member, method, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:!(p=>p.propertyName.Contains(propertyValue))
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> GetNotContains(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
|
||||
ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:!(p=>p.propertyName.StartsWith(propertyValue))
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="propertyValue"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> GetStartsWith(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
|
||||
ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:!(p=>p.propertyName.EndsWith(propertyValue))
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="propertyValue"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> GetEndsWith(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
MethodInfo method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
|
||||
ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统一参数类型(值大小比较方法中只支持int和DateTime类型,但上端传递过来的参数有可能为string类型,故需要使用反射的方式统一参数类型)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static bool UnifyParamType(Type type, ref object param)
|
||||
{
|
||||
//如果类型转换失败,说明无法转换,比如将字符串 aaa转换为 int类型等
|
||||
try
|
||||
{
|
||||
if (IsNullableType(type))
|
||||
{
|
||||
NullableConverter nullableConverter = new(type);
|
||||
param = nullableConverter.ConvertFromString(param.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (type != param.GetType())
|
||||
param = Convert.ChangeType(param, type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断可空类型
|
||||
/// </summary>
|
||||
/// <param name="theType"></param>
|
||||
/// <returns></returns>
|
||||
private static bool IsNullableType(Type theType)
|
||||
{
|
||||
return (theType.IsGenericType && theType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义小于比较
|
||||
/// </summary>
|
||||
/// <param name="e1"></param>
|
||||
/// <param name="e2"></param>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns></returns>
|
||||
private static Expression<Func<T, bool>> MyGreaterThan(Expression e1, Expression e2, ParameterExpression parameter)
|
||||
{
|
||||
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
|
||||
e2 = Expression.Convert(e2, e1.Type);
|
||||
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
|
||||
e1 = Expression.Convert(e1, e2.Type);
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(e1, e2), parameter);
|
||||
}
|
||||
|
||||
private static Expression<Func<T,bool>> MyEqual(Expression e1,Expression e2, ParameterExpression parameter)
|
||||
{
|
||||
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
|
||||
e2 = Expression.Convert(e2, e1.Type);
|
||||
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
|
||||
e1 = Expression.Convert(e1, e2.Type);
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Equal(e1, e2), parameter);
|
||||
}
|
||||
|
||||
private static Expression<Func<T, bool>> MyContains(Expression e1, Expression e2, ParameterExpression parameter)
|
||||
{
|
||||
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
|
||||
e2 = Expression.Convert(e2, e1.Type);
|
||||
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
|
||||
e1 = Expression.Convert(e1, e2.Type);
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Equal(e1, e2), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义大于比较
|
||||
/// </summary>
|
||||
/// <param name="e1"></param>
|
||||
/// <param name="e2"></param>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns></returns>
|
||||
private static Expression<Func<T, bool>> MyLessThan(Expression e1, Expression e2, ParameterExpression parameter)
|
||||
{
|
||||
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
|
||||
e2 = Expression.Convert(e2, e1.Type);
|
||||
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
|
||||
e1 = Expression.Convert(e1, e2.Type);
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.LessThan(e1, e2), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义大于等于比较
|
||||
/// </summary>
|
||||
/// <param name="e1"></param>
|
||||
/// <param name="e2"></param>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns></returns>
|
||||
private static Expression<Func<T, bool>> MyGreaterThanOrEqual(Expression e1, Expression e2, ParameterExpression parameter)
|
||||
{
|
||||
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
|
||||
e2 = Expression.Convert(e2, e1.Type);
|
||||
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
|
||||
e1 = Expression.Convert(e1, e2.Type);
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(e1, e2), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义小于等于比较
|
||||
/// </summary>
|
||||
/// <param name="e1"></param>
|
||||
/// <param name="e2"></param>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns></returns>
|
||||
private static Expression<Func<T, bool>> MyLessThanOrEqual(Expression e1, Expression e2, ParameterExpression parameter)
|
||||
{
|
||||
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
|
||||
e2 = Expression.Convert(e2, e1.Type);
|
||||
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
|
||||
e1 = Expression.Convert(e1, e2.Type);
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(e1, e2), parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.LambdaHelp
|
||||
{
|
||||
public class FilterCollection : Collection<IList<Filter>>
|
||||
{
|
||||
public FilterCollection() : base()
|
||||
{ }
|
||||
|
||||
public FilterCollection(IList<IList<Filter>> lst) : base(lst)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class Filter
|
||||
{
|
||||
public string PropertyName { get; set; }
|
||||
public Op Operation { get; set; }
|
||||
public object Value { get; set; }
|
||||
}
|
||||
|
||||
public enum Op
|
||||
{
|
||||
NULL = 0,
|
||||
NOTNUL = 1,
|
||||
//查询List<string>类型的,当Count=0的时候选中(仅在MongoDB中有效)
|
||||
Empty = 2,
|
||||
//查询List<string>类型的,当Count>0的时候选中(仅在MongoDB中有效)
|
||||
NotEmpty = 3,
|
||||
Equals = 4,
|
||||
NotEquals = 5,
|
||||
GreaterThan = 6,
|
||||
LessThan = 7,
|
||||
GreaterThanOrEqual = 8,
|
||||
LessThanOrEqual = 9,
|
||||
Contains = 10,
|
||||
NotContains = 11,
|
||||
StartsWith = 12,
|
||||
EndsWith = 13,
|
||||
//包含查询,目前仅支持List<string>
|
||||
In = 14
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.LambdaHelp
|
||||
{
|
||||
public static class LambdaBuider<T>
|
||||
{
|
||||
public static Expression<Func<T, bool>> BuildExpreesion(FilterCollection filters)
|
||||
{
|
||||
Expression<Func<T, bool>> baseExpression = t => false;
|
||||
|
||||
|
||||
|
||||
if (filters == null || filters.Count == 0)
|
||||
return t => true;
|
||||
|
||||
List<Expression<Func<T, bool>>> orExpressions = new List<Expression<Func<T, bool>>>();
|
||||
|
||||
for (int i = 0; i < filters.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < filters[i].Count; j++)
|
||||
{
|
||||
string propName = filters[i][j].PropertyName;
|
||||
object value = filters[i][j].Value;
|
||||
|
||||
switch (filters[i][j].Operation)
|
||||
{
|
||||
case Op.NULL:
|
||||
{
|
||||
if (typeof(T).GetProperty(propName).PropertyType == typeof(int) || typeof(T).GetProperty(propName) == typeof(long))
|
||||
{
|
||||
baseExpression = baseExpression.Or(LambdaHelper<T>.CreateEqual(propName, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
baseExpression = baseExpression.Or(LambdaHelper<T>.Null(propName));
|
||||
}
|
||||
}; break;
|
||||
case Op.NOTNUL:
|
||||
{
|
||||
if (typeof(T).GetProperty(propName).PropertyType == typeof(int) || typeof(T).GetProperty(propName) == typeof(long))
|
||||
{
|
||||
baseExpression = baseExpression.Or(LambdaHelper<T>.CreateNotEqual(propName, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
baseExpression = baseExpression.Or(LambdaHelper<T>.NotNull(propName));
|
||||
}
|
||||
}; break;
|
||||
case Op.Equals: baseExpression = baseExpression.Or(LambdaHelper<T>.CreateEqual(propName, value)); break;
|
||||
case Op.NotEquals: baseExpression = baseExpression.Or(LambdaHelper<T>.CreateNotEqual(propName, value)); break;
|
||||
case Op.GreaterThan: baseExpression = baseExpression.Or(LambdaHelper<T>.CreateGreaterThan(propName, value)); break;
|
||||
case Op.LessThan: baseExpression = baseExpression.Or(LambdaHelper<T>.CreateLessThan(propName, value)); break;
|
||||
case Op.GreaterThanOrEqual: baseExpression = baseExpression.Or(LambdaHelper<T>.CreateGreaterThanOrEqual(propName, value)); break;
|
||||
case Op.LessThanOrEqual: baseExpression = baseExpression.Or(LambdaHelper<T>.CreateLessThanOrEqual(propName, value)); break;
|
||||
case Op.Contains: baseExpression = baseExpression.Or(LambdaHelper<T>.GetContains(propName, value)); break;
|
||||
case Op.NotContains: baseExpression = baseExpression.Or(LambdaHelper<T>.GetNotContains(propName, value)); break;
|
||||
case Op.StartsWith: baseExpression = baseExpression.Or(LambdaHelper<T>.GetStartsWith(propName, value)); break;
|
||||
case Op.EndsWith: baseExpression = baseExpression.Or(LambdaHelper<T>.GetEndsWith(propName, value)); break;
|
||||
case Op.In: baseExpression = baseExpression.Or(LambdaHelper<T>.GetIn(propName, value)); break;
|
||||
}
|
||||
}
|
||||
|
||||
orExpressions.Add(baseExpression);
|
||||
baseExpression = p => false;
|
||||
}
|
||||
|
||||
Expression<Func<T, bool>> resultExpression = p => true;
|
||||
orExpressions.ForEach(x =>
|
||||
{
|
||||
resultExpression = resultExpression.And(x);
|
||||
});
|
||||
|
||||
return resultExpression;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.LambdaHelp
|
||||
{
|
||||
public static class LambdaHelper<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p == null
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> Null(string propertyName)
|
||||
{
|
||||
return p => p.GetType().GetProperty(propertyName).GetValue(p) == null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>true
|
||||
/// </summary>p != null
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>zhangsansss
|
||||
public static Expression<Func<T, bool>> NotNull(string propertyName)
|
||||
{
|
||||
return p => p.GetType().GetProperty(propertyName).GetValue(p) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>true
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> True()
|
||||
{
|
||||
return p => true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>false
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> False()
|
||||
{
|
||||
return p => false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <param name="sort"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, TKey>> GetOrderExpression<TKey>(string propertyName)
|
||||
{
|
||||
ParameterExpression param = Expression.Parameter(typeof(T), "t");
|
||||
//MemberExpression body = Expression.Property(param, propertyName);
|
||||
//return Expression.Lambda<Func<T, TKey>>(Expression.Convert(body, typeof(T).GetProperty(propertyName).PropertyType));
|
||||
|
||||
return
|
||||
Expression.Lambda<Func<T, TKey>>(
|
||||
Expression.Convert(
|
||||
Expression.Property(param, propertyName),
|
||||
typeof(object)),
|
||||
param);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName == propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateEqual(string propertyName, object propertyValue)
|
||||
{
|
||||
var type = typeof(T).GetProperty(propertyName).PropertyType;
|
||||
propertyValue = propertyValue.ToString();
|
||||
propertyValue = Convert.ChangeType(propertyValue, type);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Equal(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName != propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="propertyValue"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateNotEqual(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
var type = typeof(T).GetProperty(propertyName).PropertyType;
|
||||
propertyValue = Convert.ChangeType(propertyValue, type);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.NotEqual(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式: p=>propertyValue.Contains(p.propertyName) 目前仅支持 List<string>类型,后期完善
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="propertyValue"></param>
|
||||
/// <returns></returns>
|
||||
internal static Expression<Func<T, bool>> GetIn(string propertyName, object propertyValue)
|
||||
{
|
||||
//目前仅支持 List<string>类型,后期完善
|
||||
try
|
||||
{
|
||||
//使用Newtonsoft的ToObject方法将JArray转换成List<string>类型
|
||||
List<string> lst = ((dynamic)propertyValue).ToObject<List<string>>();
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
|
||||
MethodInfo method = typeof(List<string>).GetMethod("Contains", new[] { typeof(string) });
|
||||
ConstantExpression constant = Expression.Constant(lst, typeof(List<string>));
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Call(constant, method, member), parameter);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("查询的参数不合法,无法解析成表达式目录树");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName > propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateGreaterThan(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
|
||||
return MyGreaterThan(member, constant, parameter);
|
||||
|
||||
//return Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName < propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateLessThan(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
|
||||
return MyLessThan(member, constant, parameter);
|
||||
|
||||
//return Expression.Lambda<Func<T, bool>>(Expression.LessThan(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName >= propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateGreaterThanOrEqual(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
|
||||
return MyGreaterThanOrEqual(member, constant, parameter);
|
||||
|
||||
//return Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName <= propertyValue
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateLessThanOrEqual(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue);
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
|
||||
|
||||
return MyLessThanOrEqual(member, constant, parameter);
|
||||
//return Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(member, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:p=>p.propertyName.Contains(propertyValue)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> GetContains(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
|
||||
ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Call(member, method, constant), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:!(p=>p.propertyName.Contains(propertyValue))
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> GetNotContains(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
|
||||
ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:!(p=>p.propertyName.StartsWith(propertyValue))
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="propertyValue"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> GetStartsWith(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
|
||||
ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建lambda表达式:!(p=>p.propertyName.EndsWith(propertyValue))
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="propertyValue"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> GetEndsWith(string propertyName, object propertyValue)
|
||||
{
|
||||
propertyValue = propertyValue.ToString();
|
||||
|
||||
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
||||
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
||||
MethodInfo method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
|
||||
ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统一参数类型(值大小比较方法中只支持int和DateTime类型,但上端传递过来的参数有可能为string类型,故需要使用反射的方式统一参数类型)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static void UnifyParamType(Type type, ref object param)
|
||||
{
|
||||
//param = type.GetMethod("Parse", new Type[] { typeof(string) }).Invoke(param, new object[] { param.ToString() });
|
||||
if (IsNullableType(type))
|
||||
{
|
||||
NullableConverter nullableConverter = new(type);
|
||||
param = nullableConverter.ConvertFromString(param.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
param = Convert.ChangeType(param, type);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断可空类型
|
||||
/// </summary>
|
||||
/// <param name="theType"></param>
|
||||
/// <returns></returns>
|
||||
private static bool IsNullableType(Type theType)
|
||||
{
|
||||
return (theType.IsGenericType && theType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义小于比较
|
||||
/// </summary>
|
||||
/// <param name="e1"></param>
|
||||
/// <param name="e2"></param>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns></returns>
|
||||
private static Expression<Func<T, bool>> MyGreaterThan(Expression e1, Expression e2, ParameterExpression parameter)
|
||||
{
|
||||
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
|
||||
e2 = Expression.Convert(e2, e1.Type);
|
||||
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
|
||||
e1 = Expression.Convert(e1, e2.Type);
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(e1, e2), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义大于比较
|
||||
/// </summary>
|
||||
/// <param name="e1"></param>
|
||||
/// <param name="e2"></param>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns></returns>
|
||||
private static Expression<Func<T, bool>> MyLessThan(Expression e1, Expression e2, ParameterExpression parameter)
|
||||
{
|
||||
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
|
||||
e2 = Expression.Convert(e2, e1.Type);
|
||||
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
|
||||
e1 = Expression.Convert(e1, e2.Type);
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.LessThan(e1, e2), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义大于等于比较
|
||||
/// </summary>
|
||||
/// <param name="e1"></param>
|
||||
/// <param name="e2"></param>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns></returns>
|
||||
private static Expression<Func<T, bool>> MyGreaterThanOrEqual(Expression e1, Expression e2, ParameterExpression parameter)
|
||||
{
|
||||
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
|
||||
e2 = Expression.Convert(e2, e1.Type);
|
||||
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
|
||||
e1 = Expression.Convert(e1, e2.Type);
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(e1, e2), parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义小于等于比较
|
||||
/// </summary>
|
||||
/// <param name="e1"></param>
|
||||
/// <param name="e2"></param>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns></returns>
|
||||
private static Expression<Func<T, bool>> MyLessThanOrEqual(Expression e1, Expression e2, ParameterExpression parameter)
|
||||
{
|
||||
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
|
||||
e2 = Expression.Convert(e2, e1.Type);
|
||||
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
|
||||
e1 = Expression.Convert(e1, e2.Type);
|
||||
return Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(e1, e2), parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JSMachine.WMS.Infrastructure.LambdaHelp
|
||||
{
|
||||
public static class OrderExpression
|
||||
{
|
||||
public static ISugarQueryable<T> OrderByLambda<T>(this ISugarQueryable<T> source, string property, OrderByType orderByType)
|
||||
{
|
||||
return ApplyOrder<T>(source, property, orderByType.ToString());
|
||||
}
|
||||
|
||||
static ISugarQueryable<T> ApplyOrder<T>(ISugarQueryable<T> source, string property, string methodName)
|
||||
{
|
||||
string[] props = property.Split('.');
|
||||
Type type = typeof(T);
|
||||
ParameterExpression arg = Expression.Parameter(type, "x");
|
||||
Expression expr = arg;
|
||||
foreach (string prop in props)
|
||||
{
|
||||
// use reflection (not ComponentModel) to mirror LINQ
|
||||
PropertyInfo pi = type.GetProperty(prop);
|
||||
expr = Expression.Property(expr, pi);
|
||||
type = pi.PropertyType;
|
||||
}
|
||||
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
|
||||
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);
|
||||
|
||||
object result = typeof(Queryable).GetMethods().Single(
|
||||
method => method.Name == methodName
|
||||
&& method.IsGenericMethodDefinition
|
||||
&& method.GetGenericArguments().Length == 2
|
||||
&& method.GetParameters().Length == 2)
|
||||
.MakeGenericMethod(typeof(T), type)
|
||||
.Invoke(null, new object[] { source, lambda });
|
||||
return (ISugarQueryable<T>)result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" throwExceptions="false" internalLogLevel="Warn" internalLogFile="${basedir}/logs/NlogRecords.log">
|
||||
<!--指定了当NLog自己遇到Warn等级以上的报错时,生成日志到./logs/NlogRecords.log下(网站的相对路径)。除非纠错,不可以设为Trace否则速度很慢,起码Debug以上-->
|
||||
<extensions>
|
||||
<add assembly="NLog.Web.AspNetCore" />
|
||||
</extensions>
|
||||
<targets>
|
||||
<!--通过数据库记录日志 配置
|
||||
dbProvider请选择mysql或是sqlserver,同时注意连接字符串,需要安装对应的sql数据提供程序
|
||||
dbProvider="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" connectionString="server=192.168.137.10;database=EvMSDB;user=root;password=mysql@local"
|
||||
dbProvider="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient" connectionString="Server=192.168.1.204;Database=EvMSDB;User ID=sa;Password=yzhly@126"
|
||||
-->
|
||||
<!--<target name="log_database" xsi:type="Database" dbProvider="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" connectionString="server=192.168.137.10;database=MSDB;user=root;password=mysql@local;">
|
||||
<commandText>
|
||||
INSERT INTO TblLogrecords (LogDate,LogLevel,Logger,Message,MachineName,MachineIp,NetRequestMethod,NetRequestUrl,NetUserIsauthenticated,NetUserAuthtype,NetUserIdentity,Exception)
|
||||
VALUES(@LogDate,@LogLevel,@Logger,@Message,@MachineName,@MachineIp,@NetRequestMethod,@NetRequestUrl,@NetUserIsauthenticated,@NetUserAuthtype,@NetUserIdentity,@Exception);
|
||||
</commandText>
|
||||
<parameter name="@LogDate" layout="${date}" />
|
||||
<parameter name="@LogLevel" layout="${level}" />
|
||||
<parameter name="@Logger" layout="${logger}" />
|
||||
<parameter name="@Message" layout="${message}" />
|
||||
<parameter name="@MachineName" layout="${machinename}" />
|
||||
<parameter name="@MachineIp" layout="${aspnet-request-ip}" />
|
||||
<parameter name="@NetRequestMethod" layout="${aspnet-request-method}" />
|
||||
<parameter name="@NetRequestUrl" layout="${aspnet-request-url}" />
|
||||
<parameter name="@NetUserIsauthenticated" layout="${aspnet-user-isauthenticated}" />
|
||||
<parameter name="@NetUserAuthtype" layout="${aspnet-user-authtype}" />
|
||||
<parameter name="@NetUserIdentity" layout="${aspnet-user-identity}" />
|
||||
<parameter name="@Exception" layout="${exception:tostring}" />
|
||||
</target>-->
|
||||
<!--输出文件-->
|
||||
<target name="log_file" xsi:type="File" fileName="${basedir}/logs/${shortdate}.log" layout="${longdate} | ${level:uppercase=false} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" />
|
||||
<!--ColoredConsole彩色控制台 xsi:type="Console"是指定输出到普通控制台-->
|
||||
<!--<target name="log_console" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="true" layout="${longdate}|${level}|${logger}|${message} ${exception}">-->
|
||||
<target name="log_console" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="true" layout="${longdate}|${level}|${message} ${exception}">
|
||||
<highlight-row condition="level == LogLevel.Trace" foregroundColor="DarkGray" />
|
||||
<highlight-row condition="level == LogLevel.Debug" foregroundColor="Gray" />
|
||||
<highlight-row condition="level == LogLevel.Info" foregroundColor="Green" />
|
||||
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
|
||||
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
|
||||
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Magenta" backgroundColor="White" />
|
||||
</target>
|
||||
</targets>
|
||||
<rules>
|
||||
<!--跳过所有级别的Microsoft组件的日志记录-->
|
||||
<!--<logger name="Microsoft.*" maxlevel="Info" final="true" />-->
|
||||
<!-- BlackHole without writeTo -->
|
||||
<!--只通过数据库记录日志,这里的*,如果给了name名字,代码里用日志记录的时候,取logger需要把name当做参数-->
|
||||
<!--<logger name="*" minlevel="Info" writeTo="log_database" />-->
|
||||
<logger name="*" minlevel="Info" writeTo="log_console" />
|
||||
<logger name="*" minlevel="Info" writeTo="log_file" />
|
||||
<logger name="*" minlevel="Warn" writeTo="log_file" />
|
||||
<logger name="*" minlevel="Error" writeTo="log_file" />
|
||||
</rules>
|
||||
</nlog>
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("FB51D520-580D-42B0-AEF3-6C997918E9C3")]
|
||||
|
||||
[assembly: InternalsVisibleTo("JSMachine.DCS.InfrastructureTests")]
|
||||
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace JSMachine.DCS.Infrastructure.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("JSMachine.DCS.Infrastructure.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyCopyright("Copyright © J.S.Machine Team 2022")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
//[assembly: AssemblyVersion("0.0.2.0")]
|
||||
//[assembly: AssemblyFileVersion("0.0.2.0")]
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace JSMachine.WMS.Infrastructure.Static
|
||||
{
|
||||
/// <summary>
|
||||
/// 静态变量类
|
||||
/// </summary>
|
||||
public static class PaperReturnVariable
|
||||
{
|
||||
/// <summary>
|
||||
/// 地磅称重重量
|
||||
/// </summary>
|
||||
public static float ResultWeight { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 地磅当前重量
|
||||
/// </summary>
|
||||
public static float CurrentWeight { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 是否可以读取
|
||||
/// </summary>
|
||||
|
||||
public static bool CanRead { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 条码
|
||||
/// </summary>
|
||||
public static string BarCode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Text.RegularExpressions;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace JSMachine.DCS.Infrastructure
|
||||
{
|
||||
public static class SystemInfo
|
||||
{
|
||||
private const string ExtractionFailed = "<Extraction Failed>";
|
||||
|
||||
public static readonly string Caption;
|
||||
public static readonly string CSName;
|
||||
public static readonly string InstallDate;
|
||||
public static readonly string OSArchitecture;
|
||||
public static readonly string SerialNumber;
|
||||
public static readonly string Version;
|
||||
public static readonly long TotalVisibleMemorySize;
|
||||
public static readonly string CPUName;
|
||||
public static readonly DotNetFramework DotNetFrameworkVersion;
|
||||
|
||||
static SystemInfo()
|
||||
{
|
||||
var extractionRegex = new Regex("(\\w+?) ?= ?\"(.+?)\";", RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
|
||||
var systemInfo = GetManagementInfo("SELECT * FROM Win32_OperatingSystem", extractionRegex);
|
||||
var processorInfo = GetManagementInfo("SELECT * FROM Win32_Processor", extractionRegex);
|
||||
|
||||
Caption = systemInfo.GetValue("Caption");
|
||||
CSName = systemInfo.GetValue("CSName");
|
||||
InstallDate = systemInfo.GetValue("InstallDate");
|
||||
OSArchitecture = systemInfo.GetValue("OSArchitecture");
|
||||
SerialNumber = systemInfo.GetValue("SerialNumber");
|
||||
Version = systemInfo.GetValue("Version");
|
||||
TotalVisibleMemorySize = systemInfo.GetValue("TotalVisibleMemorySize").CastTo<long>();
|
||||
|
||||
CPUName = processorInfo.GetValue("Name");
|
||||
|
||||
DotNetFrameworkVersion = Get45PlusFromRegistry();
|
||||
}
|
||||
|
||||
private static IReadOnlyDictionary<string, string> GetManagementInfo(string query, Regex regex)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = new ManagementObjectSearcher(new ObjectQuery(query));
|
||||
var infoString = string.Empty;
|
||||
using (var collection = result.Get())
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
var managementObject = item as ManagementObject;
|
||||
infoString = managementObject?.GetText(TextFormat.Mof);
|
||||
if (!string.IsNullOrEmpty(infoString)) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(infoString)) return null;
|
||||
|
||||
return regex.Matches(infoString).OfType<Match>()
|
||||
.Where(item => item.Success)
|
||||
.ToDictionary(item => item.Groups[1].Value, item => item.Groups[2].Value);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error("An unexpected exception occured while getting management info. ", e);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetValue(this IReadOnlyDictionary<string, string> info, string key)
|
||||
{
|
||||
return info != null && info.TryGetValue(key, out var value) ? value : ExtractionFailed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Refer to:
|
||||
* Check Framework 45+: https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed#net_d;
|
||||
*/
|
||||
|
||||
private static DotNetFramework Get45PlusFromRegistry()
|
||||
{
|
||||
const string subKey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
|
||||
|
||||
using (RegistryKey ndpKey = RegistryKey
|
||||
.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
|
||||
.OpenSubKey(subKey))
|
||||
{
|
||||
return ndpKey?.GetValue("Release") != null
|
||||
? CheckFor45PlusVersion((int)ndpKey.GetValue("Release"))
|
||||
: DotNetFramework.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
// Checking the version using >= will enable forward compatibility.
|
||||
private static DotNetFramework CheckFor45PlusVersion(int releaseKey)
|
||||
{
|
||||
if (releaseKey >= 461808)
|
||||
return DotNetFramework.V472OrLater;
|
||||
if (releaseKey >= 461308)
|
||||
return DotNetFramework.V471;
|
||||
if (releaseKey >= 460798)
|
||||
return DotNetFramework.V47;
|
||||
if (releaseKey >= 394802)
|
||||
return DotNetFramework.V462;
|
||||
if (releaseKey >= 394254)
|
||||
return DotNetFramework.V461;
|
||||
if (releaseKey >= 393295)
|
||||
return DotNetFramework.V46;
|
||||
if (releaseKey >= 379893)
|
||||
return DotNetFramework.V452;
|
||||
if (releaseKey >= 378675)
|
||||
return DotNetFramework.V451;
|
||||
if (releaseKey >= 378389)
|
||||
return DotNetFramework.V45;
|
||||
|
||||
// This code should never execute. A non-null release key should mean
|
||||
// that 4.5 or later is installed.
|
||||
return DotNetFramework.V472OrLater;
|
||||
}
|
||||
}
|
||||
|
||||
public enum DotNetFramework
|
||||
{
|
||||
Unknown,
|
||||
V45,
|
||||
V451,
|
||||
V452,
|
||||
V46,
|
||||
V461,
|
||||
V462,
|
||||
V47,
|
||||
V471,
|
||||
V472OrLater
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user