feat(store): auto-generate store code on create and make update code optional
All checks were successful
Build and Deploy TenantApi / build-and-deploy (push) Successful in 44s
All checks were successful
Build and Deploy TenantApi / build-and-deploy (push) Successful in 44s
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using MediatR;
|
||||
using System.Security.Cryptography;
|
||||
using TakeoutSaaS.Application.App.Stores.Commands;
|
||||
using TakeoutSaaS.Application.App.Stores.Enums;
|
||||
using TakeoutSaaS.Application.App.Stores.Services;
|
||||
@@ -24,7 +25,7 @@ public sealed class CreateStoreCommandHandler(
|
||||
// 1. 解析上下文
|
||||
var context = storeContextService.GetRequiredContext();
|
||||
|
||||
// 2. 校验编码唯一性
|
||||
// 2. 生成唯一门店编码
|
||||
var existingStores = await storeRepository.SearchAsync(
|
||||
context.TenantId,
|
||||
context.MerchantId,
|
||||
@@ -35,12 +36,7 @@ public sealed class CreateStoreCommandHandler(
|
||||
keyword: null,
|
||||
includeDeleted: false,
|
||||
cancellationToken: cancellationToken);
|
||||
var normalizedCode = request.Code.Trim();
|
||||
var hasDuplicateCode = existingStores.Any(store => string.Equals(store.Code, normalizedCode, StringComparison.OrdinalIgnoreCase));
|
||||
if (hasDuplicateCode)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.Conflict, "门店编码已存在");
|
||||
}
|
||||
var generatedCode = GenerateUniqueStoreCode(existingStores);
|
||||
|
||||
// 3. 组装门店实体
|
||||
var serviceTypes = request.ServiceTypes?.Count > 0
|
||||
@@ -50,7 +46,7 @@ public sealed class CreateStoreCommandHandler(
|
||||
{
|
||||
TenantId = context.TenantId,
|
||||
MerchantId = context.MerchantId,
|
||||
Code = normalizedCode,
|
||||
Code = generatedCode,
|
||||
Name = request.Name.Trim(),
|
||||
Phone = request.ContactPhone.Trim(),
|
||||
ManagerName = request.ManagerName.Trim(),
|
||||
@@ -68,4 +64,27 @@ public sealed class CreateStoreCommandHandler(
|
||||
await storeRepository.AddStoreAsync(store, cancellationToken);
|
||||
await storeRepository.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成当前租户商户内唯一的门店编码。
|
||||
/// </summary>
|
||||
private static string GenerateUniqueStoreCode(IReadOnlyList<Store> existingStores)
|
||||
{
|
||||
var existingCodeSet = existingStores
|
||||
.Select(store => store.Code.Trim())
|
||||
.Where(code => !string.IsNullOrWhiteSpace(code))
|
||||
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
const int maxRetryCount = 20;
|
||||
for (var attempt = 0; attempt < maxRetryCount; attempt++)
|
||||
{
|
||||
var candidate = $"ST{DateTime.UtcNow:yyMMddHHmmss}{RandomNumberGenerator.GetInt32(100, 1000)}";
|
||||
if (existingCodeSet.Add(candidate))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
throw new BusinessException(ErrorCodes.Conflict, "门店编码生成失败,请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user