feat: 商户类目数据库化并增加权限种子
This commit is contained in:
@@ -32,6 +32,7 @@ public static class AppServiceCollectionExtensions
|
||||
services.AddPostgresDbContext<TakeoutAppDbContext>(DatabaseConstants.AppDataSource);
|
||||
|
||||
services.AddScoped<IMerchantRepository, EfMerchantRepository>();
|
||||
services.AddScoped<IMerchantCategoryRepository, EfMerchantCategoryRepository>();
|
||||
services.AddScoped<IStoreRepository, EfStoreRepository>();
|
||||
services.AddScoped<IProductRepository, EfProductRepository>();
|
||||
services.AddScoped<IOrderRepository, EfOrderRepository>();
|
||||
|
||||
@@ -50,6 +50,8 @@ public sealed class TakeoutAppDbContext(
|
||||
public DbSet<MerchantDocument> MerchantDocuments => Set<MerchantDocument>();
|
||||
public DbSet<MerchantContract> MerchantContracts => Set<MerchantContract>();
|
||||
public DbSet<MerchantStaff> MerchantStaff => Set<MerchantStaff>();
|
||||
public DbSet<MerchantAuditLog> MerchantAuditLogs => Set<MerchantAuditLog>();
|
||||
public DbSet<MerchantCategory> MerchantCategories => Set<MerchantCategory>();
|
||||
|
||||
public DbSet<Store> Stores => Set<Store>();
|
||||
public DbSet<StoreBusinessHour> StoreBusinessHours => Set<StoreBusinessHour>();
|
||||
@@ -144,6 +146,8 @@ public sealed class TakeoutAppDbContext(
|
||||
ConfigureMerchantDocument(modelBuilder.Entity<MerchantDocument>());
|
||||
ConfigureMerchantContract(modelBuilder.Entity<MerchantContract>());
|
||||
ConfigureMerchantStaff(modelBuilder.Entity<MerchantStaff>());
|
||||
ConfigureMerchantAuditLog(modelBuilder.Entity<MerchantAuditLog>());
|
||||
ConfigureMerchantCategory(modelBuilder.Entity<MerchantCategory>());
|
||||
ConfigureStoreBusinessHour(modelBuilder.Entity<StoreBusinessHour>());
|
||||
ConfigureStoreHoliday(modelBuilder.Entity<StoreHoliday>());
|
||||
ConfigureStoreDeliveryZone(modelBuilder.Entity<StoreDeliveryZone>());
|
||||
@@ -499,6 +503,27 @@ public sealed class TakeoutAppDbContext(
|
||||
builder.HasIndex(x => new { x.TenantId, x.MerchantId, x.Phone });
|
||||
}
|
||||
|
||||
private static void ConfigureMerchantAuditLog(EntityTypeBuilder<MerchantAuditLog> builder)
|
||||
{
|
||||
builder.ToTable("merchant_audit_logs");
|
||||
builder.HasKey(x => x.Id);
|
||||
builder.Property(x => x.MerchantId).IsRequired();
|
||||
builder.Property(x => x.Title).HasMaxLength(128).IsRequired();
|
||||
builder.Property(x => x.Description).HasMaxLength(1024);
|
||||
builder.Property(x => x.OperatorName).HasMaxLength(64);
|
||||
builder.HasIndex(x => new { x.TenantId, x.MerchantId });
|
||||
}
|
||||
|
||||
private static void ConfigureMerchantCategory(EntityTypeBuilder<MerchantCategory> builder)
|
||||
{
|
||||
builder.ToTable("merchant_categories");
|
||||
builder.HasKey(x => x.Id);
|
||||
builder.Property(x => x.Name).HasMaxLength(64).IsRequired();
|
||||
builder.Property(x => x.DisplayOrder).HasDefaultValue(0);
|
||||
builder.Property(x => x.IsActive).IsRequired();
|
||||
builder.HasIndex(x => new { x.TenantId, x.Name }).IsUnique();
|
||||
}
|
||||
|
||||
private static void ConfigureStoreBusinessHour(EntityTypeBuilder<StoreBusinessHour> builder)
|
||||
{
|
||||
builder.ToTable("store_business_hours");
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using TakeoutSaaS.Domain.Merchants.Entities;
|
||||
using TakeoutSaaS.Domain.Merchants.Repositories;
|
||||
using TakeoutSaaS.Infrastructure.App.Persistence;
|
||||
|
||||
namespace TakeoutSaaS.Infrastructure.App.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// 商户类目的 EF Core 仓储实现。
|
||||
/// </summary>
|
||||
public sealed class EfMerchantCategoryRepository(TakeoutAppDbContext context)
|
||||
: IMerchantCategoryRepository
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<MerchantCategory>> ListAsync(long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var items = await context.MerchantCategories
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == tenantId)
|
||||
.OrderBy(x => x.DisplayOrder)
|
||||
.ThenBy(x => x.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<bool> ExistsAsync(string name, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return context.MerchantCategories.AnyAsync(
|
||||
x => x.TenantId == tenantId && x.Name == name, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<MerchantCategory?> FindByIdAsync(long id, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return context.MerchantCategories
|
||||
.FirstOrDefaultAsync(x => x.TenantId == tenantId && x.Id == id, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task AddAsync(MerchantCategory category, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return context.MerchantCategories.AddAsync(category, cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task RemoveAsync(MerchantCategory category, CancellationToken cancellationToken = default)
|
||||
{
|
||||
context.MerchantCategories.Remove(category);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task UpdateRangeAsync(IEnumerable<MerchantCategory> categories, CancellationToken cancellationToken = default)
|
||||
{
|
||||
context.MerchantCategories.UpdateRange(categories);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,14 @@ public sealed class EfMerchantRepository(TakeoutAppDbContext context) : IMerchan
|
||||
return contracts;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<MerchantContract?> FindContractByIdAsync(long merchantId, long tenantId, long contractId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return context.MerchantContracts
|
||||
.Where(x => x.TenantId == tenantId && x.MerchantId == merchantId && x.Id == contractId)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<MerchantDocument>> GetDocumentsAsync(long merchantId, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -79,6 +87,14 @@ public sealed class EfMerchantRepository(TakeoutAppDbContext context) : IMerchan
|
||||
return documents;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<MerchantDocument?> FindDocumentByIdAsync(long merchantId, long tenantId, long documentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return context.MerchantDocuments
|
||||
.Where(x => x.TenantId == tenantId && x.MerchantId == merchantId && x.Id == documentId)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task AddMerchantAsync(Merchant merchant, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -97,12 +113,26 @@ public sealed class EfMerchantRepository(TakeoutAppDbContext context) : IMerchan
|
||||
return context.MerchantContracts.AddAsync(contract, cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task UpdateContractAsync(MerchantContract contract, CancellationToken cancellationToken = default)
|
||||
{
|
||||
context.MerchantContracts.Update(contract);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task AddDocumentAsync(MerchantDocument document, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return context.MerchantDocuments.AddAsync(document, cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task UpdateDocumentAsync(MerchantDocument document, CancellationToken cancellationToken = default)
|
||||
{
|
||||
context.MerchantDocuments.Update(document);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -130,4 +160,20 @@ public sealed class EfMerchantRepository(TakeoutAppDbContext context) : IMerchan
|
||||
|
||||
context.Merchants.Remove(existing);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task AddAuditLogAsync(MerchantAuditLog log, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return context.MerchantAuditLogs.AddAsync(log, cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<MerchantAuditLog>> GetAuditLogsAsync(long merchantId, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await context.MerchantAuditLogs
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == tenantId && x.MerchantId == merchantId)
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user