diff --git a/Blog.Core.Api/Blog.Core.xml b/Blog.Core.Api/Blog.Core.xml index 8effc9f..b41b293 100644 --- a/Blog.Core.Api/Blog.Core.xml +++ b/Blog.Core.Api/Blog.Core.xml @@ -1247,6 +1247,12 @@ + + + 新增数据 + + + 多租户-Id方案 测试 @@ -1264,6 +1270,44 @@ + + + 租户管理 + + + + + 获取全部租户 + + + + + + 获取租户信息 + + + + + + 新增租户信息
+ 此处只做演示,具体要以实际业务为准 +
+ +
+ + + 修改租户信息
+ 此处只做演示,具体要以实际业务为准 +
+ +
+ + + 删除租户
+ 此处只做演示,具体要以实际业务为准 +
+ +
自定义路由 /api/{version}/[controler]/[action] diff --git a/Blog.Core.Api/Controllers/Tenant/TenantByDbController.cs b/Blog.Core.Api/Controllers/Tenant/TenantByDbController.cs index 0d403ad..046f7f7 100644 --- a/Blog.Core.Api/Controllers/Tenant/TenantByDbController.cs +++ b/Blog.Core.Api/Controllers/Tenant/TenantByDbController.cs @@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Mvc; namespace Blog.Core.Api.Controllers.Tenant; /// -/// 多租户测试 +/// 多租户-多库方案 测试 /// [Produces("application/json")] [Route("api/Tenant/ByDb")] @@ -35,4 +35,16 @@ public class TenantByDbController : BaseApiController var data = await _services.Query(); return Success(data); } + + /// + /// 新增数据 + /// + /// + [HttpPost] + public async Task Post(SubLibraryBusinessTable data) + { + await _services.Db.Insertable(data).ExecuteReturnSnowflakeIdAsync(); + + return Success(); + } } \ No newline at end of file diff --git a/Blog.Core.Api/Controllers/Tenant/TenantManagerController.cs b/Blog.Core.Api/Controllers/Tenant/TenantManagerController.cs new file mode 100644 index 0000000..90133fd --- /dev/null +++ b/Blog.Core.Api/Controllers/Tenant/TenantManagerController.cs @@ -0,0 +1,87 @@ +using Blog.Core.Controllers; +using Blog.Core.IServices; +using Blog.Core.Model; +using Blog.Core.Model.Models; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Blog.Core.Api.Controllers.Tenant; + +/// +/// 租户管理 +/// +[Produces("application/json")] +[Route("api/TenantManager")] +[Authorize] +public class TenantManagerController : BaseApiController +{ + private readonly ITenantService _services; + + public TenantManagerController(ITenantService services) + { + _services = services; + } + + + /// + /// 获取全部租户 + /// + /// + [HttpGet] + public async Task>> GetAll() + { + var data = await _services.Query(); + return Success(data); + } + + + /// + /// 获取租户信息 + /// + /// + [HttpGet("{id}")] + public async Task> GetInfo(long id) + { + var data = await _services.QueryById(id); + return Success(data); + } + + /// + /// 新增租户信息
+ /// 此处只做演示,具体要以实际业务为准 + ///
+ /// + [HttpPost] + public async Task Post(SysTenant tenant) + { + await _services.SaveTenant(tenant); + return Success(); + } + + /// + /// 修改租户信息
+ /// 此处只做演示,具体要以实际业务为准 + ///
+ /// + [HttpPut] + public async Task Put(SysTenant tenant) + { + await _services.SaveTenant(tenant); + return Success(); + } + + /// + /// 删除租户
+ /// 此处只做演示,具体要以实际业务为准 + ///
+ /// + [HttpDelete] + public async Task Delete(long id) + { + //是否删除租户库? + //要根据实际情况而定 + //例如直接删除租户库、备份租户库到xx + await _services.DeleteById(id); + return Success(); + } +} \ No newline at end of file diff --git a/Blog.Core.Common/DB/BaseDBConfig.cs b/Blog.Core.Common/DB/BaseDBConfig.cs index b832b6d..1d86369 100644 --- a/Blog.Core.Common/DB/BaseDBConfig.cs +++ b/Blog.Core.Common/DB/BaseDBConfig.cs @@ -1,4 +1,5 @@ -using System; +using SqlSugar; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -106,6 +107,8 @@ namespace Blog.Core.Common.DB return mutiDBOperate; } + + } diff --git a/Blog.Core.Common/DB/TenantUtil.cs b/Blog.Core.Common/DB/TenantUtil.cs index 37ad690..deac60a 100644 --- a/Blog.Core.Common/DB/TenantUtil.cs +++ b/Blog.Core.Common/DB/TenantUtil.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using Blog.Core.Model.Models; using SqlSugar; @@ -6,6 +7,26 @@ namespace Blog.Core.Common.DB; public static class TenantUtil { + public static SysTenant DefaultTenantConfig(this SysTenant tenant) + { + tenant.DbType ??= DbType.Sqlite; + + //如果没有配置连接 + if (tenant.Connection.IsNullOrEmpty()) + { + //此处默认配置 Sqlite 地址 + //实际业务中 也会有运维、系统管理员等来维护 + switch (tenant.DbType.Value) + { + case DbType.Sqlite: + tenant.Connection = $"DataSource={Path.Combine(Environment.CurrentDirectory, tenant.ConfigId)}.db" ; + break; + } + } + + return tenant; + } + public static ConnectionConfig GetConnectionConfig(this SysTenant tenant) { if (tenant.DbType is null) @@ -13,6 +34,7 @@ public static class TenantUtil throw new ArgumentException("Tenant DbType Must"); } + return new ConnectionConfig() { ConfigId = tenant.ConfigId, diff --git a/Blog.Core.Common/Seed/DBSeed.cs b/Blog.Core.Common/Seed/DBSeed.cs index fdbb1ee..a6952e6 100644 --- a/Blog.Core.Common/Seed/DBSeed.cs +++ b/Blog.Core.Common/Seed/DBSeed.cs @@ -372,7 +372,7 @@ namespace Blog.Core.Common.Seed return false; }); - + if (!seedDataTypes.Any()) return; foreach (var seedType in seedDataTypes) { @@ -437,6 +437,7 @@ namespace Blog.Core.Common.Seed public static async Task InitTenantSeedAsync(ITenant itenant, ConnectionConfig config) { + itenant.RemoveConnection(config.ConfigId); itenant.AddConnection(config); var db = itenant.GetConnectionScope(config.ConfigId); diff --git a/Blog.Core.IServices/ITenantService.cs b/Blog.Core.IServices/ITenantService.cs new file mode 100644 index 0000000..0927b79 --- /dev/null +++ b/Blog.Core.IServices/ITenantService.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; +using Blog.Core.IServices.BASE; +using Blog.Core.Model.Models; + +namespace Blog.Core.IServices; + +public interface ITenantService : IBaseServices +{ + public Task SaveTenant(SysTenant tenant); + + public Task InitTenantDb(SysTenant tenant); +} \ No newline at end of file diff --git a/Blog.Core.Services/TenantService.cs b/Blog.Core.Services/TenantService.cs new file mode 100644 index 0000000..a552442 --- /dev/null +++ b/Blog.Core.Services/TenantService.cs @@ -0,0 +1,57 @@ +using Blog.Core.Common.DB; +using Blog.Core.Common.Seed; +using Blog.Core.IServices; +using Blog.Core.Model.Models; +using Blog.Core.Repository.UnitOfWorks; +using Blog.Core.Services.BASE; +using System.Threading.Tasks; + +namespace Blog.Core.Services; + +public class TenantService : BaseServices, ITenantService +{ + private readonly IUnitOfWorkManage _uowManager; + + public TenantService(IUnitOfWorkManage uowManage) + { + this._uowManager = uowManage; + } + + + public async Task SaveTenant(SysTenant tenant) + { + bool initDb = tenant.Id == 0; + using (var uow = _uowManager.CreateUnitOfWork()) + { + + tenant.DefaultTenantConfig(); + + if (tenant.Id == 0) + { + await Db.Insertable(tenant).ExecuteReturnSnowflakeIdAsync(); + } + else + { + var oldTenant = await QueryById(tenant.Id); + if (oldTenant.Connection != tenant.Connection) + { + initDb = true; + } + + await Db.Updateable(tenant).ExecuteCommandAsync(); + } + + uow.Commit(); + } + + if (initDb) + { + await InitTenantDb(tenant); + } + } + + public async Task InitTenantDb(SysTenant tenant) + { + await DBSeed.InitTenantSeedAsync(Db.AsTenant(), tenant.GetConnectionConfig()); + } +} \ No newline at end of file