using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace ReZero.SuperAPI { internal class MethodGeneratorAPI : IDataService { private ISqlSugarClient db; public MethodGeneratorAPI() { db = App.Db; } public async Task ExecuteAction(DataModel dataModel) { if (dataModel.MyMethodInfo == null) return null; var classType = Type.GetType(dataModel.MyMethodInfo?.MethodClassFullName); classType = GetTypeByAttribute(dataModel, classType); var methodInfo = classType.GetMyMethod(dataModel?.MyMethodInfo?.MethodName, dataModel!.MyMethodInfo!.MethodArgsCount); var classObj = ReZero.DependencyInjection.ActivatorHelper.CreateInstance(classType!, nonPublic: true, (ServiceProvider)dataModel.ServiceProvider!); object[] parameters = new object[methodInfo.GetParameters().Length]; var argsTypes = dataModel.MyMethodInfo.ArgsTypes; parameters = GetParameters(dataModel, methodInfo, parameters, argsTypes); var unitType = methodInfo.GetCustomAttributes().FirstOrDefault(it => it.GetType().GetInterfaces().Any(s => s == typeof(IUnitOfWork))); if (unitType != null) { var unitObj =(IUnitOfWork)ReZero.DependencyInjection.ActivatorHelper.CreateInstance(unitType!.GetType(), nonPublic: true, (ServiceProvider)dataModel.ServiceProvider!); unitObj.db = ((ServiceProvider)dataModel.ServiceProvider!).GetRequiredService(); try { unitObj.BeginTran(); object result = new object(); result = await ExecuteMethodAsync(methodInfo, classObj, parameters); unitObj.CommitTran(); return result; } catch (Exception) { unitObj.RollbackTran(); throw; } } else { object result = await ExecuteMethodAsync(methodInfo, classObj, parameters); return result; } } private object[] GetParameters(DataModel dataModel, MethodInfo methodInfo, object[] parameters, Type[]? argsTypes) { if (IsJObject(dataModel, parameters)) { FillJObjectParameters(dataModel, methodInfo, parameters, argsTypes); } else if (IsSingleModel(dataModel)) { parameters = FillSingleModelParameters(dataModel, methodInfo); } else { FillDefaultParameters(dataModel, methodInfo, parameters, argsTypes); } return parameters; } private static async Task ExecuteMethodAsync(MethodInfo methodInfo, object classObj, object[] parameters) { var result = methodInfo.Invoke(classObj, parameters); if (result is Task) { result = await GetTask((Task)result); } else { result = await Task.FromResult(result); } return result; } private static object[] FillSingleModelParameters(DataModel dataModel, MethodInfo methodInfo) { object[] parameters; var type = methodInfo.GetParameters().First().ParameterType; var parameterOjb = Activator.CreateInstance(type, nonPublic: true); foreach (var item in type!.GetProperties()) { var p = dataModel.DefaultParameters.First(it => it.Name == item.Name); p.Value = ConvetEmptyValue(item.PropertyType, p.Value); if (IsJson(item, p)) { item.SetValue(parameterOjb,JsonConvert.DeserializeObject(p.Value + "",item.PropertyType)); } else { item.SetValue(parameterOjb, UtilMethods.ChangeType2(p.Value, item.PropertyType)); } } parameters = new object[] { parameterOjb }; return parameters; } private static bool IsJson(PropertyInfo item, DataModelDefaultParameter p) { if (item.PropertyType?.FullName?.StartsWith("System.Collections.Generic.List")==true) { var value2 = p.Value?.ToString()?.Trim(); return value2?.StartsWith("[") == true && value2?.EndsWith("]") == true; } if (item.PropertyType?.FullName?.StartsWith("System.")==true) { return false; } var value = p.Value?.ToString()?.Trim(); return value?.StartsWith("{") == true && value?.EndsWith("}") == true; } private static bool IsSingleModel(DataModel dataModel) { return dataModel.MyMethodInfo?.ArgsTypes?.Any(it => typeof(SingleModel) == it) == true; } private static Type? GetTypeByAttribute(DataModel dataModel, Type? classType) { if (classType == null) { var ass = SuperAPIModule._apiOptions?.DependencyInjectionOptions?.Assemblies; if (ass?.Any() == true) { classType = ass.Select(it => it.GetType(dataModel.MyMethodInfo?.MethodClassFullName)).Where(it => it != null).FirstOrDefault(); } } return classType; } private void FillJObjectParameters(DataModel dataModel, MethodInfo methodInfo, object[] parameters, Type[]? argsTypes) { var value = dataModel?.DefaultParameters?.FirstOrDefault()?.Value! + ""; var type = methodInfo.GetParameters().First().ParameterType; if (!string.IsNullOrEmpty(value)) { parameters[0] = JsonConvert.DeserializeObject(value, type)!; if (parameters[0] is SaveInterfaceListModel saveInterfaceListModel) { saveInterfaceListModel.InterfaceCategoryId =Convert.ToInt64( Convert.ToDouble(saveInterfaceListModel.InterfaceCategoryId)) + ""; } } } private static bool IsJObject(DataModel dataModel, object[] parameters) { return parameters.Count() == 1 && dataModel.DefaultParameters.First().ValueType == nameof(JObject)&& dataModel.DefaultParameters.First().IsSingleParameter==true; } private static int FillDefaultParameters(DataModel dataModel, MethodInfo methodInfo, object[] parameters, Type[]? argsTypes) { var index = 0; methodInfo.GetParameters().ToList().ForEach((p) => { object? value = dataModel?.DefaultParameters?.FirstOrDefault(it => it.Name!.EqualsCase(p.Name)).Value; if (argsTypes?.Length - 1 >= index) { var type = argsTypes![index]; if (IsObject(value, type)) { try { var valueStr = value?.ToString(); if (!string.IsNullOrEmpty(valueStr)) { value = JsonConvert.DeserializeObject(valueStr, type); } } catch (JsonException ex) { throw new Exception(TextHandler.GetCommonText(p.Name + "JSON解析错误: " + ex.Message, p.Name + " JSON parsing error: " + ex.Message)); } } } try { value = ConvetEmptyValue(p.ParameterType, value); value = UtilMethods.ChangeType2(value, p.ParameterType); } catch (Exception ex) { throw new Exception(TextHandler.GetCommonText(p.Name + "参数类型不匹配 " + value + ", 错误: " + ex.Message, p.Name + " Parameter type does not match " + value + ", Error: " + ex.Message)); } parameters[p.Position] = value!; index++; }); return index; } private static object? ConvetEmptyValue(Type type, object? value) { if (value?.Equals("") == true && type != typeof(string)) { value = null; } // 处理JSON数组或对象 var strValue = value?.ToString()?.Trim(); if (strValue != null) { if ((type.IsArray || type.FullName.StartsWith("System.Collections.Generic.List")) && strValue.StartsWith("[") && strValue.EndsWith("]")) { try { return JsonConvert.DeserializeObject(strValue, type); } catch { // 保持原始值 } } else if (!type.FullName.StartsWith("System.") && strValue.StartsWith("{") && strValue.EndsWith("}")) { try { return JsonConvert.DeserializeObject(strValue, type); } catch { // 保持原始值 } } } return value; } private static async Task GetTask(Task task) { await task.ConfigureAwait(false); // 等待任务完成 var resultProperty = task.GetType().GetProperty("Result"); var result = resultProperty.GetValue(task); return result; } private static bool IsObject(object? value, Type type) { if ((type.IsArray || type.FullName.StartsWith("System.Collections.Generic.List")) && value != null) { return true; } // 检查值是否为JSON数组字符串 var valueStr = value?.ToString()?.Trim(); if (valueStr != null && valueStr.StartsWith("[") && valueStr.EndsWith("]")) { return true; } return false; } } }