feat: 管理端核心实体CRUD补齐
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.App.Stores.Dto;
|
||||
using TakeoutSaaS.Domain.Stores.Enums;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 创建门店命令。
|
||||
/// </summary>
|
||||
public sealed class CreateStoreCommand : IRequest<StoreDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// 商户 ID。
|
||||
/// </summary>
|
||||
public long MerchantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 门店编码。
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 门店名称。
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 电话。
|
||||
/// </summary>
|
||||
public string? Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 负责人。
|
||||
/// </summary>
|
||||
public string? ManagerName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public StoreStatus Status { get; set; } = StoreStatus.Closed;
|
||||
|
||||
/// <summary>
|
||||
/// 省份。
|
||||
/// </summary>
|
||||
public string? Province { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 城市。
|
||||
/// </summary>
|
||||
public string? City { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区县。
|
||||
/// </summary>
|
||||
public string? District { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 详细地址。
|
||||
/// </summary>
|
||||
public string? Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 经度。
|
||||
/// </summary>
|
||||
public double? Longitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 纬度。
|
||||
/// </summary>
|
||||
public double? Latitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 公告。
|
||||
/// </summary>
|
||||
public string? Announcement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标签。
|
||||
/// </summary>
|
||||
public string? Tags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 配送半径。
|
||||
/// </summary>
|
||||
public decimal DeliveryRadiusKm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支持堂食。
|
||||
/// </summary>
|
||||
public bool SupportsDineIn { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 支持自提。
|
||||
/// </summary>
|
||||
public bool SupportsPickup { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 支持配送。
|
||||
/// </summary>
|
||||
public bool SupportsDelivery { get; set; } = true;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using MediatR;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 删除门店命令。
|
||||
/// </summary>
|
||||
public sealed class DeleteStoreCommand : IRequest<bool>
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店 ID。
|
||||
/// </summary>
|
||||
public long StoreId { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.App.Stores.Dto;
|
||||
using TakeoutSaaS.Domain.Stores.Enums;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 更新门店命令。
|
||||
/// </summary>
|
||||
public sealed class UpdateStoreCommand : IRequest<StoreDto?>
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店 ID。
|
||||
/// </summary>
|
||||
public long StoreId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户 ID。
|
||||
/// </summary>
|
||||
public long MerchantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 门店编码。
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 门店名称。
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 电话。
|
||||
/// </summary>
|
||||
public string? Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 负责人。
|
||||
/// </summary>
|
||||
public string? ManagerName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public StoreStatus Status { get; set; } = StoreStatus.Closed;
|
||||
|
||||
/// <summary>
|
||||
/// 省份。
|
||||
/// </summary>
|
||||
public string? Province { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 城市。
|
||||
/// </summary>
|
||||
public string? City { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区县。
|
||||
/// </summary>
|
||||
public string? District { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 详细地址。
|
||||
/// </summary>
|
||||
public string? Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 经度。
|
||||
/// </summary>
|
||||
public double? Longitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 纬度。
|
||||
/// </summary>
|
||||
public double? Latitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 公告。
|
||||
/// </summary>
|
||||
public string? Announcement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标签。
|
||||
/// </summary>
|
||||
public string? Tags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 配送半径。
|
||||
/// </summary>
|
||||
public decimal DeliveryRadiusKm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支持堂食。
|
||||
/// </summary>
|
||||
public bool SupportsDineIn { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 支持自提。
|
||||
/// </summary>
|
||||
public bool SupportsPickup { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 支持配送。
|
||||
/// </summary>
|
||||
public bool SupportsDelivery { get; set; } = true;
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using TakeoutSaaS.Domain.Stores.Enums;
|
||||
using TakeoutSaaS.Shared.Abstractions.Serialization;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Dto;
|
||||
|
||||
/// <summary>
|
||||
/// 门店 DTO。
|
||||
/// </summary>
|
||||
public sealed class StoreDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店 ID。
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
|
||||
public long Id { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户 ID。
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
|
||||
public long TenantId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户 ID。
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
|
||||
public long MerchantId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 门店编码。
|
||||
/// </summary>
|
||||
public string Code { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 门店名称。
|
||||
/// </summary>
|
||||
public string Name { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 电话。
|
||||
/// </summary>
|
||||
public string? Phone { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 负责人。
|
||||
/// </summary>
|
||||
public string? ManagerName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public StoreStatus Status { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 省份。
|
||||
/// </summary>
|
||||
public string? Province { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 城市。
|
||||
/// </summary>
|
||||
public string? City { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 区县。
|
||||
/// </summary>
|
||||
public string? District { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 详细地址。
|
||||
/// </summary>
|
||||
public string? Address { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 经度。
|
||||
/// </summary>
|
||||
public double? Longitude { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 纬度。
|
||||
/// </summary>
|
||||
public double? Latitude { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 公告。
|
||||
/// </summary>
|
||||
public string? Announcement { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 标签。
|
||||
/// </summary>
|
||||
public string? Tags { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认配送半径。
|
||||
/// </summary>
|
||||
public decimal DeliveryRadiusKm { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 支持堂食。
|
||||
/// </summary>
|
||||
public bool SupportsDineIn { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 支持自提。
|
||||
/// </summary>
|
||||
public bool SupportsPickup { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 支持配送。
|
||||
/// </summary>
|
||||
public bool SupportsDelivery { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TakeoutSaaS.Application.App.Stores.Commands;
|
||||
using TakeoutSaaS.Application.App.Stores.Dto;
|
||||
using TakeoutSaaS.Domain.Stores.Entities;
|
||||
using TakeoutSaaS.Domain.Stores.Repositories;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 创建门店命令处理器。
|
||||
/// </summary>
|
||||
public sealed class CreateStoreCommandHandler(IStoreRepository storeRepository, ILogger<CreateStoreCommandHandler> logger)
|
||||
: IRequestHandler<CreateStoreCommand, StoreDto>
|
||||
{
|
||||
private readonly IStoreRepository _storeRepository = storeRepository;
|
||||
private readonly ILogger<CreateStoreCommandHandler> _logger = logger;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<StoreDto> Handle(CreateStoreCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 构建实体
|
||||
var store = new Store
|
||||
{
|
||||
MerchantId = request.MerchantId,
|
||||
Code = request.Code.Trim(),
|
||||
Name = request.Name.Trim(),
|
||||
Phone = request.Phone?.Trim(),
|
||||
ManagerName = request.ManagerName?.Trim(),
|
||||
Status = request.Status,
|
||||
Province = request.Province?.Trim(),
|
||||
City = request.City?.Trim(),
|
||||
District = request.District?.Trim(),
|
||||
Address = request.Address?.Trim(),
|
||||
Longitude = request.Longitude,
|
||||
Latitude = request.Latitude,
|
||||
Announcement = request.Announcement?.Trim(),
|
||||
Tags = request.Tags?.Trim(),
|
||||
DeliveryRadiusKm = request.DeliveryRadiusKm,
|
||||
SupportsDineIn = request.SupportsDineIn,
|
||||
SupportsPickup = request.SupportsPickup,
|
||||
SupportsDelivery = request.SupportsDelivery
|
||||
};
|
||||
|
||||
// 2. 持久化
|
||||
await _storeRepository.AddStoreAsync(store, cancellationToken);
|
||||
await _storeRepository.SaveChangesAsync(cancellationToken);
|
||||
_logger.LogInformation("创建门店 {StoreId} - {StoreName}", store.Id, store.Name);
|
||||
|
||||
// 3. 返回 DTO
|
||||
return MapToDto(store);
|
||||
}
|
||||
|
||||
private static StoreDto MapToDto(Store store) => new()
|
||||
{
|
||||
Id = store.Id,
|
||||
TenantId = store.TenantId,
|
||||
MerchantId = store.MerchantId,
|
||||
Code = store.Code,
|
||||
Name = store.Name,
|
||||
Phone = store.Phone,
|
||||
ManagerName = store.ManagerName,
|
||||
Status = store.Status,
|
||||
Province = store.Province,
|
||||
City = store.City,
|
||||
District = store.District,
|
||||
Address = store.Address,
|
||||
Longitude = store.Longitude,
|
||||
Latitude = store.Latitude,
|
||||
Announcement = store.Announcement,
|
||||
Tags = store.Tags,
|
||||
DeliveryRadiusKm = store.DeliveryRadiusKm,
|
||||
SupportsDineIn = store.SupportsDineIn,
|
||||
SupportsPickup = store.SupportsPickup,
|
||||
SupportsDelivery = store.SupportsDelivery
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TakeoutSaaS.Application.App.Stores.Commands;
|
||||
using TakeoutSaaS.Domain.Stores.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 删除门店命令处理器。
|
||||
/// </summary>
|
||||
public sealed class DeleteStoreCommandHandler(
|
||||
IStoreRepository storeRepository,
|
||||
ITenantProvider tenantProvider,
|
||||
ILogger<DeleteStoreCommandHandler> logger)
|
||||
: IRequestHandler<DeleteStoreCommand, bool>
|
||||
{
|
||||
private readonly IStoreRepository _storeRepository = storeRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
private readonly ILogger<DeleteStoreCommandHandler> _logger = logger;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> Handle(DeleteStoreCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 校验存在性
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var existing = await _storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken);
|
||||
if (existing == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 删除
|
||||
await _storeRepository.DeleteStoreAsync(request.StoreId, tenantId, cancellationToken);
|
||||
await _storeRepository.SaveChangesAsync(cancellationToken);
|
||||
_logger.LogInformation("删除门店 {StoreId}", request.StoreId);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.App.Stores.Dto;
|
||||
using TakeoutSaaS.Application.App.Stores.Queries;
|
||||
using TakeoutSaaS.Domain.Stores.Entities;
|
||||
using TakeoutSaaS.Domain.Stores.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 门店详情查询处理器。
|
||||
/// </summary>
|
||||
public sealed class GetStoreByIdQueryHandler(
|
||||
IStoreRepository storeRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<GetStoreByIdQuery, StoreDto?>
|
||||
{
|
||||
private readonly IStoreRepository _storeRepository = storeRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<StoreDto?> Handle(GetStoreByIdQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var store = await _storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken);
|
||||
return store == null ? null : MapToDto(store);
|
||||
}
|
||||
|
||||
private static StoreDto MapToDto(Store store) => new()
|
||||
{
|
||||
Id = store.Id,
|
||||
TenantId = store.TenantId,
|
||||
MerchantId = store.MerchantId,
|
||||
Code = store.Code,
|
||||
Name = store.Name,
|
||||
Phone = store.Phone,
|
||||
ManagerName = store.ManagerName,
|
||||
Status = store.Status,
|
||||
Province = store.Province,
|
||||
City = store.City,
|
||||
District = store.District,
|
||||
Address = store.Address,
|
||||
Longitude = store.Longitude,
|
||||
Latitude = store.Latitude,
|
||||
Announcement = store.Announcement,
|
||||
Tags = store.Tags,
|
||||
DeliveryRadiusKm = store.DeliveryRadiusKm,
|
||||
SupportsDineIn = store.SupportsDineIn,
|
||||
SupportsPickup = store.SupportsPickup,
|
||||
SupportsDelivery = store.SupportsDelivery
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.App.Stores.Dto;
|
||||
using TakeoutSaaS.Application.App.Stores.Queries;
|
||||
using TakeoutSaaS.Domain.Stores.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 门店列表查询处理器。
|
||||
/// </summary>
|
||||
public sealed class SearchStoresQueryHandler(
|
||||
IStoreRepository storeRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<SearchStoresQuery, IReadOnlyList<StoreDto>>
|
||||
{
|
||||
private readonly IStoreRepository _storeRepository = storeRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<StoreDto>> Handle(SearchStoresQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var stores = await _storeRepository.SearchAsync(tenantId, request.Status, cancellationToken);
|
||||
|
||||
if (request.MerchantId.HasValue)
|
||||
{
|
||||
stores = stores.Where(x => x.MerchantId == request.MerchantId.Value).ToList();
|
||||
}
|
||||
|
||||
return stores
|
||||
.Select(MapToDto)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static StoreDto MapToDto(Domain.Stores.Entities.Store store) => new()
|
||||
{
|
||||
Id = store.Id,
|
||||
TenantId = store.TenantId,
|
||||
MerchantId = store.MerchantId,
|
||||
Code = store.Code,
|
||||
Name = store.Name,
|
||||
Phone = store.Phone,
|
||||
ManagerName = store.ManagerName,
|
||||
Status = store.Status,
|
||||
Province = store.Province,
|
||||
City = store.City,
|
||||
District = store.District,
|
||||
Address = store.Address,
|
||||
Longitude = store.Longitude,
|
||||
Latitude = store.Latitude,
|
||||
Announcement = store.Announcement,
|
||||
Tags = store.Tags,
|
||||
DeliveryRadiusKm = store.DeliveryRadiusKm,
|
||||
SupportsDineIn = store.SupportsDineIn,
|
||||
SupportsPickup = store.SupportsPickup,
|
||||
SupportsDelivery = store.SupportsDelivery
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TakeoutSaaS.Application.App.Stores.Commands;
|
||||
using TakeoutSaaS.Application.App.Stores.Dto;
|
||||
using TakeoutSaaS.Domain.Stores.Entities;
|
||||
using TakeoutSaaS.Domain.Stores.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 更新门店命令处理器。
|
||||
/// </summary>
|
||||
public sealed class UpdateStoreCommandHandler(
|
||||
IStoreRepository storeRepository,
|
||||
ITenantProvider tenantProvider,
|
||||
ILogger<UpdateStoreCommandHandler> logger)
|
||||
: IRequestHandler<UpdateStoreCommand, StoreDto?>
|
||||
{
|
||||
private readonly IStoreRepository _storeRepository = storeRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
private readonly ILogger<UpdateStoreCommandHandler> _logger = logger;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<StoreDto?> Handle(UpdateStoreCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 读取门店
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var existing = await _storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken);
|
||||
if (existing == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 2. 更新字段
|
||||
existing.MerchantId = request.MerchantId;
|
||||
existing.Code = request.Code.Trim();
|
||||
existing.Name = request.Name.Trim();
|
||||
existing.Phone = request.Phone?.Trim();
|
||||
existing.ManagerName = request.ManagerName?.Trim();
|
||||
existing.Status = request.Status;
|
||||
existing.Province = request.Province?.Trim();
|
||||
existing.City = request.City?.Trim();
|
||||
existing.District = request.District?.Trim();
|
||||
existing.Address = request.Address?.Trim();
|
||||
existing.Longitude = request.Longitude;
|
||||
existing.Latitude = request.Latitude;
|
||||
existing.Announcement = request.Announcement?.Trim();
|
||||
existing.Tags = request.Tags?.Trim();
|
||||
existing.DeliveryRadiusKm = request.DeliveryRadiusKm;
|
||||
existing.SupportsDineIn = request.SupportsDineIn;
|
||||
existing.SupportsPickup = request.SupportsPickup;
|
||||
existing.SupportsDelivery = request.SupportsDelivery;
|
||||
|
||||
// 3. 持久化
|
||||
await _storeRepository.UpdateStoreAsync(existing, cancellationToken);
|
||||
await _storeRepository.SaveChangesAsync(cancellationToken);
|
||||
_logger.LogInformation("更新门店 {StoreId} - {StoreName}", existing.Id, existing.Name);
|
||||
|
||||
// 4. 返回 DTO
|
||||
return MapToDto(existing);
|
||||
}
|
||||
|
||||
private static StoreDto MapToDto(Store store) => new()
|
||||
{
|
||||
Id = store.Id,
|
||||
TenantId = store.TenantId,
|
||||
MerchantId = store.MerchantId,
|
||||
Code = store.Code,
|
||||
Name = store.Name,
|
||||
Phone = store.Phone,
|
||||
ManagerName = store.ManagerName,
|
||||
Status = store.Status,
|
||||
Province = store.Province,
|
||||
City = store.City,
|
||||
District = store.District,
|
||||
Address = store.Address,
|
||||
Longitude = store.Longitude,
|
||||
Latitude = store.Latitude,
|
||||
Announcement = store.Announcement,
|
||||
Tags = store.Tags,
|
||||
DeliveryRadiusKm = store.DeliveryRadiusKm,
|
||||
SupportsDineIn = store.SupportsDineIn,
|
||||
SupportsPickup = store.SupportsPickup,
|
||||
SupportsDelivery = store.SupportsDelivery
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.App.Stores.Dto;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Queries;
|
||||
|
||||
/// <summary>
|
||||
/// 获取门店详情查询。
|
||||
/// </summary>
|
||||
public sealed class GetStoreByIdQuery : IRequest<StoreDto?>
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店 ID。
|
||||
/// </summary>
|
||||
public long StoreId { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.App.Stores.Dto;
|
||||
using TakeoutSaaS.Domain.Stores.Enums;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Stores.Queries;
|
||||
|
||||
/// <summary>
|
||||
/// 门店列表查询。
|
||||
/// </summary>
|
||||
public sealed class SearchStoresQuery : IRequest<IReadOnlyList<StoreDto>>
|
||||
{
|
||||
/// <summary>
|
||||
/// 商户 ID(可选)。
|
||||
/// </summary>
|
||||
public long? MerchantId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态过滤。
|
||||
/// </summary>
|
||||
public StoreStatus? Status { get; init; }
|
||||
}
|
||||
Reference in New Issue
Block a user