first commit

This commit is contained in:
yanpeng200212
2026-10-08 10:43:59 +08:00
commit 8430ba0452
288 changed files with 29595 additions and 0 deletions
@@ -0,0 +1,40 @@
using F9WebAiTest.Application.Common.Exceptions;
using F9WebAiTest.Application.Interfaces.SnowflakeID;
using F9WebAiTest.Domain.Entities.SYS.RBAC;
using F9WebAiTest.Domain.Interfaces.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Commands;
/// <summary>命令定义</summary>
public record UserRole_AssignCommand(long UserId, long RoleId) : IRequest<long>;
/// <summary>命令处理器</summary>
public class UserRole_AssignCommandHandler(
IUserRoleWriteRepository userRoleWriteRepository,
IUserWriteRepository userWriteRepository,
ISnowflakeIdGenerator snowflakeIdGenerator,
IPublisher eventBus) : IRequestHandler<UserRole_AssignCommand, long>
{
public async Task<long> Handle(UserRole_AssignCommand command, CancellationToken cancellationToken)
{
if (command.UserId <= 0) throw new F9OperationException("用户ID不能为空");
if (command.RoleId <= 0) throw new F9OperationException("角色ID不能为空");
var newEntity = new UserRole(snowflakeIdGenerator.CreateId(), command.UserId, command.RoleId);
var user = await userWriteRepository.GetByIdAsync(command.UserId);
if (user == null) throw new F9NotFoundException("用户", command.UserId);
user.AddRole(newEntity.Id);
var result = await userRoleWriteRepository.AssignAsync(newEntity);
if (result == false) throw new F9OperationException("权限", "绑定");
// 发布领域事件
foreach (var domainEvent in user.DomainEvents)
await eventBus.Publish(domainEvent, cancellationToken);
user.ClearDomainEvents();
return newEntity.Id;
}
}
@@ -0,0 +1,35 @@
using F9WebAiTest.Application.Common.Exceptions;
using F9WebAiTest.Domain.Interfaces.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Commands;
/// <summary>命令定义</summary>
public record UserRole_RemoveCommand(long UserId, long RoleId) : IRequest<bool>;
/// <summary>命令处理器</summary>
public class UserRole_RemoveCommandHandler(
IUserWriteRepository userWriteRepository,
IUserRoleWriteRepository userRoleWriteRepository,
IPublisher eventBus) : IRequestHandler<UserRole_RemoveCommand, bool>
{
public async Task<bool> Handle(UserRole_RemoveCommand command, CancellationToken cancellationToken)
{
if (command.UserId <= 0) throw new F9OperationException("用户ID不能为空");
if (command.RoleId <= 0) throw new F9OperationException("角色ID不能为空");
var user = await userWriteRepository.GetByIdAsync(command.UserId);
if (user == null) throw new F9NotFoundException("用户", command.UserId);
user.RemoveRole(command.RoleId);
var result = await userRoleWriteRepository.RemoveAsync(command.UserId, command.RoleId);
if (result == false) throw new F9OperationException("权限", "解绑");
// 发布领域事件
foreach (var domainEvent in user.DomainEvents)
await eventBus.Publish(domainEvent, cancellationToken);
user.ClearDomainEvents();
return result;
}
}
@@ -0,0 +1,26 @@
using F9WebAiTest.Application.Common.Exceptions;
using F9WebAiTest.Domain.Interfaces.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Commands;
/// <summary>命令定义</summary>
public record User_ActiveOrDeactivateCommand(long Id, bool Active) : IRequest<bool>;
/// <summary>命令处理器</summary>
public class ActiveOrDeactivateUserCommandHandler(
IUserWriteRepository userWriteRepository) : IRequestHandler<User_ActiveOrDeactivateCommand, bool>
{
public async Task<bool> Handle(User_ActiveOrDeactivateCommand command, CancellationToken cancellationToken)
{
var user = await userWriteRepository.GetByIdAsync(command.Id);
if (user == null) throw new F9NotFoundException("用户", command.Id);
if (command.Active) user.Activate();
else user.Deactivate();
var result = await userWriteRepository.ActiveOrDeactive(command.Id, user.IsActive);
if (result == false) throw new F9OperationException("启用/禁用", "操作");
return result;
}
}
@@ -0,0 +1,73 @@
using F9WebAiTest.Application.Common.Exceptions;
using F9WebAiTest.Application.Interfaces.Security;
using F9WebAiTest.Application.Interfaces.SnowflakeID;
using F9WebAiTest.Application.Interfaces.UOW;
using F9WebAiTest.Domain.Entities.SYS.Departments;
using F9WebAiTest.Domain.Entities.SYS.RBAC;
using F9WebAiTest.Domain.Interfaces.SYS.Departments;
using F9WebAiTest.Domain.Interfaces.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Commands;
/// <summary>命令定义</summary>
public record User_CreateCommand(string UserName, string PhoneNumber, string LoginName, long DepartmentId, int SortOrder) : IRequest<long>;
/// <summary>命令处理器</summary>
public class CreateUserCommandHandler(
IUnitOfWork_F9 unitOfWork,
IUserWriteRepository userRepository,
IDepartmentWriteRepository departmentWriteRepository,
IDepartmentUserRepository departmentUserRepository,
IPasswordHasher passwordHasher,
ISnowflakeIdGenerator snowflakeIdGenerator,
IPublisher eventBus) : IRequestHandler<User_CreateCommand, long>
{
public async Task<long> Handle(User_CreateCommand command, CancellationToken cancellationToken)
{
// 手写校验
if (string.IsNullOrWhiteSpace(command.UserName)) throw new F9OperationException("用户名不能为空");
if (string.IsNullOrWhiteSpace(command.LoginName)) throw new F9OperationException("登录名不能为空");
if (command.DepartmentId <= 0) throw new F9OperationException("部门不能为空");
User createdUser = null;
var ok = await unitOfWork.ExecuteWithUow(async () =>
{
// 1. 验证部门是否存在(应用层协调)
var department = await departmentWriteRepository.GetByIdAsync(command.DepartmentId, cancellationToken);
if (department == null) throw new F9NotFoundException("部门不存在");
// 2. 创建用户聚合根
var user = new User(
id: snowflakeIdGenerator.CreateId(),
command.UserName,
command.PhoneNumber,
command.LoginName,
command.DepartmentId,
command.SortOrder);
// 设置默认密码
var defaultPasswordMd5 = passwordHasher.GetMd5Hash(user.GetDefaultPasswordText());
var passwordHash = passwordHasher.HashPassword(defaultPasswordMd5);
user.SetPassword(passwordHash);
await userRepository.AddAsync(user);
// 3. 创建部门用户关联
var depUser = new DepartmentUser(snowflakeIdGenerator.CreateId(), command.DepartmentId, user.Id);
await departmentUserRepository.AssignAsync(depUser);
createdUser = user;
return true;
});
if (!ok) throw new F9OperationException("用户", "新增");
// 4. 事务提交后发布领域事件
foreach (var domainEvent in createdUser.DomainEvents)
await eventBus.Publish(domainEvent, cancellationToken);
createdUser.ClearDomainEvents();
return createdUser.Id;
}
}
@@ -0,0 +1,22 @@
using F9WebAiTest.Application.Common.Exceptions;
using F9WebAiTest.Domain.Interfaces.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Commands;
/// <summary>命令定义</summary>
public record User_DelCommand(long Id) : IRequest<bool>;
/// <summary>命令处理器</summary>
public class DelUserCommandHandler(
IUserWriteRepository userWriteRepository) : IRequestHandler<User_DelCommand, bool>
{
public async Task<bool> Handle(User_DelCommand command, CancellationToken cancellationToken)
{
if (command.Id <= 0) throw new F9OperationException("用户ID不能为空");
var result = await userWriteRepository.SoftDeleteAsync(command.Id);
if (result == false) throw new F9OperationException("用户", "删除");
return result;
}
}
@@ -0,0 +1,32 @@
using F9WebAiTest.Application.Common.Exceptions;
using F9WebAiTest.Application.Interfaces.Security;
using F9WebAiTest.Domain.Interfaces.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Commands;
/// <summary>命令定义</summary>
public record User_ResetPasswordCommand(long Id) : IRequest<bool>;
/// <summary>命令处理器</summary>
public class ResetPasswordUserCommandHandler(
IUserWriteRepository userWriteRepository,
IPasswordHasher passwordHasher) : IRequestHandler<User_ResetPasswordCommand, bool>
{
public async Task<bool> Handle(User_ResetPasswordCommand command, CancellationToken cancellationToken)
{
if (command.Id <= 0) throw new F9OperationException("用户ID不能为空");
var dbUser = await userWriteRepository.GetByIdAsync(command.Id);
if (dbUser == null) throw new F9NotFoundException("用户", command.Id);
// 设置默认密码
var defaultPasswordMd5 = passwordHasher.GetMd5Hash(dbUser.GetDefaultPasswordText());
var passwordHash = passwordHasher.HashPassword(defaultPasswordMd5);
dbUser.SetPassword(passwordHash);
var result = await userWriteRepository.UpdatePassworkdAsync(command.Id, dbUser.PasswordHash);
if (result == false) throw new F9OperationException("用户", "重置密码");
return result;
}
}
@@ -0,0 +1,49 @@
using F9WebAiTest.Application.Common.Exceptions;
using F9WebAiTest.Application.Interfaces.SnowflakeID;
using F9WebAiTest.Application.Interfaces.UOW;
using F9WebAiTest.Domain.Entities.SYS.Departments;
using F9WebAiTest.Domain.Interfaces.SYS.Departments;
using F9WebAiTest.Domain.Interfaces.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Commands;
/// <summary>命令定义</summary>
public record User_UpdateCommand(long Id, string UserName, string PhoneNumber, string LoginName, long DepartmentId, int SortOrder) : IRequest<bool>;
/// <summary>命令处理器</summary>
public class User_UpdateCommandHandler(
IUnitOfWork_F9 unitOfWork,
ISnowflakeIdGenerator snowflakeIdGenerator,
IUserWriteRepository userWriteRepository,
IDepartmentUserRepository departmentUserRepository) : IRequestHandler<User_UpdateCommand, bool>
{
public async Task<bool> Handle(User_UpdateCommand command, CancellationToken cancellationToken)
{
if (command.Id <= 0) throw new F9OperationException("用户ID不能为空");
if (string.IsNullOrWhiteSpace(command.UserName)) throw new F9OperationException("用户名不能为空");
if (command.DepartmentId <= 0) throw new F9OperationException("部门不能为空");
return await unitOfWork.ExecuteWithUow(async () =>
{
// 获取数据库用户
var dbUser = await userWriteRepository.GetByIdAsync(command.Id);
if (dbUser == null) throw new F9NotFoundException("用户", command.Id);
// 移除原部门关系
await departmentUserRepository.RemoveAsync(dbUser.DepartmentId, dbUser.Id);
// 领域更新
dbUser.Update(command.UserName, command.PhoneNumber, command.LoginName, command.DepartmentId, command.SortOrder);
// 持久化
var result = await userWriteRepository.UpdateAsync(dbUser);
// 添加新部门关系
await departmentUserRepository.AssignAsync(new DepartmentUser(
snowflakeIdGenerator.CreateId(), dbUser.DepartmentId, dbUser.Id));
return result;
});
}
}
@@ -0,0 +1,13 @@
using F9WebAiTest.Application.Dtos.SYS.RBAC.Users;
using F9WebAiTest.Application.Interfaces.Repositories.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Queries;
public record GetUserByIdQuery(long id) : IRequest<UserReadDto_Edit>;
public class GetUserByIdQueryHandler(IUserReadRepository userReadRepository) : IRequestHandler<GetUserByIdQuery, UserReadDto_Edit>
{
public async Task<UserReadDto_Edit> Handle(GetUserByIdQuery query, CancellationToken ct)
=> await userReadRepository.GetByIdAsync(query.id);
}
@@ -0,0 +1,13 @@
using F9WebAiTest.Application.Dtos.SYS.RBAC.Users;
using F9WebAiTest.Application.Interfaces.Repositories.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Queries;
public record GetUserByIdsQuery(List<long> Ids) : IRequest<List<UserReadDto_Edit>>;
public class GetUserByIdsQueryHandler(IUserReadRepository userReadRepository) : IRequestHandler<GetUserByIdsQuery, List<UserReadDto_Edit>>
{
public async Task<List<UserReadDto_Edit>> Handle(GetUserByIdsQuery query, CancellationToken ct)
=> await userReadRepository.GetByIdsAsync(query.Ids);
}
@@ -0,0 +1,14 @@
using F9WebAiTest.Application.Dtos.Common;
using F9WebAiTest.Application.Dtos.SYS.RBAC.Users;
using F9WebAiTest.Application.Interfaces.Repositories.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Queries;
public record GetUserPagedQuery(long DepartmentId, string Like, int Page = 1, int PageSize = 10) : IRequest<PagedResult<UserReadDto_View>>;
public class GetUserPagedQueryHandler(IUserReadRepository userReadRepository) : IRequestHandler<GetUserPagedQuery, PagedResult<UserReadDto_View>>
{
public async Task<PagedResult<UserReadDto_View>> Handle(GetUserPagedQuery query, CancellationToken ct)
=> await userReadRepository.GetPagedAsync(query.DepartmentId, query.Like, query.Page, query.PageSize);
}
@@ -0,0 +1,13 @@
using F9WebAiTest.Application.Dtos.SYS.RBAC.Users;
using F9WebAiTest.Application.Interfaces.Repositories.SYS.RBAC.Users;
using MediatR;
namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Users.Queries;
public record GetUserRolesByUserIdQuery(long UserId) : IRequest<List<UserRoleReadDto_Cache>>;
public class GetUserRolesByUserIdQueryHandler(IUserReadRepository userReadRepository) : IRequestHandler<GetUserRolesByUserIdQuery, List<UserRoleReadDto_Cache>>
{
public async Task<List<UserRoleReadDto_Cache>> Handle(GetUserRolesByUserIdQuery query, CancellationToken ct)
=> await userReadRepository.GetUserRolesByUserId(query.UserId);
}