128 lines
4.9 KiB
C#
128 lines
4.9 KiB
C#
using FreeSql;
|
||
|
||
using LiveForum.Code.Base;
|
||
using LiveForum.Code.ExceptionExtend;
|
||
using LiveForum.IService.Permission;
|
||
using LiveForum.Model;
|
||
using LiveForum.Model.Dto.Permission;
|
||
using LiveForum.Model.Enum;
|
||
using LiveForum.Model.Enum.Users;
|
||
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace LiveForum.Service.Permission
|
||
{
|
||
/// <summary>
|
||
/// 权限服务实现 - 计算用户有效权限、校验单项权限
|
||
/// </summary>
|
||
public class PermissionService : IPermissionService
|
||
{
|
||
private readonly IBaseRepository<T_Users> _usersRepository;
|
||
private readonly IBaseRepository<T_CertificationTypePermissions> _certPermRepository;
|
||
private readonly IBaseRepository<T_UserIdentityGroups> _userGroupRepository;
|
||
private readonly IBaseRepository<T_IdentityGroupPermissions> _groupPermRepository;
|
||
private readonly ILogger<PermissionService> _logger;
|
||
|
||
private const string PermissionDeniedMessage = "您的权限不足,请联系平台客服或进行身份认证";
|
||
|
||
public PermissionService(
|
||
IBaseRepository<T_Users> usersRepository,
|
||
IBaseRepository<T_CertificationTypePermissions> certPermRepository,
|
||
IBaseRepository<T_UserIdentityGroups> userGroupRepository,
|
||
IBaseRepository<T_IdentityGroupPermissions> groupPermRepository,
|
||
ILogger<PermissionService> logger)
|
||
{
|
||
_usersRepository = usersRepository;
|
||
_certPermRepository = certPermRepository;
|
||
_userGroupRepository = userGroupRepository;
|
||
_groupPermRepository = groupPermRepository;
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<EffectivePermissionDto> GetEffectivePermissionAsync(long userId)
|
||
{
|
||
var result = new EffectivePermissionDto();
|
||
|
||
// 1. 查询用户信息
|
||
var user = await _usersRepository.Where(u => u.Id == userId).FirstAsync();
|
||
if (user == null)
|
||
{
|
||
_logger.LogWarning("GetEffectivePermissionAsync: 用户不存在, userId={UserId}", userId);
|
||
return result; // 用户不存在,所有权限为禁止
|
||
}
|
||
|
||
// 2. 查询SK认证等级权限(仅当用户认证完成时)
|
||
if (user.CertifiedStatus == CertifiedStatusEnum.认证完成
|
||
&& user.CertifiedType.HasValue
|
||
&& user.CertifiedType.Value > 0)
|
||
{
|
||
var certPerm = await _certPermRepository
|
||
.Where(p => p.CertificationTypeId == user.CertifiedType.Value)
|
||
.FirstAsync();
|
||
|
||
if (certPerm != null)
|
||
{
|
||
result.CanPost |= certPerm.CanPost;
|
||
result.CanReply |= certPerm.CanReply;
|
||
result.CanFlower |= certPerm.CanFlower;
|
||
result.CanLike |= certPerm.CanLike;
|
||
result.CanDeleteOtherPost |= certPerm.CanDeleteOtherPost;
|
||
}
|
||
}
|
||
|
||
// 3. 查询用户所有身份组
|
||
var userGroups = await _userGroupRepository
|
||
.Where(ug => ug.UserId == userId)
|
||
.ToListAsync();
|
||
|
||
if (userGroups.Any())
|
||
{
|
||
var groupIds = userGroups.Select(ug => ug.IdentityGroupId).ToList();
|
||
|
||
// 4. 查询所有身份组的权限配置
|
||
var groupPerms = await _groupPermRepository
|
||
.Where(gp => groupIds.Contains(gp.IdentityGroupId))
|
||
.ToListAsync();
|
||
|
||
// 5. OR 合并所有身份组权限
|
||
foreach (var gp in groupPerms)
|
||
{
|
||
result.CanPost |= gp.CanPost;
|
||
result.CanReply |= gp.CanReply;
|
||
result.CanFlower |= gp.CanFlower;
|
||
result.CanLike |= gp.CanLike;
|
||
result.CanDeleteOtherPost |= gp.CanDeleteOtherPost;
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task CheckPermissionAsync(long userId, PermissionType permissionType)
|
||
{
|
||
var effectivePermission = await GetEffectivePermissionAsync(userId);
|
||
|
||
bool hasPermission = permissionType switch
|
||
{
|
||
PermissionType.Post => effectivePermission.CanPost,
|
||
PermissionType.Reply => effectivePermission.CanReply,
|
||
PermissionType.Flower => effectivePermission.CanFlower,
|
||
PermissionType.Like => effectivePermission.CanLike,
|
||
PermissionType.DeleteOtherPost => effectivePermission.CanDeleteOtherPost,
|
||
_ => false
|
||
};
|
||
|
||
if (!hasPermission)
|
||
{
|
||
throw new MessageBox(ResponseCode.Forbidden, PermissionDeniedMessage);
|
||
}
|
||
}
|
||
}
|
||
}
|