赞
踩
区别于身份管理模块(Identity模块)的鉴权用户IdentityUser,业务用户(BusinessUser)是围绕业务系统中“用户”这一定义的领域模型。如:在一个医院系统中,业务用户可以是医生、护士、患者;在一个OA系统中,业务用户可以是员工、管理员、客户等。
业务用户和鉴权用户由同步机制关联,业务用户通过分布式事件(DistributedEvent)的同步器(Synchronizer)与鉴权用户关联同步。
在Health业务模块中,定义两种业务用户:
Client: 客户;
Employee: 员工。
这些业务用户继承自HealthUser,HealthUser是业务用户的基类,包含了业务用户的基本信息,如姓名,性别,出生日期,身份证号等。并且需要实现IUpdateUserData接口,以便在同步鉴权用户信息时,更新业务用户的基本信息。
Employee包含工号,职称,简介等信息。其领域模型定义如下:
- public class Employee : HealthUser<Guid>, IUser, IUpdateUserData
- {
- [StringLength(12)]
- public string EmployeeNumber { get; set; }
-
- [StringLength(64)]
- public string EmployeeTitle { get; set; }
-
- public string Introduction { get; set; }
-
- ...
- }
-
Client包含客户号,身高,体重,婚姻状况等信息。其领域模型定义如下:
- public class Client : HealthUser<Guid>, IUser, IUpdateUserData
- {
-
- //unique
-
- [StringLength(12)]
- public string ClientNumber { get; set; }
-
- public string ClientNumberType { get; set; }
-
- [Range(0.0, 250.0)]
- public double? Height { get; set; }
-
-
- [Range(0.0, 1000.0)]
- public double? Weight { get; set; }
-
- public string Marriage { get; set; }
-
- public string Status { get; set; }
- }
-
以Client为例,ClientLookupService是业务用户的查询服务,其基类UserLookupService定义了关联用户的查询接口,包括按ID查询,按用户名查询,按组织架构查询,按户关系查询等。
创建ClientLookupService, 代码如下
- public class ClientLookupService : UserLookupService<Client, IClientRepository>, IClientLookupService
- {
- public ClientLookupService(
- IClientRepository userRepository,
- IUnitOfWorkManager unitOfWorkManager)
- : base(
- userRepository,
- unitOfWorkManager)
- {
-
- }
-
- protected override Client CreateUser(IUserData externalUser)
- {
- return new Client(externalUser);
- }
- }
-
同步器订阅了分布式事件EntityUpdatedEto,当鉴权用户更新时,同步器将更新业务用户的基本信息。
创建ClientSynchronizer,代码如下
- public class ClientSynchronizer :
- IDistributedEventHandler<EntityUpdatedEto<UserEto>>,
- ITransientDependency
- {
- protected IClientRepository UserRepository { get; }
- protected IClientLookupService UserLookupService { get; }
-
- public ClientSynchronizer(
- IClientRepository userRepository,
- IClientLookupService userLookupService)
- {
- UserRepository = userRepository;
- UserLookupService = userLookupService;
- }
-
- public async Task HandleEventAsync(EntityUpdatedEto<UserEto> eventData)
- {
- var user = await UserRepository.FindAsync(eventData.Entity.Id);
- if (user != null)
- {
- if (user.Update(eventData.Entity))
- {
- await UserRepository.UpdateAsync(user);
- }
- }
- }
- }
以Employee为例
在应用层中创建EmployeeAppService,在这里我们实现对业务用户的增删改查操作。
EmployeeAppService继承自CrudAppService,它是ABP框架提供的增删改查的基类,其基类定义了增删改查的接口,包括GetAsync,GetListAsync,CreateAsync,UpdateAsync,DeleteAsync等。
OrganizationUnit为业务用户的查询接口的按组织架构查询提供查询依据。OrganizationUnitAppService注入到EmployeeAppService中。
- public class EmployeeAppService : CrudAppService<Employee, EmployeeDto, Guid, GetAllEmployeeInput, CreateEmployeeInput>, IEmployeeAppService
- {
- private readonly IOrganizationUnitAppService organizationUnitAppService;
-
- }
创建CreateWithUserAsync方法,用于创建业务用户。
- public async Task<EmployeeDto> CreateWithUserAsync(CreateEmployeeWithUserInput input)
- {
-
- var createdUser = await identityUserAppService.CreateAsync(input);
- await CurrentUnitOfWork.SaveChangesAsync();
- var currentEmployee = await userLookupService.FindByIdAsync(createdUser.Id);
- ObjectMapper.Map(input, currentEmployee);
- var updatedEmployee = await Repository.UpdateAsync(currentEmployee);
- var result = ObjectMapper.Map<Employee, EmployeeDto>(updatedEmployee);
-
- if (input.OrganizationUnitId.HasValue)
- {
- await organizationUnitAppService.AddToOrganizationUnitAsync(
- new UserToOrganizationUnitInput()
- { UserId = createdUser.Id, OrganizationUnitId = input.OrganizationUnitId.Value });
- }
- return result;
- }
删除接口由CrudAppService提供默认实现,无需重写。
创建UpdateWithUserAsync方法,用于更新业务用户。
- public async Task<EmployeeDto> UpdateWithUserAsync(CreateEmployeeInput input)
- {
-
- var currentEmployee = await userLookupService.FindByIdAsync(input.Id);
- if (currentEmployee == null)
- {
- throw new UserFriendlyException("没有找到对应的用户");
- }
- ObjectMapper.Map(input, currentEmployee);
- var updatedEmployee = await Repository.UpdateAsync(currentEmployee);
- var result = ObjectMapper.Map<Employee, EmployeeDto>(updatedEmployee);
-
- return result;
- }
-
查询单个实体接口由CrudAppService提供默认实现,无需重写。
查询集合:
以Employee为例,查询接口所需要的入参为:
OrganizationUnitId:按组织架构查询用户
IsWithoutOrganization:查询不属于任何组织架构的用户
EmployeeTitle:按职称查询用户
创建GetAllEmployeeInput,代码如下
- public class GetAllEmployeeInput : PagedAndSortedResultRequestDto
- {
- public string EmployeeTitle { get; set; }
-
- public Guid? OrganizationUnitId { get; set; }
- public bool IsWithoutOrganization { get; set; }
-
- }
重写CreateFilteredQueryAsync
-
- protected override async Task<IQueryable<Employee>> CreateFilteredQueryAsync(GetAllEmployeeInput input)
- {
- var query = await ReadOnlyRepository.GetQueryableAsync().ConfigureAwait(continueOnCapturedContext: false);
-
- if (input.OrganizationUnitId.HasValue && !input.IsWithoutOrganization)
- {
- var organizationUnitUsers = await organizationUnitAppService.GetOrganizationUnitUsersAsync(new GetOrganizationUnitUsersInput()
- {
- Id = input.OrganizationUnitId.Value
- });
- if (organizationUnitUsers.Count() > 0)
- {
- var ids = organizationUnitUsers.Select(c => c.Id);
- query = query.Where(t => ids.Contains(t.Id));
- }
- else
- {
- query = query.Where(c => false);
- }
- }
- else if (input.IsWithoutOrganization)
- {
- var organizationUnitUsers = await organizationUnitAppService.GetUsersWithoutOrganizationAsync(new GetUserWithoutOrganizationInput());
- if (organizationUnitUsers.Count() > 0)
- {
- var ids = organizationUnitUsers.Select(c => c.Id);
- query = query.Where(t => ids.Contains(t.Id));
- }
- else
- {
- query = query.Where(c => false);
- }
- }
- query = query.WhereIf(!string.IsNullOrEmpty(input.EmployeeTitle), c => c.EmployeeTitle == input.EmployeeTitle);
- return query;
- }
-
至此,我们已完成了对业务用户的增删改查功能实现。
在HttpApi项目中创建EmployeeController,代码如下:
- [Area(HealthRemoteServiceConsts.ModuleName)]
- [RemoteService(Name = HealthRemoteServiceConsts.RemoteServiceName)]
- [Route("api/Health/employee")]
- public class EmployeeController : AbpControllerBase, IEmployeeAppService
- {
- private readonly IEmployeeAppService _employeeAppService;
-
- public EmployeeController(IEmployeeAppService employeeAppService)
- {
- _employeeAppService = employeeAppService;
- }
-
- [HttpPost]
- [Route("CreateWithUser")]
-
- public Task<EmployeeDto> CreateWithUserAsync(CreateEmployeeWithUserInput input)
- {
- return _employeeAppService.CreateWithUserAsync(input);
- }
-
- [HttpDelete]
- [Route("Delete")]
- public Task DeleteAsync(Guid id)
- {
- return _employeeAppService.DeleteAsync(id);
- }
-
- [HttpPut]
- [Route("UpdateWithUser")]
-
- public Task<EmployeeDto> UpdateWithUserAsync(CreateEmployeeInput input)
- {
- return _employeeAppService.UpdateWithUserAsync(input);
- }
-
- [HttpGet]
- [Route("Get")]
- public Task<EmployeeDto> GetAsync(Guid id)
- {
- return _employeeAppService.GetAsync(id);
- }
-
- [HttpGet]
- [Route("GetAll")]
- public Task<PagedResultDto<EmployeeDto>> GetAllAsync(GetAllEmployeeInput input)
- {
- return _employeeAppService.GetAllAsync(input);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。