feat: 初始化后台管理模块与基础业务框架
1. 新增依赖注入生命周期标记接口、基础仓储与管理员仓储实现 2. 新增管理员认证与用户服务接口,补充认证相关DTO 3. 重构实体审计字段命名,统一Created/UpdatedAt规范 4. 新增大量业务实体类与API版本枚举配置 5. 集成Autofac依赖注入、JWT自动刷新与跨域配置 6. 替换原有微信小程序与旧认证服务为后台管理系统架构 7. 完善Swagger文档配置与项目基础部署配置
This commit is contained in:
267
QYZH.InteractiveMagazine.Service/AdminUserService.cs
Normal file
267
QYZH.InteractiveMagazine.Service/AdminUserService.cs
Normal file
@ -0,0 +1,267 @@
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user