PartnerScopeHelper.cs
4.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
using FoodLabeling.Application.Services.DbModels;
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);
}
if (ids.Count == 1)
{
var single = ids[0];
return query.Where(x => x.Id == single);
}
return query.In(x => x.Id, ids.ToList());
}
/// <summary>
/// 组织(fl_group)数据范围(供 auth-scope 等复用);列表请优先用 <see cref="GroupListScopeHelper"/>。
/// </summary>
public sealed class GroupScopeFilter
{
public bool IsUnrestricted { get; init; }
public IReadOnlyList<string> AllowedGroupIds { get; init; } = Array.Empty<string>();
}
/// <summary>
/// 解析当前登录用户可查询的组织 Id 范围。
/// </summary>
public static async Task<GroupScopeFilter> ResolveGroupScopeAsync(
ICurrentUser currentUser,
ISqlSugarDbContext dbContext)
{
var scope = await GroupListScopeHelper.ResolveAsync(currentUser, dbContext);
if (scope.IsUnrestricted)
{
return new GroupScopeFilter { IsUnrestricted = true };
}
if (scope.AllowedPartnerIds.Count > 0)
{
var db = dbContext.SqlSugarClient;
var groupIds = await LocationScopeBindingHelper.ResolveGroupIdsFromPartnerIdsAsync(
db, scope.AllowedPartnerIds);
return new GroupScopeFilter { AllowedGroupIds = groupIds };
}
return new GroupScopeFilter { AllowedGroupIds = scope.AllowedGroupIds.ToList() };
}
/// <summary>
/// 将组织数据范围应用到 fl_group 单表查询。
/// </summary>
public static ISugarQueryable<FlGroupDbEntity> ApplyGroupScope(
ISugarQueryable<FlGroupDbEntity> query,
GroupScopeFilter scope) =>
GroupListScopeHelper.ApplyToQuery(query, GroupListScopeHelper.FromGroupScopeFilter(scope));
/// <summary>
/// 将组织数据范围应用到 fl_group 联表查询。
/// </summary>
public static ISugarQueryable<FlGroupDbEntity, FlPartnerDbEntity> ApplyGroupScope(
ISugarQueryable<FlGroupDbEntity, FlPartnerDbEntity> query,
GroupScopeFilter scope)
{
if (scope.IsUnrestricted)
{
return query;
}
var ids = scope.AllowedGroupIds
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => x.Trim())
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
if (ids.Count == 0)
{
return query.Where((g, p) => false);
}
if (ids.Count == 1)
{
var single = ids[0];
return query.Where((g, p) => g.Id == single);
}
return query.In((g, p) => g.Id, ids);
}
}