146 lines
5.1 KiB
C#
146 lines
5.1 KiB
C#
|
|
using Microsoft.Extensions.Logging;
|
|||
|
|
using QYZH.InteractiveMagazine.IService;
|
|||
|
|
using QYZH.InteractiveMagazine.Models.Common;
|
|||
|
|
using QYZH.InteractiveMagazine.Models.Dto;
|
|||
|
|
using QYZH.InteractiveMagazine.Models.Entity;
|
|||
|
|
using QYZH.InteractiveMagazine.Repository;
|
|||
|
|
using Serilog.Core;
|
|||
|
|
using SqlSugar;
|
|||
|
|
|
|||
|
|
namespace QYZH.InteractiveMagazine.Service;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 操作日志服务实现
|
|||
|
|
/// </summary>
|
|||
|
|
public class OperationLogService(
|
|||
|
|
BaseRepository<OperationLog> operationLogRepository,
|
|||
|
|
BaseRepository<AdminUser> adminUserRepository,
|
|||
|
|
BaseRepository<Users> usersRepository,
|
|||
|
|
ILogger<OperationLogService> logger) : BaseRepository<OperationLog>, IOperationLogService
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 记录操作日志
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task LogAsync(long operatorId, string operatorName, string actionType, string targetType, long targetId, string? targetName = null, string? detail = null, string? ipAddress = null)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var log = new OperationLog
|
|||
|
|
{
|
|||
|
|
OperatorId = operatorId,
|
|||
|
|
OperatorName = operatorName,
|
|||
|
|
ActionType = actionType,
|
|||
|
|
TargetType = targetType,
|
|||
|
|
TargetId = targetId,
|
|||
|
|
TargetName = targetName,
|
|||
|
|
Detail = detail,
|
|||
|
|
IpAddress = ipAddress,
|
|||
|
|
IsDeleted = false,
|
|||
|
|
CreatedBy = operatorName,
|
|||
|
|
CreatedAt = DateTime.Now,
|
|||
|
|
UpdatedBy = operatorName,
|
|||
|
|
UpdatedAt = DateTime.Now
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
await operationLogRepository.InsertAsync(log);
|
|||
|
|
|
|||
|
|
logger.LogInformation(
|
|||
|
|
"记录操作日志,Operator: {Operator}, Action: {Action}, Target: {TargetType}/{TargetId}",
|
|||
|
|
operatorName, actionType, targetType, targetId);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
// 日志记录不应影响主业务流程
|
|||
|
|
logger.LogError(ex, "记录操作日志失败,Operator: {Operator}, Action: {Action}", operatorName, actionType);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 分页查询操作日志
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task<PageListModel<OperationLogOutput>> GetListAsync(OperationLogQueryInput input)
|
|||
|
|
{
|
|||
|
|
if (input.PageIndex <= 0)
|
|||
|
|
input.PageIndex = 1;
|
|||
|
|
|
|||
|
|
if (input.PageSize <= 0 || input.PageSize > 100)
|
|||
|
|
input.PageSize = 10;
|
|||
|
|
|
|||
|
|
RefAsync<int> totalNumber = 0;
|
|||
|
|
|
|||
|
|
var pageResult = await operationLogRepository.Queryable()
|
|||
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.OperatorName), l => l.OperatorName.Contains(input.OperatorName))
|
|||
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.ActionType), l => l.ActionType == input.ActionType)
|
|||
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.TargetType), l => l.TargetType == input.TargetType)
|
|||
|
|
.WhereIF(input.TargetId.HasValue, l => l.TargetId == input.TargetId.Value)
|
|||
|
|
.OrderByDescending(l => l.CreatedAt)
|
|||
|
|
.Select(l => new OperationLogOutput
|
|||
|
|
{
|
|||
|
|
Id = l.Id,
|
|||
|
|
OperatorId = l.OperatorId,
|
|||
|
|
OperatorName = l.OperatorName,
|
|||
|
|
ActionType = l.ActionType,
|
|||
|
|
TargetType = l.TargetType,
|
|||
|
|
TargetId = l.TargetId,
|
|||
|
|
TargetName = l.TargetName,
|
|||
|
|
Detail = l.Detail,
|
|||
|
|
IpAddress = l.IpAddress,
|
|||
|
|
CreatedAt = l.CreatedAt
|
|||
|
|
})
|
|||
|
|
.ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
|
|||
|
|
|
|||
|
|
return new PageListModel<OperationLogOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取操作日志详情
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task<OperationLogDetailOutput> GetDetailAsync(long id)
|
|||
|
|
{
|
|||
|
|
var log = await operationLogRepository.Queryable()
|
|||
|
|
.Where(l => l.Id == id && !l.IsDeleted)
|
|||
|
|
.FirstAsync();
|
|||
|
|
|
|||
|
|
if (log == null)
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("操作日志记录不存在");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var result = new OperationLogDetailOutput
|
|||
|
|
{
|
|||
|
|
Id = log.Id,
|
|||
|
|
ActionType = log.ActionType,
|
|||
|
|
TargetType = log.TargetType,
|
|||
|
|
TargetId = log.TargetId,
|
|||
|
|
TargetName = log.TargetName,
|
|||
|
|
Detail = log.Detail,
|
|||
|
|
IpAddress = log.IpAddress,
|
|||
|
|
CreatedAt = log.CreatedAt,
|
|||
|
|
OperatorName = log.OperatorName
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 查询操作人详细信息
|
|||
|
|
var adminUser = await adminUserRepository.GetByIdAsync(log.OperatorId);
|
|||
|
|
if (adminUser != null)
|
|||
|
|
{
|
|||
|
|
result.OperatorRole = adminUser.Type.ToString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 当目标类型为用户时,查询被操作人信息
|
|||
|
|
if (log.TargetType == OperationLogTargetType.User)
|
|||
|
|
{
|
|||
|
|
var targetUser = await usersRepository.GetByIdAsync(log.TargetId);
|
|||
|
|
if (targetUser != null)
|
|||
|
|
{
|
|||
|
|
result.TargetUserName = targetUser.Name;
|
|||
|
|
result.TargetUserPhone = targetUser.Phone;
|
|||
|
|
result.TargetUserAvatar = targetUser.AvatarUrl;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
}
|