Blame view

泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/Services/ThTenantProvisioningAppService.cs 3.32 KB
a1a0369d   李曜臣   5-25代码优化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  using FoodLabeling.Th.Application.Contracts.Dtos.MultiTenancy;
  using FoodLabeling.Th.Application.Contracts.IServices;
  using FoodLabeling.Th.Application.Contracts.Options;
  using FoodLabeling.Th.Application.MultiTenancy;
  using Microsoft.AspNetCore.Authorization;
  using Microsoft.Extensions.Options;
  using SqlSugar;
  using Volo.Abp;
  using Volo.Abp.Application.Services;
  using Volo.Abp.MultiTenancy;
  using Yi.Framework.TenantManagement.Application.Contracts;
  using Yi.Framework.TenantManagement.Application.Contracts.Dtos;
  
  namespace FoodLabeling.Th.Application.Services;
  
  /// <summary>
  /// 泰额版租户独立库开通(平台主库 yitenant + 租户业务库)
  /// </summary>
  [Authorize]
  public class ThTenantProvisioningAppService : ApplicationService, IThTenantProvisioningAppService
  {
      private readonly ITenantService _tenantService;
      private readonly FoodLabelingThTenantDatabaseOptions _dbOptions;
  
      public ThTenantProvisioningAppService(
          ITenantService tenantService,
          IOptions<FoodLabelingThTenantDatabaseOptions> dbOptions)
      {
          _tenantService = tenantService;
          _dbOptions = dbOptions.Value;
      }
  
      /// <inheritdoc />
      public virtual async Task<ThProvisionTenantOutputDto> ProvisionAsync(ThProvisionTenantInputVo input)
      {
          if (string.IsNullOrWhiteSpace(input.Name))
          {
              throw new UserFriendlyException("租户名称不能为空");
          }
  
          var connectionString = string.IsNullOrWhiteSpace(input.TenantConnectionString)
              ? TenantDatabaseConnectionStringBuilder.BuildMySqlConnectionString(_dbOptions, input.Name)
              : input.TenantConnectionString.Trim();
  
          var databaseName = ExtractDatabaseName(connectionString)
                             ?? TenantDatabaseConnectionStringBuilder.BuildDatabaseName(_dbOptions, input.Name);
  
          // 平台主库写入 yitenantCurrentTenant 为空时走 DbConnOptions 主库)
          var dbType = Enum.IsDefined(typeof(DbType), input.DbType)
              ? (DbType)input.DbType
              : DbType.MySql;
  
          var created = await _tenantService.CreateAsync(new TenantCreateInput
          {
              Name = input.Name.Trim(),
              TenantConnectionString = connectionString,
              DbType = dbType
          });
  
          var initialized = false;
          if (input.InitializeDatabase)
          {
              await _tenantService.InitAsync(created.Id);
              initialized = true;
          }
  
          return new ThProvisionTenantOutputDto
          {
              TenantId = created.Id,
              Name = created.Name,
              DatabaseName = databaseName,
              TenantConnectionString = connectionString,
              DatabaseInitialized = initialized
          };
      }
  
      /// <inheritdoc />
      public virtual Task InitializeTenantDatabaseAsync(Guid tenantId)
      {
          return _tenantService.InitAsync(tenantId);
      }
  
      private static string? ExtractDatabaseName(string connectionString)
      {
          const string key = "database=";
          var idx = connectionString.IndexOf(key, StringComparison.OrdinalIgnoreCase);
          if (idx < 0)
          {
              return null;
          }
  
          var start = idx + key.Length;
          var end = connectionString.IndexOf(';', start);
          return end < 0
              ? connectionString[start..].Trim()
              : connectionString[start..end].Trim();
      }
  }