LMS.service/LMS.service/Service/SoftwareService/SoftwareControlService.cs
lq1405 57402e0dda V1.0.4
1. 新增用户注册需要邮箱验证码
2. 机器码、软件权限控制、用户 隔离,除非超级管理员,其他用户只能看到自己下面的用户,管理员可以看到除超级管理员以外的所有
2025-03-16 23:01:50 +08:00

520 lines
24 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.Enum;
using LMS.DAO;
using LMS.DAO.UserDAO;
using LMS.Repository.DB;
using LMS.Repository.DTO;
using LMS.Repository.DTO.Software;
using LMS.Repository.DTO.UserDto;
using LMS.Repository.Models.DB;
using LMS.Repository.Software;
using LMS.Tools;
using LMS.Tools.Extensions;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using static LMS.Common.Enums.ResponseCodeEnum;
namespace LMS.service.Service.SoftwareService
{
public class SoftwareControlService(UserBasicDao userBasicDao, ApplicationDbContext dbContext, IMapper mapper, UserManager<User> userManager)
{
private readonly UserBasicDao _userBasicDao = userBasicDao;
private readonly ApplicationDbContext _dbContext = dbContext;
private readonly IMapper _mapper = mapper;
private readonly UserManager<User> _userManager = userManager;
#region -
/// <summary>
/// 用户自动同步软件控制和software中的一致只要没有的数据都同步上不管isUse这个会在后面过滤掉
/// </summary>
/// <param name="id"></param>
/// <param name=""></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
internal async Task<ActionResult<APIResponseModel<string>>> ApplySoftwareControl(long id, long requestUserId)
{
using var transaction = _dbContext.Database.BeginTransaction();
try
{
// 用户ID和请求ID不一致且请求ID不是管理员或超级管理员返回无权限操作
if (id != requestUserId && !await _userBasicDao.CheckUserIsAdminOrSuperAdmin(requestUserId))
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
// 检查用户是否存在
if (!await _userBasicDao.CheckUserExistsByID(id))
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.FindUserByIdFail);
}
List<SoftwareControl> softwareControl = await _dbContext.SoftwareControl.Where(x => x.UserId == id).ToListAsync();
// 判断是不是可以使用
List<Software> software = await _dbContext.Software.Where(x => x.IsUse).ToListAsync();
bool isAdd = false;
// 判断是不是所有的软件都有权限,如果没有就添加
foreach (var item in software)
{
if (softwareControl.FirstOrDefault(x => x.SoftwareId == item.Id) == null)
{
SoftwareControl softwareControlModel = new SoftwareControl
{
Id = Guid.NewGuid().ToString(),
UserId = id,
SoftwareId = item.Id,
CreatedUserId = requestUserId,
CreatedTime = BeijingTimeExtension.GetBeijingTime(),
UpdatedUserId = requestUserId,
UpdatedTime = BeijingTimeExtension.GetBeijingTime(),
Remark = string.Empty,
IsForever = false,
ExpirationTime = null,
};
await _dbContext.SoftwareControl.AddAsync(softwareControlModel);
isAdd = true;
}
}
// 判断现在的将再soft中没有的软件控制删除
foreach (var item1 in softwareControl)
{
if (software.FirstOrDefault(x => x.Id == item1.SoftwareId) == null)
{
_dbContext.SoftwareControl.Remove(item1);
isAdd = true;
}
}
await _dbContext.SaveChangesAsync();
await transaction.CommitAsync();
if (isAdd)
{
return APIResponseModel<string>.CreateSuccessResponseModel("同步所有的软件权限成功");
}
else
{
return APIResponseModel<string>.CreateSuccessResponseModel("当前已获取所有的软件控制权限,不需要做处理");
}
}
catch (Exception ex)
{
await transaction.RollbackAsync();
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region -
/// <summary>
/// 设置软件的到期时间和是否永久
/// </summary>
/// <param name="id">软件控制项的ID</param>
/// <param name="model">传入的数据</param>
/// <param name="requestUserId">请求的用户ID</param>
/// <returns></returns>
public async Task<ActionResult<APIResponseModel<string>>> ModifySoftwareControlValidity(string id, ModifySoftwareControlValidityModel model, long requestUserId)
{
try
{
if (model.IsForever == null && model.ExpirationTime == null && model.IsTry == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError);
}
model.IsTry ??= false;
// 检查用户是不是管理员
if (!await _userBasicDao.CheckUserIsAdminOrSuperAdmin(requestUserId))
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
// 判断指定ID的软件控制项是否存在
SoftwareControl? softwareControl = await _dbContext.SoftwareControl.FirstOrDefaultAsync(x => x.Id == id);
if (softwareControl == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.IdDateNotFound);
}
// 试用
if (model.IsTry == true)
{
// 设置更新时间和更新人
softwareControl.UpdatedTime = BeijingTimeExtension.GetBeijingTime();
softwareControl.UpdatedUserId = requestUserId;
double trialDays = 1;
Options? options = await _dbContext.Options.FirstOrDefaultAsync(x => x.Key == "LaiToolTrialDays");
if (options != null)
{
double s = options.GetValueObject<double>();
trialDays = s;
}
softwareControl.ExpirationTime = BeijingTimeExtension.GetBeijingTime().AddDays(trialDays);
softwareControl.IsForever = false;
// 更新数据库
_dbContext.SoftwareControl.Update(softwareControl);
await _dbContext.SaveChangesAsync();
return APIResponseModel<string>.CreateSuccessResponseModel("修改成功");
}
if (model.ExpirationTime != null)
{
// 判断model传入的枚举值是不是再对应的enum中是有效的
if (!Enum.IsDefined(typeof(SoftwareControlEnum.SoftwareControlValidityEnum), model.ExpirationTime))
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError, "传入的到期时间不在有效范围内");
}
}
// 判断当前数据是不是永久,如果是永久,就不能修改
if (softwareControl.IsForever && model.IsForever == true)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError, "当前已是永久,不可再修改");
}
// 判断传入的modal的IsForever是不是true是的话直接设置未永久不是的话设置到期时间
if (model.IsForever == true)
{
softwareControl.IsForever = true;
softwareControl.ExpirationTime = null;
}
else
{
// 这边判断现在的到期时间是不是大于现在的时间,是的话,再到期时间的基础上加上传入的时间,不是的话,直接再现在时间加上传入的时间,如果现在是永久,直接设置到期时间为现在时间加上传入的时间
if (model.ExpirationTime == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.ParameterError, "当前到期时间为空,不可修改");
}
if (softwareControl.IsForever == true)
{
softwareControl.ExpirationTime = BeijingTimeExtension.GetBeijingTime().AddDays((double)model.ExpirationTime.Value);
softwareControl.IsForever = false;
}
else
{
if (softwareControl.ExpirationTime > BeijingTimeExtension.GetBeijingTime())
{
if (model.ExpirationTime == SoftwareControlEnum.SoftwareControlValidityEnum.Zero)
{
softwareControl.ExpirationTime = BeijingTimeExtension.GetBeijingTime();
}
else
{
softwareControl.ExpirationTime = softwareControl.ExpirationTime.Value.AddDays((double)model.ExpirationTime.Value);
}
}
else
{
softwareControl.ExpirationTime = BeijingTimeExtension.GetBeijingTime().AddDays((double)model.ExpirationTime.Value);
}
}
}
// 设置更新时间和更新人
softwareControl.UpdatedTime = BeijingTimeExtension.GetBeijingTime();
softwareControl.UpdatedUserId = requestUserId;
// 更新数据库
_dbContext.SoftwareControl.Update(softwareControl);
await _dbContext.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="userId"></param>
/// <param name="softwareId"></param>
/// <param name="isForever"></param>
/// <param name="remark"></param>
/// <param name="reuqestUserId"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<ActionResult<APIResponseModel<CollectionResponse<SoftwareControlCollectionDto>>>> GetSoftwareControlCollection(int page, int pageSize, long? userId, string? softwareId, bool? isForever, string? remark, long requestUserId)
{
try
{
// 判断权限,如果不是管理员或超级管理员,就判断是不是自己的数据,不是的话,返回无权限操作
IQueryable<SoftwareControl> query = _dbContext.SoftwareControl.AsQueryable();
bool isSuperAdmin = await _userBasicDao.CheckUserIsSuperAdmin(requestUserId);
bool isAdmin = await _userBasicDao.CheckUserIsAdmin(requestUserId);
bool isAgent = await _userBasicDao.CheckUserIsAgent(requestUserId);
if (!(isSuperAdmin || isAdmin || isAgent) && userId != requestUserId)
{
return APIResponseModel<CollectionResponse<SoftwareControlCollectionDto>>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
if (userId != null)
{
query = query.Where(x => x.UserId == userId);
}
if (softwareId != null)
{
query = query.Where(x => x.SoftwareId == softwareId);
}
if (isForever != null)
{
query = query.Where(x => x.IsForever == isForever);
}
if (!string.IsNullOrWhiteSpace(remark))
{
query = query.Where(x => x.Remark.Contains(remark));
}
if (!(isSuperAdmin || isAdmin))
{
// 通过 softwareId 过滤掉isUse为false的数
List<string> softwareIds = await _dbContext.Software.Where(x => x.IsUse == true).Select(x => x.Id).ToListAsync();
query = query.Where(x => softwareIds.Contains(x.SoftwareId));
}
// 做筛选权限
// 获取相关用户ID
var userLookupQuery = _userManager.Users.AsNoTracking();
if (isAdmin && !isSuperAdmin)
{
// 除了超级管理员的代理 其他都能看到
IList<User> superUsers = await _userManager.GetUsersInRoleAsync("Super Admin");
List<long> superUserIds = superUsers.Select(x => x.Id).ToList();
var list = await userLookupQuery
.Where(u => u.ParentId == null || superUserIds.Contains((long)u.ParentId) || superUserIds.Contains(u.Id))
.Select(u => u.Id)
.ToListAsync();
HashSet<long> filteredParentIds = new(list);
if (filteredParentIds?.Count > 0)
{
query = query.Where(x => !filteredParentIds.Contains(x.UserId) || x.UserId == requestUserId);
}
}
else if (isAgent && !isSuperAdmin)
{
// 代理只能看到自己下面的用户
var list = await userLookupQuery
.Where(u => u.ParentId == requestUserId)
.Select(u => u.Id)
.ToListAsync();
HashSet<long> filteredParentIds = new(list);
if (filteredParentIds?.Count > 0)
{
query = query.Where(x => filteredParentIds.Contains(x.UserId));
}
}
else if (!isSuperAdmin)
{
// 普通用户只能看到自己的
query = query.Where(x => x.UserId == requestUserId);
}
// 通过ID降序
query = query.OrderByDescending(x => x.CreatedTime);
// 查询总数
int total = await query.CountAsync();
// 分页
query = query.Skip((page - 1) * pageSize).Take(pageSize);
List<SoftwareControl> softwareControls = await query.ToListAsync();
List<SoftwareControlCollectionDto> softwareControlCollectionDtos = new List<SoftwareControlCollectionDto>();
foreach (var item in softwareControls)
{
SoftwareControlCollectionDto softwareControlCollectionDto = new SoftwareControlCollectionDto
{
Id = item.Id,
IsForever = item.IsForever,
ExpirationTime = item.ExpirationTime,
Remark = item.Remark,
CreatedTime = item.CreatedTime,
UpdatedTime = item.UpdatedTime,
};
Software? software = await _dbContext.Software.FirstOrDefaultAsync(x => x.Id == item.SoftwareId);
if (software != null)
{
softwareControlCollectionDto.Software = software;
}
User? user = await _dbContext.Users.FirstOrDefaultAsync(x => x.Id == item.UserId);
softwareControlCollectionDto.User = _mapper.Map<UserBaseDto>(user);
softwareControlCollectionDto.User.HideContactInfo();
User? createdUser = await _dbContext.Users.FirstOrDefaultAsync(x => x.Id == item.CreatedUserId);
softwareControlCollectionDto.CreatedUser = _mapper.Map<UserBaseDto>(createdUser);
softwareControlCollectionDto.CreatedUser.HideContactInfo();
User? updatedUser = await _dbContext.Users.FirstOrDefaultAsync(x => x.Id == item.UpdatedUserId);
softwareControlCollectionDto.UpdatedUser = _mapper.Map<UserBaseDto>(updatedUser);
softwareControlCollectionDto.UpdatedUser.HideContactInfo();
softwareControlCollectionDtos.Add(softwareControlCollectionDto);
}
return APIResponseModel<CollectionResponse<SoftwareControlCollectionDto>>.CreateSuccessResponseModel(new CollectionResponse<SoftwareControlCollectionDto>
{
Total = total,
Collection = softwareControlCollectionDtos,
Current = page,
});
}
catch (Exception ex)
{
return APIResponseModel<CollectionResponse<SoftwareControlCollectionDto>>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region -
/// <summary>
/// 删除软件控制数据
/// </summary>
/// <param name="id"></param>
/// <param name="requestUserId"></param>
/// <returns></returns>
public async Task<ActionResult<APIResponseModel<string>>> DeleteSoftwareControl(string id, long requestUserId)
{
try
{
if (!await _userBasicDao.CheckUserIsAdminOrSuperAdmin(requestUserId))
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
SoftwareControl? softwareControl = await _dbContext.SoftwareControl.FirstOrDefaultAsync(x => x.Id == id);
if (softwareControl == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.IdDateNotFound);
}
_dbContext.SoftwareControl.Remove(softwareControl);
await _dbContext.SaveChangesAsync();
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="machineId"></param>
/// <param name="softwareId"></param>
/// <returns></returns>
public async Task<ActionResult<APIResponseModel<string>>> CheckSoftwareControl(long userID, string machineId, string softwareId)
{
try
{
// 判断软件是不是存在
if (!await _dbContext.Software.AnyAsync(x => x.Id == softwareId))
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.IdDateNotFound);
}
// 判断是不是有关联信息,没有的话就是没有登录,或者是机器码不一致,再其他地方登录过了
UserSoftware? userSoftware = await _dbContext.UserSoftware.FirstOrDefaultAsync(x => x.UserId == userID && x.MachineId == machineId);
if (userSoftware == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction, "无用户登录信息或登录信息不正确,请确认是不是登录多次,请重新登录");
}
// 判断是不是有权限
SoftwareControl? softwareControl = await _dbContext.SoftwareControl.FirstOrDefaultAsync(x => x.UserId == userID && x.SoftwareId == softwareId);
if (softwareControl == null)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction, "无权限操作,请先申请权限");
}
// 判断是不是还能用
if (softwareControl.IsForever == true || softwareControl.ExpirationTime > BeijingTimeExtension.GetBeijingTime())
{
// 可用
return APIResponseModel<string>.CreateSuccessResponseModel("1");
}
else
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.NotPermissionAction, "权限已过期,请重新申请");
}
}
catch (Exception ex)
{
return APIResponseModel<string>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
#region -
/// <summary>
/// 用户可申请的软件控制数量
/// </summary>
/// <param name="userId"></param>
/// <param name="requestUserId"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<ActionResult<APIResponseModel<int>>> GetUserSoftwareControlCount(long userId, long requestUserId)
{
try
{
bool isAdminOrSuperAdmin = await _userBasicDao.CheckUserIsAdminOrSuperAdmin(requestUserId);
if (!isAdminOrSuperAdmin && userId != requestUserId)
{
return APIResponseModel<int>.CreateErrorResponseModel(ResponseCode.NotPermissionAction);
}
User? user = await _dbContext.Users.FirstOrDefaultAsync(x => x.Id == userId);
if (user == null)
{
return APIResponseModel<int>.CreateErrorResponseModel(ResponseCode.FindUserByIdFail);
}
List<Software> software = await _dbContext.Software.Where(x => x.IsUse == true).ToListAsync();
List<SoftwareControl> softwareControls = await _dbContext.SoftwareControl.Where(x => x.UserId == userId).ToListAsync();
// 判断software中的softwareId是否在softwareControl中不在的话不在的话计数
int count = 0;
foreach (var item in software)
{
if (softwareControls.FirstOrDefault(x => x.SoftwareId == item.Id) == null)
{
count++;
}
}
return APIResponseModel<int>.CreateSuccessResponseModel(count);
}
catch (Exception ex)
{
return APIResponseModel<int>.CreateErrorResponseModel(ResponseCode.SystemError, ex.Message);
}
}
#endregion
}
}