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.
343 lines
16 KiB
343 lines
16 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Reflection; |
|
using System.Text; |
|
using System.Linq; |
|
using SqlSugar; |
|
using System.Reflection.Emit; |
|
namespace ReZero.SuperAPI |
|
{ |
|
public class AttibuteInterfaceInitializerService |
|
{ |
|
internal static ZeroInterfaceList GetZeroInterfaceItem(Type type, MethodInfo method) |
|
{ |
|
var classAttribute = type.GetCustomAttribute<ApiAttribute>(); |
|
var methodAttribute = method.GetCustomAttribute<ApiMethodAttribute>(); |
|
var urlParametersAttribute = method.GetCustomAttribute<UrlParametersAttribute>(); |
|
var isUrlParameters = urlParametersAttribute != null; |
|
var groupName = methodAttribute.GroupName ?? classAttribute.GroupName ?? type.Name; |
|
string url = GetUrl(type, method, classAttribute, methodAttribute); |
|
var oldUrl = isUrlParameters ? url : null; |
|
var methodDesc = methodAttribute.Description ?? string.Empty; |
|
ZeroInterfaceList it = new ZeroInterfaceList(); |
|
it.HttpMethod = methodAttribute.HttpMethod.ToString(); |
|
it.Id = SnowFlakeSingle.Instance.NextId(); |
|
it.GroupName = groupName; |
|
it.InterfaceCategoryId = classAttribute.InterfaceCategoryId; |
|
it.Name = methodDesc; |
|
it.Url = url; |
|
it.OriginalUrl = oldUrl; |
|
it.IsInitialized = false; |
|
it.IsAttributeMethod = true; |
|
it.DataModel = new DataModel() |
|
{ |
|
TableId = EntityInfoInitializerProvider.Id_ZeroInterfaceList, |
|
ActionType = ActionType.MethodGeneratorAPI, |
|
MyMethodInfo = new MyMethodInfo() |
|
{ |
|
MethodArgsCount = method.GetParameters().Count(), |
|
MethodClassFullName = type.FullName, |
|
MethodName = method.Name |
|
} |
|
}; |
|
it.DataModel.DefaultParameters = new List<DataModelDefaultParameter>(); |
|
var isAdd = true; |
|
foreach (var item in method.GetParameters()) |
|
{ |
|
var nonNullableType = item.ParameterType.GetNonNullableType(); |
|
it.Url = GetUrl(type, isUrlParameters, it.Url, item, nonNullableType); |
|
DataModelDefaultParameter dataModelDefaultParameter = new DataModelDefaultParameter(); |
|
dataModelDefaultParameter.Name = item.Name; |
|
if (IsDefaultType(item.ParameterType)) |
|
{ |
|
dataModelDefaultParameter.ValueType = item.ParameterType.GetNonNullableType().Name; |
|
} |
|
else if (item.ParameterType == typeof(byte[])) |
|
{ |
|
dataModelDefaultParameter.ValueType = "Byte[]"; |
|
} |
|
else if (IsObject(item.ParameterType)) |
|
{ |
|
dataModelDefaultParameter.ValueType = "Json"; |
|
object obj = Activator.CreateInstance(item.ParameterType); |
|
dataModelDefaultParameter.Value = new SerializeService().SerializeObject(obj); |
|
} |
|
else if (method.GetParameters().Count() == 1) |
|
{ |
|
isAdd = false; |
|
it.DataModel.MyMethodInfo.ArgsTypes = new Type[] { typeof(SingleModel) }; |
|
var paramters = item.ParameterType.GetProperties(); |
|
AddSingleClassParameters(it, paramters); |
|
} |
|
else |
|
{ |
|
dataModelDefaultParameter.ValueType = "Json"; |
|
object obj = Activator.CreateInstance(item.ParameterType); |
|
dataModelDefaultParameter.Value = new SerializeService().SerializeObject(obj); |
|
} |
|
if (isAdd) |
|
it.DataModel.DefaultParameters.Add(dataModelDefaultParameter); |
|
} |
|
return it; |
|
} |
|
|
|
private static string GetUrl(Type type, bool isUrlParameters, string url, ParameterInfo item, Type nonNullableType) |
|
{ |
|
if (isUrlParameters && !(nonNullableType.IsValueType || nonNullableType == typeof(string))) |
|
{ |
|
throw new Exception(TextHandler.GetCommonText($"{type.FullName}中的{item.Name}方法使用[UrlParameters] 只能是基础类型参数。{nonNullableType.Name}类型不支持", $"The {item.Name} method in {type.FullName} uses [UrlParameters] as a base type parameter only. The {nonNullableType.Name} type is not supported")); |
|
} |
|
else if (isUrlParameters) |
|
{ |
|
url += "/{" + item.Name + "}"; |
|
} |
|
return url; |
|
} |
|
|
|
private static string GetUrl(Type type, MethodInfo method, ApiAttribute classAttribute, ApiMethodAttribute methodAttribute) |
|
{ |
|
if (string.IsNullOrEmpty(methodAttribute.Url)&& !string.IsNullOrEmpty(classAttribute.Url)) |
|
{ |
|
return methodAttribute.Url ?? $"/{classAttribute.Url.TrimStart('/')}/{method.Name?.ToLower()}"; |
|
} |
|
return methodAttribute.Url ?? $"/api/{classAttribute.InterfaceCategoryId}/{type.Name?.ToLower()}/{method.Name?.ToLower()}"; |
|
} |
|
|
|
private static void AddSingleClassParameters(ZeroInterfaceList it, PropertyInfo[] paramters) |
|
{ |
|
foreach (var p in paramters) |
|
{ |
|
DataModelDefaultParameter addItem = new DataModelDefaultParameter(); |
|
addItem.Name = p.Name; |
|
if (IsDefaultType(p.PropertyType)) |
|
{ |
|
addItem.ValueType = p.PropertyType.GetNonNullableType().Name; |
|
} |
|
else if (p.PropertyType == typeof(byte[])) |
|
{ |
|
addItem.ValueType = "Byte[]"; |
|
} |
|
else if (typeof(Newtonsoft.Json.Linq.JToken).IsAssignableFrom(p.PropertyType)) |
|
{ |
|
// 特殊处理JToken类型(包括JObject, JArray等) |
|
addItem.ValueType = "Json"; |
|
if (p.PropertyType == typeof(Newtonsoft.Json.Linq.JObject)) |
|
{ |
|
addItem.Value = "{}"; |
|
} |
|
else if (p.PropertyType == typeof(Newtonsoft.Json.Linq.JArray)) |
|
{ |
|
addItem.Value = "[]"; |
|
} |
|
else |
|
{ |
|
addItem.Value = "null"; |
|
} |
|
} |
|
else |
|
{ |
|
addItem.ValueType = "Json"; |
|
try |
|
{ |
|
object obj = Activator.CreateInstance(p.PropertyType); |
|
addItem.Value = new SerializeService().SerializeObject(obj); |
|
} |
|
catch (Exception) |
|
{ |
|
// 如果无法创建实例,设置为默认值 |
|
addItem.Value = "{}"; |
|
} |
|
} |
|
it!.DataModel!.DefaultParameters!.Add(addItem); |
|
} |
|
} |
|
|
|
private static bool IsDefaultType(Type type) |
|
{ |
|
return type.GetNonNullableType().IsValueType || type.GetNonNullableType() == typeof(string); |
|
} |
|
|
|
internal static void InitDynamicAttributeApi(List<Type>? types) |
|
{ |
|
types = AttibuteInterfaceInitializerService.GetTypesWithDynamicApiAttribute(types ?? new List<Type>()); |
|
List<ZeroInterfaceList> zeroInterfaceLists = new List<ZeroInterfaceList>(); |
|
foreach (var type in types) |
|
{ |
|
var methods = AttibuteInterfaceInitializerService.GetMethodsWithDynamicMethodAttribute(type); |
|
if (methods.Any()) |
|
{ |
|
foreach (var method in methods) |
|
{ |
|
var addItem = AttibuteInterfaceInitializerService.GetZeroInterfaceItem(type, method); |
|
if (addItem.Url == PubConst.InitApi_SystemSaveConfig) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.SaveConfigId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_SystemGetInitConfig) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.GetInitConfigId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_VerifyCode) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.VerifyCodeId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_SaveUser) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.SaveUserId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_GetUserById) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.GetUserById_Id; |
|
} |
|
if (addItem.Url == PubConst.InitApi_DeleteUserById) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.DeleteUserById_Id; |
|
} |
|
if (addItem.Url == PubConst.InitApi_GetCurrentUser) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.GetCurrentUserId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_GetBizUsers) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.GetBizUsersId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_ViewTemplate) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.ViewTemplateId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_AddTokenManage) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.AddTokenManageId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_UpdateTokenManage) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.UpdateTokenManageId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_DeleteTokenManage) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.DeleteTokenManageId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_GetTokenManageById) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.GetTokenManageById_Id; |
|
} |
|
if (addItem.Url == PubConst.InitApi_GetPermissionList) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.GetPermissionListId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_AddPermission) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.AddPermissionId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_UpdatePermission) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.UpdatePermissionId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_DeletePermission) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.DeletePermissionId; |
|
} |
|
if (addItem.Url == PubConst.InitApi_GetSavePermissionModelById) |
|
{ |
|
addItem.IsInitialized = true; |
|
addItem.Id = InterfaceListInitializerProvider.GetSavePermissionModelById_Id; |
|
} |
|
zeroInterfaceLists.Add(addItem); |
|
} |
|
} |
|
} |
|
var db = App.PreStartupDb; |
|
if (db != null) |
|
{ |
|
db!.QueryFilter.ClearAndBackup(); |
|
try |
|
{ |
|
db!.Ado.BeginTran(); |
|
var list = db.Queryable<ZeroInterfaceList>().Where(it => it.IsAttributeMethod == true).ToList(); |
|
db.Deleteable<ZeroInterfaceList>().Where(it => it.IsAttributeMethod == true).ExecuteCommand(); |
|
foreach (var item in zeroInterfaceLists) |
|
{ |
|
if (list.FirstOrDefault(it => it.Url == item.Url) is { } data) |
|
{ |
|
item.Id = data.Id; |
|
} |
|
} |
|
db.Insertable(zeroInterfaceLists).ExecuteCommand(); |
|
db!.Ado.CommitTran(); |
|
} |
|
catch (Exception) |
|
{ |
|
db!.Ado.RollbackTran(); |
|
throw; |
|
} |
|
db!.QueryFilter.Restore(); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Get the list of types with the DynamicApiAttribute |
|
/// </summary> |
|
/// <param name="types">The list of types</param> |
|
/// <returns>The list of types with the DynamicApiAttribute</returns> |
|
public static List<Type> GetTypesWithDynamicApiAttribute(List<Type> types) |
|
{ |
|
List<Type> typesWithDynamicApiAttribute = new List<Type>(); |
|
|
|
foreach (var type in types) |
|
{ |
|
// Check if the type has the DynamicApiAttribute |
|
if (type.GetCustomAttributes(typeof(ApiAttribute), true).Length > 0) |
|
{ |
|
typesWithDynamicApiAttribute.Add(type); |
|
} |
|
} |
|
|
|
return typesWithDynamicApiAttribute; |
|
} |
|
|
|
|
|
/// <summary> |
|
/// Get the list of methods with the DynamicMethodAttribute for a given type |
|
/// </summary> |
|
/// <param name="type">The type</param> |
|
/// <returns>The list of methods with the DynamicMethodAttribute</returns> |
|
public static List<MethodInfo> GetMethodsWithDynamicMethodAttribute(Type type) |
|
{ |
|
List<MethodInfo> methodsWithDynamicMethodAttribute = new List<MethodInfo>(); |
|
|
|
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); |
|
|
|
foreach (var method in methods) |
|
{ |
|
if (method.GetCustomAttributes(typeof(ApiMethodAttribute), true).Length > 0) |
|
{ |
|
methodsWithDynamicMethodAttribute.Add(method); |
|
} |
|
} |
|
|
|
return methodsWithDynamicMethodAttribute; |
|
} |
|
|
|
private static bool IsObject(Type type) |
|
{ |
|
return (type.IsArray || type.FullName.StartsWith("System.Collections.Generic.List")); |
|
} |
|
} |
|
}
|
|
|