refactor: 清理租户API旧模块代码

This commit is contained in:
2026-02-17 09:57:26 +08:00
parent 2711893474
commit 992930a821
924 changed files with 7 additions and 191722 deletions

View File

@@ -1,40 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 批量更新营业时段命令验证器。
/// </summary>
public sealed class BatchUpdateBusinessHoursCommandValidator : AbstractValidator<BatchUpdateBusinessHoursCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public BatchUpdateBusinessHoursCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleForEach(x => x.Items).ChildRules(item =>
{
item.RuleFor(x => x.StartTime).NotNull();
item.RuleFor(x => x.EndTime).NotNull();
item.RuleFor(x => x.CapacityLimit).GreaterThanOrEqualTo(0).When(x => x.CapacityLimit.HasValue);
item.RuleFor(x => x.Notes).MaximumLength(256);
});
RuleFor(x => x.Items).Custom((items, context) =>
{
if (items == null || items.Count == 0)
{
return;
}
var error = BusinessHourValidators.ValidateOverlap(items);
if (!string.IsNullOrWhiteSpace(error))
{
context.AddFailure(error);
}
});
}
}

View File

@@ -1,65 +0,0 @@
using System.Linq;
using TakeoutSaaS.Application.App.Stores.Dto;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 营业时段校验助手。
/// </summary>
public static class BusinessHourValidators
{
/// <summary>
/// 校验营业时段是否存在重叠。
/// </summary>
/// <param name="items">营业时段列表。</param>
/// <returns>错误信息,若为空表示通过。</returns>
public static string? ValidateOverlap(IReadOnlyList<StoreBusinessHourInputDto> items)
{
if (items.Count == 0)
{
return null;
}
var segments = new List<(DayOfWeek Day, TimeSpan Start, TimeSpan End)>();
foreach (var item in items)
{
if (item.StartTime == item.EndTime)
{
return "营业时段开始时间不能等于结束时间";
}
if (item.StartTime < item.EndTime)
{
segments.Add((item.DayOfWeek, item.StartTime, item.EndTime));
continue;
}
var nextDay = NextDay(item.DayOfWeek);
segments.Add((item.DayOfWeek, item.StartTime, TimeSpan.FromDays(1)));
segments.Add((nextDay, TimeSpan.Zero, item.EndTime));
}
var grouped = segments.GroupBy(x => x.Day).ToList();
foreach (var group in grouped)
{
var ordered = group.OrderBy(x => x.Start).ToList();
for (var index = 0; index < ordered.Count - 1; index++)
{
var current = ordered[index];
var next = ordered[index + 1];
if (next.Start < current.End)
{
return "营业时段存在重叠,请调整";
}
}
}
return null;
}
private static DayOfWeek NextDay(DayOfWeek day)
{
var next = (int)day + 1;
return next > 6 ? DayOfWeek.Sunday : (DayOfWeek)next;
}
}

View File

@@ -1,26 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Queries;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 费用预览计算查询验证器。
/// </summary>
public sealed class CalculateStoreFeeQueryValidator : AbstractValidator<CalculateStoreFeeQuery>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public CalculateStoreFeeQueryValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.OrderAmount).GreaterThanOrEqualTo(0);
RuleForEach(x => x.Items).ChildRules(item =>
{
item.RuleFor(x => x.SkuId).GreaterThan(0);
item.RuleFor(x => x.Quantity).GreaterThan(0);
item.RuleFor(x => x.PackagingFee).GreaterThanOrEqualTo(0);
});
}
}

View File

@@ -1,20 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Queries;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 配送范围检测查询验证器。
/// </summary>
public sealed class CheckStoreDeliveryZoneQueryValidator : AbstractValidator<CheckStoreDeliveryZoneQuery>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public CheckStoreDeliveryZoneQueryValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.Longitude).InclusiveBetween(-180, 180);
RuleFor(x => x.Latitude).InclusiveBetween(-90, 90);
}
}

View File

@@ -1,21 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 创建营业时段命令验证器。
/// </summary>
public sealed class CreateStoreBusinessHourCommandValidator : AbstractValidator<CreateStoreBusinessHourCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public CreateStoreBusinessHourCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.StartTime).NotEqual(x => x.EndTime).WithMessage("开始时间不能等于结束时间");
RuleFor(x => x.CapacityLimit).GreaterThanOrEqualTo(0).When(x => x.CapacityLimit.HasValue);
RuleFor(x => x.Notes).MaximumLength(256);
}
}

View File

@@ -1,33 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 创建门店命令验证器。
/// </summary>
public sealed class CreateStoreCommandValidator : AbstractValidator<CreateStoreCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public CreateStoreCommandValidator()
{
RuleFor(x => x.MerchantId).GreaterThan(0);
RuleFor(x => x.Code).NotEmpty().MaximumLength(32);
RuleFor(x => x.Name).NotEmpty().MaximumLength(128);
RuleFor(x => x.Phone).MaximumLength(32);
RuleFor(x => x.ManagerName).MaximumLength(64);
RuleFor(x => x.SignboardImageUrl).NotEmpty().MaximumLength(500);
RuleFor(x => x.OwnershipType).IsInEnum();
RuleFor(x => x.Province).MaximumLength(64);
RuleFor(x => x.City).MaximumLength(64);
RuleFor(x => x.District).MaximumLength(64);
RuleFor(x => x.Address).MaximumLength(256);
RuleFor(x => x.Longitude).NotNull();
RuleFor(x => x.Latitude).NotNull();
RuleFor(x => x.Announcement).MaximumLength(512);
RuleFor(x => x.Tags).MaximumLength(256);
RuleFor(x => x.DeliveryRadiusKm).GreaterThanOrEqualTo(0);
}
}

View File

@@ -1,24 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 创建配送区域命令验证器。
/// </summary>
public sealed class CreateStoreDeliveryZoneCommandValidator : AbstractValidator<CreateStoreDeliveryZoneCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public CreateStoreDeliveryZoneCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.ZoneName).NotEmpty().MaximumLength(64);
RuleFor(x => x.PolygonGeoJson).NotEmpty();
RuleFor(x => x.MinimumOrderAmount).GreaterThanOrEqualTo(0).When(x => x.MinimumOrderAmount.HasValue);
RuleFor(x => x.DeliveryFee).GreaterThanOrEqualTo(0).When(x => x.DeliveryFee.HasValue);
RuleFor(x => x.EstimatedMinutes).GreaterThan(0).When(x => x.EstimatedMinutes.HasValue);
RuleFor(x => x.SortOrder).GreaterThanOrEqualTo(0);
}
}

View File

@@ -1,22 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 创建排班命令验证器。
/// </summary>
public sealed class CreateStoreEmployeeShiftCommandValidator : AbstractValidator<CreateStoreEmployeeShiftCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public CreateStoreEmployeeShiftCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.StaffId).GreaterThan(0);
RuleFor(x => x.ShiftDate).NotEmpty();
RuleFor(x => x.StartTime).LessThan(x => x.EndTime).WithMessage("结束时间必须晚于开始时间");
RuleFor(x => x.Notes).MaximumLength(256);
}
}

View File

@@ -1,41 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 创建节假日命令验证器。
/// </summary>
public sealed class CreateStoreHolidayCommandValidator : AbstractValidator<CreateStoreHolidayCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public CreateStoreHolidayCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.Date).NotEmpty();
RuleFor(x => x.EndDate)
.GreaterThanOrEqualTo(x => x.Date)
.When(x => x.EndDate.HasValue)
.WithMessage("结束日期不能早于开始日期");
RuleFor(x => x.StartTime)
.NotNull()
.When(x => !x.IsAllDay)
.WithMessage("非全天模式下必须填写开始时间");
RuleFor(x => x.EndTime)
.NotNull()
.When(x => !x.IsAllDay)
.WithMessage("非全天模式下必须填写结束时间");
RuleFor(x => x.EndTime)
.GreaterThan(x => x.StartTime)
.When(x => !x.IsAllDay && x.StartTime.HasValue && x.EndTime.HasValue)
.WithMessage("结束时间必须晚于开始时间");
RuleFor(x => x.Reason).MaximumLength(200);
}
}

View File

@@ -1,23 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 创建自提档期验证器。
/// </summary>
public sealed class CreateStorePickupSlotCommandValidator : AbstractValidator<CreateStorePickupSlotCommand>
{
/// <summary>
/// 初始化规则。
/// </summary>
public CreateStorePickupSlotCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.Name).NotEmpty().MaximumLength(64);
RuleFor(x => x.Capacity).GreaterThan(0);
RuleFor(x => x.Weekdays).NotEmpty().MaximumLength(32);
RuleFor(x => x.CutoffMinutes).GreaterThanOrEqualTo(0);
RuleFor(x => x.EndTime).GreaterThan(x => x.StartTime);
}
}

View File

@@ -1,42 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
using TakeoutSaaS.Domain.Stores.Enums;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 创建门店资质命令验证器。
/// </summary>
public sealed class CreateStoreQualificationCommandValidator : AbstractValidator<CreateStoreQualificationCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public CreateStoreQualificationCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.QualificationType).IsInEnum();
RuleFor(x => x.FileUrl).NotEmpty().MaximumLength(500);
RuleFor(x => x.SortOrder).GreaterThanOrEqualTo(0);
RuleFor(x => x.DocumentNumber).MaximumLength(100);
RuleFor(x => x.ExpiresAt)
.Must(date => date.HasValue && date.Value > DateOnly.FromDateTime(DateTime.UtcNow))
.When(x => IsLicenseType(x.QualificationType))
.WithMessage("证照有效期必须晚于今天");
RuleFor(x => x.DocumentNumber)
.NotEmpty()
.MinimumLength(2)
.When(x => IsLicenseType(x.QualificationType))
.WithMessage("证照编号不能为空");
RuleFor(x => x.ExpiresAt)
.Must(date => !date.HasValue || date.Value > DateOnly.FromDateTime(DateTime.UtcNow))
.When(x => !IsLicenseType(x.QualificationType))
.WithMessage("证照有效期必须晚于今天");
}
private static bool IsLicenseType(StoreQualificationType type)
=> type is StoreQualificationType.BusinessLicense or StoreQualificationType.FoodServiceLicense;
}

View File

@@ -1,21 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 创建门店员工命令验证器。
/// </summary>
public sealed class CreateStoreStaffCommandValidator : AbstractValidator<CreateStoreStaffCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public CreateStoreStaffCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.Name).NotEmpty().MaximumLength(64);
RuleFor(x => x.Phone).NotEmpty().MaximumLength(32);
RuleFor(x => x.Email).EmailAddress().When(x => !string.IsNullOrWhiteSpace(x.Email));
}
}

View File

@@ -1,21 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 创建桌台区域命令验证器。
/// </summary>
public sealed class CreateStoreTableAreaCommandValidator : AbstractValidator<CreateStoreTableAreaCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public CreateStoreTableAreaCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.Name).NotEmpty().MaximumLength(64);
RuleFor(x => x.Description).MaximumLength(256);
RuleFor(x => x.SortOrder).GreaterThanOrEqualTo(0);
}
}

View File

@@ -1,19 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 删除自提档期验证器。
/// </summary>
public sealed class DeleteStorePickupSlotCommandValidator : AbstractValidator<DeleteStorePickupSlotCommand>
{
/// <summary>
/// 初始化规则。
/// </summary>
public DeleteStorePickupSlotCommandValidator()
{
RuleFor(x => x.SlotId).GreaterThan(0);
RuleFor(x => x.StoreId).GreaterThan(0);
}
}

View File

@@ -1,19 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 删除门店资质命令验证器。
/// </summary>
public sealed class DeleteStoreQualificationCommandValidator : AbstractValidator<DeleteStoreQualificationCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public DeleteStoreQualificationCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.QualificationId).GreaterThan(0);
}
}

View File

@@ -1,23 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 批量生成桌码命令验证器。
/// </summary>
public sealed class GenerateStoreTablesCommandValidator : AbstractValidator<GenerateStoreTablesCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public GenerateStoreTablesCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.TableCodePrefix).NotEmpty().MaximumLength(16);
RuleFor(x => x.StartNumber).GreaterThan(0);
RuleFor(x => x.Count).GreaterThan(0).LessThanOrEqualTo(500);
RuleFor(x => x.DefaultCapacity).GreaterThan(0).LessThanOrEqualTo(50);
RuleFor(x => x.Tags).MaximumLength(128);
}
}

View File

@@ -1,18 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Queries;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 桌码上下文查询验证器。
/// </summary>
public sealed class GetStoreTableContextQueryValidator : AbstractValidator<GetStoreTableContextQuery>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public GetStoreTableContextQueryValidator()
{
RuleFor(x => x.TableCode).NotEmpty().MaximumLength(32);
}
}

View File

@@ -1,20 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Queries;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 门店列表查询验证器。
/// </summary>
public sealed class SearchStoresQueryValidator : AbstractValidator<SearchStoresQuery>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public SearchStoresQueryValidator()
{
RuleFor(x => x.Page).GreaterThan(0);
RuleFor(x => x.PageSize).InclusiveBetween(1, 200);
RuleFor(x => x.SortBy).MaximumLength(64);
}
}

View File

@@ -1,18 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 提交门店审核命令验证器。
/// </summary>
public sealed class SubmitStoreAuditCommandValidator : AbstractValidator<SubmitStoreAuditCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public SubmitStoreAuditCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
}
}

View File

@@ -1,29 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
using TakeoutSaaS.Domain.Stores.Enums;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 切换门店经营状态命令验证器。
/// </summary>
public sealed class ToggleBusinessStatusCommandValidator : AbstractValidator<ToggleBusinessStatusCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public ToggleBusinessStatusCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.BusinessStatus)
.Must(status => status is StoreBusinessStatus.Open or StoreBusinessStatus.Resting)
.WithMessage("仅允许切换营业中或休息中");
RuleFor(x => x.ClosureReason)
.NotNull()
.When(x => x.BusinessStatus == StoreBusinessStatus.Resting)
.WithMessage("切换休息中必须选择歇业原因");
RuleFor(x => x.ClosureReasonText).MaximumLength(500);
}
}

View File

@@ -1,22 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新营业时段命令验证器。
/// </summary>
public sealed class UpdateStoreBusinessHourCommandValidator : AbstractValidator<UpdateStoreBusinessHourCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public UpdateStoreBusinessHourCommandValidator()
{
RuleFor(x => x.BusinessHourId).GreaterThan(0);
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.StartTime).NotEqual(x => x.EndTime).WithMessage("开始时间不能等于结束时间");
RuleFor(x => x.CapacityLimit).GreaterThanOrEqualTo(0).When(x => x.CapacityLimit.HasValue);
RuleFor(x => x.Notes).MaximumLength(256);
}
}

View File

@@ -1,31 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新门店命令验证器。
/// </summary>
public sealed class UpdateStoreCommandValidator : AbstractValidator<UpdateStoreCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public UpdateStoreCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.MerchantId).GreaterThan(0);
RuleFor(x => x.Code).NotEmpty().MaximumLength(32);
RuleFor(x => x.Name).NotEmpty().MaximumLength(128);
RuleFor(x => x.Phone).MaximumLength(32);
RuleFor(x => x.ManagerName).MaximumLength(64);
RuleFor(x => x.SignboardImageUrl).MaximumLength(500);
RuleFor(x => x.Province).MaximumLength(64);
RuleFor(x => x.City).MaximumLength(64);
RuleFor(x => x.District).MaximumLength(64);
RuleFor(x => x.Address).MaximumLength(256);
RuleFor(x => x.Announcement).MaximumLength(512);
RuleFor(x => x.Tags).MaximumLength(256);
RuleFor(x => x.DeliveryRadiusKm).GreaterThanOrEqualTo(0);
}
}

View File

@@ -1,25 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新配送区域命令验证器。
/// </summary>
public sealed class UpdateStoreDeliveryZoneCommandValidator : AbstractValidator<UpdateStoreDeliveryZoneCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public UpdateStoreDeliveryZoneCommandValidator()
{
RuleFor(x => x.DeliveryZoneId).GreaterThan(0);
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.ZoneName).NotEmpty().MaximumLength(64);
RuleFor(x => x.PolygonGeoJson).NotEmpty();
RuleFor(x => x.MinimumOrderAmount).GreaterThanOrEqualTo(0).When(x => x.MinimumOrderAmount.HasValue);
RuleFor(x => x.DeliveryFee).GreaterThanOrEqualTo(0).When(x => x.DeliveryFee.HasValue);
RuleFor(x => x.EstimatedMinutes).GreaterThan(0).When(x => x.EstimatedMinutes.HasValue);
RuleFor(x => x.SortOrder).GreaterThanOrEqualTo(0);
}
}

View File

@@ -1,23 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新排班命令验证器。
/// </summary>
public sealed class UpdateStoreEmployeeShiftCommandValidator : AbstractValidator<UpdateStoreEmployeeShiftCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public UpdateStoreEmployeeShiftCommandValidator()
{
RuleFor(x => x.ShiftId).GreaterThan(0);
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.StaffId).GreaterThan(0);
RuleFor(x => x.ShiftDate).NotEmpty();
RuleFor(x => x.StartTime).LessThan(x => x.EndTime).WithMessage("结束时间必须晚于开始时间");
RuleFor(x => x.Notes).MaximumLength(256);
}
}

View File

@@ -1,87 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
using TakeoutSaaS.Domain.Stores.Enums;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新门店费用配置命令验证器。
/// </summary>
public sealed class UpdateStoreFeeCommandValidator : AbstractValidator<UpdateStoreFeeCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public UpdateStoreFeeCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.MinimumOrderAmount).GreaterThanOrEqualTo(0).LessThanOrEqualTo(9999.99m);
RuleFor(x => x.DeliveryFee).GreaterThanOrEqualTo(0).LessThanOrEqualTo(999.99m);
RuleFor(x => x.FreeDeliveryThreshold).GreaterThanOrEqualTo(0).When(x => x.FreeDeliveryThreshold.HasValue);
RuleFor(x => x.FixedPackagingFee)
.NotNull()
.When(x => x.PackagingFeeMode == PackagingFeeMode.Fixed && x.OrderPackagingFeeMode == OrderPackagingFeeMode.Fixed)
.WithMessage("总计打包费模式下必须填写固定打包费");
RuleFor(x => x.FixedPackagingFee)
.Must(fee => !fee.HasValue || fee.Value <= 99.99m)
.WithMessage("固定打包费不能超过 99.99");
RuleFor(x => x.FixedPackagingFee)
.Must(fee => !fee.HasValue || fee.Value >= 0)
.WithMessage("固定打包费不能为负数");
RuleFor(x => x)
.Custom((command, context) =>
{
if (command.PackagingFeeMode != PackagingFeeMode.Fixed || command.OrderPackagingFeeMode != OrderPackagingFeeMode.Tiered)
{
return;
}
if (command.PackagingFeeTiers is null || command.PackagingFeeTiers.Count == 0)
{
context.AddFailure("阶梯价模式必须配置至少 1 个区间");
return;
}
if (command.PackagingFeeTiers.Count > 10)
{
context.AddFailure("阶梯价最多支持 10 个区间");
return;
}
var expectedMin = 0m;
for (var index = 0; index < command.PackagingFeeTiers.Count; index++)
{
var tier = command.PackagingFeeTiers[index];
if (tier.Fee < 0 || tier.Fee > 99.99m)
{
context.AddFailure($"第 {index + 1} 个阶梯打包费需在 0~99.99 之间");
return;
}
if (tier.MaxPrice.HasValue && tier.MaxPrice.Value <= expectedMin)
{
context.AddFailure($"第 {index + 1} 个阶梯上限必须大于 {expectedMin:0.##}");
return;
}
if (!tier.MaxPrice.HasValue && index != command.PackagingFeeTiers.Count - 1)
{
context.AddFailure("仅允许最后一个阶梯的上限为空");
return;
}
if (tier.MaxPrice.HasValue && tier.MaxPrice.Value > 99999.99m)
{
context.AddFailure($"第 {index + 1} 个阶梯上限不能超过 99999.99");
return;
}
expectedMin = tier.MaxPrice ?? expectedMin;
}
});
}
}

View File

@@ -1,42 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新节假日命令验证器。
/// </summary>
public sealed class UpdateStoreHolidayCommandValidator : AbstractValidator<UpdateStoreHolidayCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public UpdateStoreHolidayCommandValidator()
{
RuleFor(x => x.HolidayId).GreaterThan(0);
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.Date).NotEmpty();
RuleFor(x => x.EndDate)
.GreaterThanOrEqualTo(x => x.Date)
.When(x => x.EndDate.HasValue)
.WithMessage("结束日期不能早于开始日期");
RuleFor(x => x.StartTime)
.NotNull()
.When(x => !x.IsAllDay)
.WithMessage("非全天模式下必须填写开始时间");
RuleFor(x => x.EndTime)
.NotNull()
.When(x => !x.IsAllDay)
.WithMessage("非全天模式下必须填写结束时间");
RuleFor(x => x.EndTime)
.GreaterThan(x => x.StartTime)
.When(x => !x.IsAllDay && x.StartTime.HasValue && x.EndTime.HasValue)
.WithMessage("结束时间必须晚于开始时间");
RuleFor(x => x.Reason).MaximumLength(200);
}
}

View File

@@ -1,24 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新自提档期验证器。
/// </summary>
public sealed class UpdateStorePickupSlotCommandValidator : AbstractValidator<UpdateStorePickupSlotCommand>
{
/// <summary>
/// 初始化规则。
/// </summary>
public UpdateStorePickupSlotCommandValidator()
{
RuleFor(x => x.SlotId).GreaterThan(0);
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.Name).NotEmpty().MaximumLength(64);
RuleFor(x => x.Capacity).GreaterThan(0);
RuleFor(x => x.Weekdays).NotEmpty().MaximumLength(32);
RuleFor(x => x.CutoffMinutes).GreaterThanOrEqualTo(0);
RuleFor(x => x.EndTime).GreaterThan(x => x.StartTime);
}
}

View File

@@ -1,26 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新门店资质命令验证器。
/// </summary>
public sealed class UpdateStoreQualificationCommandValidator : AbstractValidator<UpdateStoreQualificationCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public UpdateStoreQualificationCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.QualificationId).GreaterThan(0);
RuleFor(x => x.FileUrl).MaximumLength(500).When(x => !string.IsNullOrWhiteSpace(x.FileUrl));
RuleFor(x => x.DocumentNumber).MaximumLength(100).When(x => !string.IsNullOrWhiteSpace(x.DocumentNumber));
RuleFor(x => x.SortOrder).GreaterThanOrEqualTo(0).When(x => x.SortOrder.HasValue);
RuleFor(x => x.ExpiresAt)
.Must(date => !date.HasValue || date.Value > DateOnly.FromDateTime(DateTime.UtcNow))
.When(x => x.ExpiresAt.HasValue)
.WithMessage("证照有效期必须晚于今天");
}
}

View File

@@ -1,22 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新门店员工命令验证器。
/// </summary>
public sealed class UpdateStoreStaffCommandValidator : AbstractValidator<UpdateStoreStaffCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public UpdateStoreStaffCommandValidator()
{
RuleFor(x => x.StaffId).GreaterThan(0);
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.Name).NotEmpty().MaximumLength(64);
RuleFor(x => x.Phone).NotEmpty().MaximumLength(32);
RuleFor(x => x.Email).EmailAddress().When(x => !string.IsNullOrWhiteSpace(x.Email));
}
}

View File

@@ -1,22 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新桌台区域命令验证器。
/// </summary>
public sealed class UpdateStoreTableAreaCommandValidator : AbstractValidator<UpdateStoreTableAreaCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public UpdateStoreTableAreaCommandValidator()
{
RuleFor(x => x.AreaId).GreaterThan(0);
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.Name).NotEmpty().MaximumLength(64);
RuleFor(x => x.Description).MaximumLength(256);
RuleFor(x => x.SortOrder).GreaterThanOrEqualTo(0);
}
}

View File

@@ -1,22 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 更新桌码命令验证器。
/// </summary>
public sealed class UpdateStoreTableCommandValidator : AbstractValidator<UpdateStoreTableCommand>
{
/// <summary>
/// 初始化验证规则。
/// </summary>
public UpdateStoreTableCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.TableId).GreaterThan(0);
RuleFor(x => x.TableCode).NotEmpty().MaximumLength(32);
RuleFor(x => x.Capacity).GreaterThan(0).LessThanOrEqualTo(50);
RuleFor(x => x.Tags).MaximumLength(128);
}
}

View File

@@ -1,21 +0,0 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Stores.Commands;
namespace TakeoutSaaS.Application.App.Stores.Validators;
/// <summary>
/// 自提配置验证器。
/// </summary>
public sealed class UpsertStorePickupSettingCommandValidator : AbstractValidator<UpsertStorePickupSettingCommand>
{
/// <summary>
/// 初始化规则。
/// </summary>
public UpsertStorePickupSettingCommandValidator()
{
RuleFor(x => x.StoreId).GreaterThan(0);
RuleFor(x => x.AllowDaysAhead).GreaterThanOrEqualTo(0);
RuleFor(x => x.DefaultCutoffMinutes).GreaterThanOrEqualTo(0);
RuleFor(x => x.MaxQuantityPerOrder).GreaterThan(0).When(x => x.MaxQuantityPerOrder.HasValue);
}
}