style: 命令不可变化与规范补充
This commit is contained in:
43
AGENTS.md
43
AGENTS.md
@@ -143,6 +143,49 @@
|
|||||||
6. [ ] **精度丢失**:Long 类型的 ID 是否转为了 String?
|
6. [ ] **精度丢失**:Long 类型的 ID 是否转为了 String?
|
||||||
7. [ ] **配置硬编码**:是否直接写死了连接串或密钥?
|
7. [ ] **配置硬编码**:是否直接写死了连接串或密钥?
|
||||||
|
|
||||||
|
## 17. .NET 10 / C# 14 现代语法最佳实践(增量)
|
||||||
|
> 2025 年推荐的 20 条语法规范,新增特性优先,保持极简。
|
||||||
|
1. **field 关键字**:属性内直接使用 `field` 处理后备字段,`set => field = value.Trim();`。
|
||||||
|
2. **空值条件赋值 `?.=`**:仅对象非空时赋值,减少 `if`。
|
||||||
|
3. **未绑定泛型 nameof**:`nameof(List<>)` 获取泛型类型名,无需占位类型参数。
|
||||||
|
4. **Lambda 参数修饰符**:在 Lambda 中可用 `ref/out/in` 与默认参数,例如 `(ref int x, int bonus = 10) => x += bonus;`。
|
||||||
|
5. **主构造函数 (Primary Constructor)**:服务/数据类优先 `class Foo(IDep dep, ILogger<Foo> logger) { }`。
|
||||||
|
6. **record/required/init**:DTO 默认用 record;关键属性用 `required`;不可变属性用 `init`。
|
||||||
|
7. **集合表达式与展开**:使用 `[]` 创建集合,`[..other]` 拼接,`str[1..^1]` 进行切片。
|
||||||
|
8. **模式匹配**:列表模式 `[1, 2, .. var rest]`、属性模式 `{ IsActive: true }`、switch 表达式简化分支。
|
||||||
|
9. **文件范围命名空间/全局 using**:减少缩进与重复引用;复杂泛型用别名。
|
||||||
|
10. **顶级语句**:Program.cs 保持顶级语句风格。
|
||||||
|
11. **原始/UTF-8 字面量**:多行文本用 `"""`,性能场景用 `"text"u8`。
|
||||||
|
12. **不可变命令优先**:命令/DTO 优先用 record 和 `with` 非破坏性拷贝,例如 `command = command with { MerchantId = merchantId };`,避免直接 `command.Property = ...` 带来的副作用。
|
||||||
|
|
||||||
|
(其余规则继续遵循上文约束:分层、命名、异步、日志、验证、租户/ID 策略等。)
|
||||||
|
|
||||||
|
## 18. .NET 10 极致性能优化最佳实践(增量)
|
||||||
|
> 侧重零分配、并发与底层优化,遵循 2025 推荐方案。
|
||||||
|
1. **Span/ReadOnlySpan 优先**:API 参数尽量用 `ReadOnlySpan<char>` 处理字符串/切片,避免 Substring/复制。
|
||||||
|
2. **栈分配与数组池**:小缓冲用 `stackalloc`,大缓冲统一用 `ArrayPool<T>.Shared`,禁止直接 `new` 大数组。
|
||||||
|
3. **UTF-8 字面量**:常量字节使用 `"text"u8`,避免运行时编码。
|
||||||
|
4. **避免装箱**:热点路径规避隐式装箱,必要时用 `ref struct` 约束栈分配。
|
||||||
|
5. **Frozen 集合**:只读查找表用 `FrozenDictionary/FrozenSet`,初始化后不再修改。
|
||||||
|
6. **SearchValues SIMD 查找**:Span 内多字符搜索用 `SearchValues.Create(...)` + `ContainsAny`。
|
||||||
|
7. **预设集合容量**:`List/Dictionary` 预知规模必须指定 `Capacity`。
|
||||||
|
8. **ValueTask 热点返回**:可能同步完成的异步返回 `ValueTask<T>`,减少 Task 分配。
|
||||||
|
9. **Parallel.ForEachAsync 控并发**:I/O 并发用 Parallel.ForEachAsync 控制并行度,替代粗暴 Task.WhenAll。
|
||||||
|
10. **避免 Task.Run**:在 ASP.NET Core 请求中不使用 Task.Run 做后台工作,改用 IHostedService 或 Channel 模式。
|
||||||
|
11. **Channel<T> 代替锁**:多线程数据传递优先使用 Channels,实现无锁生产者-消费者。
|
||||||
|
12. **NativeAOT/PGO/向量化**:微服务/工具开启 NativeAOT;保留动态 PGO;计算密集场景考虑 System.Runtime.Intrinsics。
|
||||||
|
13. **System.Text.Json + 源生成器**:全面替换 Newtonsoft.Json;使用 `[JsonSerializable]` + 生成的 `JsonSerializerContext`,兼容 NativeAOT,零反射。
|
||||||
|
14. **Pipelines 处理流**:TCP/文件流解析使用 `PipeReader/PipeWriter`,获得零拷贝与缓冲管理。
|
||||||
|
15. **HybridCache**:内存+分布式缓存统一用 HybridCache,利用防击穿合并并发请求。
|
||||||
|
|
||||||
|
## 19. 架构优化(增量)
|
||||||
|
> 架构优化方案
|
||||||
|
1. **Chiseled 容器优先**:生产镜像基于 `mcr.microsoft.com/dotnet/runtime-deps:10.0-jammy-chiseled`,无 Shell、非 root,缩小攻击面,符合零信任要求。
|
||||||
|
2. **默认集成 OpenTelemetry**:架构内置 OTel,统一通过 OTLP 导出 Metrics/Traces/Logs,避免依赖专有 APM 探针。
|
||||||
|
3. **内部同步调用首选 gRPC**:微服务间禁止 JSON over HTTP,同步调用统一使用 gRPC,配合 Protobuf 源生成器获取强类型契约与更小载荷。
|
||||||
|
4. **Outbox 模式强制**:处理领域事件时,事件记录必须与业务数据同事务写入 Outbox 表;后台 Worker 轮询 Outbox 再推送 MQ(RabbitMQ/Kafka),禁止事务提交后直接发消息以避免不一致。
|
||||||
|
5. **共享资源必加分布式锁**:涉及库存扣减、定时任务抢占等共享资源时,必须引入分布式锁(如 Redis RedLock),防止并发竞争与脏写。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,20 +16,15 @@ namespace TakeoutSaaS.AdminApi.Controllers;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 配送单管理。
|
/// 配送单管理。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 初始化控制器。
|
||||||
|
/// </remarks>
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/admin/v{version:apiVersion}/deliveries")]
|
[Route("api/admin/v{version:apiVersion}/deliveries")]
|
||||||
public sealed class DeliveriesController : BaseApiController
|
public sealed class DeliveriesController(IMediator mediator) : BaseApiController
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化控制器。
|
|
||||||
/// </summary>
|
|
||||||
public DeliveriesController(IMediator mediator)
|
|
||||||
{
|
|
||||||
_mediator = mediator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建配送单。
|
/// 创建配送单。
|
||||||
@@ -39,7 +34,7 @@ public sealed class DeliveriesController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<DeliveryOrderDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(ApiResponse<DeliveryOrderDto>), StatusCodes.Status200OK)]
|
||||||
public async Task<ApiResponse<DeliveryOrderDto>> Create([FromBody] CreateDeliveryOrderCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<DeliveryOrderDto>> Create([FromBody] CreateDeliveryOrderCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return ApiResponse<DeliveryOrderDto>.Ok(result);
|
return ApiResponse<DeliveryOrderDto>.Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +53,7 @@ public sealed class DeliveriesController : BaseApiController
|
|||||||
[FromQuery] bool sortDesc = true,
|
[FromQuery] bool sortDesc = true,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new SearchDeliveryOrdersQuery
|
var result = await mediator.Send(new SearchDeliveryOrdersQuery
|
||||||
{
|
{
|
||||||
OrderId = orderId,
|
OrderId = orderId,
|
||||||
Status = status,
|
Status = status,
|
||||||
@@ -80,7 +75,7 @@ public sealed class DeliveriesController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<DeliveryOrderDto>> Detail(long deliveryOrderId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<DeliveryOrderDto>> Detail(long deliveryOrderId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new GetDeliveryOrderByIdQuery { DeliveryOrderId = deliveryOrderId }, cancellationToken);
|
var result = await mediator.Send(new GetDeliveryOrderByIdQuery { DeliveryOrderId = deliveryOrderId }, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<DeliveryOrderDto>.Error(ErrorCodes.NotFound, "配送单不存在")
|
? ApiResponse<DeliveryOrderDto>.Error(ErrorCodes.NotFound, "配送单不存在")
|
||||||
: ApiResponse<DeliveryOrderDto>.Ok(result);
|
: ApiResponse<DeliveryOrderDto>.Ok(result);
|
||||||
@@ -95,8 +90,11 @@ public sealed class DeliveriesController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<DeliveryOrderDto>> Update(long deliveryOrderId, [FromBody] UpdateDeliveryOrderCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<DeliveryOrderDto>> Update(long deliveryOrderId, [FromBody] UpdateDeliveryOrderCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
command.DeliveryOrderId = command.DeliveryOrderId == 0 ? deliveryOrderId : command.DeliveryOrderId;
|
if (command.DeliveryOrderId == 0)
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
{
|
||||||
|
command = command with { DeliveryOrderId = deliveryOrderId };
|
||||||
|
}
|
||||||
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<DeliveryOrderDto>.Error(ErrorCodes.NotFound, "配送单不存在")
|
? ApiResponse<DeliveryOrderDto>.Error(ErrorCodes.NotFound, "配送单不存在")
|
||||||
: ApiResponse<DeliveryOrderDto>.Ok(result);
|
: ApiResponse<DeliveryOrderDto>.Ok(result);
|
||||||
@@ -111,7 +109,7 @@ public sealed class DeliveriesController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<object>> Delete(long deliveryOrderId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<object>> Delete(long deliveryOrderId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var success = await _mediator.Send(new DeleteDeliveryOrderCommand { DeliveryOrderId = deliveryOrderId }, cancellationToken);
|
var success = await mediator.Send(new DeleteDeliveryOrderCommand { DeliveryOrderId = deliveryOrderId }, cancellationToken);
|
||||||
return success
|
return success
|
||||||
? ApiResponse<object>.Ok(null)
|
? ApiResponse<object>.Ok(null)
|
||||||
: ApiResponse<object>.Error(ErrorCodes.NotFound, "配送单不存在");
|
: ApiResponse<object>.Error(ErrorCodes.NotFound, "配送单不存在");
|
||||||
|
|||||||
@@ -16,20 +16,15 @@ namespace TakeoutSaaS.AdminApi.Controllers;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商户管理。
|
/// 商户管理。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 初始化控制器。
|
||||||
|
/// </remarks>
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/admin/v{version:apiVersion}/merchants")]
|
[Route("api/admin/v{version:apiVersion}/merchants")]
|
||||||
public sealed class MerchantsController : BaseApiController
|
public sealed class MerchantsController(IMediator mediator) : BaseApiController
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化控制器。
|
|
||||||
/// </summary>
|
|
||||||
public MerchantsController(IMediator mediator)
|
|
||||||
{
|
|
||||||
_mediator = mediator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建商户。
|
/// 创建商户。
|
||||||
@@ -39,7 +34,7 @@ public sealed class MerchantsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<MerchantDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(ApiResponse<MerchantDto>), StatusCodes.Status200OK)]
|
||||||
public async Task<ApiResponse<MerchantDto>> Create([FromBody] CreateMerchantCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<MerchantDto>> Create([FromBody] CreateMerchantCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return ApiResponse<MerchantDto>.Ok(result);
|
return ApiResponse<MerchantDto>.Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +52,7 @@ public sealed class MerchantsController : BaseApiController
|
|||||||
[FromQuery] bool sortDesc = true,
|
[FromQuery] bool sortDesc = true,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new SearchMerchantsQuery
|
var result = await mediator.Send(new SearchMerchantsQuery
|
||||||
{
|
{
|
||||||
Status = status,
|
Status = status,
|
||||||
Page = page,
|
Page = page,
|
||||||
@@ -77,9 +72,12 @@ public sealed class MerchantsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<MerchantDto>> Update(long merchantId, [FromBody] UpdateMerchantCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<MerchantDto>> Update(long merchantId, [FromBody] UpdateMerchantCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
command.MerchantId = command.MerchantId == 0 ? merchantId : command.MerchantId;
|
if (command.MerchantId == 0)
|
||||||
|
{
|
||||||
|
command = command with { MerchantId = merchantId };
|
||||||
|
}
|
||||||
|
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<MerchantDto>.Error(ErrorCodes.NotFound, "商户不存在")
|
? ApiResponse<MerchantDto>.Error(ErrorCodes.NotFound, "商户不存在")
|
||||||
: ApiResponse<MerchantDto>.Ok(result);
|
: ApiResponse<MerchantDto>.Ok(result);
|
||||||
@@ -94,7 +92,7 @@ public sealed class MerchantsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<object>> Delete(long merchantId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<object>> Delete(long merchantId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var success = await _mediator.Send(new DeleteMerchantCommand { MerchantId = merchantId }, cancellationToken);
|
var success = await mediator.Send(new DeleteMerchantCommand { MerchantId = merchantId }, cancellationToken);
|
||||||
return success
|
return success
|
||||||
? ApiResponse<object>.Ok(null)
|
? ApiResponse<object>.Ok(null)
|
||||||
: ApiResponse<object>.Error(ErrorCodes.NotFound, "商户不存在");
|
: ApiResponse<object>.Error(ErrorCodes.NotFound, "商户不存在");
|
||||||
@@ -109,7 +107,7 @@ public sealed class MerchantsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<MerchantDto>> Detail(long merchantId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<MerchantDto>> Detail(long merchantId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new GetMerchantByIdQuery { MerchantId = merchantId }, cancellationToken);
|
var result = await mediator.Send(new GetMerchantByIdQuery { MerchantId = merchantId }, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<MerchantDto>.Error(ErrorCodes.NotFound, "商户不存在")
|
? ApiResponse<MerchantDto>.Error(ErrorCodes.NotFound, "商户不存在")
|
||||||
: ApiResponse<MerchantDto>.Ok(result);
|
: ApiResponse<MerchantDto>.Ok(result);
|
||||||
|
|||||||
@@ -17,20 +17,15 @@ namespace TakeoutSaaS.AdminApi.Controllers;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 订单管理。
|
/// 订单管理。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 初始化控制器。
|
||||||
|
/// </remarks>
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/admin/v{version:apiVersion}/orders")]
|
[Route("api/admin/v{version:apiVersion}/orders")]
|
||||||
public sealed class OrdersController : BaseApiController
|
public sealed class OrdersController(IMediator mediator) : BaseApiController
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化控制器。
|
|
||||||
/// </summary>
|
|
||||||
public OrdersController(IMediator mediator)
|
|
||||||
{
|
|
||||||
_mediator = mediator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建订单。
|
/// 创建订单。
|
||||||
@@ -40,7 +35,7 @@ public sealed class OrdersController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<OrderDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(ApiResponse<OrderDto>), StatusCodes.Status200OK)]
|
||||||
public async Task<ApiResponse<OrderDto>> Create([FromBody] CreateOrderCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<OrderDto>> Create([FromBody] CreateOrderCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return ApiResponse<OrderDto>.Ok(result);
|
return ApiResponse<OrderDto>.Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +56,7 @@ public sealed class OrdersController : BaseApiController
|
|||||||
[FromQuery] bool sortDesc = true,
|
[FromQuery] bool sortDesc = true,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new SearchOrdersQuery
|
var result = await mediator.Send(new SearchOrdersQuery
|
||||||
{
|
{
|
||||||
StoreId = storeId,
|
StoreId = storeId,
|
||||||
Status = status,
|
Status = status,
|
||||||
@@ -85,7 +80,7 @@ public sealed class OrdersController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<OrderDto>> Detail(long orderId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<OrderDto>> Detail(long orderId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new GetOrderByIdQuery { OrderId = orderId }, cancellationToken);
|
var result = await mediator.Send(new GetOrderByIdQuery { OrderId = orderId }, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<OrderDto>.Error(ErrorCodes.NotFound, "订单不存在")
|
? ApiResponse<OrderDto>.Error(ErrorCodes.NotFound, "订单不存在")
|
||||||
: ApiResponse<OrderDto>.Ok(result);
|
: ApiResponse<OrderDto>.Ok(result);
|
||||||
@@ -100,8 +95,11 @@ public sealed class OrdersController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<OrderDto>> Update(long orderId, [FromBody] UpdateOrderCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<OrderDto>> Update(long orderId, [FromBody] UpdateOrderCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
command.OrderId = command.OrderId == 0 ? orderId : command.OrderId;
|
if (command.OrderId == 0)
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
{
|
||||||
|
command = command with { OrderId = orderId };
|
||||||
|
}
|
||||||
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<OrderDto>.Error(ErrorCodes.NotFound, "订单不存在")
|
? ApiResponse<OrderDto>.Error(ErrorCodes.NotFound, "订单不存在")
|
||||||
: ApiResponse<OrderDto>.Ok(result);
|
: ApiResponse<OrderDto>.Ok(result);
|
||||||
@@ -116,7 +114,7 @@ public sealed class OrdersController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<object>> Delete(long orderId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<object>> Delete(long orderId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var success = await _mediator.Send(new DeleteOrderCommand { OrderId = orderId }, cancellationToken);
|
var success = await mediator.Send(new DeleteOrderCommand { OrderId = orderId }, cancellationToken);
|
||||||
return success
|
return success
|
||||||
? ApiResponse<object>.Ok(null)
|
? ApiResponse<object>.Ok(null)
|
||||||
: ApiResponse<object>.Error(ErrorCodes.NotFound, "订单不存在");
|
: ApiResponse<object>.Error(ErrorCodes.NotFound, "订单不存在");
|
||||||
|
|||||||
@@ -16,20 +16,15 @@ namespace TakeoutSaaS.AdminApi.Controllers;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付记录管理。
|
/// 支付记录管理。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 初始化控制器。
|
||||||
|
/// </remarks>
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/admin/v{version:apiVersion}/payments")]
|
[Route("api/admin/v{version:apiVersion}/payments")]
|
||||||
public sealed class PaymentsController : BaseApiController
|
public sealed class PaymentsController(IMediator mediator) : BaseApiController
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化控制器。
|
|
||||||
/// </summary>
|
|
||||||
public PaymentsController(IMediator mediator)
|
|
||||||
{
|
|
||||||
_mediator = mediator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建支付记录。
|
/// 创建支付记录。
|
||||||
@@ -39,7 +34,7 @@ public sealed class PaymentsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<PaymentDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(ApiResponse<PaymentDto>), StatusCodes.Status200OK)]
|
||||||
public async Task<ApiResponse<PaymentDto>> Create([FromBody] CreatePaymentCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<PaymentDto>> Create([FromBody] CreatePaymentCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return ApiResponse<PaymentDto>.Ok(result);
|
return ApiResponse<PaymentDto>.Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +53,7 @@ public sealed class PaymentsController : BaseApiController
|
|||||||
[FromQuery] bool sortDesc = true,
|
[FromQuery] bool sortDesc = true,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new SearchPaymentsQuery
|
var result = await mediator.Send(new SearchPaymentsQuery
|
||||||
{
|
{
|
||||||
OrderId = orderId,
|
OrderId = orderId,
|
||||||
Status = status,
|
Status = status,
|
||||||
@@ -80,7 +75,7 @@ public sealed class PaymentsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<PaymentDto>> Detail(long paymentId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<PaymentDto>> Detail(long paymentId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new GetPaymentByIdQuery { PaymentId = paymentId }, cancellationToken);
|
var result = await mediator.Send(new GetPaymentByIdQuery { PaymentId = paymentId }, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<PaymentDto>.Error(ErrorCodes.NotFound, "支付记录不存在")
|
? ApiResponse<PaymentDto>.Error(ErrorCodes.NotFound, "支付记录不存在")
|
||||||
: ApiResponse<PaymentDto>.Ok(result);
|
: ApiResponse<PaymentDto>.Ok(result);
|
||||||
@@ -95,8 +90,11 @@ public sealed class PaymentsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<PaymentDto>> Update(long paymentId, [FromBody] UpdatePaymentCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<PaymentDto>> Update(long paymentId, [FromBody] UpdatePaymentCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
command.PaymentId = command.PaymentId == 0 ? paymentId : command.PaymentId;
|
if (command.PaymentId == 0)
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
{
|
||||||
|
command = command with { PaymentId = paymentId };
|
||||||
|
}
|
||||||
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<PaymentDto>.Error(ErrorCodes.NotFound, "支付记录不存在")
|
? ApiResponse<PaymentDto>.Error(ErrorCodes.NotFound, "支付记录不存在")
|
||||||
: ApiResponse<PaymentDto>.Ok(result);
|
: ApiResponse<PaymentDto>.Ok(result);
|
||||||
@@ -111,7 +109,7 @@ public sealed class PaymentsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<object>> Delete(long paymentId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<object>> Delete(long paymentId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var success = await _mediator.Send(new DeletePaymentCommand { PaymentId = paymentId }, cancellationToken);
|
var success = await mediator.Send(new DeletePaymentCommand { PaymentId = paymentId }, cancellationToken);
|
||||||
return success
|
return success
|
||||||
? ApiResponse<object>.Ok(null)
|
? ApiResponse<object>.Ok(null)
|
||||||
: ApiResponse<object>.Error(ErrorCodes.NotFound, "支付记录不存在");
|
: ApiResponse<object>.Error(ErrorCodes.NotFound, "支付记录不存在");
|
||||||
|
|||||||
@@ -16,20 +16,15 @@ namespace TakeoutSaaS.AdminApi.Controllers;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商品管理。
|
/// 商品管理。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 初始化控制器。
|
||||||
|
/// </remarks>
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/admin/v{version:apiVersion}/products")]
|
[Route("api/admin/v{version:apiVersion}/products")]
|
||||||
public sealed class ProductsController : BaseApiController
|
public sealed class ProductsController(IMediator mediator) : BaseApiController
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化控制器。
|
|
||||||
/// </summary>
|
|
||||||
public ProductsController(IMediator mediator)
|
|
||||||
{
|
|
||||||
_mediator = mediator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建商品。
|
/// 创建商品。
|
||||||
@@ -39,7 +34,7 @@ public sealed class ProductsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<ProductDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(ApiResponse<ProductDto>), StatusCodes.Status200OK)]
|
||||||
public async Task<ApiResponse<ProductDto>> Create([FromBody] CreateProductCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<ProductDto>> Create([FromBody] CreateProductCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return ApiResponse<ProductDto>.Ok(result);
|
return ApiResponse<ProductDto>.Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +54,7 @@ public sealed class ProductsController : BaseApiController
|
|||||||
[FromQuery] bool sortDesc = true,
|
[FromQuery] bool sortDesc = true,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new SearchProductsQuery
|
var result = await mediator.Send(new SearchProductsQuery
|
||||||
{
|
{
|
||||||
StoreId = storeId,
|
StoreId = storeId,
|
||||||
CategoryId = categoryId,
|
CategoryId = categoryId,
|
||||||
@@ -82,7 +77,7 @@ public sealed class ProductsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<ProductDto>> Detail(long productId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<ProductDto>> Detail(long productId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new GetProductByIdQuery { ProductId = productId }, cancellationToken);
|
var result = await mediator.Send(new GetProductByIdQuery { ProductId = productId }, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<ProductDto>.Error(ErrorCodes.NotFound, "商品不存在")
|
? ApiResponse<ProductDto>.Error(ErrorCodes.NotFound, "商品不存在")
|
||||||
: ApiResponse<ProductDto>.Ok(result);
|
: ApiResponse<ProductDto>.Ok(result);
|
||||||
@@ -97,8 +92,11 @@ public sealed class ProductsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<ProductDto>> Update(long productId, [FromBody] UpdateProductCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<ProductDto>> Update(long productId, [FromBody] UpdateProductCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
command.ProductId = command.ProductId == 0 ? productId : command.ProductId;
|
if (command.ProductId == 0)
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
{
|
||||||
|
command = command with { ProductId = productId };
|
||||||
|
}
|
||||||
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<ProductDto>.Error(ErrorCodes.NotFound, "商品不存在")
|
? ApiResponse<ProductDto>.Error(ErrorCodes.NotFound, "商品不存在")
|
||||||
: ApiResponse<ProductDto>.Ok(result);
|
: ApiResponse<ProductDto>.Ok(result);
|
||||||
@@ -113,7 +111,7 @@ public sealed class ProductsController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<object>> Delete(long productId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<object>> Delete(long productId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var success = await _mediator.Send(new DeleteProductCommand { ProductId = productId }, cancellationToken);
|
var success = await mediator.Send(new DeleteProductCommand { ProductId = productId }, cancellationToken);
|
||||||
return success
|
return success
|
||||||
? ApiResponse<object>.Ok(null)
|
? ApiResponse<object>.Ok(null)
|
||||||
: ApiResponse<object>.Error(ErrorCodes.NotFound, "商品不存在");
|
: ApiResponse<object>.Error(ErrorCodes.NotFound, "商品不存在");
|
||||||
|
|||||||
@@ -16,20 +16,15 @@ namespace TakeoutSaaS.AdminApi.Controllers;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 门店管理。
|
/// 门店管理。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 初始化控制器。
|
||||||
|
/// </remarks>
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/admin/v{version:apiVersion}/stores")]
|
[Route("api/admin/v{version:apiVersion}/stores")]
|
||||||
public sealed class StoresController : BaseApiController
|
public sealed class StoresController(IMediator mediator) : BaseApiController
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化控制器。
|
|
||||||
/// </summary>
|
|
||||||
public StoresController(IMediator mediator)
|
|
||||||
{
|
|
||||||
_mediator = mediator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建门店。
|
/// 创建门店。
|
||||||
@@ -39,7 +34,7 @@ public sealed class StoresController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<StoreDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(ApiResponse<StoreDto>), StatusCodes.Status200OK)]
|
||||||
public async Task<ApiResponse<StoreDto>> Create([FromBody] CreateStoreCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<StoreDto>> Create([FromBody] CreateStoreCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return ApiResponse<StoreDto>.Ok(result);
|
return ApiResponse<StoreDto>.Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +53,7 @@ public sealed class StoresController : BaseApiController
|
|||||||
[FromQuery] bool sortDesc = true,
|
[FromQuery] bool sortDesc = true,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new SearchStoresQuery
|
var result = await mediator.Send(new SearchStoresQuery
|
||||||
{
|
{
|
||||||
MerchantId = merchantId,
|
MerchantId = merchantId,
|
||||||
Status = status,
|
Status = status,
|
||||||
@@ -80,7 +75,7 @@ public sealed class StoresController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<StoreDto>> Detail(long storeId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<StoreDto>> Detail(long storeId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await _mediator.Send(new GetStoreByIdQuery { StoreId = storeId }, cancellationToken);
|
var result = await mediator.Send(new GetStoreByIdQuery { StoreId = storeId }, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<StoreDto>.Error(ErrorCodes.NotFound, "门店不存在")
|
? ApiResponse<StoreDto>.Error(ErrorCodes.NotFound, "门店不存在")
|
||||||
: ApiResponse<StoreDto>.Ok(result);
|
: ApiResponse<StoreDto>.Ok(result);
|
||||||
@@ -95,8 +90,11 @@ public sealed class StoresController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<StoreDto>> Update(long storeId, [FromBody] UpdateStoreCommand command, CancellationToken cancellationToken)
|
public async Task<ApiResponse<StoreDto>> Update(long storeId, [FromBody] UpdateStoreCommand command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
command.StoreId = command.StoreId == 0 ? storeId : command.StoreId;
|
if (command.StoreId == 0)
|
||||||
var result = await _mediator.Send(command, cancellationToken);
|
{
|
||||||
|
command = command with { StoreId = storeId };
|
||||||
|
}
|
||||||
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
return result == null
|
return result == null
|
||||||
? ApiResponse<StoreDto>.Error(ErrorCodes.NotFound, "门店不存在")
|
? ApiResponse<StoreDto>.Error(ErrorCodes.NotFound, "门店不存在")
|
||||||
: ApiResponse<StoreDto>.Ok(result);
|
: ApiResponse<StoreDto>.Ok(result);
|
||||||
@@ -111,7 +109,7 @@ public sealed class StoresController : BaseApiController
|
|||||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||||
public async Task<ApiResponse<object>> Delete(long storeId, CancellationToken cancellationToken)
|
public async Task<ApiResponse<object>> Delete(long storeId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var success = await _mediator.Send(new DeleteStoreCommand { StoreId = storeId }, cancellationToken);
|
var success = await mediator.Send(new DeleteStoreCommand { StoreId = storeId }, cancellationToken);
|
||||||
return success
|
return success
|
||||||
? ApiResponse<object>.Ok(null)
|
? ApiResponse<object>.Ok(null)
|
||||||
: ApiResponse<object>.Error(ErrorCodes.NotFound, "门店不存在");
|
: ApiResponse<object>.Error(ErrorCodes.NotFound, "门店不存在");
|
||||||
|
|||||||
@@ -7,65 +7,65 @@ namespace TakeoutSaaS.Application.App.Deliveries.Commands;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新配送单命令。
|
/// 更新配送单命令。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class UpdateDeliveryOrderCommand : IRequest<DeliveryOrderDto?>
|
public sealed record UpdateDeliveryOrderCommand : IRequest<DeliveryOrderDto?>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 配送单 ID。
|
/// 配送单 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long DeliveryOrderId { get; set; }
|
public long DeliveryOrderId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 订单 ID。
|
/// 订单 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long OrderId { get; set; }
|
public long OrderId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 服务商。
|
/// 服务商。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DeliveryProvider Provider { get; set; } = DeliveryProvider.InHouse;
|
public DeliveryProvider Provider { get; init; } = DeliveryProvider.InHouse;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 第三方单号。
|
/// 第三方单号。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ProviderOrderId { get; set; }
|
public string? ProviderOrderId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 状态。
|
/// 状态。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DeliveryStatus Status { get; set; } = DeliveryStatus.Pending;
|
public DeliveryStatus Status { get; init; } = DeliveryStatus.Pending;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 配送费。
|
/// 配送费。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal? DeliveryFee { get; set; }
|
public decimal? DeliveryFee { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 骑手姓名。
|
/// 骑手姓名。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? CourierName { get; set; }
|
public string? CourierName { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 骑手电话。
|
/// 骑手电话。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? CourierPhone { get; set; }
|
public string? CourierPhone { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下发时间。
|
/// 下发时间。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? DispatchedAt { get; set; }
|
public DateTime? DispatchedAt { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 取餐时间。
|
/// 取餐时间。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? PickedUpAt { get; set; }
|
public DateTime? PickedUpAt { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 完成时间。
|
/// 完成时间。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? DeliveredAt { get; set; }
|
public DateTime? DeliveredAt { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异常原因。
|
/// 异常原因。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? FailureReason { get; set; }
|
public string? FailureReason { get; init; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,45 +7,45 @@ namespace TakeoutSaaS.Application.App.Merchants.Commands;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新商户命令。
|
/// 更新商户命令。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class UpdateMerchantCommand : IRequest<MerchantDto?>
|
public sealed record UpdateMerchantCommand : IRequest<MerchantDto?>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商户 ID。
|
/// 商户 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long MerchantId { get; set; }
|
public long MerchantId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 品牌名称。
|
/// 品牌名称。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string BrandName { get; set; } = string.Empty;
|
public string BrandName { get; init; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 品牌简称。
|
/// 品牌简称。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? BrandAlias { get; set; }
|
public string? BrandAlias { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Logo 地址。
|
/// Logo 地址。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? LogoUrl { get; set; }
|
public string? LogoUrl { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 品类。
|
/// 品类。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Category { get; set; }
|
public string? Category { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 联系电话。
|
/// 联系电话。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ContactPhone { get; set; } = string.Empty;
|
public string ContactPhone { get; init; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 联系邮箱。
|
/// 联系邮箱。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ContactEmail { get; set; }
|
public string? ContactEmail { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 入驻状态。
|
/// 入驻状态。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MerchantStatus Status { get; set; }
|
public MerchantStatus Status { get; init; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,110 +8,110 @@ namespace TakeoutSaaS.Application.App.Orders.Commands;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新订单命令。
|
/// 更新订单命令。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class UpdateOrderCommand : IRequest<OrderDto?>
|
public sealed record UpdateOrderCommand : IRequest<OrderDto?>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 订单 ID。
|
/// 订单 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long OrderId { get; set; }
|
public long OrderId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 订单号。
|
/// 订单号。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string OrderNo { get; set; } = string.Empty;
|
public string OrderNo { get; init; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 门店 ID。
|
/// 门店 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long StoreId { get; set; }
|
public long StoreId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 渠道。
|
/// 渠道。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public OrderChannel Channel { get; set; } = OrderChannel.MiniProgram;
|
public OrderChannel Channel { get; init; } = OrderChannel.MiniProgram;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 履约方式。
|
/// 履约方式。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DeliveryType DeliveryType { get; set; } = DeliveryType.DineIn;
|
public DeliveryType DeliveryType { get; init; } = DeliveryType.DineIn;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 状态。
|
/// 状态。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public OrderStatus Status { get; set; } = OrderStatus.PendingPayment;
|
public OrderStatus Status { get; init; } = OrderStatus.PendingPayment;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付状态。
|
/// 支付状态。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PaymentStatus PaymentStatus { get; set; } = PaymentStatus.Unpaid;
|
public PaymentStatus PaymentStatus { get; init; } = PaymentStatus.Unpaid;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 顾客姓名。
|
/// 顾客姓名。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? CustomerName { get; set; }
|
public string? CustomerName { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 顾客手机号。
|
/// 顾客手机号。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? CustomerPhone { get; set; }
|
public string? CustomerPhone { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 桌号。
|
/// 桌号。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? TableNo { get; set; }
|
public string? TableNo { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 排队号。
|
/// 排队号。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? QueueNumber { get; set; }
|
public string? QueueNumber { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 预约 ID。
|
/// 预约 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long? ReservationId { get; set; }
|
public long? ReservationId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商品金额。
|
/// 商品金额。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal ItemsAmount { get; set; }
|
public decimal ItemsAmount { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 优惠金额。
|
/// 优惠金额。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal DiscountAmount { get; set; }
|
public decimal DiscountAmount { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应付金额。
|
/// 应付金额。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal PayableAmount { get; set; }
|
public decimal PayableAmount { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 实付金额。
|
/// 实付金额。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal PaidAmount { get; set; }
|
public decimal PaidAmount { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付时间。
|
/// 支付时间。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? PaidAt { get; set; }
|
public DateTime? PaidAt { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 完成时间。
|
/// 完成时间。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? FinishedAt { get; set; }
|
public DateTime? FinishedAt { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 取消时间。
|
/// 取消时间。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? CancelledAt { get; set; }
|
public DateTime? CancelledAt { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 取消原因。
|
/// 取消原因。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? CancelReason { get; set; }
|
public string? CancelReason { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 备注。
|
/// 备注。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Remark { get; set; }
|
public string? Remark { get; init; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,55 +7,55 @@ namespace TakeoutSaaS.Application.App.Payments.Commands;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新支付记录命令。
|
/// 更新支付记录命令。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class UpdatePaymentCommand : IRequest<PaymentDto?>
|
public sealed record UpdatePaymentCommand : IRequest<PaymentDto?>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付记录 ID。
|
/// 支付记录 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long PaymentId { get; set; }
|
public long PaymentId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 订单 ID。
|
/// 订单 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long OrderId { get; set; }
|
public long OrderId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付方式。
|
/// 支付方式。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PaymentMethod Method { get; set; } = PaymentMethod.Unknown;
|
public PaymentMethod Method { get; init; } = PaymentMethod.Unknown;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付状态。
|
/// 支付状态。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PaymentStatus Status { get; set; } = PaymentStatus.Unpaid;
|
public PaymentStatus Status { get; init; } = PaymentStatus.Unpaid;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 金额。
|
/// 金额。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal Amount { get; set; }
|
public decimal Amount { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 平台交易号。
|
/// 平台交易号。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? TradeNo { get; set; }
|
public string? TradeNo { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 渠道单号。
|
/// 渠道单号。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ChannelTransactionId { get; set; }
|
public string? ChannelTransactionId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付时间。
|
/// 支付时间。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? PaidAt { get; set; }
|
public DateTime? PaidAt { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 备注。
|
/// 备注。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Remark { get; set; }
|
public string? Remark { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 原始回调。
|
/// 原始回调。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Payload { get; set; }
|
public string? Payload { get; init; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,100 +7,100 @@ namespace TakeoutSaaS.Application.App.Products.Commands;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新商品命令。
|
/// 更新商品命令。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class UpdateProductCommand : IRequest<ProductDto?>
|
public sealed record UpdateProductCommand : IRequest<ProductDto?>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商品 ID。
|
/// 商品 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long ProductId { get; set; }
|
public long ProductId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 门店 ID。
|
/// 门店 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long StoreId { get; set; }
|
public long StoreId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 分类 ID。
|
/// 分类 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long CategoryId { get; set; }
|
public long CategoryId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商品编码。
|
/// 商品编码。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SpuCode { get; set; } = string.Empty;
|
public string SpuCode { get; init; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 名称。
|
/// 名称。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; init; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 副标题。
|
/// 副标题。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Subtitle { get; set; }
|
public string? Subtitle { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 单位。
|
/// 单位。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Unit { get; set; }
|
public string? Unit { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 现价。
|
/// 现价。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal Price { get; set; }
|
public decimal Price { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 原价。
|
/// 原价。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal? OriginalPrice { get; set; }
|
public decimal? OriginalPrice { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 库存数量。
|
/// 库存数量。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? StockQuantity { get; set; }
|
public int? StockQuantity { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 每单限购。
|
/// 每单限购。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? MaxQuantityPerOrder { get; set; }
|
public int? MaxQuantityPerOrder { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 状态。
|
/// 状态。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ProductStatus Status { get; set; } = ProductStatus.Draft;
|
public ProductStatus Status { get; init; } = ProductStatus.Draft;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 主图。
|
/// 主图。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? CoverImage { get; set; }
|
public string? CoverImage { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 图集。
|
/// 图集。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? GalleryImages { get; set; }
|
public string? GalleryImages { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 描述。
|
/// 描述。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Description { get; set; }
|
public string? Description { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支持堂食。
|
/// 支持堂食。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool EnableDineIn { get; set; } = true;
|
public bool EnableDineIn { get; init; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支持自提。
|
/// 支持自提。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool EnablePickup { get; set; } = true;
|
public bool EnablePickup { get; init; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支持配送。
|
/// 支持配送。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool EnableDelivery { get; set; } = true;
|
public bool EnableDelivery { get; init; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否推荐。
|
/// 是否推荐。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsFeatured { get; set; }
|
public bool IsFeatured { get; init; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,100 +7,100 @@ namespace TakeoutSaaS.Application.App.Stores.Commands;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新门店命令。
|
/// 更新门店命令。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class UpdateStoreCommand : IRequest<StoreDto?>
|
public sealed record UpdateStoreCommand : IRequest<StoreDto?>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 门店 ID。
|
/// 门店 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long StoreId { get; set; }
|
public long StoreId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商户 ID。
|
/// 商户 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long MerchantId { get; set; }
|
public long MerchantId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 门店编码。
|
/// 门店编码。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Code { get; set; } = string.Empty;
|
public string Code { get; init; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 门店名称。
|
/// 门店名称。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; init; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 电话。
|
/// 电话。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Phone { get; set; }
|
public string? Phone { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 负责人。
|
/// 负责人。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ManagerName { get; set; }
|
public string? ManagerName { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 状态。
|
/// 状态。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StoreStatus Status { get; set; } = StoreStatus.Closed;
|
public StoreStatus Status { get; init; } = StoreStatus.Closed;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 省份。
|
/// 省份。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Province { get; set; }
|
public string? Province { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 城市。
|
/// 城市。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? City { get; set; }
|
public string? City { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 区县。
|
/// 区县。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? District { get; set; }
|
public string? District { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 详细地址。
|
/// 详细地址。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Address { get; set; }
|
public string? Address { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 经度。
|
/// 经度。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double? Longitude { get; set; }
|
public double? Longitude { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 纬度。
|
/// 纬度。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double? Latitude { get; set; }
|
public double? Latitude { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 公告。
|
/// 公告。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Announcement { get; set; }
|
public string? Announcement { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 标签。
|
/// 标签。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Tags { get; set; }
|
public string? Tags { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 配送半径。
|
/// 配送半径。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal DeliveryRadiusKm { get; set; }
|
public decimal DeliveryRadiusKm { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支持堂食。
|
/// 支持堂食。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool SupportsDineIn { get; set; } = true;
|
public bool SupportsDineIn { get; init; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支持自提。
|
/// 支持自提。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool SupportsPickup { get; set; } = true;
|
public bool SupportsPickup { get; init; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支持配送。
|
/// 支持配送。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool SupportsDelivery { get; set; } = true;
|
public bool SupportsDelivery { get; init; } = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user