LMS.service/LMS.service/Service/OptionsService.cs
lq1405 c07369c297 V 1.1.1
优化公共数据获取权限控制
2025-05-23 21:05:17 +08:00

605 lines
25 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AutoMapper;
using LMS.Common.Dictionary;
using LMS.Common.Enums;
using LMS.Common.Templates;
using LMS.DAO;
using LMS.DAO.UserDAO;
using LMS.Repository.DB;
using LMS.Repository.DTO;
using LMS.Repository.Models.DB;
using LMS.Repository.Options;
using LMS.service.Extensions.Mail;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System.Linq;
using static LMS.Common.Enums.ResponseCodeEnum;
using Options = LMS.Repository.DB.Options;
using System.Linq.Dynamic.Core;
using LinqKit;
using LMS.Repository.DTO.OptionDto;
using LMS.Common.Extensions;
namespace LMS.service.Service
{
public class OptionsService(ApplicationDbContext context, UserManager<User> userManager, RoleManager<Role> roleManager, IMapper mapper, UserBasicDao userBasicDao, EmailService emailService)
{
private readonly ApplicationDbContext _context = context;
private readonly UserManager<User> _userManager = userManager;
private readonly RoleManager<Role> _roleManager = roleManager;
private readonly IMapper _mapper = mapper;
private readonly UserBasicDao _userBasicDao = userBasicDao;
private readonly EmailService _emailService = emailService;
#region
/// <summary>
/// 获取简单的配置项,无需权限
/// </summary>
/// <param name="optionsKey">配置项键</param>
/// <returns>API响应模型</returns>
internal async Task<ActionResult<APIResponseModel<List<OptionsDto>>>> GetSimpleOptions(string optionsKey)
{
try
{
if (!SimpleOptions.SimpleOptionsRequestQuery.TryGetValue(optionsKey, out List<string>? value))
{
return APIResponseModel<List<OptionsDto>>.CreateErrorResponseModel(ResponseCode.ParameterError);
}
// 从数据库中获取配置项
List<Options> options = await _context.Options.Where(x => value.Contains(x.Key)).ToListAsync();
if (options == null || options.Count <= 0)
{
return APIResponseModel<List<OptionsDto>>.CreateErrorResponseModel(ResponseCode.FindOptionsFail);
}
else
{
List<OptionsDto> optionsDto = options.Select(x => _mapper.Map<OptionsDto>(x)).ToList();
return APIResponseModel<List<OptionsDto>>.CreateSuccessResponseModel(optionsDto);
}
}
catch (Exception ex)
{
return APIResponseModel<List<OptionsDto>>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region
/// <summary>
/// 获取所有的配置项,需要管理员权限
/// </summary>
/// <param name="requestUserId">请求用户ID</param>
/// <returns>API响应模型</returns>
internal async Task<ActionResult<APIResponseModel<List<OptionsDto>>>> GetAllOptions(string optionsKey, long requestUserId)
{
try
{
User? user = await _userManager.FindByIdAsync(requestUserId.ToString());
if (user == null)
{
return APIResponseModel<List<OptionsDto>>.CreateErrorResponseModel(ResponseCode.FindUserByIdFail);
}
bool isAdminOrSuperAdmin = await _userManager.IsInRoleAsync(user, "Admin") || await _userManager.IsInRoleAsync(user, "Super Admin");
// 判断用户是不是管理员
if (!isAdminOrSuperAdmin)
{
return APIResponseModel<List<OptionsDto>>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
IQueryable<Options> query = _context.Options;
if (optionsKey != "all")
{
List<string> optionsKeyName = [];
if (AllOptions.AllOptionsRequestQuery.TryGetValue(optionsKey, out List<string>? value))
{
optionsKeyName = value;
}
else
{
return APIResponseModel<List<OptionsDto>>.CreateErrorResponseModel(ResponseCode.ParameterError);
}
query = query.Where(x => optionsKeyName.Contains(x.Key));
}
List<Options> options = await query.ToListAsync();
List<OptionsDto> optionsDto = options.Select(x => new OptionsDto
{
Key = x.Key,
Value = x.Value,
Type = x.Type,
}).ToList();
return APIResponseModel<List<OptionsDto>>.CreateSuccessResponseModel(optionsDto);
}
catch (Exception ex)
{
return APIResponseModel<List<OptionsDto>>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region
/// <summary>
/// 修改配置项
/// </summary>
/// <param name="models">要修改的配置项模型列表</param>
/// <param name="userId">用户ID</param>
/// <returns>API响应模型</returns>
internal async Task<ActionResult<APIResponseModel<string>>> ModifyOptions(List<ModofyOptionsModel> models, long userId)
{
using var transaction = await _context.Database.BeginTransactionAsync();
try
{
bool isAdminOrSuperAdmin = await _userBasicDao.CheckUserIsAdminOrSuperAdmin(userId);
// 判断用户是不是管理员
if (!isAdminOrSuperAdmin)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
// 开始修改配置项
for (int i = 0; i < models.Count; i++)
{
ModofyOptionsModel model = models[i];
Options? options = await _context.Options.FirstOrDefaultAsync(x => x.Key == model.Key);
if (options == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.FindOptionsFail);
}
options.Value = model.Value;
_context.Options.Update(options);
}
await _context.SaveChangesAsync();
await transaction.CommitAsync();
return APIResponseModel<string>.CreateSuccessResponseModel("修改成功");
}
catch (Exception ex)
{
await transaction.RollbackAsync();
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region
/// <summary>
/// 测试邮箱发送
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<ActionResult<APIResponseModel<string>>> TestSendMail(long userId)
{
try
{
// 判断是不是超级管理员
bool isSuperAdmin = await _userBasicDao.CheckUserIsSuperAdmin(userId);
if (!isSuperAdmin)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
var emailBody = EmailTemplateService.ReplaceTemplate(EmailTemplateService.RegisterHtmlTemplates, new Dictionary<string, string>
{
{ "RegisterCode", "验证码" }
});
// 调用发送邮件的方法
await _emailService.SendEmailAsync("user@example.com", "邮件连通测试", emailBody, true);
return APIResponseModel<string>.CreateSuccessResponseModel("邮箱测试发送成功");
}
catch (Exception ex)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region
/// <summary>
/// 获取指定的配置项,只能获取不需要权限的
/// </summary>
/// <param name="userId"></param>
/// <param name="category"></param>
/// <param name="optionsKey"></param>
/// <returns></returns>
public async Task<ActionResult<APIResponseModel<OptionsDto>>> GetOptionsByKey(long userId, int category, string optionsKey)
{
try
{
// 判断分类是不是在对应的enum里面
if (!Enum.IsDefined(typeof(OptionCategory), category))
{
return APIResponseModel<OptionsDto>.CreateErrorResponseModel(ResponseCode.ParameterError, "该分类不存在");
}
Options? options = await _context.Options.FirstOrDefaultAsync(x => x.Key == optionsKey && (OptionCategory)category == x.Category) ?? throw new Exception("数据不存在");
if (options.RoleIds != null && options.RoleIds.Count != 0)
{
return APIResponseModel<OptionsDto>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
else
{
return APIResponseModel<OptionsDto>.CreateSuccessResponseModel(_mapper.Map<OptionsDto>(options));
}
//List<long> roleIds = [];
//if (userId != 0)
//{
// roleIds = await _userBasicDao.GetUserRoleIds(userId);
//}
//// 数据存在 对比权限
//if (options.RoleIds.Count == 0)
//{
// // 不需要权限 直接返回
// return APIResponseModel<OptionsDto>.CreateSuccessResponseModel(_mapper.Map<OptionsDto>(options));
//}
//else
//{
// // 需要判断权限 判断 roleIds 是不是有权限在 options.RoleIds 里面
// bool hasPermission = false;
// foreach (var roleId in roleIds)
// {
// if (options.RoleIds.Contains(roleId))
// {
// hasPermission = true;
// break;
// }
// }
// if (!hasPermission)
// {
// return APIResponseModel<OptionsDto>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
// }
// else
// {
// return APIResponseModel<OptionsDto>.CreateSuccessResponseModel(_mapper.Map<OptionsDto>(options));
// }
//}
}
catch (Exception ex)
{
return APIResponseModel<OptionsDto>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region
internal async Task<ActionResult<APIResponseModel<string>>> ModifyOptionsByKey(string key, ModifyOptionByKeyModel model, long userId)
{
try
{
bool isAdminOrSuperAdmin = await _userBasicDao.CheckUserIsAdminOrSuperAdmin(userId);
// 判断type 和 category 是不是在enum中
// 判断分类是不是在对应的enum里面
if (!Enum.IsDefined(typeof(OptionCategory), model.Category))
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError, "该分类不存在");
}
if (!Enum.IsDefined(typeof(OptionTypeEnum), model.Type))
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError, "该类型不存在");
}
// 判断用户是不是管理员
if (!isAdminOrSuperAdmin)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
Options? options = await _context.Options.FirstOrDefaultAsync(x => x.Key == key);
if (options == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.FindOptionsFail);
}
List<long> ids = [];
// 判断所有的roleId是不是都存在
if (model.RoleNames != null && model.RoleNames.Count > 0)
{
foreach (var roleId in model.RoleNames)
{
Role? role = await _roleManager.FindByNameAsync(roleId.ToString());
if (role == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError, "角色列表中有部分ID不存在");
}
ids.Add(role.Id);
}
}
// 开始修改配置项
options.Value = model.Value;
options.RoleIds = ids;
options.Type = model.Type;
options.Category = model.Category;
_context.Options.Update(options);
await _context.SaveChangesAsync();
return APIResponseModel<string>.CreateSuccessResponseModel("修改成功");
}
catch (Exception ex)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region
/// <summary>
/// 查询数据信息的集合
/// </summary>
/// <param name="page"></param>
/// <param name="pageSize"></param>
/// <param name="key"></param>
/// <param name="type"></param>
/// <param name="category"></param>
/// <param name="roleIds"></param>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<ActionResult<APIResponseModel<CollectionResponse<OptionSimpleDto>>>> QueryOptionCollection(int page, int pageSize, string? key, int? type, int? category, string[]? roleNames, long userId)
{
try
{
bool isAdminOrSuperAdmin = await _userBasicDao.CheckUserIsAdminOrSuperAdmin(userId);
// 判断用户是不是管理员
if (!isAdminOrSuperAdmin)
{
return APIResponseModel<CollectionResponse<OptionSimpleDto>>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
IQueryable<Options> query = _context.Options;
if (!string.IsNullOrWhiteSpace(key))
{
query = query.Where(x => x.Key.Contains(key));
}
if (type != null)
{
if (!Enum.IsDefined(typeof(OptionTypeEnum), type))
{
return APIResponseModel<CollectionResponse<OptionSimpleDto>>.CreateErrorResponseModel(ResponseCode.ParameterError, "该类型不存在");
}
query = query.Where(x => x.Type == (OptionTypeEnum)type);
}
if (category != null)
{
if (!Enum.IsDefined(typeof(OptionCategory), category))
{
return APIResponseModel<CollectionResponse<OptionSimpleDto>>.CreateErrorResponseModel(ResponseCode.ParameterError, "该分类不存在");
}
query = query.Where(x => x.Category == (OptionCategory)category);
}
List<long> ids = [];
if (roleNames != null && roleNames.Length > 0)
{
// 判断所有的roleId是不是都存在
foreach (var roleId in roleNames)
{
Role? role = await _roleManager.FindByNameAsync(roleId.ToString());
if (role != null)
{
ids.Add(role.Id);
}
}
}
if (ids.Count > 0)
{
var predicate = PredicateBuilder.New<Options>(false);
foreach (var roleId in ids)
{
var localId = roleId; // 闭包捕获
predicate = predicate.Or(x => EF.Functions.JsonContains(x.RoleIds, localId.ToString()));
// 如果你的 RoleIds 存数字localId.ToString(),否则加引号
// predicate = predicate.Or(x => EF.Functions.JsonContains(x.RoleIds, $"\"{localId}\""));
}
query = query.Where(predicate);
}
// 查询总数
int total = await query.CountAsync();
// 创建时间倒叙
query = query.OrderByDescending(x => x.CreatedTime);
// 分页
query = query.Skip((page - 1) * pageSize).Take(pageSize);
List<Options>? options = await query.ToListAsync();
List<Role> roles = await _context.Roles.ToListAsync();
List<OptionSimpleDto> optionDtos = new List<OptionSimpleDto>();
foreach (var option in options)
{
OptionSimpleDto optionDto = new()
{
Key = option.Key,
Value = option.Value,
Type = option.Type,
Category = option.Category,
RoleNames = option.RoleIds.Select(x => roles.FirstOrDefault(r => r.Id == x)).Where(r => r != null).Select(r => r.Name).ToList()
};
optionDtos.Add(optionDto);
}
return APIResponseModel<CollectionResponse<OptionSimpleDto>>.CreateSuccessResponseModel(new CollectionResponse<OptionSimpleDto>
{
Total = total,
Collection = optionDtos,
Current = page
});
}
catch (Exception ex)
{
return APIResponseModel<CollectionResponse<OptionSimpleDto>>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region
public async Task<ActionResult<APIResponseModel<string>>> AddOptions(AddOptionModel option, long userId)
{
try
{
bool isSuperAdmin = await _userBasicDao.CheckUserIsSuperAdmin(userId);
if (!isSuperAdmin)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
// 判断type 和 category 是不是在enum中
// 判断分类是不是在对应的enum里面
if (!Enum.IsDefined(typeof(OptionCategory), option.Category))
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError, "该分类不存在");
}
if (!Enum.IsDefined(typeof(OptionTypeEnum), option.Type))
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError, "该类型不存在");
}
List<long> ids = [];
// 判断所有的roleId是不是都存在
if (option.RoleNames != null && option.RoleNames.Count > 0)
{
foreach (var roleId in option.RoleNames)
{
Role? role = await _roleManager.FindByNameAsync(roleId.ToString());
if (role == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError, "角色列表中有部分ID不存在");
}
ids.Add(role.Id);
}
}
// 判断当前的key是不是已经存在
Options? options = await _context.Options.FirstOrDefaultAsync(x => x.Key == option.Key && x.Category == option.Category);
if (options != null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError, "当前分类的key已经存在");
}
if (string.IsNullOrWhiteSpace(option.Value))
{
option.Value = string.Empty;
}
Options options1 = new()
{
Key = option.Key,
Value = option.Value,
Type = option.Type,
Category = option.Category,
RoleIds = ids,
CreatedTime = BeijingTimeExtension.GetBeijingTime()
};
// 添加数据
await _context.Options.AddAsync(options1);
await _context.SaveChangesAsync();
return APIResponseModel<string>.CreateSuccessResponseModel("添加成功");
}
catch (Exception ex)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region key的数据
/// <summary>
/// 删除指定的数据
/// </summary>
/// <param name="category"></param>
/// <param name="key"></param>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<ActionResult<APIResponseModel<string>>> DeleteOptionsByKey(int category, string key, long userId)
{
try
{
var isSuperAdmin = await _userBasicDao.CheckUserIsSuperAdmin(userId);
// 判断用户是不是管理员
if (!isSuperAdmin)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
Options? options = await _context.Options.FirstOrDefaultAsync(x => x.Key == key && x.Category == (OptionCategory)category);
if (options == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.FindOptionsFail);
}
// 删除数据
_context.Options.Remove(options);
await _context.SaveChangesAsync();
return APIResponseModel<string>.CreateSuccessResponseModel("删除成功");
}
catch (Exception ex)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region
internal async Task<ActionResult<APIResponseModel<OptionSimpleDto>>> GetAllMessageOptionsByKey(int category, string optionsKey, long userId)
{
try
{
bool isAdminOrSuperAdmin = await _userBasicDao.CheckUserIsAdminOrSuperAdmin(userId);
// 判断用户是不是管理员
if (!isAdminOrSuperAdmin)
{
return APIResponseModel<OptionSimpleDto>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
// 判断分类是不是在对应的enum里面
if (!Enum.IsDefined(typeof(OptionCategory), category))
{
return APIResponseModel<OptionSimpleDto>.CreateErrorResponseModel(ResponseCode.ParameterError, "该分类不存在");
}
Options? options = await _context.Options.FirstOrDefaultAsync(x => x.Key == optionsKey && (OptionCategory)category == x.Category) ?? throw new Exception("数据不存在");
OptionSimpleDto optionSimpleDto = new()
{
Key = options.Key,
Value = options.Value,
Type = options.Type,
Category = options.Category,
RoleNames = options.RoleIds.Select(x => _roleManager.Roles.FirstOrDefault(r => r.Id == x)).Where(r => r != null).Select(r => r.Name).ToList()
};
// 不需要权限 直接返回
return APIResponseModel<OptionSimpleDto>.CreateSuccessResponseModel(optionSimpleDto);
}
catch (Exception ex)
{
return APIResponseModel<OptionSimpleDto>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
}
}