Skip to content

Commit 3d2f050

Browse files
committed
重构接口文档同步,支持多项目与gRPC调用
- Swagger 配置调整,支持项目级自动同步(AutoSyncToDb) - Api 文档同步逻辑重写,改为 gRPC 方式,支持多项目并发 - 拆分并重构数据库服务、多语言中间件扩展 - 新增 gRPC 接口同步方法,完善异常与日志处理 - 优化启动流程,自动同步接口数据 - 代码结构优化,提升可维护性与扩展性
1 parent db855a6 commit 3d2f050

15 files changed

Lines changed: 222 additions & 116 deletions

File tree

src/modules/admin/ZhonTai.Admin.Core/Configs/AppConfig.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,11 +319,6 @@ public class SwaggerConfig
319319
/// 项目列表
320320
/// </summary>
321321
public List<ProjectConfig> Projects { get; set; }
322-
323-
/// <summary>
324-
/// 启用自动同步
325-
/// </summary>
326-
public bool EnableAutoSync { get; set; }
327322
}
328323

329324
/// <summary>
@@ -483,6 +478,11 @@ public class ProjectConfig
483478
/// 描述
484479
/// </summary>
485480
public string Description { get; set; }
481+
482+
/// <summary>
483+
/// 自动同步接口到数据库
484+
/// </summary>
485+
public bool AutoSyncToDb { get; set; } = false;
486486
}
487487

488488
/// <summary>

src/modules/admin/ZhonTai.Admin.Core/Db/DBServiceCollectionExtensions.cs renamed to src/modules/admin/ZhonTai.Admin.Core/Db/DBExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace ZhonTai.Admin.Core.Db;
1313
/// <summary>
1414
/// 数据库服务集合扩展
1515
/// </summary>
16-
public static class DBServiceCollectionExtensions
16+
public static class DBExtensions
1717
{
1818
/// <summary>
1919
/// 添加数据库

src/modules/admin/ZhonTai.Admin.Core/Db/DbHelper.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ void SyncDataAuditValue(object s, AuditValueEventArgs e)
492492
db.Aop.AuditValue -= SyncDataAuditValue;
493493
}
494494

495-
Console.WriteLine($"sync {dbConfig.Key} data succeed{Environment.NewLine}");
495+
Console.WriteLine($"sync {dbConfig.Key} data succeed");
496496
}
497497
catch (Exception ex)
498498
{
@@ -528,7 +528,7 @@ public static async Task GenerateDataAsync(IFreeSql db, AppConfig appConfig = nu
528528
}
529529
}
530530

531-
Console.WriteLine($"generate {dbConfig.Key} data succeed{Environment.NewLine}");
531+
Console.WriteLine($"generate {dbConfig.Key} data succeed");
532532
}
533533
catch (Exception ex)
534534
{
@@ -583,7 +583,7 @@ HostAppOptions hostAppOptions
583583
freeSqlBuilder.UseMonitorCommand(cmd => { }, (cmd, traceLog) =>
584584
{
585585
//Console.WriteLine($"{cmd.CommandText}\n{traceLog}{Environment.NewLine}");
586-
Console.WriteLine($"{cmd.CommandText}{Environment.NewLine}");
586+
Console.WriteLine($"{Environment.NewLine}{cmd.CommandText}");
587587
});
588588
}
589589

@@ -694,7 +694,7 @@ HostAppOptions hostAppOptions
694694
{
695695
MiniProfiler.Current.CustomTiming("CurdBefore", e.Sql);
696696
}
697-
Console.WriteLine($"{e.Sql}{Environment.NewLine}");
697+
Console.WriteLine($"{Environment.NewLine}{e.Sql}");
698698
};
699699
fsql.Aop.CurdAfter += (s, e) =>
700700
{

src/modules/admin/ZhonTai.Admin.Core/Db/FreeSqlDbContextExtensions.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
using ZhonTai.Admin.Core.Repositories;
2-
using FreeScheduler;
1+
using FreeScheduler;
2+
using System.Data;
33
using ZhonTai.Admin.Core.Configs;
4+
using ZhonTai.Admin.Core.Repositories;
45
using ZhonTai.Admin.Domain;
56

67
namespace ZhonTai.Admin.Core.Db;
@@ -72,9 +73,11 @@ public static void SyncSchedulerStructure(this IFreeSql that, DbConfig dbConfig,
7273

7374
if (dbConfig.SyncStructure)
7475
{
76+
Console.WriteLine($"{Environment.NewLine}sync scheduler {dbConfig.Key} {dbConfig.Type} structure started");
7577
that.CodeFirst.SyncStructure<TaskInfo>();
7678
that.CodeFirst.SyncStructure<TaskLog>();
7779
that.CodeFirst.SyncStructure<TaskInfoExt>();
80+
Console.WriteLine($"sync structure {dbConfig.Key} {dbConfig.Type} scheduler succeed");
7881
}
7982

8083
}

src/modules/admin/ZhonTai.Admin.Core/Db/FreeSqlExt.cs renamed to src/modules/admin/ZhonTai.Admin.Core/Db/FreeSqlExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ protected override Expression VisitMember(MemberExpression node)
2626
}
2727
}
2828

29-
public static class FreeSqlExt
29+
public static class FreeSqlExtensions
3030
{
3131
/// <summary>
3232
/// 执行忽略列查询

src/modules/admin/ZhonTai.Admin.Core/Extensions/ApplicationBuilderExtensions.cs renamed to src/modules/admin/ZhonTai.Admin.Core/Extensions/LocalizationExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace ZhonTai.Admin.Core.Extensions;
77

8-
public static class ApplicationBuilderExtensions
8+
public static class LocalizationExtensions
99
{
1010
/// <summary>
1111
/// 使用多语言
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using ProtoBuf;
2+
3+
namespace ZhonTai.Admin.Core.GrpcServices.Dtos;
4+
5+
/// <summary>
6+
/// 接口同步
7+
/// </summary>
8+
[ProtoContract(ImplicitFields = ImplicitFields.None)]
9+
public class ApiSyncGrpcInput
10+
{
11+
public static class Models
12+
{
13+
/// <summary>
14+
/// 接口同步模型
15+
/// </summary>
16+
[ProtoContract(ImplicitFields = ImplicitFields.None)]
17+
public class ApiSyncModel
18+
{
19+
/// <summary>
20+
/// 接口名称
21+
/// </summary>
22+
[ProtoMember(1)]
23+
public string Label { get; set; }
24+
25+
/// <summary>
26+
/// 接口地址
27+
/// </summary>
28+
[ProtoMember(2)]
29+
public string Path { get; set; }
30+
31+
/// <summary>
32+
/// 父级路径
33+
/// </summary>
34+
[ProtoMember(3)]
35+
public string ParentPath { get; set; }
36+
37+
/// <summary>
38+
/// 接口提交方法
39+
/// </summary>
40+
[ProtoMember(4)]
41+
public string HttpMethods { get; set; }
42+
}
43+
}
44+
45+
/// <summary>
46+
/// 接口同步列表
47+
/// </summary>
48+
public List<Models.ApiSyncModel> Apis { get; set; }
49+
}

src/modules/admin/ZhonTai.Admin.Core/GrpcServices/IApiGrpcService.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ namespace ZhonTai.Admin.Core.GrpcServices;
1212
public interface IApiGrpcService
1313
{
1414
Task<GrpcOutput<List<ApiGrpcOutput>>> GetApiList(CallContext context = default);
15+
16+
Task SyncAsync(ApiSyncGrpcInput input, CallContext context = default);
1517
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
using Microsoft.Extensions.Logging;
2+
using Swashbuckle.AspNetCore.Swagger;
3+
using ZhonTai.Admin.Core.Configs;
4+
using ZhonTai.Admin.Core.GrpcServices;
5+
using ZhonTai.Admin.Core.GrpcServices.Dtos;
6+
7+
namespace ZhonTai.Admin.Core.Handlers;
8+
9+
/// <summary>
10+
/// Api文档处理器
11+
/// </summary>
12+
public class ApiDocumentHandler : IApiDocumentHandler
13+
{
14+
private readonly AppConfig _appConfig;
15+
private readonly ISwaggerProvider _swaggerProvider;
16+
private readonly IApiGrpcService _apiGrpcService;
17+
private readonly ILogger<ApiDocumentHandler> _logger;
18+
19+
public ApiDocumentHandler(AppConfig appConfig, ISwaggerProvider swaggerProvider, IApiGrpcService apiGrpcService,
20+
ILogger<ApiDocumentHandler> logger)
21+
{
22+
_appConfig = appConfig;
23+
_swaggerProvider = swaggerProvider;
24+
_apiGrpcService = apiGrpcService;
25+
_logger = logger;
26+
}
27+
28+
/// <summary>
29+
/// 同步Api文档
30+
/// </summary>
31+
/// <returns></returns>
32+
public async Task SyncAsync()
33+
{
34+
var projects = _appConfig.Swagger.Projects;
35+
if (projects == null || projects.Count == 0)
36+
{
37+
return;
38+
}
39+
40+
var tasks = projects.Select(SyncProjectAsync);
41+
42+
try
43+
{
44+
await Task.WhenAll(tasks);
45+
}
46+
catch (Exception ex)
47+
{
48+
// 记录聚合异常
49+
if (ex is AggregateException aggEx)
50+
{
51+
foreach (var innerEx in aggEx.InnerExceptions)
52+
{
53+
_logger.LogError(innerEx, "API文档同步失败");
54+
}
55+
}
56+
else
57+
{
58+
_logger.LogError(ex, "API文档同步失败");
59+
}
60+
}
61+
}
62+
63+
private async Task SyncProjectAsync(ProjectConfig project)
64+
{
65+
try
66+
{
67+
if (project.AutoSyncToDb == false)
68+
{
69+
return;
70+
}
71+
72+
var apis = new List<ApiSyncGrpcInput.Models.ApiSyncModel>();
73+
var apiDocument = _swaggerProvider.GetSwagger(project.Code.ToLower());
74+
75+
apis.Add(new ApiSyncGrpcInput.Models.ApiSyncModel()
76+
{
77+
Label = project.Name,
78+
Path = project.Code.ToLower()
79+
});
80+
foreach (var tag in apiDocument.Tags)
81+
{
82+
var apiSyncDto = new ApiSyncGrpcInput.Models.ApiSyncModel()
83+
{
84+
Label = tag.Description,
85+
Path = project.Code.ToLower() + "/" + tag.Name,
86+
ParentPath = project.Code.ToLower(),
87+
};
88+
apis.Add(apiSyncDto);
89+
}
90+
91+
foreach (var path in apiDocument.Paths)
92+
{
93+
foreach (var openApiOperation in path.Value.Operations)
94+
{
95+
var apiSyncDto = new ApiSyncGrpcInput.Models.ApiSyncModel()
96+
{
97+
Path = path.Key,
98+
ParentPath = project.Code.ToLower() + "/" + openApiOperation.Value.Tags.First().Name,
99+
HttpMethods = openApiOperation.Key.Method.ToLower(),
100+
Label = openApiOperation.Value.Summary
101+
};
102+
apis.Add(apiSyncDto);
103+
}
104+
}
105+
106+
if (apis.Count == 0)
107+
{
108+
return;
109+
}
110+
111+
var apiSyncInput = new ApiSyncGrpcInput { Apis = apis };
112+
await _apiGrpcService.SyncAsync(apiSyncInput);
113+
114+
Console.WriteLine($"{project.Name}同步{apis.Count}个接口成功");
115+
}
116+
catch (Exception)
117+
{
118+
Console.WriteLine($"{project.Name}同步失败");
119+
throw;
120+
}
121+
}
122+
}

src/modules/admin/ZhonTai.Admin/Core/Handlers/IApiDocumentHandler.cs renamed to src/modules/admin/ZhonTai.Admin.Core/Handlers/IApiDocumentHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
public interface IApiDocumentHandler
44
{
55
/// <summary>
6-
/// 同步API文档数据
6+
/// 同步Api文档
77
/// </summary>
88
/// <returns></returns>
99
Task SyncAsync();

0 commit comments

Comments
 (0)