Skip to content

Commit 4663a70

Browse files
committed
[feat] 完善数据权限
1 parent f68988a commit 4663a70

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1381
-1153
lines changed

Ape.Volo.Api/Authentication/Jwt/TokenService.cs

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public async Task<Token> IssueTokenAsync(LoginUserInfo loginUserInfo, bool refre
3838
new(AuthConstants.JwtClaimTypes.Jti, loginUserInfo.UserId.ToString()),
3939
new(AuthConstants.JwtClaimTypes.Name, loginUserInfo.Account),
4040
new(AuthConstants.JwtClaimTypes.TenantId, loginUserInfo.TenantId.ToString()),
41+
new(AuthConstants.JwtClaimTypes.DeptId, loginUserInfo.DeptId.ToString()),
4142
new(AuthConstants.JwtClaimTypes.Iat, nowTime.ToUnixTimeStampSecond().ToString()),
4243
new(AuthConstants.JwtClaimTypes.Ip, loginUserInfo.Ip)
4344
};

Ape.Volo.Api/Controllers/Auth/AuthorizationController.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ public async Task<ActionResult<object>> RefreshToken(string token = "")
124124
}
125125

126126
var tokenMd5 = token.ToMd5String16();
127-
var tokenBlacklist = await _tokenBlacklistService.TableWhere(x => x.AccessToken == tokenMd5).FirstAsync();
127+
var tokenBlacklist = await _tokenBlacklistService.TableWhere(x => x.AccessToken == tokenMd5, null, null, true)
128+
.FirstAsync();
128129
if (tokenBlacklist.IsNull())
129130
{
130131
var jwtSecurityToken = await _tokenService.ReadJwtToken(token);
@@ -219,9 +220,14 @@ await _apeContext.Cache.RemoveAsync(GlobalConstants.CachePrefix.OnlineKey +
219220
_apeContext.HttpUser.JwtToken.ToMd5String16());
220221
await _apeContext.Cache.RemoveAsync(GlobalConstants.CachePrefix.UserInfoById +
221222
_apeContext.HttpUser.Id.ToString().ToMd5String16());
222-
223223
await _apeContext.Cache.RemoveAsync(GlobalConstants.CachePrefix.UserMenuById +
224224
_apeContext.HttpUser.Id.ToString().ToMd5String16());
225+
await _apeContext.Cache.RemoveAsync(GlobalConstants.CachePrefix.UserPermissionRoles +
226+
_apeContext.HttpUser.Id.ToString().ToMd5String16());
227+
await _apeContext.Cache.RemoveAsync(GlobalConstants.CachePrefix.UserPermissionUrls +
228+
_apeContext.HttpUser.Id.ToString().ToMd5String16());
229+
await _apeContext.Cache.RemoveAsync(GlobalConstants.CachePrefix.UserDataScopeById +
230+
_apeContext.HttpUser.Id.ToString().ToMd5String16());
225231

226232

227233
return Success();

Ape.Volo.Api/Controllers/Permission/DeptController.cs

+14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Ape.Volo.IBusiness.Interface.Permission;
1010
using Ape.Volo.IBusiness.QueryModel;
1111
using Ape.Volo.IBusiness.RequestModel;
12+
using Microsoft.AspNetCore.Authorization;
1213
using Microsoft.AspNetCore.Mvc;
1314

1415
namespace Ape.Volo.Api.Controllers.Permission;
@@ -124,6 +125,19 @@ public async Task<ActionResult<object>> Query(DeptQueryCriteria deptQueryCriteri
124125
});
125126
}
126127

128+
129+
[HttpGet]
130+
[Route("queryTree")]
131+
[Description("树形部门数据")]
132+
public async Task<ActionResult<object>> QueryTree()
133+
{
134+
var deptList = await _departmentService.QueryAllAsync();
135+
136+
var menuTree = TreeHelper<DepartmentDto>.ListToTrees(deptList, "Id", "ParentId", 0);
137+
return menuTree.ToJson();
138+
}
139+
140+
127141
/// <summary>
128142
/// 导出部门
129143
/// </summary>

Ape.Volo.Api/Controllers/Permission/PermissionsController.cs

-24
Original file line numberDiff line numberDiff line change
@@ -51,30 +51,6 @@ public PermissionsController(IRoleService roleService, IMenuService menuService,
5151
public async Task<ActionResult<object>> QueryAllMenus()
5252
{
5353
var menus = await _menuService.QueryAllAsync();
54-
foreach (var item in menus)
55-
{
56-
if (item.Children.Count == 0)
57-
{
58-
item.Children = null;
59-
}
60-
else
61-
{
62-
foreach (var item2 in item.Children)
63-
{
64-
if (item2.Children.Count == 0)
65-
{
66-
item2.Children = null;
67-
}
68-
else
69-
{
70-
foreach (var item3 in item2.Children.Where(item3 => item3.Children.Count == 0))
71-
{
72-
item3.Children = null;
73-
}
74-
}
75-
}
76-
}
77-
}
7854

7955
var menuTree = TreeHelper<MenuDto>.ListToTrees(menus, "Id", "ParentId", 0);
8056
return menuTree.ToJson();

Ape.Volo.Api/Extensions/AuthorizationSetup.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Microsoft.AspNetCore.Authentication;
1010
using Microsoft.AspNetCore.Authentication.JwtBearer;
1111
using Microsoft.AspNetCore.Authorization;
12+
using Microsoft.AspNetCore.Http;
1213
using Microsoft.Extensions.DependencyInjection;
1314
using Microsoft.IdentityModel.Tokens;
1415

@@ -79,7 +80,7 @@ public static void AddAuthorizationSetup(this IServiceCollection services, Confi
7980
// 如果过期,把过期信息添加到头部
8081
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
8182
{
82-
context.Response.Headers.Add("Token-Expired", "true");
83+
context.Response.Headers.Append("Token-Expired", "true");
8384
}
8485

8586
return Task.CompletedTask;

Ape.Volo.Api/Extensions/SqlSugarSetup.cs

+119-12
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
using Ape.Volo.Common.Extensions;
1010
using Ape.Volo.Common.Global;
1111
using Ape.Volo.Common.Helper;
12+
using Ape.Volo.Common.Helper.Serilog;
1213
using Ape.Volo.Common.Model;
1314
using Ape.Volo.Common.SnowflakeIdHelper;
1415
using Ape.Volo.Common.WebApp;
1516
using Ape.Volo.Entity.Base;
17+
using Ape.Volo.IBusiness.Interface.Permission;
1618
using Microsoft.Extensions.DependencyInjection;
1719
using Serilog;
1820
using SqlSugar;
@@ -26,6 +28,8 @@ namespace Ape.Volo.Api.Extensions;
2628
/// </summary>
2729
public static class SqlSugarSetup
2830
{
31+
private static readonly ILogger Logger = SerilogManager.GetLogger(typeof(SqlSugarSetup));
32+
2933
public static void AddSqlSugarSetup(this IServiceCollection services, Configs configs)
3034
{
3135
if (services.IsNull())
@@ -98,7 +102,7 @@ public static void AddSqlSugarSetup(this IServiceCollection services, Configs co
98102
MoreSettings = new ConnMoreSettings
99103
{
100104
IsAutoRemoveDataCache = true,
101-
SqlServerCodeFirstNvarchar = true, //sqlserver默认使用nvarchar
105+
SqlServerCodeFirstNvarchar = true //sqlserver默认使用nvarchar
102106
},
103107
ConfigureExternalServices = new ConfigureExternalServices
104108
{
@@ -152,6 +156,9 @@ public static void AddSqlSugarSetup(this IServiceCollection services, Configs co
152156
//租户
153157
sugarScopeProvider.ConfiguringTenantFilter();
154158

159+
//数据权限 这个要放在最后
160+
sugarScopeProvider.ConfiguringUserDataScopeFilter();
161+
155162
#endregion
156163

157164
#region 读写事件
@@ -193,6 +200,8 @@ private static void DataExecuting(object value, DataFilterModel entityInfo)
193200
rootEntity.Id = IdHelper.GetLongId();
194201
}
195202

203+
#region BaseEntity
204+
196205
if (entityInfo.EntityValue is BaseEntity baseEntity)
197206
{
198207
switch (entityInfo.OperationType)
@@ -212,31 +221,88 @@ private static void DataExecuting(object value, DataFilterModel entityInfo)
212221
}
213222

214223
var httpUser = AutofacHelper.GetService<IHttpUser>();
215-
if (httpUser.IsNull()) return;
216-
switch (entityInfo.OperationType)
224+
if (httpUser.IsNotNull() && !httpUser.Account.IsNullOrEmpty())
217225
{
218-
case DataFilterType.InsertByObject:
226+
switch (entityInfo.OperationType)
219227
{
220-
if (baseEntity.CreateBy.IsNullOrEmpty())
228+
case DataFilterType.InsertByObject:
221229
{
222-
baseEntity.CreateBy = httpUser.Account;
223-
}
230+
if (baseEntity.CreateBy.IsNullOrEmpty())
231+
{
232+
baseEntity.CreateBy = httpUser.Account;
233+
}
224234

225-
if (baseEntity is ITenantEntity tenant && httpUser.TenantId > 0)
226-
{
227-
if (tenant.TenantId == 0)
235+
var tenant = baseEntity as ITenantEntity;
236+
if (tenant != null && httpUser.TenantId > 0)
228237
{
229-
tenant.TenantId = httpUser.TenantId;
238+
if (tenant.TenantId == 0)
239+
{
240+
tenant.TenantId = httpUser.TenantId;
241+
}
230242
}
243+
244+
break;
245+
}
246+
case DataFilterType.UpdateByObject:
247+
baseEntity.UpdateBy = httpUser.Account;
248+
break;
249+
}
250+
}
251+
}
252+
253+
#endregion
254+
255+
#region BaseEntityNoDataScope
256+
257+
if (entityInfo.EntityValue is BaseEntityNoDataScope baseEntityNoDataScope)
258+
{
259+
switch (entityInfo.OperationType)
260+
{
261+
case DataFilterType.InsertByObject:
262+
{
263+
if (baseEntityNoDataScope.CreateTime == DateTime.MinValue)
264+
{
265+
baseEntityNoDataScope.CreateTime = DateTime.Now;
231266
}
232267

233268
break;
234269
}
235270
case DataFilterType.UpdateByObject:
236-
baseEntity.UpdateBy = httpUser.Account;
271+
baseEntityNoDataScope.UpdateTime = DateTime.Now;
237272
break;
238273
}
274+
275+
var httpUser = AutofacHelper.GetService<IHttpUser>();
276+
if (httpUser.IsNotNull() && !httpUser.Account.IsNullOrEmpty())
277+
{
278+
switch (entityInfo.OperationType)
279+
{
280+
case DataFilterType.InsertByObject:
281+
{
282+
if (baseEntityNoDataScope.CreateBy.IsNullOrEmpty())
283+
{
284+
baseEntityNoDataScope.CreateBy = httpUser.Account;
285+
}
286+
287+
var tenant = baseEntityNoDataScope as ITenantEntity;
288+
if (tenant != null && httpUser.TenantId > 0)
289+
{
290+
if (tenant.TenantId == 0)
291+
{
292+
tenant.TenantId = httpUser.TenantId;
293+
}
294+
}
295+
296+
break;
297+
}
298+
case DataFilterType.UpdateByObject:
299+
baseEntityNoDataScope.UpdateBy = httpUser.Account;
300+
break;
301+
}
302+
}
239303
}
304+
305+
#endregion
240306
}
241307

242308
#endregion
@@ -339,4 +405,45 @@ private static void ConfiguringTenantFilter(this SqlSugarScopeProvider db)
339405
db.QueryFilter.AddTableFilter<ITenantEntity>(it => it.TenantId == httpUser.TenantId);
340406
}
341407
}
408+
409+
/// <summary>
410+
/// 配置用户数据权限
411+
/// </summary>
412+
/// <param name="db"></param>
413+
private static void ConfiguringUserDataScopeFilter(this SqlSugarScopeProvider db)
414+
{
415+
var httpUser = AutofacHelper.GetService<IHttpUser>();
416+
if (httpUser.IsNull() || httpUser.Account.IsNullOrEmpty()) return;
417+
var dataScopeService = AutofacHelper.GetService<IDataScopeService>();
418+
if (dataScopeService == null) return;
419+
420+
try
421+
{
422+
var accounts = AsyncHelper.RunSync(() =>
423+
dataScopeService.GetDataScopeAccountsAsync(httpUser.Id));
424+
if (accounts.Count > 0)
425+
{
426+
if (accounts.Count == 1)
427+
{
428+
if (!accounts[0].Equals("All"))
429+
{
430+
db.QueryFilter.AddTableFilter<ICreateByEntity>(it => it.CreateBy == accounts[0]);
431+
}
432+
}
433+
else
434+
{
435+
db.QueryFilter.AddTableFilter<ICreateByEntity>(it => accounts.Contains(it.CreateBy));
436+
}
437+
}
438+
else
439+
{
440+
db.QueryFilter.AddTableFilter<ICreateByEntity>(it => it.CreateBy == httpUser.Account);
441+
}
442+
}
443+
catch (Exception e)
444+
{
445+
Logger.Fatal("配置用户数据权限错误:\r\n" + ExceptionHelper.GetExceptionAllMsg(e));
446+
db.QueryFilter.AddTableFilter<ICreateByEntity>(it => it.CreateBy == httpUser.Account);
447+
}
448+
}
342449
}

Ape.Volo.Api/wwwroot/resources/db/sys_apis.tsv

+14-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
{
1313
"group":"授权管理",
1414
"url":"/auth/refreshtoken",
15-
"description":"刷新Token",
15+
"description":"刷新Token(必需)",
1616
"method":"POST",
1717
"isDeleted":false,
1818
"createBy":"apevolo",
@@ -22,7 +22,7 @@
2222
{
2323
"group":"授权管理",
2424
"url":"/auth/info",
25-
"description":"个人信息",
25+
"description":"个人信息(必需)",
2626
"method":"GET",
2727
"isDeleted":false,
2828
"createBy":"apevolo",
@@ -322,7 +322,7 @@
322322
{
323323
"group":"菜单管理",
324324
"url":"/api/menu/build",
325-
"description":"构建菜单",
325+
"description":"构建菜单(必需)",
326326
"method":"GET",
327327
"isDeleted":false,
328328
"createBy":"apevolo",
@@ -1128,5 +1128,15 @@
11281128
"createBy":"apevolo",
11291129
"CreateTime":"\/Date(1609430400000+0800)\/",
11301130
"id":"1763017911204581312"
1131-
}
1131+
},
1132+
{
1133+
"group":"部门管理",
1134+
"url":"/api/dept/queryTree",
1135+
"description":"获取部门树形数据",
1136+
"method":"GET",
1137+
"isDeleted":false,
1138+
"createBy":"apevolo",
1139+
"CreateTime":"\/Date(1609430400000+0800)\/",
1140+
"id":"1763017911204581313"
1141+
},
11321142
]

Ape.Volo.Api/wwwroot/resources/db/sys_dict.tsv

+11
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,16 @@
9797
"UpdateBy": null,
9898
"UpdateTime": null,
9999
"IsDeleted": false
100+
},
101+
{
102+
"Id": "1799832924720205825",
103+
"DictType": 2,
104+
"Name": "data_scope_type",
105+
"Description": "数据权限",
106+
"CreateBy": "apevolo",
107+
"CreateTime": "/Date(1609430400000+0800)/",
108+
"UpdateBy": null,
109+
"UpdateTime": null,
110+
"IsDeleted": false
100111
}
101112
]

0 commit comments

Comments
 (0)