You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
5.6 KiB
C#

using System.Reflection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using NPin.Framework.Ddd.Application;
using NPin.Framework.SqlSugarCore.Abstractions;
using NPin.Framework.TenantManagement.Application.Contracts;
using NPin.Framework.TenantManagement.Application.Contracts.Dtos;
using NPin.Framework.TenantManagement.Domain;
using SqlSugar;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Data;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
namespace NPin.Framework.TenantManagement.Application;
public class TenantService : NPinCrudAppService<TenantAggregateRoot, TenantGetOutputDto, TenantGetListOutputDto, Guid,
TenantGetListInput, TenantCreateInput, TenantUpdateInput>, ITenantService
{
private ISqlSugarRepository<TenantAggregateRoot, Guid> _repository;
private IDataSeeder _dataSeeder;
public TenantService(IRepository<TenantAggregateRoot, Guid> repository,
ISqlSugarRepository<TenantAggregateRoot, Guid> sqlSugarRepository, IDataSeeder dataSeeder) : base(repository)
{
_repository = sqlSugarRepository;
_dataSeeder = dataSeeder;
}
/// <summary>
/// 租户单查
/// </summary>
/// <param name="id">唯一ID</param>
/// <returns></returns>
public override Task<TenantGetOutputDto> GetAsync(Guid id)
{
return base.GetAsync(id);
}
/// <summary>
/// 租户多查
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public override async Task<PagedResultDto<TenantGetListOutputDto>> GetListAsync(TenantGetListInput input)
{
RefAsync<int> total = 0;
var entities = await _repository.DbQueryable
.WhereIF(!string.IsNullOrEmpty(input.Name), x => x.Name.Contains(input.Name!))
.WhereIF(input.StartTime is not null && input.EndTime is not null,
x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<TenantGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
}
/// <summary>
/// 租户选项列表(显示名称)
/// </summary>
/// <returns></returns>
public async Task<List<TenantSelectOutputDto>> GetSelectAsync()
{
var entities = await _repository.DbQueryable.ToListAsync();
return entities.Select(x => new TenantSelectOutputDto { Id = x.Id, Name = x.Name })
.ToList();
}
/// <summary>
/// 创建租户
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public override async Task<TenantGetOutputDto> CreateAsync(TenantCreateInput input)
{
// 检查是否存在
if (await _repository.IsAnyAsync(x => x.Name == input.Name))
{
throw new UserFriendlyException("创建失败,当前租户已存在");
}
return await base.CreateAsync(input);
}
/// <summary>
/// 更新租户信息
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
public override async Task<TenantGetOutputDto> UpdateAsync(Guid id, TenantUpdateInput input)
{
if (await _repository.IsAnyAsync(x => x.Name == input.Name && x.Id != id))
{
throw new UserFriendlyException("更新失败,更新后租户已存在");
}
return await base.UpdateAsync(id, input);
}
/// <summary>
/// 租户删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public override Task DeleteAsync(IEnumerable<Guid> ids)
{
return base.DeleteAsync(ids);
}
/// <summary>
/// 初始化租户
/// </summary>
/// <param name="id"></param>
[HttpPost("tenant/init/{id}")]
public async Task InitAsync([FromRoute] Guid id)
{
await CurrentUnitOfWork.SaveChangesAsync();
using (CurrentTenant.Change(id))
{
// 初始化 租户数据库/表 结构
await CodeFirst(LazyServiceProvider);
// 插入 种子数据
await _dataSeeder.SeedAsync(id);
}
}
/// <summary>
/// 数据库 / 表 初始化
/// </summary>
/// <param name="service"></param>
private async Task CodeFirst(IServiceProvider service)
{
var moduleContainer = service.GetRequiredService<IModuleContainer>();
// 没有数据库,不能创建工作单元,先创建库再关闭
ISqlSugarClient db = null;
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
db = await _repository.GetDbContextAsync();
// 尝试创建数据库
db.DbMaintenance.CreateDatabase();
await uow.CompleteAsync();
}
List<Type> types = new List<Type>();
foreach (var module in moduleContainer.Modules)
{
types.AddRange(module.Assembly.GetTypes()
.Where(x => x.GetCustomAttribute<IgnoreCodeFirstAttribute>() == null)
.Where(x => x.GetCustomAttribute<SugarTable>() != null)
.Where(x => x.GetCustomAttribute<DefaultTenantTableAttribute>() is null)
.Where(x => x.GetCustomAttribute<SplitTableAttribute>() is null));
}
if (types.Count > 0)
{
db.CopyNew().CodeFirst.InitTables(types.ToArray());
}
}
}