From 4cf39b4d42ef822d5ff4ccf72ccb64bbd961b9ad Mon Sep 17 00:00:00 2001
From: MSuMshk <2039814060@qq.com>
Date: Thu, 29 Jan 2026 01:57:39 +0000
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=9D=E5=A7=8B=E5=8C=96=20BuildingB?=
=?UTF-8?q?locks=20=E4=BB=93=E5=BA=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 7 +
.../Constants/DatabaseConstants.cs | 27 +++
.../Constants/ErrorCodes.cs | 47 ++++
.../Data/DatabaseConnectionRole.cs | 17 ++
.../Data/IDapperExecutor.cs | 48 +++++
.../Diagnostics/TraceContext.cs | 37 ++++
.../Entities/AuditableEntityBase.cs | 37 ++++
.../Entities/EntityBase.cs | 12 ++
.../Entities/IAuditableEntity.cs | 37 ++++
.../Entities/IMultiTenantEntity.cs | 12 ++
.../Entities/ISoftDeleteEntity.cs | 12 ++
.../Entities/MultiTenantEntityBase.cs | 12 ++
.../Exceptions/BusinessException.cs | 13 ++
.../Exceptions/ValidationException.cs | 13 ++
.../Ids/IIdGenerator.cs | 13 ++
.../Ids/IdGeneratorOptions.cs | 26 +++
.../Results/ApiResponse.NonGeneric.cs | 43 ++++
.../Results/ApiResponse.cs | 203 ++++++++++++++++++
.../Results/PagedResult.cs | 36 ++++
.../Security/ICurrentUserAccessor.cs | 17 ++
.../Serialization/SnowflakeIdJsonConverter.cs | 52 +++++
.../TakeoutSaaS.Shared.Abstractions.csproj | 13 ++
.../Tenancy/ITenantContextAccessor.cs | 12 ++
.../Tenancy/ITenantProvider.cs | 13 ++
.../Tenancy/TenantConstants.cs | 12 ++
.../Tenancy/TenantContext.cs | 38 ++++
.../Ids/SnowflakeIdGenerator.cs | 104 +++++++++
.../TakeoutSaaS.Shared.Kernel.csproj | 14 ++
.../Api/BaseApiController.cs | 15 ++
.../ApplicationBuilderExtensions.cs | 22 ++
.../Extensions/ServiceCollectionExtensions.cs | 53 +++++
.../Filters/ApiResponseResultFilter.cs | 115 ++++++++++
.../Filters/ValidateModelAttribute.cs | 33 +++
.../Middleware/CorrelationIdMiddleware.cs | 108 ++++++++++
.../Middleware/ExceptionHandlingMiddleware.cs | 139 ++++++++++++
.../Middleware/RequestLoggingMiddleware.cs | 41 ++++
.../Middleware/SecurityHeadersMiddleware.cs | 25 +++
.../Security/ClaimsPrincipalExtensions.cs | 27 +++
.../HttpContextCurrentUserAccessor.cs | 35 +++
.../Security/TenantHttpContextExtensions.cs | 31 +++
.../Swagger/ConfigureSwaggerOptions.cs | 60 ++++++
.../Swagger/SwaggerDocumentSettings.cs | 22 ++
.../Swagger/SwaggerExtensions.cs | 116 ++++++++++
.../TakeoutSaaS.Shared.Web.csproj | 30 +++
44 files changed, 1799 insertions(+)
create mode 100644 README.md
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Constants/DatabaseConstants.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Constants/ErrorCodes.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Data/DatabaseConnectionRole.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Data/IDapperExecutor.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Diagnostics/TraceContext.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Entities/AuditableEntityBase.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Entities/EntityBase.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Entities/IAuditableEntity.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Entities/IMultiTenantEntity.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Entities/ISoftDeleteEntity.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Entities/MultiTenantEntityBase.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Exceptions/BusinessException.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Exceptions/ValidationException.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Ids/IIdGenerator.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Ids/IdGeneratorOptions.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Results/ApiResponse.NonGeneric.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Results/ApiResponse.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Results/PagedResult.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Security/ICurrentUserAccessor.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Serialization/SnowflakeIdJsonConverter.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/TakeoutSaaS.Shared.Abstractions.csproj
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Tenancy/ITenantContextAccessor.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Tenancy/ITenantProvider.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Tenancy/TenantConstants.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Abstractions/Tenancy/TenantContext.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Kernel/Ids/SnowflakeIdGenerator.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Kernel/TakeoutSaaS.Shared.Kernel.csproj
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Api/BaseApiController.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Extensions/ApplicationBuilderExtensions.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Extensions/ServiceCollectionExtensions.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Filters/ApiResponseResultFilter.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Filters/ValidateModelAttribute.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Middleware/CorrelationIdMiddleware.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Middleware/ExceptionHandlingMiddleware.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Middleware/RequestLoggingMiddleware.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Middleware/SecurityHeadersMiddleware.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Security/ClaimsPrincipalExtensions.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Security/HttpContextCurrentUserAccessor.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Security/TenantHttpContextExtensions.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Swagger/ConfigureSwaggerOptions.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Swagger/SwaggerDocumentSettings.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/Swagger/SwaggerExtensions.cs
create mode 100644 src/Core/TakeoutSaaS.Shared.Web/TakeoutSaaS.Shared.Web.csproj
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..65a7544
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+# TakeoutSaaS.BuildingBlocks
+
+该仓库用于承载 TakeoutSaaS 的可复用基础组件(Building Blocks)。
+
+## 约定
+- 该仓库通常以 git submodule 的形式被 `TakeoutSaaS.AdminApi` / `TakeoutSaaS.TenantApi` 引用。
+- 共享代码不应包含租户过滤等“租户侧专属”能力。
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Constants/DatabaseConstants.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Constants/DatabaseConstants.cs
new file mode 100644
index 0000000..4e9e458
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Constants/DatabaseConstants.cs
@@ -0,0 +1,27 @@
+namespace TakeoutSaaS.Shared.Abstractions.Constants;
+
+///
+/// 数据源名称常量,统一配置键与使用说明。
+///
+public static class DatabaseConstants
+{
+ ///
+ /// 默认业务库(AppDatabase).
+ ///
+ public const string AppDataSource = "AppDatabase";
+
+ ///
+ /// 身份认证库(IdentityDatabase)。
+ ///
+ public const string IdentityDataSource = "IdentityDatabase";
+
+ ///
+ /// 字典库(DictionaryDatabase)。
+ ///
+ public const string DictionaryDataSource = "DictionaryDatabase";
+
+ ///
+ /// 日志库(LogsDatabase)。
+ ///
+ public const string LogsDataSource = "LogsDatabase";
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Constants/ErrorCodes.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Constants/ErrorCodes.cs
new file mode 100644
index 0000000..3214155
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Constants/ErrorCodes.cs
@@ -0,0 +1,47 @@
+namespace TakeoutSaaS.Shared.Abstractions.Constants;
+
+///
+/// 统一错误码常量。
+///
+public static class ErrorCodes
+{
+ ///
+ /// 请求参数错误。
+ ///
+ public const int BadRequest = 400;
+
+ ///
+ /// 未授权访问。
+ ///
+ public const int Unauthorized = 401;
+
+ ///
+ /// 权限不足。
+ ///
+ public const int Forbidden = 403;
+
+ ///
+ /// 资源未找到。
+ ///
+ public const int NotFound = 404;
+
+ ///
+ /// 资源冲突。
+ ///
+ public const int Conflict = 409;
+
+ ///
+ /// 校验失败。
+ ///
+ public const int ValidationFailed = 422;
+
+ ///
+ /// 服务器内部错误。
+ ///
+ public const int InternalServerError = 500;
+
+ ///
+ /// 业务自定义错误(10000+)。
+ ///
+ public const int BusinessError = 10001;
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Data/DatabaseConnectionRole.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Data/DatabaseConnectionRole.cs
new file mode 100644
index 0000000..175f9f6
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Data/DatabaseConnectionRole.cs
@@ -0,0 +1,17 @@
+namespace TakeoutSaaS.Shared.Abstractions.Data;
+
+///
+/// 数据库连接角色,用于区分主写与从读连接。
+///
+public enum DatabaseConnectionRole
+{
+ ///
+ /// 主写连接,用于写入或强一致读。
+ ///
+ Write = 1,
+
+ ///
+ /// 从读连接,用于只读查询或报表。
+ ///
+ Read = 2
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Data/IDapperExecutor.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Data/IDapperExecutor.cs
new file mode 100644
index 0000000..0423468
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Data/IDapperExecutor.cs
@@ -0,0 +1,48 @@
+using System.Data;
+
+namespace TakeoutSaaS.Shared.Abstractions.Data;
+
+///
+/// Dapper 查询/命令执行器抽象,封装连接获取与读写路由。
+///
+public interface IDapperExecutor
+{
+ ///
+ /// 使用指定数据源与读写角色执行异步查询,并返回结果。
+ ///
+ /// 查询结果类型。
+ /// 逻辑数据源名称。
+ /// 连接角色(读/写)。
+ /// 查询委托,提供已打开的连接和取消标记。
+ /// 取消标记。
+ /// 查询结果。
+ Task QueryAsync(
+ string dataSourceName,
+ DatabaseConnectionRole role,
+ Func> query,
+ CancellationToken cancellationToken = default);
+
+ ///
+ /// 使用指定数据源与读写角色执行异步命令。
+ ///
+ /// 逻辑数据源名称。
+ /// 连接角色(读/写)。
+ /// 命令委托,提供已打开的连接和取消标记。
+ /// 取消标记。
+ /// 异步执行任务。
+ Task ExecuteAsync(
+ string dataSourceName,
+ DatabaseConnectionRole role,
+ Func command,
+ CancellationToken cancellationToken = default);
+
+ ///
+ /// 获取指定数据源及角色的默认命令超时时间(秒)。
+ ///
+ /// 逻辑数据源名称。
+ /// 连接角色,默认读取从库。
+ /// 命令超时时间(秒)。
+ int GetDefaultCommandTimeoutSeconds(
+ string dataSourceName,
+ DatabaseConnectionRole role = DatabaseConnectionRole.Read);
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Diagnostics/TraceContext.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Diagnostics/TraceContext.cs
new file mode 100644
index 0000000..ae8284b
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Diagnostics/TraceContext.cs
@@ -0,0 +1,37 @@
+namespace TakeoutSaaS.Shared.Abstractions.Diagnostics;
+
+///
+/// 轻量级 TraceId/SpanId 上下文,便于跨层访问当前请求的追踪标识。
+///
+public static class TraceContext
+{
+ private static readonly AsyncLocal TraceIdHolder = new();
+ private static readonly AsyncLocal SpanIdHolder = new();
+
+ ///
+ /// 当前请求的 TraceId。
+ ///
+ public static string? TraceId
+ {
+ get => TraceIdHolder.Value;
+ set => TraceIdHolder.Value = value;
+ }
+
+ ///
+ /// 当前请求的 SpanId。
+ ///
+ public static string? SpanId
+ {
+ get => SpanIdHolder.Value;
+ set => SpanIdHolder.Value = value;
+ }
+
+ ///
+ /// 清理 TraceId,避免 AsyncLocal 污染其它请求。
+ ///
+ public static void Clear()
+ {
+ TraceIdHolder.Value = null;
+ SpanIdHolder.Value = null;
+ }
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/AuditableEntityBase.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/AuditableEntityBase.cs
new file mode 100644
index 0000000..6dbcf9c
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/AuditableEntityBase.cs
@@ -0,0 +1,37 @@
+namespace TakeoutSaaS.Shared.Abstractions.Entities;
+
+///
+/// 审计实体基类:提供创建、更新时间以及软删除时间。
+///
+public abstract class AuditableEntityBase : EntityBase, IAuditableEntity
+{
+ ///
+ /// 创建时间(UTC)。
+ ///
+ public DateTime CreatedAt { get; set; }
+
+ ///
+ /// 最近一次更新时间(UTC),从未更新时为 null。
+ ///
+ public DateTime? UpdatedAt { get; set; }
+
+ ///
+ /// 软删除时间(UTC),未删除时为 null。
+ ///
+ public DateTime? DeletedAt { get; set; }
+
+ ///
+ /// 创建人用户标识,匿名或系统操作时为 null。
+ ///
+ public long? CreatedBy { get; set; }
+
+ ///
+ /// 最后更新人用户标识,匿名或系统操作时为 null。
+ ///
+ public long? UpdatedBy { get; set; }
+
+ ///
+ /// 删除人用户标识(软删除),未删除时为 null。
+ ///
+ public long? DeletedBy { get; set; }
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/EntityBase.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/EntityBase.cs
new file mode 100644
index 0000000..e1e2aa4
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/EntityBase.cs
@@ -0,0 +1,12 @@
+namespace TakeoutSaaS.Shared.Abstractions.Entities;
+
+///
+/// 实体基类,统一提供主键标识。
+///
+public abstract class EntityBase
+{
+ ///
+ /// 实体唯一标识。
+ ///
+ public long Id { get; set; }
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/IAuditableEntity.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/IAuditableEntity.cs
new file mode 100644
index 0000000..844ad54
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/IAuditableEntity.cs
@@ -0,0 +1,37 @@
+namespace TakeoutSaaS.Shared.Abstractions.Entities;
+
+///
+/// 审计字段接口:提供创建、更新、删除时间与操作者标识。
+///
+public interface IAuditableEntity : ISoftDeleteEntity
+{
+ ///
+ /// 创建时间(UTC)。
+ ///
+ DateTime CreatedAt { get; set; }
+
+ ///
+ /// 更新时间(UTC),未更新时为 null。
+ ///
+ DateTime? UpdatedAt { get; set; }
+
+ ///
+ /// 删除时间(UTC),未删除时为 null。
+ ///
+ new DateTime? DeletedAt { get; set; }
+
+ ///
+ /// 创建人用户标识,匿名或系统操作时为 null。
+ ///
+ long? CreatedBy { get; set; }
+
+ ///
+ /// 最后更新人用户标识,匿名或系统操作时为 null。
+ ///
+ long? UpdatedBy { get; set; }
+
+ ///
+ /// 删除人用户标识(软删除),未删除时为 null。
+ ///
+ long? DeletedBy { get; set; }
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/IMultiTenantEntity.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/IMultiTenantEntity.cs
new file mode 100644
index 0000000..1a0fecd
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/IMultiTenantEntity.cs
@@ -0,0 +1,12 @@
+namespace TakeoutSaaS.Shared.Abstractions.Entities;
+
+///
+/// 多租户实体约定:所有持久化实体须包含租户标识字段。
+///
+public interface IMultiTenantEntity
+{
+ ///
+ /// 所属租户 ID。
+ ///
+ long TenantId { get; set; }
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/ISoftDeleteEntity.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/ISoftDeleteEntity.cs
new file mode 100644
index 0000000..4bc3fba
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/ISoftDeleteEntity.cs
@@ -0,0 +1,12 @@
+namespace TakeoutSaaS.Shared.Abstractions.Entities;
+
+///
+/// 软删除实体约定:提供可空的删除时间戳以支持全局过滤。
+///
+public interface ISoftDeleteEntity
+{
+ ///
+ /// 删除时间(UTC),未删除时为 null。
+ ///
+ DateTime? DeletedAt { get; set; }
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/MultiTenantEntityBase.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/MultiTenantEntityBase.cs
new file mode 100644
index 0000000..df6417e
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Entities/MultiTenantEntityBase.cs
@@ -0,0 +1,12 @@
+namespace TakeoutSaaS.Shared.Abstractions.Entities;
+
+///
+/// 多租户审计实体基类:提供租户标识、审计字段与软删除标记。
+///
+public abstract class MultiTenantEntityBase : AuditableEntityBase, IMultiTenantEntity
+{
+ ///
+ /// 所属租户 ID。
+ ///
+ public long TenantId { get; set; }
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Exceptions/BusinessException.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Exceptions/BusinessException.cs
new file mode 100644
index 0000000..b14dc4a
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Exceptions/BusinessException.cs
@@ -0,0 +1,13 @@
+namespace TakeoutSaaS.Shared.Abstractions.Exceptions;
+
+///
+/// 业务异常(用于可预期的业务校验错误)。
+///
+public class BusinessException(int errorCode, string message) : Exception(message)
+{
+ ///
+ /// 业务错误码。
+ ///
+ public int ErrorCode { get; } = errorCode;
+}
+
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Exceptions/ValidationException.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Exceptions/ValidationException.cs
new file mode 100644
index 0000000..f95bf0b
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Exceptions/ValidationException.cs
@@ -0,0 +1,13 @@
+namespace TakeoutSaaS.Shared.Abstractions.Exceptions;
+
+///
+/// 验证异常(用于聚合验证错误信息)。
+///
+public class ValidationException(IDictionary errors) : Exception("一个或多个验证错误")
+{
+ ///
+ /// 字段/属性的错误集合。
+ ///
+ public IDictionary Errors { get; } = errors;
+}
+
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Ids/IIdGenerator.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Ids/IIdGenerator.cs
new file mode 100644
index 0000000..ce8dff4
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Ids/IIdGenerator.cs
@@ -0,0 +1,13 @@
+namespace TakeoutSaaS.Shared.Abstractions.Ids;
+
+///
+/// 雪花 ID 生成器接口。
+///
+public interface IIdGenerator
+{
+ ///
+ /// 生成下一个唯一长整型 ID。
+ ///
+ /// 雪花 ID。
+ long NextId();
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Ids/IdGeneratorOptions.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Ids/IdGeneratorOptions.cs
new file mode 100644
index 0000000..6d9b40f
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Ids/IdGeneratorOptions.cs
@@ -0,0 +1,26 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace TakeoutSaaS.Shared.Abstractions.Ids;
+
+///
+/// 雪花 ID 生成器配置。
+///
+public sealed class IdGeneratorOptions
+{
+ ///
+ /// 配置节名称。
+ ///
+ public const string SectionName = "IdGenerator";
+
+ ///
+ /// 工作节点标识,0-31。
+ ///
+ [Range(0, 31)]
+ public int WorkerId { get; set; }
+
+ ///
+ /// 机房标识,0-31。
+ ///
+ [Range(0, 31)]
+ public int DatacenterId { get; set; }
+}
diff --git a/src/Core/TakeoutSaaS.Shared.Abstractions/Results/ApiResponse.NonGeneric.cs b/src/Core/TakeoutSaaS.Shared.Abstractions/Results/ApiResponse.NonGeneric.cs
new file mode 100644
index 0000000..04f400c
--- /dev/null
+++ b/src/Core/TakeoutSaaS.Shared.Abstractions/Results/ApiResponse.NonGeneric.cs
@@ -0,0 +1,43 @@
+namespace TakeoutSaaS.Shared.Abstractions.Results;
+
+///
+/// 非泛型便捷封装。
+///
+public static class ApiResponse
+{
+ ///
+ /// 仅返回成功消息(无数据)。
+ ///
+ /// 提示信息。
+ /// 封装后的成功响应。
+ public static ApiResponse