diff --git a/src/PaySharp.Core/FastActivator.cs b/src/PaySharp.Core/FastActivator.cs new file mode 100644 index 0000000..e4ab82c --- /dev/null +++ b/src/PaySharp.Core/FastActivator.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Reflection; +using System.Linq.Expressions; + +namespace PaySharp.Core +{ + public static class FastActivator + { + public static Func Generate() + { + ConstructorInfo constructorInfo = typeof(TResult).GetConstructor(new Type[] { typeof(T), }); +#if DEBUG + ParameterInfo[] parameters = constructorInfo.GetParameters(); + ParameterExpression parameterExpression = Expression.Parameter(typeof(T), parameters[0].Name); +#else + ParameterExpression parameterExpression = Expression.Parameter(typeof(T)); +#endif + Expression> expression = Expression.Lambda>( + Expression.New( + constructorInfo, + parameterExpression), + parameterExpression); + Func functor = expression.Compile(); + return functor; + } + + } +} diff --git a/src/PaySharp.Wechatpay/ConvertUtil.cs b/src/PaySharp.Wechatpay/ConvertUtil.cs index 654d83a..dfe1b37 100644 --- a/src/PaySharp.Wechatpay/ConvertUtil.cs +++ b/src/PaySharp.Wechatpay/ConvertUtil.cs @@ -2,12 +2,16 @@ using PaySharp.Core.Utils; using System; using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; namespace PaySharp.Wechatpay { internal static class ConvertUtil { - public static List ToList(GatewayData gatewayData, int index) + + public static List ToList(GatewayData gatewayData, int index) where T:new() where TChildren:new() { var flag = true; var list = new List(); @@ -15,7 +19,7 @@ public static List ToList(GatewayData gatewayData, int index) while (flag) { var type = typeof(T); - var obj = Activator.CreateInstance(type); + var obj = new T(); var properties = type.GetProperties(); var isFirstProperty = true; @@ -28,16 +32,7 @@ public static List ToList(GatewayData gatewayData, int index) continue; } - string key; - var renameAttribute = item.GetCustomAttributes(typeof(ReNameAttribute), true); - if (renameAttribute.Length > 0) - { - key = ((ReNameAttribute)renameAttribute[0]).Name; - } - else - { - key = item.Name.ToSnakeCase(); - } + string key = GetRealName(item); if (index > -1) { key += $"_{index}"; @@ -70,5 +65,101 @@ public static List ToList(GatewayData gatewayData, int index) return list; } + + /// + /// 获取字段json中的名字 + /// + /// + /// + private static string GetRealName(System.Reflection.PropertyInfo item) + { + string key; + var renameAttribute = item.GetCustomAttributes(typeof(ReNameAttribute), true); + if (renameAttribute.Length > 0) + { + key = ((ReNameAttribute)renameAttribute[0]).Name; + } + else + { + key = item.Name.ToSnakeCase(); + } + + return key; + } + + /// + /// 将微信返回值特殊格式转化为列表 + /// + /// + /// + /// + public static List ToList(GatewayData gatewayData) where T : new() + { + var list = new List(); + var properties = typeof(T).GetProperties(); + var keyfirst = properties[0]; + var count = gatewayData.Keys.Where(p => Regex.IsMatch(p, $@"{GetRealName(keyfirst)}_\d")).Count(); + + for (var i = 0; i < count; i++) + { + var item = new T(); + foreach(var field in properties) + { + string keyname = $"{GetRealName(field)}_{i}"; + field.SetValue(item, gatewayData.GetStringValue(keyname)); + } + list.Add(item); + } + return list; + } + + /// + /// 将微信返回值特殊格式转化为列表(二级) + /// + /// + /// + /// + /// + public static List ToList(GatewayData gatewayData) where T : new() where TChildren : new() + { + var list = new List(); + var properties = typeof(T).GetProperties(); + var keyfirst = properties[0]; + var count = gatewayData.Keys.Where(p => Regex.IsMatch(p, $@"{GetRealName(keyfirst)}_\d")).Count(); + + for (var i = 0; i < count; i++) + { + var item = new T(); + foreach (var field in properties) + { + if (field.PropertyType == typeof(List)) + { + var sublist = new List(); + var subProperties = typeof(TChildren).GetProperties(); + var subFirstkey = subProperties[0]; + var SubFirstName = GetRealName(subFirstkey); + var subCount = gatewayData.Keys.Where(p => Regex.IsMatch(p, $@"{SubFirstName}_{i}_\d")).Count(); + for(var j = 0; j < subCount; j++) + { + var subItem = new TChildren(); + foreach (var subfield in subProperties) + { + string keyname = $"{GetRealName(subfield)}_{i}_{j}"; + subfield.SetValue(subItem, gatewayData.GetStringValue(keyname)); + } + sublist.Add(subItem); + } + field.SetValue(item, sublist); + } + else + { + string keyname = $"{GetRealName(field)}_{i}"; + field.SetValue(item, gatewayData.GetStringValue(keyname)); + } + } + list.Add(item); + } + return list; + } } } \ No newline at end of file diff --git a/src/PaySharp.Wechatpay/Response/QueryResponse.cs b/src/PaySharp.Wechatpay/Response/QueryResponse.cs index f7e99d1..629780b 100644 --- a/src/PaySharp.Wechatpay/Response/QueryResponse.cs +++ b/src/PaySharp.Wechatpay/Response/QueryResponse.cs @@ -123,7 +123,7 @@ public class QueryResponse : BaseResponse internal override void Execute(Merchant merchant, Request request) { - Coupons = ConvertUtil.ToList(GatewayData, -1); + Coupons = ConvertUtil.ToList(GatewayData); } public class CouponResponse diff --git a/src/PaySharp.Wechatpay/Response/RefundQueryResponse.cs b/src/PaySharp.Wechatpay/Response/RefundQueryResponse.cs index 5b7cb5e..6f9db5f 100644 --- a/src/PaySharp.Wechatpay/Response/RefundQueryResponse.cs +++ b/src/PaySharp.Wechatpay/Response/RefundQueryResponse.cs @@ -64,7 +64,7 @@ public class RefundQueryResponse : BaseResponse internal override void Execute(Merchant merchant, Request request) { - Refunds = ConvertUtil.ToList(GatewayData, -1); + Refunds = ConvertUtil.ToList(GatewayData); } public class RefundResponse diff --git a/src/PaySharp.Wechatpay/Response/RefundResponse.cs b/src/PaySharp.Wechatpay/Response/RefundResponse.cs index 54259c3..85b192d 100644 --- a/src/PaySharp.Wechatpay/Response/RefundResponse.cs +++ b/src/PaySharp.Wechatpay/Response/RefundResponse.cs @@ -99,7 +99,7 @@ public class RefundResponse : BaseResponse internal override void Execute(Merchant merchant, Request request) { - RefundCoupons = ConvertUtil.ToList(GatewayData, -1); + RefundCoupons = ConvertUtil.ToList(GatewayData); } public class RefundCouponResponse diff --git a/src/PaySharp.Wechatpay/WechatpayGateway.cs b/src/PaySharp.Wechatpay/WechatpayGateway.cs index 90365fc..b4ecd3d 100644 --- a/src/PaySharp.Wechatpay/WechatpayGateway.cs +++ b/src/PaySharp.Wechatpay/WechatpayGateway.cs @@ -85,7 +85,7 @@ protected override async Task ValidateNotifyAsync() if (string.IsNullOrEmpty(NotifyResponse.ReqInfo)) { - NotifyResponse.Coupons = ConvertUtil.ToList(GatewayData, -1); + NotifyResponse.Coupons = ConvertUtil.ToList(GatewayData); if (NotifyResponse.Sign != SubmitProcess.BuildSign(GatewayData, _merchant.Key)) { throw new GatewayException("签名不一致");