using System;
using Swashbuckle.AspNetCore.Annotations;
namespace SimApi.Attributes;
///
/// 快捷自定义接口文档类(所有参数均可省略, 支持命名参数)。
/// 对应仓颉版 SimApiDoc:
/// tags → 接口标签(逗号分隔, 如 "认证,用户")
/// name → API 名称(映射到 Summary, 作为文档接口标题)
/// description → API 详细描述
/// groupNames → 所属文档组(逗号分隔, 如 "api,admin"; "*" 表示所有文档; null/空 → 仅默认 "api" 文档)
/// ignore → true 时不出现在任何文档中(路由不受影响)
/// 写法示例:
/// [SimApiDoc("认证", "登录")] 位置参数(保持旧版兼容)
/// [SimApiDoc(tags: "认证", name: "登录", description: "...")]
/// [SimApiDoc(groupNames: "api,admin")] 仅指定文档组
/// [SimApiDoc(GroupNames = "*", Ignore = false)] 属性命名参数
/// [SimApiDoc] 全部默认(可标在类上, 仅用 Ignore/GroupNames 等)
/// 属性命名参数优先于构造命名参数。
///
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class SimApiDocAttribute : SwaggerOperationAttribute
{
///
/// 出现在所有文档组中的通配符
///
public const string AllGroups = "*";
///
/// 接口所属的文档组(逗号分隔, 如 "api,admin"); "*" 表示所有文档; null/空 表示未分组(仅默认 "api" 文档)
///
public string? GroupNames { get; set; }
///
/// 为 true 时该接口不出现在任何文档中(不影响路由)
///
public bool Ignore { get; set; }
///
/// 定义接口说明(全部可选)
///
/// 接口标签, 逗号分隔, 如 "认证,用户"
/// 接口名称
/// 接口描述
/// 所属文档组, 逗号分隔; "*" 表示所有文档
/// true 时不出现在任何文档
public SimApiDocAttribute(string? tags = null, string? name = null, string? description = null,
string? groupNames = null, bool ignore = false)
{
Apply(tags, name, description, groupNames, ignore);
}
///
/// 定义接口说明(标签以数组传入)
///
/// 接口标签列表
/// 接口名称
/// 接口描述
/// 所属文档组, 逗号分隔; "*" 表示所有文档
/// true 时不出现在任何文档
public SimApiDocAttribute(string[] tags, string? name = null, string? description = null,
string? groupNames = null, bool ignore = false)
{
Apply(tags, name, description, groupNames, ignore);
}
private void Apply(string? tags, string? name, string? description,
string? groupNames, bool ignore)
{
if (!string.IsNullOrWhiteSpace(tags))
{
Tags = tags.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
}
ApplyCore(name, description, groupNames, ignore);
}
private void Apply(string[] tags, string? name, string? description,
string? groupNames, bool ignore)
{
if (tags is { Length: > 0 })
{
Tags = tags;
}
ApplyCore(name, description, groupNames, ignore);
}
private void ApplyCore(string? name, string? description, string? groupNames, bool ignore)
{
if (!string.IsNullOrEmpty(name))
{
Summary = name;
}
if (!string.IsNullOrEmpty(description))
{
Description = description;
}
GroupNames = groupNames;
Ignore = ignore;
}
}