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; /// /// 操作日志服务实现 /// public class OperationLogService( BaseRepository operationLogRepository, BaseRepository adminUserRepository, BaseRepository usersRepository, ILogger logger) : BaseRepository, IOperationLogService { /// /// 记录操作日志 /// 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); } } /// /// 分页查询操作日志 /// public async Task> GetListAsync(OperationLogQueryInput input) { if (input.PageIndex <= 0) input.PageIndex = 1; if (input.PageSize <= 0 || input.PageSize > 100) input.PageSize = 10; RefAsync 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(pageResult, input.PageIndex, input.PageSize, totalNumber); } /// /// 获取操作日志详情 /// public async Task GetDetailAsync(long id) { var log = await operationLogRepository.Queryable() .Where(l => l.Id == id && !l.IsDeleted) .FirstAsync(); if (log == null) { throw new BusinessException("操作日志记录不存在", ResultCode.NOT_FOUND); } 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.TargetUserAvatar = targetUser.AvatarUrl; // Phone 已迁移到 WxUser 表,通过 WxUserId 关联查询 var wxUser = await usersRepository.Context.Queryable() .Where(w => w.Id == targetUser.WxUserId && !w.IsDeleted) .FirstAsync(); result.TargetUserPhone = wxUser?.Phone; } } return result; } }