Files
QYZH.InteractiveMagazine/QYZH.InteractiveMagazine.Service/AdminUserService.cs
glz 831f8ba7f5 feat: 初始化后台管理模块与基础业务框架
1.  新增依赖注入生命周期标记接口、基础仓储与管理员仓储实现
2.  新增管理员认证与用户服务接口,补充认证相关DTO
3.  重构实体审计字段命名,统一Created/UpdatedAt规范
4.  新增大量业务实体类与API版本枚举配置
5.  集成Autofac依赖注入、JWT自动刷新与跨域配置
6.  替换原有微信小程序与旧认证服务为后台管理系统架构
7.  完善Swagger文档配置与项目基础部署配置
2026-06-01 17:59:23 +08:00

268 lines
8.9 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 System.Linq.Expressions;
using BCrypt.Net;
using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.IService.Dto;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Repository;
namespace QYZH.InteractiveMagazine.Service;
/// <summary>
/// 管理员用户服务实现
/// </summary>
public class AdminUserService : IAdminUserService
{
private readonly IAdminUserRepository _adminUserRepository;
private readonly ILogger<AdminUserService> _logger;
public AdminUserService(IAdminUserRepository adminUserRepository, ILogger<AdminUserService> logger)
{
_adminUserRepository = adminUserRepository;
_logger = logger;
}
/// <summary>
/// 创建管理员
/// </summary>
public async Task<AdminUserOutput> CreateAsync(AdminUserInput input)
{
_logger.LogInformation("正在创建管理员,用户名: {UserName}", input.UserName);
if (string.IsNullOrWhiteSpace(input.UserName))
{
throw new BusinessException("用户名不能为空", 400);
}
if (string.IsNullOrWhiteSpace(input.Password))
{
throw new BusinessException("密码不能为空", 400);
}
// 检查用户名是否已存在
var existingUser = await _adminUserRepository.GetByUserNameAsync(input.UserName);
if (existingUser != null)
{
_logger.LogWarning("创建管理员失败,用户名已存在: {UserName}", input.UserName);
throw new BusinessException("用户名已存在", 400);
}
var adminUser = new AdminUser
{
UserName = input.UserName.Trim(),
PasswordHash = BCrypt.Net.BCrypt.HashPassword(input.Password),
Type = input.Type,
Status = input.Status,
CreatedBy = "System",
UpdatedBy = "System",
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
IsDeleted = false
};
var result = await _adminUserRepository.InsertAsync(adminUser);
if (!result)
{
_logger.LogError("管理员创建失败,用户名: {UserName}", input.UserName);
throw new BusinessException("创建管理员失败", 500);
}
_logger.LogInformation("管理员创建成功,用户名: {UserName}, ID: {Id}", input.UserName, adminUser.Id);
return MapToOutput(adminUser);
}
/// <summary>
/// 更新管理员
/// </summary>
public async Task<AdminUserOutput> UpdateAsync(long id, AdminUserInput input)
{
_logger.LogInformation("正在更新管理员ID: {Id}", id);
var adminUser = await _adminUserRepository.GetByIdAsync(id);
if (adminUser == null)
{
_logger.LogWarning("未找到要更新的管理员ID: {Id}", id);
throw new BusinessException("管理员不存在", 404);
}
// 如果用户名有变更,检查是否与其他用户重复
if (!string.IsNullOrWhiteSpace(input.UserName) && input.UserName != adminUser.UserName)
{
var existingUser = await _adminUserRepository.GetByUserNameAsync(input.UserName.Trim());
if (existingUser != null && existingUser.Id != id)
{
_logger.LogWarning("更新管理员失败,用户名已存在: {UserName}", input.UserName);
throw new BusinessException("用户名已存在", 400);
}
adminUser.UserName = input.UserName.Trim();
}
// 如果提供了密码,则更新密码
if (!string.IsNullOrWhiteSpace(input.Password))
{
adminUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(input.Password);
}
if (!string.IsNullOrWhiteSpace(input.Type))
{
adminUser.Type = input.Type;
}
if (!string.IsNullOrWhiteSpace(input.Status))
{
adminUser.Status = input.Status;
}
adminUser.UpdatedBy = "System";
adminUser.UpdatedAt = DateTime.Now;
var result = await _adminUserRepository.UpdateAsync(adminUser);
if (!result)
{
_logger.LogError("管理员更新失败ID: {Id}", id);
throw new BusinessException("更新管理员失败", 500);
}
_logger.LogInformation("管理员更新成功ID: {Id}", id);
return MapToOutput(adminUser);
}
/// <summary>
/// 删除管理员(软删除)
/// </summary>
public async Task DeleteAsync(long id)
{
_logger.LogInformation("正在删除管理员ID: {Id}", id);
var adminUser = await _adminUserRepository.GetByIdAsync(id);
if (adminUser == null)
{
_logger.LogWarning("未找到要删除的管理员ID: {Id}", id);
throw new BusinessException("管理员不存在", 404);
}
var result = await _adminUserRepository.DeleteByIdAsync(id);
if (!result)
{
_logger.LogError("管理员删除失败ID: {Id}", id);
throw new BusinessException("删除管理员失败", 500);
}
_logger.LogInformation("管理员删除成功ID: {Id}", id);
}
/// <summary>
/// 根据ID获取管理员
/// </summary>
public async Task<AdminUserOutput> GetByIdAsync(long id)
{
_logger.LogInformation("正在获取管理员信息ID: {Id}", id);
var adminUser = await _adminUserRepository.GetByIdAsync(id);
if (adminUser == null)
{
_logger.LogWarning("未找到管理员ID: {Id}", id);
throw new BusinessException("管理员不存在", 404);
}
return MapToOutput(adminUser);
}
/// <summary>
/// 分页查询管理员列表
/// </summary>
public async Task<PageListModel<AdminUserOutput>> GetListAsync(AdminUserQueryInput input)
{
_logger.LogInformation("正在查询管理员列表,页码: {PageIndex}, 每页条数: {PageSize}", input.PageIndex, input.PageSize);
if (input.PageIndex <= 0)
{
throw new BusinessException("页码必须大于0", 400);
}
if (input.PageSize <= 0 || input.PageSize > 100)
{
throw new BusinessException("每页条数必须在1-100之间", 400);
}
var pageResult = await _adminUserRepository.GetPageListAsync(
BuildQueryExpression(input),
input
);
// 转换为输出DTO
var outputList = pageResult.List?.Select(MapToOutput).ToList() ?? new List<AdminUserOutput>();
return new PageListModel<AdminUserOutput>
{
List = outputList,
TotalCount = pageResult.TotalCount,
PageIndex = pageResult.PageIndex,
PageSize = pageResult.PageSize
};
}
/// <summary>
/// 构建查询表达式
/// </summary>
private static Expression<Func<AdminUser, bool>> BuildQueryExpression(AdminUserQueryInput input)
{
Expression<Func<AdminUser, bool>> where = x => !x.IsDeleted;
if (!string.IsNullOrWhiteSpace(input.UserName))
{
var userName = input.UserName;
Expression<Func<AdminUser, bool>> userNameCondition = x => x.UserName.Contains(userName);
where = Expression.Lambda<Func<AdminUser, bool>>(
Expression.AndAlso(where.Body,
Expression.Invoke(userNameCondition, where.Parameters[0])),
where.Parameters);
}
if (!string.IsNullOrWhiteSpace(input.Type))
{
var type = input.Type;
Expression<Func<AdminUser, bool>> typeCondition = x => x.Type == type;
where = Expression.Lambda<Func<AdminUser, bool>>(
Expression.AndAlso(where.Body,
Expression.Invoke(typeCondition, where.Parameters[0])),
where.Parameters);
}
if (!string.IsNullOrWhiteSpace(input.Status))
{
var status = input.Status;
Expression<Func<AdminUser, bool>> statusCondition = x => x.Status == status;
where = Expression.Lambda<Func<AdminUser, bool>>(
Expression.AndAlso(where.Body,
Expression.Invoke(statusCondition, where.Parameters[0])),
where.Parameters);
}
return where;
}
/// <summary>
/// 将实体映射为输出DTO
/// </summary>
private static AdminUserOutput MapToOutput(AdminUser adminUser)
{
return new AdminUserOutput
{
Id = adminUser.Id,
UserName = adminUser.UserName,
Type = adminUser.Type,
Status = adminUser.Status,
CreatedBy = adminUser.CreatedBy,
CreatedAt = adminUser.CreatedAt,
UpdatedBy = adminUser.UpdatedBy,
UpdatedAt = adminUser.UpdatedAt
};
}
}