swagger controller
This commit is contained in:
		@@ -1,4 +1,5 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.OpenApi.Models;
 | 
			
		||||
using Swashbuckle.AspNetCore.SwaggerGen;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
@@ -18,7 +19,9 @@ public class SwaggerController : ControllerBase
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc/>
 | 
			
		||||
    [Route("get/{version}")]
 | 
			
		||||
    [Produces("text/html")]
 | 
			
		||||
    [HttpGet]
 | 
			
		||||
    [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
 | 
			
		||||
    public ActionResult GetApi(string version)
 | 
			
		||||
    {
 | 
			
		||||
        var model = generator.GetSwagger(version);
 | 
			
		||||
@@ -29,106 +32,245 @@ public class SwaggerController : ControllerBase
 | 
			
		||||
    <meta charset=""UTF-8"">
 | 
			
		||||
    <title>Flower Story - API 接口文档</title>
 | 
			
		||||
    <style type=""text/css"">
 | 
			
		||||
        body {{ background-color: rgb(243,244,246) }}
 | 
			
		||||
        pre {{
 | 
			
		||||
            padding: 1rem;
 | 
			
		||||
            background-color: rgb(107 114 128);
 | 
			
		||||
            color: #fff;
 | 
			
		||||
        }}
 | 
			
		||||
        table,
 | 
			
		||||
        table td,
 | 
			
		||||
        table th {{
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: 0;
 | 
			
		||||
            border: 1px solid #000;
 | 
			
		||||
            border: 1px solid #e5e7eb;
 | 
			
		||||
            border-collapse: collapse;
 | 
			
		||||
        }}
 | 
			
		||||
 | 
			
		||||
        table {{
 | 
			
		||||
            table-layout: fixed;
 | 
			
		||||
            word-break: break-all;
 | 
			
		||||
        }}
 | 
			
		||||
 | 
			
		||||
        tr {{
 | 
			
		||||
            height: 20px;
 | 
			
		||||
            font-size: 12px;
 | 
			
		||||
        }}
 | 
			
		||||
        td {{ padding: .75rem }}
 | 
			
		||||
 | 
			
		||||
        .red {{ color: #f00 }}
 | 
			
		||||
        .box {{
 | 
			
		||||
            background-color: #fff;
 | 
			
		||||
            box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.04) 0px 4px 6px -1px;
 | 
			
		||||
            padding: .75rem;
 | 
			
		||||
            border-radius: .375rem;
 | 
			
		||||
            margin-bottom: 2.5rem;
 | 
			
		||||
        }}
 | 
			
		||||
        .method-get {{ color: #61affe }}
 | 
			
		||||
        .method-delete {{ color: #f93e3e }}
 | 
			
		||||
        .method-post {{ color: #49cc90 }}
 | 
			
		||||
        .method-put {{ color: #fca130 }}
 | 
			
		||||
        .header {{ color: rbg(107 114 128) }}
 | 
			
		||||
        .wrapper {{
 | 
			
		||||
            width: 1000px;
 | 
			
		||||
            margin: 0 auto;
 | 
			
		||||
        }}
 | 
			
		||||
 | 
			
		||||
        .operation {{
 | 
			
		||||
            width: 100%;
 | 
			
		||||
        }}
 | 
			
		||||
 | 
			
		||||
        .bg {{
 | 
			
		||||
            background-color: rgb(84, 127, 177);
 | 
			
		||||
        }}
 | 
			
		||||
        .operation {{ width: 100% }}
 | 
			
		||||
        .bg {{ background-color: rgb(84, 127, 177) }}
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div class=""wrapper"">
 | 
			
		||||
        <h1>{model.Info.Title}</h1>
 | 
			
		||||
        <h3>接口文档 {model.Info.Version}</h3>
 | 
			
		||||
        <p>{model.Info.Description}</p>");
 | 
			
		||||
        foreach (var item in model.Paths)
 | 
			
		||||
        <div class=""box"">
 | 
			
		||||
            <p>{model.Info.Description}</p>
 | 
			
		||||
        </div>");
 | 
			
		||||
        foreach (var tag in model.Tags)
 | 
			
		||||
        {
 | 
			
		||||
            if (item.Value.Operations != null)
 | 
			
		||||
            if (tag == null)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var operation in item.Value.Operations)
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            builder.Append($@"
 | 
			
		||||
        <h3>{tag.Description}</h3>
 | 
			
		||||
        <div class=""box"">");
 | 
			
		||||
            foreach (var item in model.Paths)
 | 
			
		||||
            {
 | 
			
		||||
                if (item.Value.Operations != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (string.IsNullOrEmpty(operation.Value.Summary))
 | 
			
		||||
                    foreach (var operation in item.Value.Operations)
 | 
			
		||||
                    {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    builder.Append($@"
 | 
			
		||||
        <h3>{operation.Value.Summary}</h3>
 | 
			
		||||
        <table class=""operation"">
 | 
			
		||||
            <tr class=""bg""><td colspan=""5""></td></tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>URL</td>
 | 
			
		||||
                <td colspan=""4"">{item.Key}</td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>请求方式</td>
 | 
			
		||||
                <td colspan=""4"">{operation.Key}</td>
 | 
			
		||||
            </tr>");
 | 
			
		||||
                    if (operation.Value.Parameters?.Count > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        builder.Append(@"
 | 
			
		||||
            <tr class=""bg"">
 | 
			
		||||
                <td>参数</td>
 | 
			
		||||
                <td>参数类型</td>
 | 
			
		||||
                <td>是否必须</td>
 | 
			
		||||
                <td colspan=""2"">说明</td>
 | 
			
		||||
            </tr>");
 | 
			
		||||
                        foreach (var param in operation.Value.Parameters)
 | 
			
		||||
                        if (!operation.Value.Tags.Any(t => t.Name == tag.Name))
 | 
			
		||||
                        {
 | 
			
		||||
                            builder.Append($@"
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>{param.Name}</td>
 | 
			
		||||
                <td>{param.In}</td>
 | 
			
		||||
                <td>{param.Required}</td>
 | 
			
		||||
                <td colspan=""2"">{param.Description}</td>
 | 
			
		||||
            </tr>");
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                        var method = operation.Key.ToString();
 | 
			
		||||
                        builder.Append($@"
 | 
			
		||||
            <h4>{operation.Value.Summary}</h4>
 | 
			
		||||
            <pre><span class=""method-{method.ToLower()}"">{method.ToUpper()}</span> {item.Key}</pre>");
 | 
			
		||||
                        if (operation.Value.Parameters?.Count > 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            builder.Append(@"
 | 
			
		||||
            <p>请求参数</p>
 | 
			
		||||
            <table class=""operation"">
 | 
			
		||||
                <tr class=""header""><td>参数</td><td>位置</td><td>类型</td><td>说明</td></tr>");
 | 
			
		||||
                            foreach (var param in operation.Value.Parameters)
 | 
			
		||||
                            {
 | 
			
		||||
                                var required = param.Required ? "<span class=\"red\">*</span>" : string.Empty;
 | 
			
		||||
                                builder.Append($@"
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>{required}{param.Name}</td>
 | 
			
		||||
                    <td>{param.In}</td>
 | 
			
		||||
                    <td>{param.Schema.Type}</td>
 | 
			
		||||
                    <td>{param.Description}</td>
 | 
			
		||||
                </tr>");
 | 
			
		||||
                            }
 | 
			
		||||
                            builder.Append(@"
 | 
			
		||||
            </table>");
 | 
			
		||||
                        }
 | 
			
		||||
                        if (operation.Value.RequestBody?.Content != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            foreach (var content in operation.Value.RequestBody.Content)
 | 
			
		||||
                            {
 | 
			
		||||
                                builder.Append($@"
 | 
			
		||||
            <p>请求实体 ({content.Key})</p>
 | 
			
		||||
            <table class=""operation"">
 | 
			
		||||
                <tr class=""header""><td>字段</td><td>类型</td><td>说明</td></tr>");
 | 
			
		||||
                                if (content.Value.Schema.Type == "array")
 | 
			
		||||
                                {
 | 
			
		||||
                                    builder.Append($@"
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>.</td>
 | 
			
		||||
                    <td>{content.Value.Schema.Items.Type}[]</td>
 | 
			
		||||
                    <td>{operation.Value.RequestBody.Description}</td>
 | 
			
		||||
                </tr>");
 | 
			
		||||
                                }
 | 
			
		||||
                                else
 | 
			
		||||
                                {
 | 
			
		||||
                                    IDictionary<string, OpenApiSchema> properties;
 | 
			
		||||
                                    if (content.Value.Schema.Reference != null && model.Components.Schemas.TryGetValue(content.Value.Schema.Reference.Id, out var schema))
 | 
			
		||||
                                    {
 | 
			
		||||
                                        properties = schema.Properties;
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else
 | 
			
		||||
                                    {
 | 
			
		||||
                                        properties = content.Value.Schema.Properties;
 | 
			
		||||
                                    }
 | 
			
		||||
                                    foreach (var prop in properties)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        var required = content.Value.Schema.Required.Contains(prop.Key) ? "<span class=\"red\">*</span>" : string.Empty;
 | 
			
		||||
                                        var type = prop.Value.Type;
 | 
			
		||||
                                        if (type == "string" && prop.Value.Format == "binary")
 | 
			
		||||
                                        {
 | 
			
		||||
                                            type = "file";
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else if (type == "array")
 | 
			
		||||
                                        {
 | 
			
		||||
                                            type = prop.Value.Items.Type;
 | 
			
		||||
                                            if (type == "string" && prop.Value.Items.Format == "binary")
 | 
			
		||||
                                            {
 | 
			
		||||
                                                type = "file";
 | 
			
		||||
                                            }
 | 
			
		||||
                                            type += "[]";
 | 
			
		||||
                                        }
 | 
			
		||||
                                        builder.Append($@"
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>{required}{prop.Key}</td>
 | 
			
		||||
                    <td>{type}</td>
 | 
			
		||||
                    <td>{prop.Value.Description}</td>
 | 
			
		||||
                </tr>");
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                builder.Append(@"
 | 
			
		||||
            </table>");
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        if (operation.Value.Responses?.Count > 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            builder.Append(@"
 | 
			
		||||
            <p>响应 HTTP 状态</p>
 | 
			
		||||
            <table class=""operation"">
 | 
			
		||||
                <tr class=""header""><td>状态码</td><td>说明</td></tr>");
 | 
			
		||||
                            foreach (var response in operation.Value.Responses)
 | 
			
		||||
                            {
 | 
			
		||||
                                builder.Append($@"
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>{response.Key}</td>
 | 
			
		||||
                    <td>{response.Value.Description}</td>
 | 
			
		||||
                </tr>");
 | 
			
		||||
                                if (response.Key == "200")
 | 
			
		||||
                                {
 | 
			
		||||
                                    foreach (var content in response.Value.Content)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        builder.Append($@"
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td colspan=""2"">
 | 
			
		||||
                        <p>{content.Key}</p>
 | 
			
		||||
                        <table class=""operation"">
 | 
			
		||||
                            <tr><td>字段</td><td>类型</td><td>说明</td></tr>");
 | 
			
		||||
                                        OpenApiSchema schema;
 | 
			
		||||
                                        if (content.Value.Schema.Type == "array")
 | 
			
		||||
                                        {
 | 
			
		||||
                                            schema = content.Value.Schema.Items;
 | 
			
		||||
                                            builder.Append($@"
 | 
			
		||||
                            <tr><td>.</td><td>{schema.Reference?.Id ?? schema.Type}[]</td><td></td></tr>");
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else
 | 
			
		||||
                                        {
 | 
			
		||||
                                            schema = content.Value.Schema;
 | 
			
		||||
                                        }
 | 
			
		||||
                                        if (schema.Reference != null && model.Components.Schemas.TryGetValue(schema.Reference.Id, out var s))
 | 
			
		||||
                                        {
 | 
			
		||||
                                            schema = s;
 | 
			
		||||
                                        }
 | 
			
		||||
                                        if (schema.Properties.Count > 0)
 | 
			
		||||
                                        {
 | 
			
		||||
                                            foreach (var p in schema.Properties)
 | 
			
		||||
                                            {
 | 
			
		||||
                                                bool isArray = p.Value.Type == "array";
 | 
			
		||||
                                                string type = isArray ? $"{p.Value.Items.Reference?.Id ?? p.Value.Items.Type}[]" : p.Value.Type;
 | 
			
		||||
                                                builder.Append($@"
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td>{p.Key}</td>
 | 
			
		||||
                                <td>{type}</td>
 | 
			
		||||
                                <td>{p.Value.Description}</td>
 | 
			
		||||
                            </tr>");
 | 
			
		||||
                                                if (isArray && p.Value.Items.Reference != null && model.Components.Schemas.TryGetValue(p.Value.Items.Reference.Id, out s))
 | 
			
		||||
                                                {
 | 
			
		||||
                                                    foreach (var p2 in s.Properties)
 | 
			
		||||
                                                    {
 | 
			
		||||
                                                        builder.Append($@"
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td>  {p2.Key}</td>
 | 
			
		||||
                                <td>{p2.Value.Type}</td>
 | 
			
		||||
                                <td>{p2.Value.Description}</td>
 | 
			
		||||
                            </tr>");
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else
 | 
			
		||||
                                        {
 | 
			
		||||
                                            builder.Append($@"
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td>.</td>
 | 
			
		||||
                                <td>{schema.Type}</td>
 | 
			
		||||
                                <td></td>
 | 
			
		||||
                            </tr>");
 | 
			
		||||
                                        }
 | 
			
		||||
                                        builder.Append(@"
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>");
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            builder.Append(@"
 | 
			
		||||
            </table>");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (operation.Value.Responses?.Count > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        builder.Append(@"
 | 
			
		||||
            <tr class=""bg"">
 | 
			
		||||
                <td>状态码</td>
 | 
			
		||||
                <td colspan=""4"">说明</td>
 | 
			
		||||
            </tr>");
 | 
			
		||||
                        foreach (var response in operation.Value.Responses)
 | 
			
		||||
                        {
 | 
			
		||||
                            builder.Append($@"
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>{response.Key}</td>
 | 
			
		||||
                <td colspan=""4"">{response.Value.Description}</td>
 | 
			
		||||
            </tr>");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    builder.Append(@"
 | 
			
		||||
        </table>");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            builder.Append(@"
 | 
			
		||||
        </div>");
 | 
			
		||||
        }
 | 
			
		||||
        builder.Append(@"
 | 
			
		||||
    </div>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user