Compare commits

...

2 Commits

Author SHA1 Message Date
551ac09f78 feat:升级框架总线
All checks were successful
Build and Deploy / deploy (push) Successful in 1m6s
2026-10-13 15:20:53 +08:00
cf77ffe943 Merge remote-tracking branch 'prod/test' into test 2026-10-13 10:54:45 +08:00
11 changed files with 92 additions and 232 deletions

View File

@ -1,6 +1,8 @@
<Project>
<Import Project="Fake.Local.EventBus.props" Condition="Exists('Fake.Local.EventBus.props')" />
<PropertyGroup>
<!-- All Fake packages -->
<FakePackageVersion>8.0.5.20</FakePackageVersion>
<FakePackageVersion>8.0.5.21</FakePackageVersion>
</PropertyGroup>
</Project>

13
Fake.Local.EventBus.props Normal file
View File

@ -0,0 +1,13 @@
<Project>
<!--
本地调试 Fake 框架模块:不发包,直接工程引用。
切回 NuGet:UseLocalFakeEventBus / UseLocalFakeModules = false
-->
<PropertyGroup>
<FakeRepoRoot Condition="'$(FakeRepoRoot)' == ''">C:\Users\BSI\RiderProjects\fake2</FakeRepoRoot>
<!-- EventBus / Dashboard / IntegrationEventLog -->
<UseLocalFakeEventBus Condition="'$(UseLocalFakeEventBus)' == ''">false</UseLocalFakeEventBus>
<!-- RBAC / FileManagement(表前缀 fk_ 等框架改动需同源) -->
<UseLocalFakeModules Condition="'$(UseLocalFakeModules)' == ''">false</UseLocalFakeModules>
</PropertyGroup>
</Project>

View File

@ -16,6 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "items", "items", "{BE5132AD
db.sql = db.sql
Directory.Build.props = Directory.Build.props
.gitea\workflows\deploy.yml = .gitea\workflows\deploy.yml
Fake.Local.EventBus.props = Fake.Local.EventBus.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleAdmin.Api", "src\SimpleAdmin.Api\SimpleAdmin.Api.csproj", "{229ED167-9ECC-4736-8DFB-522EEA8FF680}"

View File

@ -18,13 +18,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fake.EventBus.IntegrationEventLog" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.EventBus.RabbitMQ" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.ObjectMapping.AutoMapper" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.ObjectStorage" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.RabbitMQ" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.Rbac.Application" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.Rbac.Infrastructure" Version="$(FakePackageVersion)" />
<PackageReference Include="DocumentFormat.OpenXml" Version="3.0.2" />
<PackageReference Include="FreeRedis" Version="1.5.5" />
<PackageReference Include="MailKit" Version="4.17.0" />
@ -35,6 +30,29 @@
<PackageReference Include="ZXing.Net.Bindings.ImageSharp.V3" Version="0.16.15" />
</ItemGroup>
<!-- EventBus / RabbitMQ:本地工程引用(调试) / NuGet(发包后) -->
<ItemGroup Condition="'$(UseLocalFakeEventBus)' == 'true'">
<ProjectReference Include="$(FakeRepoRoot)\src\Fake.EventBus\Fake.EventBus.csproj" />
<ProjectReference Include="$(FakeRepoRoot)\src\Fake.EventBus.RabbitMQ\Fake.EventBus.RabbitMQ.csproj" />
<ProjectReference Include="$(FakeRepoRoot)\src\Fake.EventBus.IntegrationEventLog\Fake.EventBus.IntegrationEventLog.csproj" />
<ProjectReference Include="$(FakeRepoRoot)\src\Fake.RabbitMQ\Fake.RabbitMQ.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(UseLocalFakeEventBus)' != 'true'">
<PackageReference Include="Fake.EventBus.IntegrationEventLog" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.EventBus.RabbitMQ" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.RabbitMQ" Version="$(FakePackageVersion)" />
</ItemGroup>
<!-- RBAC:本地工程(表前缀) / NuGet -->
<ItemGroup Condition="'$(UseLocalFakeModules)' == 'true'">
<ProjectReference Include="$(FakeRepoRoot)\modules\rbac\Fake.Rbac.Application\Fake.Rbac.Application.csproj" />
<ProjectReference Include="$(FakeRepoRoot)\modules\rbac\Fake.Rbac.Infrastructure\Fake.Rbac.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(UseLocalFakeModules)' != 'true'">
<PackageReference Include="Fake.Rbac.Application" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.Rbac.Infrastructure" Version="$(FakePackageVersion)" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Oms.Tests" />
</ItemGroup>

View File

@ -14,8 +14,18 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Fake.Autofac" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.EventBus.IntegrationEventLog" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.Testing" Version="$(FakePackageVersion)" />
</ItemGroup>
<!-- EventBus:与 Oms.Application / SimpleAdmin.Api 保持一致(本地工程或 NuGet) -->
<ItemGroup Condition="'$(UseLocalFakeEventBus)' == 'true'">
<ProjectReference Include="$(FakeRepoRoot)\src\Fake.EventBus.IntegrationEventLog\Fake.EventBus.IntegrationEventLog.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(UseLocalFakeEventBus)' != 'true'">
<PackageReference Include="Fake.EventBus.IntegrationEventLog" Version="$(FakePackageVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="8.7.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.11" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />

View File

@ -1,10 +1,16 @@
using Fake.EntityFrameworkCore;
using Serilog;
using SimpleAdmin.Api;
var builder = WebApplication.CreateSlimBuilder(args);
var configuration = builder.Configuration;
builder.Configuration.AddConsul("idwms/common", source => source.ReloadOnChange = true);
builder.Configuration.AddConsul("idwms/admin", source => source.ReloadOnChange = true);
var prefix = builder.Environment.EnvironmentName == "Development" ? "dev" : "idwms";
builder.Configuration.AddConsul($"{prefix}/common", source => source.ReloadOnChange = true);
builder.Configuration.AddConsul($"{prefix}/admin", source => source.ReloadOnChange = true);
// Fake 框架表前缀(默认 fk_):须在 AddApplication / Migrate 之前生效
FakeDbProperties.Configure(configuration[FakeDbProperties.TablePrefixConfigurationKey]);
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();

View File

@ -15,15 +15,35 @@
<ItemGroup>
<PackageReference Include="Fake.Autofac" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.Consul" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.EventBus.IntegrationEventLog" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.FileManagement.Application" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.FileManagement.Infrastructure" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.ObjectStorage.TencentCos" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.Rbac.Application" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.Serilog" Version="$(FakePackageVersion)" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
</ItemGroup>
<!-- EventBus:本地工程引用(调试) / NuGet(发包后) -->
<ItemGroup Condition="'$(UseLocalFakeEventBus)' == 'true'">
<ProjectReference Include="$(FakeRepoRoot)\src\Fake.EventBus\Fake.EventBus.csproj" />
<ProjectReference Include="$(FakeRepoRoot)\src\Fake.EventBus.IntegrationEventLog\Fake.EventBus.IntegrationEventLog.csproj" />
<ProjectReference Include="$(FakeRepoRoot)\src\Fake.EventBus.Dashboard\Fake.EventBus.Dashboard.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(UseLocalFakeEventBus)' != 'true'">
<PackageReference Include="Fake.EventBus.IntegrationEventLog" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.EventBus.Dashboard" Version="$(FakePackageVersion)" />
</ItemGroup>
<!-- RBAC / FileManagement:本地工程(表前缀 fk_ 等) / NuGet -->
<ItemGroup Condition="'$(UseLocalFakeModules)' == 'true'">
<ProjectReference Include="$(FakeRepoRoot)\modules\rbac\Fake.Rbac.Application\Fake.Rbac.Application.csproj" />
<ProjectReference Include="$(FakeRepoRoot)\modules\rbac\Fake.Rbac.Infrastructure\Fake.Rbac.Infrastructure.csproj" />
<ProjectReference Include="$(FakeRepoRoot)\modules\file-management\Fake.FileManagement.Application\Fake.FileManagement.Application.csproj" />
<ProjectReference Include="$(FakeRepoRoot)\modules\file-management\Fake.FileManagement.Infrastructure\Fake.FileManagement.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(UseLocalFakeModules)' != 'true'">
<PackageReference Include="Fake.FileManagement.Application" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.FileManagement.Infrastructure" Version="$(FakePackageVersion)" />
<PackageReference Include="Fake.Rbac.Application" Version="$(FakePackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Oms.Application\Oms.Application.csproj" />
<ProjectReference Include="..\Oms.SqlSugarCore\Oms.SqlSugarCore.csproj" />

View File

@ -7,6 +7,7 @@ using Fake.AspNetCore.Auditing;
using Fake.AspNetCore.ExceptionHandling;
using Fake.AspNetCore.Newtonsoft;
using Fake.AspNetCore.Swagger;
using Fake.EventBus.Dashboard;
using Fake.EventBus.IntegrationEventLog;
using Fake.FeiShu;
using Fake.FileManagement.Application;
@ -40,6 +41,8 @@ namespace SimpleAdmin.Api;
typeof(FakeObjectStorageTencentCosModule),
// 在 RabbitMQ 物理总线之后 Replace IDistributedEventBus → Outbox
typeof(FakeEventBusIntegrationEventLogModule),
// 独立 EventBus Dashboard(本地工程引用调试;默认 /eventbus)
typeof(FakeEventBusDashboardModule),
typeof(FakeAspNetCoreModule),
typeof(FakeSerilogModule)
)]
@ -184,6 +187,9 @@ public class SimpleAdminApiModule : FakeModule
// 路由 - 必须在认证和授权之前
app.UseRouting();
// EventBus Dashboard(CAP 风格;也可依赖 IStartupFilter 自动挂载,这里显式保证顺序)
app.UseFakeEventBusDashboard();
// OpenAPI 验签需读取原始 Body,允许二次读流
app.Use(async (ctx, next) =>
{
@ -205,16 +211,6 @@ public class SimpleAdminApiModule : FakeModule
// 端点映射
app.MapControllers();
// FileManagement / Outbox 与业务同库并行(EF)
using (var scope = app.Services.CreateScope())
{
var fileDb = scope.ServiceProvider.GetRequiredService<FileManagementDbContext>();
fileDb.Database.Migrate();
var outboxDb = scope.ServiceProvider.GetRequiredService<IntegrationEventLogContext>();
IntegrationEventLogSchema.EnsureTablesAsync(outboxDb).GetAwaiter().GetResult();
}
app.Services.GetRequiredService<IFeiShuNotificationService>().Send("Application started");
}
}

View File

@ -1,48 +0,0 @@
using Fake.EventBus.IntegrationEventLog;
using Microsoft.EntityFrameworkCore;
namespace SimpleAdmin.Api.Storage;
/// <summary>
/// Outbox/Inbox 与业务同库时 EnsureCreated 无效(库已存在),用 IF NOT EXISTS 建表。
/// </summary>
internal static class IntegrationEventLogSchema
{
public static async Task EnsureTablesAsync(
IntegrationEventLogContext db,
CancellationToken cancellationToken = default)
{
await db.Database.ExecuteSqlRawAsync(
"""
CREATE TABLE IF NOT EXISTS `OutboxEventLog` (
`EventId` char(36) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
`EventTypeName` varchar(512) NOT NULL,
`State` int NOT NULL,
`TimesSent` int NOT NULL,
`CreationTime` datetime(6) NOT NULL,
`Content` longtext NOT NULL,
`TransactionId` varchar(64) NOT NULL,
`LockExpiresAt` datetime(6) NULL,
PRIMARY KEY (`EventId`),
KEY `IX_OutboxEventLog_State_CreationTime` (`State`, `CreationTime`),
KEY `IX_OutboxEventLog_TransactionId` (`TransactionId`)
) CHARACTER SET utf8mb4;
""",
cancellationToken);
await db.Database.ExecuteSqlRawAsync(
"""
CREATE TABLE IF NOT EXISTS `InboxEventLog` (
`EventId` char(36) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
`EventTypeName` varchar(512) NOT NULL,
`State` int NOT NULL,
`ProcessedTime` datetime(6) NOT NULL,
`Content` longtext NOT NULL,
`ErrorMessage` longtext NULL,
PRIMARY KEY (`EventId`),
KEY `IX_InboxEventLog_ProcessedTime` (`ProcessedTime`)
) CHARACTER SET utf8mb4;
""",
cancellationToken);
}
}

View File

@ -1,158 +0,0 @@
{
"UseLocalConfigs": false,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.EntityFrameworkCore": "Information"
}
},
"ConnectionStrings": {
"Default": "Server=127.0.0.1;Port=3306;Database=oms;Uid=root;Pwd=你的密码;CharSet=utf8mb4;"
},
"App": {
"Urls": ["http://localhost:5281"],
"CorsOrigins": [
"http://localhost:5173",
"http://localhost:5281",
"https://oms.nanafa.com",
"http://oms.nanafa.com"
],
"SendStartupNotification": false
},
"Jwt": {
"SecretKey": "local-dev-secret-key-change-me",
"Issuer": "SimpleAdmin.Api",
"Audience": "SimpleAdmin.Api",
"ExpiryInMinutes": "480",
"RefreshExpiryInDays": "7",
"ClockSkewMinutes": "5"
},
"JwtSettings": {
"SecretKey": "local-dev-secret-key-change-me",
"Issuer": "SimpleAdmin.Api",
"Audience": "SimpleAdmin.Api",
"ExpiryInMinutes": "480",
"RefreshExpiryInDays": "7",
"ClockSkewMinutes": "5"
},
"FeiShuNotice": {
"Webhook": "https://example.com/webhook",
"EnableFeiShuExceptionSubscribe": false
},
"Redis": {
"Host": "127.0.0.1:6379",
"Password": "",
"Database": 0,
"MaxPoolSize": 50,
"MinPoolSize": 1,
"IdleTimeout": 20000,
"ConnectTimeout": 5000
},
"WeChat": {
"Mp": {
"AppId": "wxfffea62e089ee15f",
"Secret": "379f51a89419dc36fbb9167feef6f89a",
"Token": "c6ca74013df823c0e1da0feaaaf8bf66",
"EncodingAesKey": "",
"OAuthRedirectBase": "https://oms.nanafa.com",
"FollowUrl": ""
}
},
"ObjectStorage": {
"Provider": "Local",
"KeyPrefix": "",
"SignUrlsByDefault": true,
"DefaultSignedUrlExpiresSeconds": 3600,
"DefaultUploadExpiresSeconds": 600,
"Local": {
"BasePath": "wwwroot",
"BaseUrl": ""
},
"TencentCos": {
"SecretId": "",
"SecretKey": "",
"Region": "ap-guangzhou",
"Bucket": "your-bucket-1250000000",
"BaseUrl": "",
"SignUrls": true,
"UseHttps": true,
"DurationSecond": 600
}
},
"FileManagement": {
"SignUrlsByDefault": true,
"DefaultSignedUrlExpiresSeconds": 3600,
"DefaultMaxSizeBytes": 20971520,
"DefaultStorageSource": "default"
},
"Oms": {
"TrackService": {
"Enabled": true,
"BaseUrl": "http://api.nanafa.com/track",
"AppKey": "W2606001",
"AppSecret": "ziK8UzlQ39m3kdL346XEBg8nljY8os52",
"TimeoutSeconds": 30
},
"Itfx": {
"BaseUrl": "http://api.nanafa.com/itfx",
"TimeoutSeconds": 30,
"Customs9610StandardCode": "customs9610Declare",
"Customs9610ManifestStandardCode": "customs9610Manifest",
"Customs9610DeclarationFormStandardCode": "customs9610DeclarationForm"
},
"PlatformShop": {
"FrontendBaseUrl": "http://localhost:5173",
"Lazada": {
"AppKey": "123631",
"AppSecret": "7vBz2EaD6rIupeGEfwrgkabsTNsXt2ix",
"AuthorizeUrl": "https://auth.lazada.com/oauth/authorize",
"AccessTokenUrl": "https://auth.lazada.com/rest"
},
"Shopee": {
"PartnerId": 2004112,
"PartnerKey": "2f385d7ea38b087d5d71f7292e06a09c9f19022ca6c3f60ec0110a8214ef7d65",
"HostUrl": "https://openplatform.shopee.cn",
"HostAuthUrl": "https://partner.shopeemobile.com"
},
"Tiktok": {
"AppKey": "6hc64lc6vl312",
"AppSecret": "5a691a96ee6d844534769bab5c21de1f848fb678",
"HostAuth": "https://auth.tiktok-shops.com",
"HostApi": "https://open-api.tiktokglobalshop.com"
},
"Temu": {
"AppKey": "4ebbc9190ae410443d65b4c2faca981f",
"AppSecret": "4782d2d827276688bf4758bed55dbdd4bbe79a79",
"HostAuthUrl": "https://openapi-b-us.temu.com/openapi/router"
}
}
},
"RabbitMQ": {
"Connections": {
"Default": {
"HostName": "127.0.0.1",
"Port": 5672,
"UserName": "oms",
"Password": "oms123"
}
},
"EventBus": {
"QueueName": "nanafa.oms",
"RetryCount": 5
}
},
"OrderBatch": {
"RabbitMq": {
"Enabled": false
}
},
"IntegrationEventLog": {
"OutboxPublisher": {
"StartupDelay": "00:00:05",
"ScanInterval": "00:00:10",
"BatchSize": 100,
"MaxDegreeOfParallelism": 8
}
}
}

View File

@ -1,7 +1,7 @@
{
"UseLocalConfigs": false,
"Consul": {
"Address": "https://consul.nanafa.com",
"Token": "97217125-df0b-5c0a-dbfc-8885def5e471"
"Address": "http://test.ideship.com:30850",
"Token": "c0aea902-dca0-ac29-299b-a0d47e5402aa"
}
}