TeamMemberRoleHelper.cs
5.45 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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
using SqlSugar;
using Volo.Abp.Users;
using Yi.Framework.Rbac.Domain.Shared.Consts;
namespace FoodLabeling.Application.Helpers;
/// <summary>
/// Team Member 角色识别(Company Admin / Partner Admin 等)。
/// </summary>
public static class TeamMemberRoleHelper
{
/// <summary>
/// UI 展示为 Company Admin,库内常见为 Partner Admin 或 RoleCode 含 partner / CompanyAdmin。
/// </summary>
public static bool IsCompanyAdminRoleName(string? roleName)
{
if (string.IsNullOrWhiteSpace(roleName))
{
return false;
}
if (IsCompanyAdminRoleToken(roleName))
{
return true;
}
var name = roleName.Trim();
if (string.Equals(name, "Company Admin", StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (string.Equals(name, "Partner Admin", StringComparison.OrdinalIgnoreCase))
{
return true;
}
return name.Contains("partner", StringComparison.OrdinalIgnoreCase) &&
name.Contains("admin", StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// 当前登录用户是否为 Company Admin 类角色(JWT 声明 + 库内 Role)。
/// </summary>
public static async Task<bool> IsCompanyAdminUserAsync(ISqlSugarClient db, ICurrentUser currentUser)
{
if (IsCompanyAdminFromClaims(currentUser))
{
return true;
}
if (currentUser.Id is null)
{
return false;
}
return await IsCompanyAdminUserAsync(db, currentUser.Id.Value);
}
/// <summary>
/// 指定用户是否为 Company Admin 类角色(按库内 Role 判定,用于登录等无 JWT 声明场景)。
/// </summary>
public static async Task<bool> IsCompanyAdminUserAsync(ISqlSugarClient db, Guid userId)
{
var roleRows = await LoadUserRoleRowsAsync(db, userId);
return roleRows.Any(r =>
IsCompanyAdminRoleName(r.RoleName) || IsCompanyAdminRoleToken(r.RoleCode));
}
/// <summary>
/// 是否 Company Admin 类角色(按 RoleId 查库)。
/// </summary>
public static async Task<bool> IsCompanyAdminRoleAsync(ISqlSugarClient db, Guid? roleId)
{
if (roleId is null)
{
return false;
}
var roleRows = await db.Ado.SqlQueryAsync<UserRoleNameRow>(
"""
SELECT RoleCode, RoleName
FROM Role
WHERE IsDeleted = 0 AND Id = @RoleId
LIMIT 1
""",
new { RoleId = roleId.Value });
var role = roleRows.FirstOrDefault();
if (role is null)
{
return false;
}
return IsCompanyAdminRoleName(role.RoleName) || IsCompanyAdminRoleToken(role.RoleCode);
}
/// <summary>
/// 读取用户角色(raw SQL,避免 RBAC 数据权限过滤器中 Select 表达式导致 SqlSugar 解析失败)。
/// </summary>
private static Task<List<UserRoleNameRow>> LoadUserRoleRowsAsync(ISqlSugarClient db, Guid userId) =>
db.Ado.SqlQueryAsync<UserRoleNameRow>(
"""
SELECT r.RoleCode, r.RoleName
FROM UserRole ur
INNER JOIN Role r ON ur.RoleId = r.Id
WHERE ur.UserId = @UserId AND r.IsDeleted = 0 AND r.State = 1
""",
new { UserId = userId });
/// <summary>
/// 列表/详情出参:Partner Admin → Company Admin(与 Web UI 一致)。
/// </summary>
public static string? FormatDisplayRoleName(string? roleName)
{
if (IsCompanyAdminRoleName(roleName) &&
!string.Equals(roleName?.Trim(), "Company Admin", StringComparison.OrdinalIgnoreCase))
{
return "Company Admin";
}
return roleName;
}
/// <summary>
/// JWT / RoleCode / RoleName 中的 Company Admin 标识(含 <c>CompanyAdmin</c>)。
/// </summary>
public static bool IsCompanyAdminRoleToken(string? value)
{
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
var key = NormalizeRoleKey(value);
if (key == "companyadmin" || key.Contains("companyadmin", StringComparison.Ordinal))
{
return true;
}
return value.Trim().Contains("partner", StringComparison.OrdinalIgnoreCase);
}
private static bool IsCompanyAdminFromClaims(ICurrentUser currentUser)
{
if (currentUser.Roles is not null)
{
foreach (var r in currentUser.Roles)
{
if (IsCompanyAdminRoleToken(r))
{
return true;
}
}
}
var rolesClaim = currentUser.FindClaims(TokenTypeConst.Roles).Select(x => x.Value).FirstOrDefault();
if (string.IsNullOrWhiteSpace(rolesClaim))
{
return false;
}
foreach (var part in rolesClaim.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
{
if (IsCompanyAdminRoleToken(part))
{
return true;
}
}
return false;
}
private static string NormalizeRoleKey(string value) =>
new string(value.Trim().ToLowerInvariant().Where(c => char.IsLetterOrDigit(c)).ToArray());
private sealed class UserRoleNameRow
{
public string? RoleCode { get; set; }
public string? RoleName { get; set; }
}
}