PartnerScopeHelper.cs 4.33 KB
using FoodLabeling.Application.Services.DbModels;
using FoodLabeling.Domain.Entities;
using SqlSugar;
using Volo.Abp.Users;
using Yi.Framework.SqlSugarCore.Abstractions;

namespace FoodLabeling.Application.Helpers;

/// <summary>
/// 合作伙伴(公司)数据范围:管理员可见全部;非管理员仅可见其 <c>userlocation</c> 绑定门店所属公司。
/// </summary>
public static class PartnerScopeHelper
{
    /// <summary>
    /// <see cref="IsUnrestricted"/> 为 true 时不限制;
    /// 否则仅 <see cref="AllowedPartnerIds"/> 中的公司 Id(<c>fl_partner.Id</c>)可见;无绑定时为空列表。
    /// </summary>
    public sealed class PartnerScopeFilter
    {
        public bool IsUnrestricted { get; init; }

        public IReadOnlyList<string> AllowedPartnerIds { get; init; } = Array.Empty<string>();
    }

    /// <summary>
    /// 解析当前登录用户可查询的合作伙伴 Id 范围。
    /// </summary>
    public static async Task<PartnerScopeFilter> ResolvePartnerScopeAsync(
        ICurrentUser currentUser,
        ISqlSugarDbContext dbContext)
    {
        if (ReportsRoleHelper.IsAdminRole(currentUser))
        {
            return new PartnerScopeFilter { IsUnrestricted = true };
        }

        if (currentUser.Id is null)
        {
            return new PartnerScopeFilter();
        }

        var db = dbContext.SqlSugarClient;
        var locationIds = await LocationScopeBindingHelper.ResolveBoundLocationIdsForUserAsync(
            db, currentUser.Id.Value);
        if (locationIds.Count == 0)
        {
            return new PartnerScopeFilter();
        }

        var allowedIds = await LocationScopeBindingHelper.ResolvePartnerIdsFromLocationIdsAsync(
            db, locationIds);
        return new PartnerScopeFilter { AllowedPartnerIds = allowedIds };
    }

    /// <summary>
    /// 将数据范围应用到合作伙伴查询(须在其它 Where 之前或之后均可,建议在 IsDeleted 之后)。
    /// </summary>
    public static ISugarQueryable<FlPartnerDbEntity> ApplyPartnerScope(
        ISugarQueryable<FlPartnerDbEntity> query,
        PartnerScopeFilter scope)
    {
        if (scope.IsUnrestricted)
        {
            return query;
        }

        var ids = scope.AllowedPartnerIds;
        if (ids.Count == 0)
        {
            return query.Where(_ => false);
        }

        return query.Where(x => ids.Contains(x.Id));
    }

    /// <summary>
    /// 组织(fl_group)数据范围:管理员可见全部;Company Admin 可见绑定公司下全部 Region(与 Team Member 详情 <c>regionIds</c> 一致);
    /// 其它非管理员仅可见其绑定门店反推的 Region。
    /// </summary>
    public sealed class GroupScopeFilter
    {
        public bool IsUnrestricted { get; init; }

        public IReadOnlyList<string> AllowedGroupIds { get; init; } = Array.Empty<string>();
    }

    /// <summary>
    /// 解析当前登录用户可查询的组织 Id 范围(与 Team Member 编辑回显 <c>regionIds</c>/<c>groupIds</c> 对齐)。
    /// </summary>
    public static async Task<GroupScopeFilter> ResolveGroupScopeAsync(
        ICurrentUser currentUser,
        ISqlSugarDbContext dbContext)
    {
        if (ReportsRoleHelper.IsAdminRole(currentUser))
        {
            return new GroupScopeFilter { IsUnrestricted = true };
        }

        if (currentUser.Id is null)
        {
            return new GroupScopeFilter();
        }

        var regionIds = await LocationScopeBindingHelper.ResolveDisplayRegionIdsForCurrentUserAsync(
            dbContext.SqlSugarClient, currentUser);

        return new GroupScopeFilter { AllowedGroupIds = regionIds };
    }

    /// <summary>
    /// 将组织数据范围应用到 fl_group 联表查询。
    /// </summary>
    public static ISugarQueryable<FlGroupDbEntity, FlPartnerDbEntity> ApplyGroupScope(
        ISugarQueryable<FlGroupDbEntity, FlPartnerDbEntity> query,
        GroupScopeFilter scope)
    {
        if (scope.IsUnrestricted)
        {
            return query;
        }

        var allowedGuids = TeamMemberListScopeHelper.ParseGuidHashSet(scope.AllowedGroupIds);
        if (allowedGuids.Count == 0)
        {
            return query.Where((g, p) => false);
        }

        var guidList = allowedGuids.ToList();
        return query.Where((g, p) => guidList.Contains(SqlFunc.ToGuid(g.Id)));
    }
}