refactor: 管理端去租户过滤并Portal化RBAC菜单
This commit is contained in:
@@ -4,10 +4,20 @@ using TakeoutSaaS.Shared.Abstractions.Entities;
|
||||
namespace TakeoutSaaS.Domain.Identity.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 管理后台账户实体(平台管理员、租户管理员或商户员工)。
|
||||
/// 后台账户实体(按 Portal 区分平台管理员与租户后台账号)。
|
||||
/// </summary>
|
||||
public sealed class IdentityUser : MultiTenantEntityBase
|
||||
public sealed class IdentityUser : AuditableEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 账号所属 Portal。
|
||||
/// </summary>
|
||||
public PortalType Portal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属租户 ID(Portal=Tenant 时必填;Portal=Admin 时必须为空)。
|
||||
/// </summary>
|
||||
public long? TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录账号。
|
||||
/// </summary>
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
using TakeoutSaaS.Shared.Abstractions.Entities;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Identity.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 管理端菜单定义。
|
||||
/// 后台菜单定义(按 Portal 区分 Admin/Tenant 两套菜单树)。
|
||||
/// </summary>
|
||||
public sealed class MenuDefinition : MultiTenantEntityBase
|
||||
public sealed class MenuDefinition : AuditableEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 菜单所属 Portal。
|
||||
/// </summary>
|
||||
public PortalType Portal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 父级菜单 ID,根节点为 0。
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
using TakeoutSaaS.Shared.Abstractions.Entities;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Identity.Entities;
|
||||
@@ -5,8 +6,13 @@ namespace TakeoutSaaS.Domain.Identity.Entities;
|
||||
/// <summary>
|
||||
/// 权限定义。
|
||||
/// </summary>
|
||||
public sealed class Permission : MultiTenantEntityBase
|
||||
public sealed class Permission : AuditableEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 权限所属 Portal。
|
||||
/// </summary>
|
||||
public PortalType Portal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 父级权限 ID,根节点为 0。
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
using TakeoutSaaS.Shared.Abstractions.Entities;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Identity.Entities;
|
||||
@@ -5,8 +6,18 @@ namespace TakeoutSaaS.Domain.Identity.Entities;
|
||||
/// <summary>
|
||||
/// 角色定义。
|
||||
/// </summary>
|
||||
public sealed class Role : MultiTenantEntityBase
|
||||
public sealed class Role : AuditableEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色所属 Portal。
|
||||
/// </summary>
|
||||
public PortalType Portal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属租户 ID(Portal=Tenant 时必填;Portal=Admin 时必须为空)。
|
||||
/// </summary>
|
||||
public long? TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色名称。
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
using TakeoutSaaS.Shared.Abstractions.Entities;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Identity.Entities;
|
||||
@@ -5,8 +6,18 @@ namespace TakeoutSaaS.Domain.Identity.Entities;
|
||||
/// <summary>
|
||||
/// 角色-权限关系。
|
||||
/// </summary>
|
||||
public sealed class RolePermission : MultiTenantEntityBase
|
||||
public sealed class RolePermission : AuditableEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 关系所属 Portal。
|
||||
/// </summary>
|
||||
public PortalType Portal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属租户 ID(Portal=Tenant 时必填;Portal=Admin 时必须为空)。
|
||||
/// </summary>
|
||||
public long? TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色 ID。
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
using TakeoutSaaS.Shared.Abstractions.Entities;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Identity.Entities;
|
||||
@@ -5,8 +6,18 @@ namespace TakeoutSaaS.Domain.Identity.Entities;
|
||||
/// <summary>
|
||||
/// 用户-角色关系。
|
||||
/// </summary>
|
||||
public sealed class UserRole : MultiTenantEntityBase
|
||||
public sealed class UserRole : AuditableEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 关系所属 Portal。
|
||||
/// </summary>
|
||||
public PortalType Portal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属租户 ID(Portal=Tenant 时必填;Portal=Admin 时必须为空)。
|
||||
/// </summary>
|
||||
public long? TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户 ID。
|
||||
/// </summary>
|
||||
|
||||
18
src/Domain/TakeoutSaaS.Domain/Identity/Enums/PortalType.cs
Normal file
18
src/Domain/TakeoutSaaS.Domain/Identity/Enums/PortalType.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace TakeoutSaaS.Domain.Identity.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// 后台端类型(用于区分平台管理端与租户管理端)。
|
||||
/// </summary>
|
||||
public enum PortalType
|
||||
{
|
||||
/// <summary>
|
||||
/// 平台管理端(Admin)。
|
||||
/// </summary>
|
||||
Admin = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 租户管理端(Tenant)。
|
||||
/// </summary>
|
||||
Tenant = 1
|
||||
}
|
||||
|
||||
@@ -74,14 +74,6 @@ public interface IIdentityUserRepository
|
||||
/// <returns>后台用户或 null。</returns>
|
||||
Task<IdentityUser?> FindByIdAsync(long userId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 根据 ID 获取后台用户(忽略租户过滤器,仅用于只读查询)。
|
||||
/// </summary>
|
||||
/// <param name="userId">用户 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>后台用户或 null。</returns>
|
||||
Task<IdentityUser?> FindByIdIgnoringTenantAsync(long userId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 根据 ID 获取后台用户(用于更新,返回可跟踪实体)。
|
||||
/// </summary>
|
||||
@@ -90,28 +82,13 @@ public interface IIdentityUserRepository
|
||||
/// <returns>后台用户或 null。</returns>
|
||||
Task<IdentityUser?> GetForUpdateAsync(long userId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 根据 ID 获取后台用户(用于更新,忽略租户过滤器)。
|
||||
/// </summary>
|
||||
/// <remarks>用于跨租户场景(如平台生成的重置密码链接)。</remarks>
|
||||
/// <param name="userId">用户 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>后台用户或 null。</returns>
|
||||
Task<IdentityUser?> GetForUpdateIgnoringTenantAsync(long userId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 根据 ID 获取后台用户(用于更新,包含已删除数据)。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="userId">用户 ID。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>后台用户或 null。</returns>
|
||||
Task<IdentityUser?> GetForUpdateIncludingDeletedAsync(
|
||||
long tenantId,
|
||||
long userId,
|
||||
bool ignoreTenantFilter = false,
|
||||
CancellationToken cancellationToken = default);
|
||||
Task<IdentityUser?> GetForUpdateIncludingDeletedAsync(long userId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 按租户与关键字查询后台用户列表(仅读)。
|
||||
@@ -126,12 +103,10 @@ public interface IIdentityUserRepository
|
||||
/// 分页查询后台用户列表。
|
||||
/// </summary>
|
||||
/// <param name="filter">查询过滤条件。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤器。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>分页结果。</returns>
|
||||
Task<(IReadOnlyList<IdentityUser> Items, int Total)> SearchPagedAsync(
|
||||
IdentityUserSearchFilter filter,
|
||||
bool ignoreTenantFilter = false,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
@@ -149,14 +124,12 @@ public interface IIdentityUserRepository
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="userIds">用户 ID 集合。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤器。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>后台用户列表。</returns>
|
||||
Task<IReadOnlyList<IdentityUser>> GetForUpdateByIdsAsync(
|
||||
long tenantId,
|
||||
IEnumerable<long> userIds,
|
||||
bool includeDeleted,
|
||||
bool ignoreTenantFilter = false,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using TakeoutSaaS.Domain.Identity.Entities;
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Identity.Repositories;
|
||||
|
||||
@@ -8,14 +9,19 @@ namespace TakeoutSaaS.Domain.Identity.Repositories;
|
||||
public interface IMenuRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// 按租户获取菜单列表。
|
||||
/// 按 Portal 获取菜单列表。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<MenuDefinition>> GetByTenantAsync(long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
Task<IReadOnlyList<MenuDefinition>> GetByPortalAsync(PortalType portal, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 根据 ID 查询菜单。
|
||||
/// </summary>
|
||||
Task<MenuDefinition?> FindByIdAsync(long id, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="id">菜单 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
Task<MenuDefinition?> FindByIdAsync(long id, PortalType portal, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 新增菜单。
|
||||
@@ -30,7 +36,10 @@ public interface IMenuRepository
|
||||
/// <summary>
|
||||
/// 删除菜单。
|
||||
/// </summary>
|
||||
Task DeleteAsync(long id, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="id">菜单 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
Task DeleteAsync(long id, PortalType portal, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 持久化变更。
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
using TakeoutSaaS.Domain.Identity.Entities;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Identity.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// 权限仓储。
|
||||
/// 权限仓储(全局权限定义,按 Portal 区分)。
|
||||
/// </summary>
|
||||
public interface IPermissionRepository
|
||||
{
|
||||
@@ -11,46 +12,42 @@ public interface IPermissionRepository
|
||||
/// 根据 ID 查询权限。
|
||||
/// </summary>
|
||||
/// <param name="permissionId">权限 ID。</param>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>权限实体或 null。</returns>
|
||||
Task<Permission?> FindByIdAsync(long permissionId, long tenantId, CancellationToken cancellationToken = default);
|
||||
Task<Permission?> FindByIdAsync(long permissionId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 根据编码查询权限。
|
||||
/// </summary>
|
||||
/// <param name="code">权限编码。</param>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>权限实体或 null。</returns>
|
||||
Task<Permission?> FindByCodeAsync(string code, long tenantId, CancellationToken cancellationToken = default);
|
||||
Task<Permission?> FindByCodeAsync(string code, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 根据编码集合查询权限列表。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="codes">权限编码集合。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>权限集合。</returns>
|
||||
Task<IReadOnlyList<Permission>> GetByCodesAsync(long tenantId, IEnumerable<string> codes, CancellationToken cancellationToken = default);
|
||||
Task<IReadOnlyList<Permission>> GetByCodesAsync(IEnumerable<string> codes, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 根据 ID 集合查询权限列表。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="permissionIds">权限 ID 集合。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>权限集合。</returns>
|
||||
Task<IReadOnlyList<Permission>> GetByIdsAsync(long tenantId, IEnumerable<long> permissionIds, CancellationToken cancellationToken = default);
|
||||
Task<IReadOnlyList<Permission>> GetByIdsAsync(IEnumerable<long> permissionIds, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 按关键字搜索权限。
|
||||
/// 按 Portal 与关键字搜索权限。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="keyword">关键字。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>权限集合。</returns>
|
||||
Task<IReadOnlyList<Permission>> SearchAsync(long tenantId, string? keyword, CancellationToken cancellationToken = default);
|
||||
Task<IReadOnlyList<Permission>> SearchAsync(PortalType portal, string? keyword, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 新增权限。
|
||||
@@ -72,10 +69,9 @@ public interface IPermissionRepository
|
||||
/// 删除权限。
|
||||
/// </summary>
|
||||
/// <param name="permissionId">权限 ID。</param>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>异步操作任务。</returns>
|
||||
Task DeleteAsync(long permissionId, long tenantId, CancellationToken cancellationToken = default);
|
||||
Task DeleteAsync(long permissionId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 保存仓储变更。
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using TakeoutSaaS.Domain.Identity.Entities;
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Identity.Repositories;
|
||||
|
||||
@@ -10,11 +11,16 @@ public interface IRolePermissionRepository
|
||||
/// <summary>
|
||||
/// 根据角色 ID 集合获取角色权限关系。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="roleIds">角色 ID 集合。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>角色权限关系列表。</returns>
|
||||
Task<IReadOnlyList<RolePermission>> GetByRoleIdsAsync(long tenantId, IEnumerable<long> roleIds, CancellationToken cancellationToken = default);
|
||||
Task<IReadOnlyList<RolePermission>> GetByRoleIdsAsync(
|
||||
PortalType portal,
|
||||
long? tenantId,
|
||||
IEnumerable<long> roleIds,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 批量新增角色权限关系。
|
||||
@@ -27,12 +33,18 @@ public interface IRolePermissionRepository
|
||||
/// <summary>
|
||||
/// 替换角色的权限集合。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="roleId">角色 ID。</param>
|
||||
/// <param name="permissionIds">权限 ID 集合。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>异步操作任务。</returns>
|
||||
Task ReplaceRolePermissionsAsync(long tenantId, long roleId, IEnumerable<long> permissionIds, CancellationToken cancellationToken = default);
|
||||
Task ReplaceRolePermissionsAsync(
|
||||
PortalType portal,
|
||||
long? tenantId,
|
||||
long roleId,
|
||||
IEnumerable<long> permissionIds,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 提交持久化变更。
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using TakeoutSaaS.Domain.Identity.Entities;
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Identity.Repositories;
|
||||
|
||||
@@ -11,37 +12,45 @@ public interface IRoleRepository
|
||||
/// 根据 ID 查询角色。
|
||||
/// </summary>
|
||||
/// <param name="roleId">角色 ID。</param>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>角色实体或 null。</returns>
|
||||
Task<Role?> FindByIdAsync(long roleId, long tenantId, CancellationToken cancellationToken = default);
|
||||
Task<Role?> FindByIdAsync(PortalType portal, long? tenantId, long roleId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 根据编码查询角色。
|
||||
/// </summary>
|
||||
/// <param name="code">角色编码。</param>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>角色实体或 null。</returns>
|
||||
Task<Role?> FindByCodeAsync(string code, long tenantId, CancellationToken cancellationToken = default);
|
||||
Task<Role?> FindByCodeAsync(PortalType portal, long? tenantId, string code, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 批量获取角色列表。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="roleIds">角色 ID 集合。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>角色集合。</returns>
|
||||
Task<IReadOnlyList<Role>> GetByIdsAsync(long tenantId, IEnumerable<long> roleIds, CancellationToken cancellationToken = default);
|
||||
Task<IReadOnlyList<Role>> GetByIdsAsync(
|
||||
PortalType portal,
|
||||
long? tenantId,
|
||||
IEnumerable<long> roleIds,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 按关键字搜索角色。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="keyword">关键字。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>角色集合。</returns>
|
||||
Task<IReadOnlyList<Role>> SearchAsync(long tenantId, string? keyword, CancellationToken cancellationToken = default);
|
||||
Task<IReadOnlyList<Role>> SearchAsync(PortalType portal, long? tenantId, string? keyword, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 新增角色。
|
||||
@@ -63,10 +72,11 @@ public interface IRoleRepository
|
||||
/// 删除角色。
|
||||
/// </summary>
|
||||
/// <param name="roleId">角色 ID。</param>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>异步操作任务。</returns>
|
||||
Task DeleteAsync(long roleId, long tenantId, CancellationToken cancellationToken = default);
|
||||
Task DeleteAsync(PortalType portal, long? tenantId, long roleId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 保存仓储变更。
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using TakeoutSaaS.Domain.Identity.Entities;
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
|
||||
namespace TakeoutSaaS.Domain.Identity.Repositories;
|
||||
|
||||
@@ -10,39 +11,56 @@ public interface IUserRoleRepository
|
||||
/// <summary>
|
||||
/// 批量获取指定用户的角色关系。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="userIds">用户 ID 集合。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>用户角色关系集合。</returns>
|
||||
Task<IReadOnlyList<UserRole>> GetByUserIdsAsync(long tenantId, IEnumerable<long> userIds, CancellationToken cancellationToken = default);
|
||||
Task<IReadOnlyList<UserRole>> GetByUserIdsAsync(
|
||||
PortalType portal,
|
||||
long? tenantId,
|
||||
IEnumerable<long> userIds,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 获取单个用户的角色关系。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="userId">用户 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>指定用户的角色关系列表。</returns>
|
||||
Task<IReadOnlyList<UserRole>> GetByUserIdAsync(long tenantId, long userId, CancellationToken cancellationToken = default);
|
||||
Task<IReadOnlyList<UserRole>> GetByUserIdAsync(
|
||||
PortalType portal,
|
||||
long? tenantId,
|
||||
long userId,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 替换用户的角色列表。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="userId">用户 ID。</param>
|
||||
/// <param name="roleIds">角色 ID 集合。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>异步操作任务。</returns>
|
||||
Task ReplaceUserRolesAsync(long tenantId, long userId, IEnumerable<long> roleIds, CancellationToken cancellationToken = default);
|
||||
Task ReplaceUserRolesAsync(
|
||||
PortalType portal,
|
||||
long? tenantId,
|
||||
long userId,
|
||||
IEnumerable<long> roleIds,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 统计指定角色下的用户数量。
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="portal">Portal 类型。</param>
|
||||
/// <param name="tenantId">租户 ID(Portal=Tenant 必填;Portal=Admin 必须为空)。</param>
|
||||
/// <param name="roleId">角色 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>用户数量。</returns>
|
||||
Task<int> CountUsersByRoleAsync(long tenantId, long roleId, CancellationToken cancellationToken = default);
|
||||
Task<int> CountUsersByRoleAsync(PortalType portal, long? tenantId, long roleId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 提交持久化变更。
|
||||
|
||||
@@ -11,7 +11,11 @@ public interface IStoreRepository
|
||||
/// <summary>
|
||||
/// 依据标识获取门店。
|
||||
/// </summary>
|
||||
Task<Store?> FindByIdAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="tenantId">租户 ID(为空则不做租户过滤)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
Task<Store?> FindByIdAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定商户的门店列表。
|
||||
@@ -22,14 +26,14 @@ public interface IStoreRepository
|
||||
/// 按租户筛选门店列表。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<Store>> SearchAsync(
|
||||
long tenantId,
|
||||
long? tenantId,
|
||||
long? merchantId,
|
||||
StoreStatus? status,
|
||||
StoreAuditStatus? auditStatus,
|
||||
StoreBusinessStatus? businessStatus,
|
||||
StoreOwnershipType? ownershipType,
|
||||
string? keyword,
|
||||
bool ignoreTenantFilter = false,
|
||||
bool includeDeleted = false,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
@@ -51,12 +55,20 @@ public interface IStoreRepository
|
||||
/// <summary>
|
||||
/// 获取门店营业时段。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<StoreBusinessHour>> GetBusinessHoursAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="tenantId">租户 ID(为空则不做租户过滤)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
Task<IReadOnlyList<StoreBusinessHour>> GetBusinessHoursAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 获取门店费用配置。
|
||||
/// </summary>
|
||||
Task<StoreFee?> GetStoreFeeAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="tenantId">租户 ID(为空则不做租户过滤)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
Task<StoreFee?> GetStoreFeeAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 新增门店费用配置。
|
||||
@@ -71,7 +83,11 @@ public interface IStoreRepository
|
||||
/// <summary>
|
||||
/// 获取门店资质列表。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<StoreQualification>> GetQualificationsAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="tenantId">租户 ID(为空则不做租户过滤)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
Task<IReadOnlyList<StoreQualification>> GetQualificationsAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 依据标识获取门店资质。
|
||||
@@ -111,22 +127,38 @@ public interface IStoreRepository
|
||||
/// <summary>
|
||||
/// 获取门店配送区域配置。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<StoreDeliveryZone>> GetDeliveryZonesAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="tenantId">租户 ID(为空则不做租户过滤)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
Task<IReadOnlyList<StoreDeliveryZone>> GetDeliveryZonesAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 依据标识获取配送区域。
|
||||
/// </summary>
|
||||
Task<StoreDeliveryZone?> FindDeliveryZoneByIdAsync(long deliveryZoneId, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="deliveryZoneId">配送区域 ID。</param>
|
||||
/// <param name="tenantId">租户 ID(为空则不做租户过滤)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
Task<StoreDeliveryZone?> FindDeliveryZoneByIdAsync(long deliveryZoneId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 获取门店节假日配置。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<StoreHoliday>> GetHolidaysAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="tenantId">租户 ID(为空则不做租户过滤)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
Task<IReadOnlyList<StoreHoliday>> GetHolidaysAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 依据标识获取节假日配置。
|
||||
/// </summary>
|
||||
Task<StoreHoliday?> FindHolidayByIdAsync(long holidayId, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="holidayId">节假日配置 ID。</param>
|
||||
/// <param name="tenantId">租户 ID(为空则不做租户过滤)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
Task<StoreHoliday?> FindHolidayByIdAsync(long holidayId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 获取门店桌台区域。
|
||||
@@ -276,12 +308,18 @@ public interface IStoreRepository
|
||||
/// <summary>
|
||||
/// 删除配送区域。
|
||||
/// </summary>
|
||||
Task DeleteDeliveryZoneAsync(long deliveryZoneId, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="deliveryZoneId">配送区域 ID。</param>
|
||||
/// <param name="tenantId">租户 ID(为空则不做租户过滤)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
Task DeleteDeliveryZoneAsync(long deliveryZoneId, long? tenantId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 删除节假日。
|
||||
/// </summary>
|
||||
Task DeleteHolidayAsync(long holidayId, long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <param name="holidayId">节假日配置 ID。</param>
|
||||
/// <param name="tenantId">租户 ID(为空则不做租户过滤)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
Task DeleteHolidayAsync(long holidayId, long? tenantId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 删除桌台区域。
|
||||
|
||||
@@ -15,60 +15,60 @@ public interface ISubscriptionRepository
|
||||
/// </summary>
|
||||
/// <param name="subscriptionId">订阅 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤(用于平台级查询/任务)。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <returns>订阅实体,未找到返回 null。</returns>
|
||||
Task<TenantSubscription?> FindByIdAsync(
|
||||
long subscriptionId,
|
||||
CancellationToken cancellationToken = default,
|
||||
bool ignoreTenantFilter = false);
|
||||
bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 按 ID 列表批量查询订阅。
|
||||
/// </summary>
|
||||
/// <param name="subscriptionIds">订阅 ID 列表。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤(用于平台级查询/任务)。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <returns>订阅实体列表。</returns>
|
||||
Task<IReadOnlyList<TenantSubscription>> FindByIdsAsync(
|
||||
IEnumerable<long> subscriptionIds,
|
||||
CancellationToken cancellationToken = default,
|
||||
bool ignoreTenantFilter = false);
|
||||
bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询订阅列表(含关联信息)。
|
||||
/// </summary>
|
||||
/// <param name="filter">查询过滤条件。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤(用于平台级查询/任务)。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <returns>分页结果。</returns>
|
||||
Task<(IReadOnlyList<SubscriptionWithRelations> Items, int Total)> SearchPagedAsync(
|
||||
SubscriptionSearchFilter filter,
|
||||
CancellationToken cancellationToken = default,
|
||||
bool ignoreTenantFilter = false);
|
||||
bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 获取订阅详情(含关联信息)。
|
||||
/// </summary>
|
||||
/// <param name="subscriptionId">订阅 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤(用于平台级查询/任务)。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <returns>订阅详情信息。</returns>
|
||||
Task<SubscriptionDetailInfo?> GetDetailAsync(
|
||||
long subscriptionId,
|
||||
CancellationToken cancellationToken = default,
|
||||
bool ignoreTenantFilter = false);
|
||||
bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 按 ID 列表批量查询订阅(含租户信息)。
|
||||
/// </summary>
|
||||
/// <param name="subscriptionIds">订阅 ID 列表。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤(用于平台级查询/任务)。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <returns>订阅与租户信息列表。</returns>
|
||||
Task<IReadOnlyList<SubscriptionWithTenant>> FindByIdsWithTenantAsync(
|
||||
IEnumerable<long> subscriptionIds,
|
||||
CancellationToken cancellationToken = default,
|
||||
bool ignoreTenantFilter = false);
|
||||
bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 查询自动续费候选订阅(活跃 + 开启自动续费 + 即将到期)。
|
||||
@@ -76,13 +76,13 @@ public interface ISubscriptionRepository
|
||||
/// <param name="now">当前时间(UTC)。</param>
|
||||
/// <param name="renewalThreshold">续费阈值时间(UTC),到期时间小于等于该时间视为候选。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤(用于平台级查询/任务)。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <returns>候选订阅集合(含套餐信息)。</returns>
|
||||
Task<IReadOnlyList<AutoRenewalCandidate>> FindAutoRenewalCandidatesAsync(
|
||||
DateTime now,
|
||||
DateTime renewalThreshold,
|
||||
CancellationToken cancellationToken = default,
|
||||
bool ignoreTenantFilter = false);
|
||||
bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 查询续费提醒候选订阅(活跃 + 未开启自动续费 + 到期时间落在指定日期范围)。
|
||||
@@ -90,25 +90,25 @@ public interface ISubscriptionRepository
|
||||
/// <param name="startOfDay">筛选开始时间(UTC,含)。</param>
|
||||
/// <param name="endOfDay">筛选结束时间(UTC,不含)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤(用于平台级查询/任务)。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <returns>候选订阅集合(含租户与套餐信息)。</returns>
|
||||
Task<IReadOnlyList<RenewalReminderCandidate>> FindRenewalReminderCandidatesAsync(
|
||||
DateTime startOfDay,
|
||||
DateTime endOfDay,
|
||||
CancellationToken cancellationToken = default,
|
||||
bool ignoreTenantFilter = false);
|
||||
bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 查询已到期仍处于 Active 的订阅(用于进入宽限期)。
|
||||
/// </summary>
|
||||
/// <param name="now">当前时间(UTC)。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤(用于平台级查询/任务)。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <returns>到期订阅集合。</returns>
|
||||
Task<IReadOnlyList<TenantSubscription>> FindExpiredActiveSubscriptionsAsync(
|
||||
DateTime now,
|
||||
CancellationToken cancellationToken = default,
|
||||
bool ignoreTenantFilter = false);
|
||||
bool includeDeleted = false);
|
||||
|
||||
/// <summary>
|
||||
/// 查询宽限期已结束的订阅(用于自动暂停)。
|
||||
@@ -116,13 +116,13 @@ public interface ISubscriptionRepository
|
||||
/// <param name="now">当前时间(UTC)。</param>
|
||||
/// <param name="gracePeriodDays">宽限期天数。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤(用于平台级查询/任务)。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <returns>宽限期到期订阅集合。</returns>
|
||||
Task<IReadOnlyList<TenantSubscription>> FindGracePeriodExpiredSubscriptionsAsync(
|
||||
DateTime now,
|
||||
int gracePeriodDays,
|
||||
CancellationToken cancellationToken = default,
|
||||
bool ignoreTenantFilter = false);
|
||||
bool includeDeleted = false);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -177,12 +177,12 @@ public interface ISubscriptionRepository
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <param name="ignoreTenantFilter">是否忽略租户过滤(用于平台级查询/任务)。</param>
|
||||
/// <param name="includeDeleted">是否包含已删除数据。</param>
|
||||
/// <returns>配额使用列表。</returns>
|
||||
Task<IReadOnlyList<TenantQuotaUsage>> GetQuotaUsagesAsync(
|
||||
long tenantId,
|
||||
CancellationToken cancellationToken = default,
|
||||
bool ignoreTenantFilter = false);
|
||||
bool includeDeleted = false);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
Reference in New Issue
Block a user