fengling-platform/Fengling.Platform.Infrastructure/TenantStore.cs
movingsam 7877f89d35
Some checks failed
Build and Push Docker / build (push) Failing after 16s
Publish NuGet Packages / build (push) Failing after 1h7m51s
feat(platform): 增强 Infrastructure 层可扩展性,添加 NuGet 发布脚本与 CI/CD
## 主要变更

### Infrastructure 层重构
- `PlatformDbContext`: 构造函数改为接受泛型 `DbContextOptions`,支持派生上下文
- `TenantStore<TContext>`: 泛型化实现,支持不同的数据库上下文
- `Extensions`: 新增 `AddPlatformCore<TContext>` 扩展方法,简化服务注册

### 依赖调整
- 移除 Npgsql.EntityFrameworkCore.PostgreSQL 直接依赖,由使用方自行决定数据库提供程序

### CI/CD 集成
- 新增 `.gitea/workflows/publish-nuget.yml` Gitea Actions 工作流
- 新增 `push-platform-nuget.sh` 脚本,支持:
  - 从 git tag 自动获取版本号
  - HTTP/HTTPS 双模式支持
  - 独立 NuGet 配置文件
  - CI/CD 友好的环境变量配置

### 其他
- `NuGet.Config`: 新增 NuGet 配置文件
- `Fengling.Platform.Domain`: 添加 Items 文件夹占位
2026-02-27 13:58:09 +08:00

189 lines
7.1 KiB
C#

namespace Fengling.Platform.Infrastructure;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Fengling.Platform.Domain.AggregatesModel.TenantAggregate;
public class TenantStore<TContext> : ITenantStore
where TContext : PlatformDbContext
{
private readonly TContext _context;
private readonly DbSet<Tenant> _tenants;
public TenantStore(TContext context)
{
_context = context;
_tenants = context.Tenants;
}
public void Dispose() { }
public virtual Task<Tenant?> FindByIdAsync(long? tenantId, CancellationToken cancellationToken = default)
{
if (tenantId == null) return Task.FromResult<Tenant?>(null);
return _tenants.FirstOrDefaultAsync(t => t.Id == tenantId, cancellationToken);
}
public virtual Task<Tenant?> FindByTenantCodeAsync(string tenantCode, CancellationToken cancellationToken = default)
{
return _tenants.FirstOrDefaultAsync(t => t.TenantCode == tenantCode, cancellationToken);
}
public virtual async Task<IList<Tenant>> GetAllAsync(CancellationToken cancellationToken = default)
{
return await _tenants.ToListAsync(cancellationToken);
}
public virtual async Task<IList<Tenant>> GetPagedAsync(int page, int pageSize, string? name = null,
string? tenantCode = null, TenantStatus? status = null, CancellationToken cancellationToken = default)
{
var query = _tenants.AsQueryable();
if (!string.IsNullOrEmpty(name))
query = query.Where(t => t.Name.Contains(name));
if (!string.IsNullOrEmpty(tenantCode))
query = query.Where(t => t.TenantCode.Contains(tenantCode));
if (status.HasValue)
query = query.Where(t => t.Status == status);
return await query
.OrderByDescending(t => t.CreatedAt)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync(cancellationToken);
}
public virtual async Task<int> GetCountAsync(string? name = null, string? tenantCode = null,
TenantStatus? status = null, CancellationToken cancellationToken = default)
{
var query = _tenants.AsQueryable();
if (!string.IsNullOrEmpty(name))
query = query.Where(t => t.Name.Contains(name));
if (!string.IsNullOrEmpty(tenantCode))
query = query.Where(t => t.TenantCode.Contains(tenantCode));
if (status.HasValue)
query = query.Where(t => t.Status == status);
return await query.CountAsync(cancellationToken);
}
public virtual async Task<IdentityResult> CreateAsync(Tenant tenant, CancellationToken cancellationToken = default)
{
_tenants.Add(tenant);
await _context.SaveChangesAsync(cancellationToken);
return IdentityResult.Success;
}
public virtual async Task<IdentityResult> UpdateAsync(Tenant tenant, CancellationToken cancellationToken = default)
{
tenant.UpdatedAt = DateTime.UtcNow;
_tenants.Update(tenant);
await _context.SaveChangesAsync(cancellationToken);
return IdentityResult.Success;
}
public virtual async Task<IdentityResult> DeleteAsync(Tenant tenant, CancellationToken cancellationToken = default)
{
_tenants.Remove(tenant);
await _context.SaveChangesAsync(cancellationToken);
return IdentityResult.Success;
}
public virtual async Task<int> GetUserCountAsync(long tenantId, CancellationToken cancellationToken = default)
{
return await _context.Users.CountAsync(u => u.TenantInfo.TenantId == tenantId && !u.IsDeleted, cancellationToken);
}
public virtual Task<string> GetTenantCodeAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.TenantCode);
public virtual Task<string> GetNameAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.Name);
public virtual Task<string> GetContactNameAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.ContactName);
public virtual Task<string> GetContactEmailAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.ContactEmail);
public virtual Task<string?> GetContactPhoneAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.ContactPhone);
public virtual Task<int?> GetMaxUsersAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.MaxUsers);
public virtual Task<string?> GetDescriptionAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.Description);
public virtual Task<TenantStatus> GetStatusAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.Status);
public virtual Task<DateTime?> GetExpiresAtAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.ExpiresAt);
public virtual Task<DateTime> GetCreatedAtAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.CreatedAt);
public virtual Task<DateTime?> GetUpdatedAtAsync(Tenant tenant, CancellationToken cancellationToken = default)
=> Task.FromResult(tenant.UpdatedAt);
public virtual Task SetTenantCodeAsync(Tenant tenant, string code, CancellationToken cancellationToken = default)
{
tenant.TenantCode = code;
return Task.CompletedTask;
}
public virtual Task SetNameAsync(Tenant tenant, string name, CancellationToken cancellationToken = default)
{
tenant.Name = name;
return Task.CompletedTask;
}
public virtual Task SetContactNameAsync(Tenant tenant, string name, CancellationToken cancellationToken = default)
{
tenant.ContactName = name;
return Task.CompletedTask;
}
public virtual Task SetContactEmailAsync(Tenant tenant, string email, CancellationToken cancellationToken = default)
{
tenant.ContactEmail = email;
return Task.CompletedTask;
}
public virtual Task SetContactPhoneAsync(Tenant tenant, string? phone, CancellationToken cancellationToken = default)
{
tenant.ContactPhone = phone;
return Task.CompletedTask;
}
public virtual Task SetMaxUsersAsync(Tenant tenant, int? maxUsers, CancellationToken cancellationToken = default)
{
tenant.MaxUsers = maxUsers;
return Task.CompletedTask;
}
public virtual Task SetDescriptionAsync(Tenant tenant, string? description, CancellationToken cancellationToken = default)
{
tenant.Description = description;
return Task.CompletedTask;
}
public virtual Task SetStatusAsync(Tenant tenant, TenantStatus status, CancellationToken cancellationToken = default)
{
tenant.Status = status;
return Task.CompletedTask;
}
public virtual Task SetExpiresAtAsync(Tenant tenant, DateTime? expiresAt, CancellationToken cancellationToken = default)
{
tenant.ExpiresAt = expiresAt;
return Task.CompletedTask;
}
}