完成门店管理后端接口与任务
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using TakeoutSaaS.Application.App.StoreAudits.Commands;
|
||||
using TakeoutSaaS.Application.App.StoreAudits.Dto;
|
||||
using TakeoutSaaS.Application.App.StoreAudits.Queries;
|
||||
using TakeoutSaaS.Module.Authorization.Attributes;
|
||||
using TakeoutSaaS.Shared.Abstractions.Constants;
|
||||
using TakeoutSaaS.Shared.Abstractions.Results;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
using TakeoutSaaS.Shared.Web.Api;
|
||||
|
||||
namespace TakeoutSaaS.AdminApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 门店审核与风控管理(平台)。
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize]
|
||||
[Route("api/platform/store-audits")]
|
||||
[Route("api/admin/v{version:apiVersion}/platform/store-audits")]
|
||||
public sealed class StoreAuditsController(IMediator mediator, ITenantContextAccessor tenantContextAccessor) : BaseApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询待审核门店列表。
|
||||
/// </summary>
|
||||
/// <returns>待审核门店分页列表。</returns>
|
||||
[HttpGet("pending")]
|
||||
[PermissionAuthorize("store-audit:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<PagedResult<PendingStoreAuditDto>>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<PagedResult<PendingStoreAuditDto>>> ListPending(
|
||||
[FromQuery] ListPendingStoreAuditsQuery query,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 查询待审核门店列表
|
||||
var result = await ExecuteAsPlatformAsync(() => mediator.Send(query, cancellationToken));
|
||||
|
||||
// 2. 返回分页结果
|
||||
return ApiResponse<PagedResult<PendingStoreAuditDto>>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取门店审核详情。
|
||||
/// </summary>
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>审核详情。</returns>
|
||||
[HttpGet("{storeId:long}")]
|
||||
[PermissionAuthorize("store-audit:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreAuditDetailDto>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||
public async Task<ApiResponse<StoreAuditDetailDto>> GetDetail(long storeId, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 获取审核详情
|
||||
var result = await ExecuteAsPlatformAsync(() =>
|
||||
mediator.Send(new GetStoreAuditDetailQuery { StoreId = storeId }, cancellationToken));
|
||||
|
||||
// 2. 返回详情或未找到
|
||||
return result is null
|
||||
? ApiResponse<StoreAuditDetailDto>.Error(ErrorCodes.NotFound, "门店不存在")
|
||||
: ApiResponse<StoreAuditDetailDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 审核通过。
|
||||
/// </summary>
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="command">审核命令。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>操作结果。</returns>
|
||||
[HttpPost("{storeId:long}/approve")]
|
||||
[PermissionAuthorize("store-audit:approve")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreAuditActionResultDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreAuditActionResultDto>> Approve(
|
||||
long storeId,
|
||||
[FromBody, Required] ApproveStoreCommand command,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 执行审核通过
|
||||
var request = command with { StoreId = storeId };
|
||||
var result = await ExecuteAsPlatformAsync(() => mediator.Send(request, cancellationToken));
|
||||
|
||||
// 2. 返回结果
|
||||
return ApiResponse<StoreAuditActionResultDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 审核驳回。
|
||||
/// </summary>
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="command">驳回命令。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>操作结果。</returns>
|
||||
[HttpPost("{storeId:long}/reject")]
|
||||
[PermissionAuthorize("store-audit:reject")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreAuditActionResultDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreAuditActionResultDto>> Reject(
|
||||
long storeId,
|
||||
[FromBody, Required] RejectStoreCommand command,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 执行审核驳回
|
||||
var request = command with { StoreId = storeId };
|
||||
var result = await ExecuteAsPlatformAsync(() => mediator.Send(request, cancellationToken));
|
||||
|
||||
// 2. 返回结果
|
||||
return ApiResponse<StoreAuditActionResultDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询审核记录。
|
||||
/// </summary>
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="page">页码。</param>
|
||||
/// <param name="pageSize">每页数量。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>审核记录分页列表。</returns>
|
||||
[HttpGet("{storeId:long}/records")]
|
||||
[PermissionAuthorize("store-audit:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<PagedResult<StoreAuditRecordDto>>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<PagedResult<StoreAuditRecordDto>>> ListRecords(
|
||||
long storeId,
|
||||
[FromQuery] int page = 1,
|
||||
[FromQuery] int pageSize = 20,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
// 1. 执行记录查询
|
||||
var query = new ListStoreAuditRecordsQuery
|
||||
{
|
||||
StoreId = storeId,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
var result = await ExecuteAsPlatformAsync(() => mediator.Send(query, cancellationToken));
|
||||
|
||||
// 2. 返回分页结果
|
||||
return ApiResponse<PagedResult<StoreAuditRecordDto>>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取审核统计数据。
|
||||
/// </summary>
|
||||
/// <param name="query">查询参数。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>统计数据。</returns>
|
||||
[HttpGet("statistics")]
|
||||
[PermissionAuthorize("store-audit:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreAuditStatisticsDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreAuditStatisticsDto>> GetStatistics(
|
||||
[FromQuery] GetStoreAuditStatisticsQuery query,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 执行统计查询
|
||||
var result = await ExecuteAsPlatformAsync(() => mediator.Send(query, cancellationToken));
|
||||
|
||||
// 2. 返回统计结果
|
||||
return ApiResponse<StoreAuditStatisticsDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 强制关闭门店。
|
||||
/// </summary>
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="command">关闭命令。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>操作结果。</returns>
|
||||
[HttpPost("{storeId:long}/force-close")]
|
||||
[PermissionAuthorize("store-audit:force-close")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreAuditActionResultDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreAuditActionResultDto>> ForceClose(
|
||||
long storeId,
|
||||
[FromBody, Required] ForceCloseStoreCommand command,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 执行强制关闭
|
||||
var request = command with { StoreId = storeId };
|
||||
var result = await ExecuteAsPlatformAsync(() => mediator.Send(request, cancellationToken));
|
||||
|
||||
// 2. 返回结果
|
||||
return ApiResponse<StoreAuditActionResultDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解除强制关闭。
|
||||
/// </summary>
|
||||
/// <param name="storeId">门店 ID。</param>
|
||||
/// <param name="command">解除命令。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>操作结果。</returns>
|
||||
[HttpPost("{storeId:long}/reopen")]
|
||||
[PermissionAuthorize("store-audit:force-close")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreAuditActionResultDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreAuditActionResultDto>> Reopen(
|
||||
long storeId,
|
||||
[FromBody, Required] ReopenStoreCommand command,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 执行解除强制关闭
|
||||
var request = command with { StoreId = storeId };
|
||||
var result = await ExecuteAsPlatformAsync(() => mediator.Send(request, cancellationToken));
|
||||
|
||||
// 2. 返回结果
|
||||
return ApiResponse<StoreAuditActionResultDto>.Ok(result);
|
||||
}
|
||||
|
||||
private async Task<T> ExecuteAsPlatformAsync<T>(Func<Task<T>> action)
|
||||
{
|
||||
var original = tenantContextAccessor.Current;
|
||||
tenantContextAccessor.Current = new TenantContext(0, null, "platform");
|
||||
|
||||
// 1. (空行后) 切换到平台上下文执行
|
||||
try
|
||||
{
|
||||
return await action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
tenantContextAccessor.Current = original;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using TakeoutSaaS.Application.App.Stores.Dto;
|
||||
using TakeoutSaaS.Application.App.Stores.Queries;
|
||||
using TakeoutSaaS.Module.Authorization.Attributes;
|
||||
using TakeoutSaaS.Shared.Abstractions.Results;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
using TakeoutSaaS.Shared.Web.Api;
|
||||
|
||||
namespace TakeoutSaaS.AdminApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 门店资质预警(平台)。
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize]
|
||||
[Route("api/platform/store-qualifications")]
|
||||
[Route("api/admin/v{version:apiVersion}/platform/store-qualifications")]
|
||||
public sealed class StoreQualificationsController(
|
||||
IMediator mediator,
|
||||
ITenantContextAccessor tenantContextAccessor)
|
||||
: BaseApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询资质即将过期/已过期列表。
|
||||
/// </summary>
|
||||
/// <param name="query">查询参数。</param>
|
||||
/// <param name="cancellationToken">取消标记。</param>
|
||||
/// <returns>资质预警分页结果。</returns>
|
||||
[HttpGet("expiring")]
|
||||
[PermissionAuthorize("store-qualification:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreQualificationAlertResultDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreQualificationAlertResultDto>> ListExpiring(
|
||||
[FromQuery] ListExpiringStoreQualificationsQuery query,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 查询资质预警
|
||||
var result = await ExecuteAsPlatformAsync(() => mediator.Send(query, cancellationToken));
|
||||
|
||||
// 2. (空行后) 返回结果
|
||||
return ApiResponse<StoreQualificationAlertResultDto>.Ok(result);
|
||||
}
|
||||
|
||||
private async Task<T> ExecuteAsPlatformAsync<T>(Func<Task<T>> action)
|
||||
{
|
||||
var original = tenantContextAccessor.Current;
|
||||
tenantContextAccessor.Current = new TenantContext(0, null, "platform");
|
||||
|
||||
// 1. (空行后) 切换到平台上下文执行
|
||||
try
|
||||
{
|
||||
return await action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
tenantContextAccessor.Current = original;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,10 @@ public sealed class StoresController(IMediator mediator) : BaseApiController
|
||||
public async Task<ApiResponse<PagedResult<StoreDto>>> List(
|
||||
[FromQuery] long? merchantId,
|
||||
[FromQuery] StoreStatus? status,
|
||||
[FromQuery] StoreAuditStatus? auditStatus,
|
||||
[FromQuery] StoreBusinessStatus? businessStatus,
|
||||
[FromQuery] StoreOwnershipType? ownershipType,
|
||||
[FromQuery] string? keyword,
|
||||
[FromQuery] int page = 1,
|
||||
[FromQuery] int pageSize = 20,
|
||||
[FromQuery] string? sortBy = null,
|
||||
@@ -58,6 +62,10 @@ public sealed class StoresController(IMediator mediator) : BaseApiController
|
||||
{
|
||||
MerchantId = merchantId,
|
||||
Status = status,
|
||||
AuditStatus = auditStatus,
|
||||
BusinessStatus = businessStatus,
|
||||
OwnershipType = ownershipType,
|
||||
Keyword = keyword,
|
||||
Page = page,
|
||||
PageSize = pageSize,
|
||||
SortBy = sortBy,
|
||||
@@ -131,6 +139,170 @@ public sealed class StoresController(IMediator mediator) : BaseApiController
|
||||
: ApiResponse<object>.Error(ErrorCodes.NotFound, "门店不存在");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交门店审核。
|
||||
/// </summary>
|
||||
[HttpPost("{storeId:long}/submit")]
|
||||
[PermissionAuthorize("store:update")]
|
||||
[ProducesResponseType(typeof(ApiResponse<bool>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<bool>> SubmitAudit(long storeId, [FromBody] SubmitStoreAuditCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 绑定门店 ID
|
||||
if (command.StoreId == 0)
|
||||
{
|
||||
command = command with { StoreId = storeId };
|
||||
}
|
||||
|
||||
// 2. (空行后) 执行提交
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
|
||||
// 3. (空行后) 返回结果
|
||||
return ApiResponse<bool>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换门店经营状态。
|
||||
/// </summary>
|
||||
[HttpPost("{storeId:long}/business-status")]
|
||||
[PermissionAuthorize("store:update")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreDto>> ToggleBusinessStatus(long storeId, [FromBody] ToggleBusinessStatusCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 绑定门店 ID
|
||||
if (command.StoreId == 0)
|
||||
{
|
||||
command = command with { StoreId = storeId };
|
||||
}
|
||||
|
||||
// 2. (空行后) 执行切换
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
|
||||
// 3. (空行后) 返回结果
|
||||
return ApiResponse<StoreDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询门店资质列表。
|
||||
/// </summary>
|
||||
[HttpGet("{storeId:long}/qualifications")]
|
||||
[PermissionAuthorize("store:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<IReadOnlyList<StoreQualificationDto>>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<IReadOnlyList<StoreQualificationDto>>> ListQualifications(long storeId, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 查询资质列表
|
||||
var result = await mediator.Send(new ListStoreQualificationsQuery { StoreId = storeId }, cancellationToken);
|
||||
|
||||
// 2. 返回结果
|
||||
return ApiResponse<IReadOnlyList<StoreQualificationDto>>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查门店资质完整性。
|
||||
/// </summary>
|
||||
[HttpGet("{storeId:long}/qualifications/check")]
|
||||
[PermissionAuthorize("store:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreQualificationCheckResultDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreQualificationCheckResultDto>> CheckQualifications(long storeId, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 执行检查
|
||||
var result = await mediator.Send(new CheckStoreQualificationsQuery { StoreId = storeId }, cancellationToken);
|
||||
|
||||
// 2. 返回检查结果
|
||||
return ApiResponse<StoreQualificationCheckResultDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增门店资质。
|
||||
/// </summary>
|
||||
[HttpPost("{storeId:long}/qualifications")]
|
||||
[PermissionAuthorize("store:update")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreQualificationDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreQualificationDto>> CreateQualification(long storeId, [FromBody] CreateStoreQualificationCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 绑定门店 ID
|
||||
if (command.StoreId == 0)
|
||||
{
|
||||
command = command with { StoreId = storeId };
|
||||
}
|
||||
|
||||
// 2. (空行后) 执行创建
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
|
||||
// 3. (空行后) 返回结果
|
||||
return ApiResponse<StoreQualificationDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新门店资质。
|
||||
/// </summary>
|
||||
[HttpPut("{storeId:long}/qualifications/{qualificationId:long}")]
|
||||
[PermissionAuthorize("store:update")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreQualificationDto>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
|
||||
public async Task<ApiResponse<StoreQualificationDto>> UpdateQualification(
|
||||
long storeId,
|
||||
long qualificationId,
|
||||
[FromBody] UpdateStoreQualificationCommand command,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 绑定资质 ID
|
||||
if (command.StoreId == 0 || command.QualificationId == 0)
|
||||
{
|
||||
command = command with { StoreId = storeId, QualificationId = qualificationId };
|
||||
}
|
||||
|
||||
// 2. (空行后) 执行更新
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
|
||||
// 3. (空行后) 返回结果或 404
|
||||
return result is null
|
||||
? ApiResponse<StoreQualificationDto>.Error(ErrorCodes.NotFound, "资质不存在")
|
||||
: ApiResponse<StoreQualificationDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除门店资质。
|
||||
/// </summary>
|
||||
[HttpDelete("{storeId:long}/qualifications/{qualificationId:long}")]
|
||||
[PermissionAuthorize("store:update")]
|
||||
[ProducesResponseType(typeof(ApiResponse<bool>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<bool>> DeleteQualification(long storeId, long qualificationId, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 执行删除
|
||||
var result = await mediator.Send(new DeleteStoreQualificationCommand
|
||||
{
|
||||
StoreId = storeId,
|
||||
QualificationId = qualificationId
|
||||
}, cancellationToken);
|
||||
|
||||
// 2. 返回结果
|
||||
return ApiResponse<bool>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量更新营业时段。
|
||||
/// </summary>
|
||||
[HttpPut("{storeId:long}/business-hours/batch")]
|
||||
[PermissionAuthorize("store:update")]
|
||||
[ProducesResponseType(typeof(ApiResponse<IReadOnlyList<StoreBusinessHourDto>>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<IReadOnlyList<StoreBusinessHourDto>>> BatchUpdateBusinessHours(
|
||||
long storeId,
|
||||
[FromBody] BatchUpdateBusinessHoursCommand command,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 绑定门店 ID
|
||||
if (command.StoreId == 0)
|
||||
{
|
||||
command = command with { StoreId = storeId };
|
||||
}
|
||||
|
||||
// 2. (空行后) 执行批量更新
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
|
||||
// 3. (空行后) 返回结果
|
||||
return ApiResponse<IReadOnlyList<StoreBusinessHourDto>>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询门店营业时段。
|
||||
/// </summary>
|
||||
@@ -259,6 +431,90 @@ public sealed class StoresController(IMediator mediator) : BaseApiController
|
||||
: ApiResponse<object>.Error(ErrorCodes.NotFound, "配送区域不存在");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配送范围检测。
|
||||
/// </summary>
|
||||
[HttpPost("{storeId:long}/delivery-check")]
|
||||
[PermissionAuthorize("store:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreDeliveryCheckResultDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreDeliveryCheckResultDto>> CheckDeliveryZone(
|
||||
long storeId,
|
||||
[FromBody] CheckStoreDeliveryZoneQuery query,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 绑定门店 ID
|
||||
if (query.StoreId == 0)
|
||||
{
|
||||
query = query with { StoreId = storeId };
|
||||
}
|
||||
|
||||
// 2. (空行后) 执行检测
|
||||
var result = await mediator.Send(query, cancellationToken);
|
||||
|
||||
// 3. (空行后) 返回结果
|
||||
return ApiResponse<StoreDeliveryCheckResultDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取门店费用配置。
|
||||
/// </summary>
|
||||
[HttpGet("{storeId:long}/fee")]
|
||||
[PermissionAuthorize("store:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreFeeDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreFeeDto>> GetFee(long storeId, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 查询费用配置
|
||||
var result = await mediator.Send(new GetStoreFeeQuery { StoreId = storeId }, cancellationToken);
|
||||
|
||||
// 2. 返回结果
|
||||
return ApiResponse<StoreFeeDto>.Ok(result ?? new StoreFeeDto());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新门店费用配置。
|
||||
/// </summary>
|
||||
[HttpPut("{storeId:long}/fee")]
|
||||
[PermissionAuthorize("store:update")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreFeeDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreFeeDto>> UpdateFee(long storeId, [FromBody] UpdateStoreFeeCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 绑定门店 ID
|
||||
if (command.StoreId == 0)
|
||||
{
|
||||
command = command with { StoreId = storeId };
|
||||
}
|
||||
|
||||
// 2. (空行后) 执行更新
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
|
||||
// 3. (空行后) 返回结果
|
||||
return ApiResponse<StoreFeeDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 门店费用预览。
|
||||
/// </summary>
|
||||
[HttpPost("{storeId:long}/fee/calculate")]
|
||||
[PermissionAuthorize("store:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<StoreFeeCalculationResultDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<StoreFeeCalculationResultDto>> CalculateFee(
|
||||
long storeId,
|
||||
[FromBody] CalculateStoreFeeQuery query,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 绑定门店 ID
|
||||
if (query.StoreId == 0)
|
||||
{
|
||||
query = query with { StoreId = storeId };
|
||||
}
|
||||
|
||||
// 2. (空行后) 执行计算
|
||||
var result = await mediator.Send(query, cancellationToken);
|
||||
|
||||
// 3. (空行后) 返回结果
|
||||
return ApiResponse<StoreFeeCalculationResultDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询门店节假日。
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user