You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

579 lines
25 KiB

3 weeks ago
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<object> 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<ISqlSugarClient>();
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)
{
// 先检查method的参数类型
var methodParams = methodInfo.GetParameters();
// 先尝试判断是否是JToken/JObject参数
if (methodParams.Length == 1 &&
(typeof(Newtonsoft.Json.Linq.JToken).IsAssignableFrom(methodParams[0].ParameterType)))
{
System.Diagnostics.Debug.WriteLine($"检测到JToken类型参数: {methodParams[0].ParameterType.Name}");
// 直接通过参数类型判断
FillJObjectDirectly(dataModel, methodParams[0].ParameterType, parameters);
}
else if (IsJObject(dataModel, parameters))
3 weeks ago
{
// 通过参数定义判断
3 weeks ago
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<object> 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())
{
// 确保属性有set方法
if (!item.CanWrite)
continue;
// 获取对应的参数数据
var propertyParam = dataModel.DefaultParameters.FirstOrDefault(it => it.Name == item.Name);
if (propertyParam == null)
continue;
try
3 weeks ago
{
propertyParam.Value = ConvetEmptyValue(item.PropertyType, propertyParam.Value);
// 特殊处理JToken及其子类型
if (typeof(Newtonsoft.Json.Linq.JToken).IsAssignableFrom(item.PropertyType))
{
if (item.PropertyType == typeof(Newtonsoft.Json.Linq.JObject))
{
string jsonStr = propertyParam.Value?.ToString() ?? "{}";
if (jsonStr.Trim() == "null") jsonStr = "{}";
try
{
item.SetValue(parameterOjb, Newtonsoft.Json.Linq.JObject.Parse(jsonStr));
}
catch
{
item.SetValue(parameterOjb, new Newtonsoft.Json.Linq.JObject());
}
}
else if (item.PropertyType == typeof(Newtonsoft.Json.Linq.JArray))
{
string jsonStr = propertyParam.Value?.ToString() ?? "[]";
if (jsonStr.Trim() == "null") jsonStr = "[]";
try
{
item.SetValue(parameterOjb, Newtonsoft.Json.Linq.JArray.Parse(jsonStr));
}
catch
{
item.SetValue(parameterOjb, new Newtonsoft.Json.Linq.JArray());
}
}
else if (item.PropertyType == typeof(Newtonsoft.Json.Linq.JToken))
{
string jsonStr = propertyParam.Value?.ToString() ?? "null";
try
{
item.SetValue(parameterOjb, Newtonsoft.Json.Linq.JToken.Parse(jsonStr));
}
catch
{
item.SetValue(parameterOjb, Newtonsoft.Json.Linq.JValue.CreateNull());
}
}
}
else if (IsJson(item, propertyParam))
{
try
{
var value = JsonConvert.DeserializeObject(propertyParam.Value + "", item.PropertyType);
item.SetValue(parameterOjb, value);
}
catch
{
// 如果JSON反序列化失败,尝试使用默认值
if (item.PropertyType.IsValueType)
item.SetValue(parameterOjb, Activator.CreateInstance(item.PropertyType));
else
item.SetValue(parameterOjb, null);
}
}
else
{
// 尝试使用类型转换设置值
try
{
var convertedValue = UtilMethods.ChangeType2(propertyParam.Value, item.PropertyType);
item.SetValue(parameterOjb, convertedValue);
}
catch
{
// 如果类型转换失败,使用默认值
if (item.PropertyType.IsValueType)
item.SetValue(parameterOjb, Activator.CreateInstance(item.PropertyType));
else
item.SetValue(parameterOjb, null);
}
}
3 weeks ago
}
catch (Exception)
3 weeks ago
{
// 如果设置属性值失败,继续处理下一个属性
continue;
3 weeks ago
}
}
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)
{
try
3 weeks ago
{
// 检查DefaultParameters是否有效
if (dataModel?.DefaultParameters == null || !dataModel.DefaultParameters.Any())
{
System.Diagnostics.Debug.WriteLine("DefaultParameters为空或null");
return; // 无法继续
}
// 获取第一个参数的值
var param = dataModel.DefaultParameters.First();
var value = param.Value?.ToString() ?? "";
System.Diagnostics.Debug.WriteLine($"参数值: {value}");
var type = methodInfo.GetParameters().First().ParameterType;
System.Diagnostics.Debug.WriteLine($"参数类型: {type.FullName}");
// 检查值是否为JSON格式
if (!string.IsNullOrWhiteSpace(value))
3 weeks ago
{
value = value.Trim();
if (!((value.StartsWith("{") && value.EndsWith("}")) ||
(value.StartsWith("[") && value.EndsWith("]"))))
{
System.Diagnostics.Debug.WriteLine("值不是有效的JSON格式");
// 尝试将值包装为JSON格式
value = $"{{\"_value\": {value}}}";
System.Diagnostics.Debug.WriteLine($"转换为: {value}");
}
3 weeks ago
}
// JToken及其派生类的特殊处理
if (typeof(Newtonsoft.Json.Linq.JToken).IsAssignableFrom(type))
{
System.Diagnostics.Debug.WriteLine("处理JToken类型");
try
{
if (type == typeof(Newtonsoft.Json.Linq.JObject))
{
if (string.IsNullOrEmpty(value) || value == "null")
{
value = "{}";
}
parameters[0] = Newtonsoft.Json.Linq.JObject.Parse(value);
System.Diagnostics.Debug.WriteLine("JObject解析成功");
}
else if (type == typeof(Newtonsoft.Json.Linq.JArray))
{
if (string.IsNullOrEmpty(value) || value == "null")
{
value = "[]";
}
parameters[0] = Newtonsoft.Json.Linq.JArray.Parse(value);
}
else // JToken或其他子类
{
if (string.IsNullOrEmpty(value))
{
value = "null";
}
parameters[0] = Newtonsoft.Json.Linq.JToken.Parse(value);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"JSON解析错误: {ex.Message}");
// 如果解析失败,创建一个空对象
if (type == typeof(Newtonsoft.Json.Linq.JObject))
{
parameters[0] = new Newtonsoft.Json.Linq.JObject();
}
else if (type == typeof(Newtonsoft.Json.Linq.JArray))
{
parameters[0] = new Newtonsoft.Json.Linq.JArray();
}
else
{
parameters[0] = Newtonsoft.Json.Linq.JValue.CreateNull();
}
}
}
else if (!string.IsNullOrEmpty(value))
{
System.Diagnostics.Debug.WriteLine("处理非JToken类型");
// 非JToken类型的常规处理
try
{
parameters[0] = JsonConvert.DeserializeObject(value, type)!;
if (parameters[0] is SaveInterfaceListModel saveInterfaceListModel)
{
saveInterfaceListModel.InterfaceCategoryId = Convert.ToInt64(Convert.ToDouble(saveInterfaceListModel.InterfaceCategoryId)) + "";
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"非JToken反序列化错误: {ex.Message}");
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"FillJObjectParameters总体异常: {ex.Message}");
3 weeks ago
}
}
private static bool IsJObject(DataModel dataModel, object[] parameters)
{
if (parameters.Length != 1 || dataModel.DefaultParameters.Count == 0)
return false;
var firstParam = dataModel.DefaultParameters.First();
// 检查是否已标记为JObject类型
bool isJObjectType = firstParam.ValueType == nameof(JObject) ||
firstParam.ValueType == nameof(JToken) ||
firstParam.ValueType == "JTokenType" ||
firstParam.ValueType == "Json" ||
firstParam.ValueType?.Contains("JObject") == true ||
firstParam.ValueType?.Contains("JToken") == true;
// 检查是否为单个参数
bool isSingleParam = dataModel.DefaultParameters.Count == 1;
// 检查JSON字符串
bool isJsonString = firstParam.Value != null && IsJsonString(firstParam.Value.ToString());
return isSingleParam && (isJObjectType || isJsonString);
}
private static bool IsJsonString(string value)
{
if (string.IsNullOrEmpty(value))
return false;
value = value.Trim();
return (value.StartsWith("{") && value.EndsWith("}")) ||
(value.StartsWith("[") && value.EndsWith("]"));
3 weeks ago
}
private static int FillDefaultParameters(DataModel dataModel, MethodInfo methodInfo, object[] parameters, Type[]? argsTypes)
{
var index = 0;
methodInfo.GetParameters().ToList<System.Reflection.ParameterInfo>().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));
}
3 weeks ago
}
}
try
{
value = ConvetEmptyValue(p.ParameterType, value);
value = UtilMethods.ChangeType2(value, p.ParameterType);
}
catch (Exception ex)
3 weeks ago
{
throw new Exception(TextHandler.GetCommonText(p.Name + "参数类型不匹配 " + value + ", 错误: " + ex.Message,
p.Name + " Parameter type does not match " + value + ", Error: " + ex.Message));
3 weeks ago
}
parameters[p.Position] = value!;
index++;
});
return index;
}
private static object? ConvetEmptyValue(Type type, object? value)
{
if (value?.Equals("") == true && type != typeof(string))
{
value = null;
}
// 处理JToken及其子类型
if (typeof(Newtonsoft.Json.Linq.JToken).IsAssignableFrom(type))
{
var jTokenValue = value?.ToString()?.Trim();
if (string.IsNullOrEmpty(jTokenValue))
{
// 为各种JToken类型提供默认值
if (type == typeof(Newtonsoft.Json.Linq.JObject))
return "{}";
else if (type == typeof(Newtonsoft.Json.Linq.JArray))
return "[]";
else
return "null";
}
return jTokenValue;
}
// 处理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
{
// 保持原始值
}
}
}
3 weeks ago
return value;
}
private static async Task<object> 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;
3 weeks ago
}
// 直接填充JObject参数,简化处理
private void FillJObjectDirectly(DataModel dataModel, Type parameterType, object[] parameters)
{
try
{
System.Diagnostics.Debug.WriteLine("直接填充JObject参数");
if (dataModel?.DefaultParameters == null || !dataModel.DefaultParameters.Any())
{
System.Diagnostics.Debug.WriteLine("直接填充JObject - 参数列表为空");
parameters[0] = CreateDefaultJToken(parameterType);
return;
}
var jsonData = dataModel.DefaultParameters.First().Value?.ToString();
if (string.IsNullOrEmpty(jsonData))
{
System.Diagnostics.Debug.WriteLine("直接填充JObject - 参数值为空");
parameters[0] = CreateDefaultJToken(parameterType);
return;
}
System.Diagnostics.Debug.WriteLine($"直接填充JObject - JSON数据: {jsonData}");
try
{
// 检查是否需要处理嵌套的数据结构
if (jsonData.Contains("\"methodName\"") && jsonData.Contains("\"data\"") &&
parameterType == typeof(Newtonsoft.Json.Linq.JObject))
{
var jobj = Newtonsoft.Json.Linq.JObject.Parse(jsonData);
// ExecuteTransaction方法直接需要整个请求对象,无需处理
parameters[0] = jobj;
}
else if (parameterType == typeof(Newtonsoft.Json.Linq.JObject))
{
parameters[0] = Newtonsoft.Json.Linq.JObject.Parse(jsonData);
}
else if (parameterType == typeof(Newtonsoft.Json.Linq.JArray))
{
parameters[0] = Newtonsoft.Json.Linq.JArray.Parse(jsonData);
}
else
{
parameters[0] = Newtonsoft.Json.Linq.JToken.Parse(jsonData);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"直接填充JObject - 解析异常: {ex.Message}");
parameters[0] = CreateDefaultJToken(parameterType);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"直接填充JObject - 总异常: {ex.Message}");
parameters[0] = CreateDefaultJToken(parameterType);
}
}
// 创建默认的JToken对象
private static Newtonsoft.Json.Linq.JToken CreateDefaultJToken(Type parameterType)
{
if (parameterType == typeof(Newtonsoft.Json.Linq.JObject))
return new Newtonsoft.Json.Linq.JObject();
else if (parameterType == typeof(Newtonsoft.Json.Linq.JArray))
return new Newtonsoft.Json.Linq.JArray();
else
return Newtonsoft.Json.Linq.JValue.CreateNull();
}
3 weeks ago
}
}