mirror of
https://gitee.com/ccnetcore/Yi
synced 2026-03-30 21:56:37 +08:00
refactor: ai+人工重构优化 framework
This commit is contained in:
@@ -9,65 +9,129 @@ using Volo.Abp.Reflection;
|
||||
|
||||
namespace Yi.Framework.AspNetCore.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义路由构建器,用于生成API路由规则
|
||||
/// </summary>
|
||||
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
|
||||
[ExposeServices(typeof(IConventionalRouteBuilder))]
|
||||
public class YiConventionalRouteBuilder : ConventionalRouteBuilder
|
||||
{
|
||||
public YiConventionalRouteBuilder(IOptions<AbpConventionalControllerOptions> options) : base(options)
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="options">ABP约定控制器配置选项</param>
|
||||
public YiConventionalRouteBuilder(IOptions<AbpConventionalControllerOptions> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建API路由
|
||||
/// </summary>
|
||||
/// <param name="rootPath">根路径</param>
|
||||
/// <param name="controllerName">控制器名称</param>
|
||||
/// <param name="action">Action模型</param>
|
||||
/// <param name="httpMethod">HTTP方法</param>
|
||||
/// <param name="configuration">控制器配置</param>
|
||||
/// <returns>构建的路由URL</returns>
|
||||
public override string Build(
|
||||
string rootPath,
|
||||
string controllerName,
|
||||
ActionModel action,
|
||||
string httpMethod,
|
||||
[CanBeNull] ConventionalControllerSetting configuration)
|
||||
string rootPath,
|
||||
string controllerName,
|
||||
ActionModel action,
|
||||
string httpMethod,
|
||||
[CanBeNull] ConventionalControllerSetting configuration)
|
||||
{
|
||||
|
||||
// 获取API路由前缀
|
||||
var apiRoutePrefix = GetApiRoutePrefix(action, configuration);
|
||||
var controllerNameInUrl =
|
||||
NormalizeUrlControllerName(rootPath, controllerName, action, httpMethod, configuration);
|
||||
|
||||
// 规范化控制器名称
|
||||
var normalizedControllerName = NormalizeUrlControllerName(
|
||||
rootPath,
|
||||
controllerName,
|
||||
action,
|
||||
httpMethod,
|
||||
configuration);
|
||||
|
||||
var url = $"{rootPath}/{NormalizeControllerNameCase(controllerNameInUrl, configuration)}";
|
||||
// 构建基础URL
|
||||
var url = $"{rootPath}/{NormalizeControllerNameCase(normalizedControllerName, configuration)}";
|
||||
|
||||
//Add {id} path if needed
|
||||
var idParameterModel = action.Parameters.FirstOrDefault(p => p.ParameterName == "id");
|
||||
if (idParameterModel != null)
|
||||
{
|
||||
if (TypeHelper.IsPrimitiveExtended(idParameterModel.ParameterType, includeEnums: true))
|
||||
{
|
||||
url += "/{id}";
|
||||
}
|
||||
else
|
||||
{
|
||||
var properties = idParameterModel
|
||||
.ParameterType
|
||||
.GetProperties(BindingFlags.Instance | BindingFlags.Public);
|
||||
// 处理ID参数路由
|
||||
url = BuildIdParameterRoute(url, action, configuration);
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
url += "/{" + NormalizeIdPropertyNameCase(property, configuration) + "}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Add action name if needed
|
||||
var actionNameInUrl = NormalizeUrlActionName(rootPath, controllerName, action, httpMethod, configuration);
|
||||
if (!actionNameInUrl.IsNullOrEmpty())
|
||||
{
|
||||
url += $"/{NormalizeActionNameCase(actionNameInUrl, configuration)}";
|
||||
|
||||
//Add secondary Id
|
||||
var secondaryIds = action.Parameters
|
||||
.Where(p => p.ParameterName.EndsWith("Id", StringComparison.Ordinal)).ToList();
|
||||
if (secondaryIds.Count == 1)
|
||||
{
|
||||
url += $"/{{{NormalizeSecondaryIdNameCase(secondaryIds[0], configuration)}}}";
|
||||
}
|
||||
}
|
||||
// 处理Action名称路由
|
||||
url = BuildActionNameRoute(url, rootPath, controllerName, action, httpMethod, configuration);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建ID参数路由部分
|
||||
/// </summary>
|
||||
private string BuildIdParameterRoute(
|
||||
string baseUrl,
|
||||
ActionModel action,
|
||||
ConventionalControllerSetting configuration)
|
||||
{
|
||||
var idParameter = action.Parameters.FirstOrDefault(p => p.ParameterName == "id");
|
||||
if (idParameter == null)
|
||||
{
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
// 处理原始类型ID
|
||||
if (TypeHelper.IsPrimitiveExtended(idParameter.ParameterType, includeEnums: true))
|
||||
{
|
||||
return $"{baseUrl}/{{id}}";
|
||||
}
|
||||
|
||||
// 处理复杂类型ID
|
||||
var properties = idParameter.ParameterType
|
||||
.GetProperties(BindingFlags.Instance | BindingFlags.Public);
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
baseUrl += $"/{{{NormalizeIdPropertyNameCase(property, configuration)}}}";
|
||||
}
|
||||
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建Action名称路由部分
|
||||
/// </summary>
|
||||
private string BuildActionNameRoute(
|
||||
string baseUrl,
|
||||
string rootPath,
|
||||
string controllerName,
|
||||
ActionModel action,
|
||||
string httpMethod,
|
||||
ConventionalControllerSetting configuration)
|
||||
{
|
||||
var actionNameInUrl = NormalizeUrlActionName(
|
||||
rootPath,
|
||||
controllerName,
|
||||
action,
|
||||
httpMethod,
|
||||
configuration);
|
||||
|
||||
if (actionNameInUrl.IsNullOrEmpty())
|
||||
{
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
baseUrl += $"/{NormalizeActionNameCase(actionNameInUrl, configuration)}";
|
||||
|
||||
// 处理次要ID参数
|
||||
var secondaryIds = action.Parameters
|
||||
.Where(p => p.ParameterName.EndsWith("Id", StringComparison.Ordinal))
|
||||
.ToList();
|
||||
|
||||
if (secondaryIds.Count == 1)
|
||||
{
|
||||
baseUrl += $"/{{{NormalizeSecondaryIdNameCase(secondaryIds[0], configuration)}}}";
|
||||
}
|
||||
|
||||
return baseUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,24 +13,46 @@ using Volo.Abp.Reflection;
|
||||
|
||||
namespace Yi.Framework.AspNetCore.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义服务约定实现,用于处理API路由和HTTP方法约束
|
||||
/// </summary>
|
||||
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
|
||||
[ExposeServices(typeof(IAbpServiceConvention))]
|
||||
public class YiServiceConvention : AbpServiceConvention
|
||||
{
|
||||
public YiServiceConvention(IOptions<AbpAspNetCoreMvcOptions> options, IConventionalRouteBuilder conventionalRouteBuilder) : base(options, conventionalRouteBuilder)
|
||||
/// <summary>
|
||||
/// 初始化服务约定的新实例
|
||||
/// </summary>
|
||||
/// <param name="options">ABP AspNetCore MVC 配置选项</param>
|
||||
/// <param name="conventionalRouteBuilder">约定路由构建器</param>
|
||||
public YiServiceConvention(
|
||||
IOptions<AbpAspNetCoreMvcOptions> options,
|
||||
IConventionalRouteBuilder conventionalRouteBuilder)
|
||||
: base(options, conventionalRouteBuilder)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void ConfigureSelector(string rootPath, string controllerName, ActionModel action, ConventionalControllerSetting? configuration)
|
||||
/// <summary>
|
||||
/// 配置选择器,处理路由和HTTP方法约束
|
||||
/// </summary>
|
||||
protected override void ConfigureSelector(
|
||||
string rootPath,
|
||||
string controllerName,
|
||||
ActionModel action,
|
||||
ConventionalControllerSetting? configuration)
|
||||
{
|
||||
// 移除空选择器
|
||||
RemoveEmptySelectors(action.Selectors);
|
||||
|
||||
var remoteServiceAtt = ReflectionHelper.GetSingleAttributeOrDefault<RemoteServiceAttribute>(action.ActionMethod);
|
||||
if (remoteServiceAtt != null && !remoteServiceAtt.IsEnabledFor(action.ActionMethod))
|
||||
// 检查远程服务特性
|
||||
var remoteServiceAttr = ReflectionHelper
|
||||
.GetSingleAttributeOrDefault<RemoteServiceAttribute>(action.ActionMethod);
|
||||
if (remoteServiceAttr != null && !remoteServiceAttr.IsEnabledFor(action.ActionMethod))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据选择器是否存在执行不同的配置
|
||||
if (!action.Selectors.Any())
|
||||
{
|
||||
AddAbpServiceSelector(rootPath, controllerName, action, configuration);
|
||||
@@ -41,56 +63,92 @@ namespace Yi.Framework.AspNetCore.Mvc
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void AddAbpServiceSelector(string rootPath, string controllerName, ActionModel action, ConventionalControllerSetting? configuration)
|
||||
{
|
||||
base.AddAbpServiceSelector(rootPath, controllerName, action, configuration);
|
||||
}
|
||||
|
||||
protected override void NormalizeSelectorRoutes(string rootPath, string controllerName, ActionModel action, ConventionalControllerSetting? configuration)
|
||||
/// <summary>
|
||||
/// 规范化选择器路由
|
||||
/// </summary>
|
||||
protected override void NormalizeSelectorRoutes(
|
||||
string rootPath,
|
||||
string controllerName,
|
||||
ActionModel action,
|
||||
ConventionalControllerSetting? configuration)
|
||||
{
|
||||
foreach (var selector in action.Selectors)
|
||||
{
|
||||
var httpMethod = selector.ActionConstraints
|
||||
.OfType<HttpMethodActionConstraint>()
|
||||
.FirstOrDefault()?
|
||||
.HttpMethods?
|
||||
.FirstOrDefault();
|
||||
|
||||
if (httpMethod == null)
|
||||
{
|
||||
httpMethod = SelectHttpMethod(action, configuration);
|
||||
}
|
||||
|
||||
if (selector.AttributeRouteModel == null)
|
||||
{
|
||||
selector.AttributeRouteModel = CreateAbpServiceAttributeRouteModel(rootPath, controllerName, action, httpMethod, configuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
var template = selector.AttributeRouteModel.Template;
|
||||
if (!template.StartsWith("/"))
|
||||
{
|
||||
var route = $"{rootPath}/{template}";
|
||||
selector.AttributeRouteModel.Template = route;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!selector.ActionConstraints.OfType<HttpMethodActionConstraint>().Any())
|
||||
{
|
||||
selector.ActionConstraints.Add(new HttpMethodActionConstraint(new[] { httpMethod }));
|
||||
}
|
||||
// 获取HTTP方法约束
|
||||
var httpMethod = GetOrCreateHttpMethod(selector, action, configuration);
|
||||
|
||||
// 处理路由模板
|
||||
ConfigureRouteTemplate(selector, rootPath, controllerName, action, httpMethod, configuration);
|
||||
|
||||
// 确保HTTP方法约束存在
|
||||
EnsureHttpMethodConstraint(selector, httpMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或创建HTTP方法
|
||||
/// </summary>
|
||||
private string GetOrCreateHttpMethod(
|
||||
SelectorModel selector,
|
||||
ActionModel action,
|
||||
ConventionalControllerSetting? configuration)
|
||||
{
|
||||
return selector.ActionConstraints
|
||||
.OfType<HttpMethodActionConstraint>()
|
||||
.FirstOrDefault()?
|
||||
.HttpMethods?
|
||||
.FirstOrDefault()
|
||||
?? SelectHttpMethod(action, configuration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置路由模板
|
||||
/// </summary>
|
||||
private void ConfigureRouteTemplate(
|
||||
SelectorModel selector,
|
||||
string rootPath,
|
||||
string controllerName,
|
||||
ActionModel action,
|
||||
string httpMethod,
|
||||
ConventionalControllerSetting? configuration)
|
||||
{
|
||||
if (selector.AttributeRouteModel == null)
|
||||
{
|
||||
selector.AttributeRouteModel = CreateAbpServiceAttributeRouteModel(
|
||||
rootPath,
|
||||
controllerName,
|
||||
action,
|
||||
httpMethod,
|
||||
configuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
NormalizeAttributeRouteTemplate(selector, rootPath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 规范化特性路由模板
|
||||
/// </summary>
|
||||
private void NormalizeAttributeRouteTemplate(SelectorModel selector, string rootPath)
|
||||
{
|
||||
var template = selector.AttributeRouteModel.Template;
|
||||
if (!template.StartsWith("/"))
|
||||
{
|
||||
selector.AttributeRouteModel.Template = $"{rootPath}/{template}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 确保HTTP方法约束存在
|
||||
/// </summary>
|
||||
private void EnsureHttpMethodConstraint(SelectorModel selector, string httpMethod)
|
||||
{
|
||||
if (!selector.ActionConstraints.OfType<HttpMethodActionConstraint>().Any())
|
||||
{
|
||||
selector.ActionConstraints.Add(
|
||||
new HttpMethodActionConstraint(new[] { httpMethod }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user