390 lines
14 KiB
C#
390 lines
14 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Tiku.Api.Contracts;
|
|
using Tiku.Application.Commerce;
|
|
using Tiku.Application.Security;
|
|
using Tiku.Domain.Commerce;
|
|
|
|
namespace Tiku.Api.Controllers;
|
|
|
|
[ApiController]
|
|
[Authorize(Policy = TikuPolicies.TenantAdmin)]
|
|
[Produces("application/json")]
|
|
[Route("api/tenant-commerce")]
|
|
public sealed class TenantCommerceController(
|
|
ICommerceAdminService commerceAdminService,
|
|
ICurrentUser currentUser,
|
|
ITenantContext currentTenant) : ControllerBase
|
|
{
|
|
[HttpGet("payment-accounts")]
|
|
[EndpointSummary("查询租户支付账号")]
|
|
[ProducesResponseType<IReadOnlyCollection<TenantPaymentProviderItem>>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<IReadOnlyCollection<TenantPaymentProviderItem>>> PaymentAccounts(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetPaymentAccountsAsync(
|
|
ResolveActor(),
|
|
ToQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPut("payment-accounts")]
|
|
[EndpointSummary("新增或更新租户支付账号")]
|
|
[ProducesResponseType<TenantPaymentProviderItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantPaymentProviderItem>> UpsertPaymentAccount(
|
|
UpsertPaymentAccountDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.UpsertPaymentAccountAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPut("secrets")]
|
|
[EndpointSummary("写入或轮换租户密钥")]
|
|
[ProducesResponseType<TenantSecretItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantSecretItem>> UpsertSecret(
|
|
UpsertTenantSecretDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.UpsertTenantSecretAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("orders")]
|
|
[EndpointSummary("查询租户订单")]
|
|
[ProducesResponseType<AdminOrderList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<AdminOrderList>> Orders(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetOrdersAsync(
|
|
ResolveActor(),
|
|
ToQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("payments")]
|
|
[EndpointSummary("查询租户支付记录")]
|
|
[ProducesResponseType<AdminPaymentList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<AdminPaymentList>> Payments(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetPaymentsAsync(
|
|
ResolveActor(),
|
|
ToQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPost("code-batches")]
|
|
[EndpointSummary("创建兑换码批次")]
|
|
[ProducesResponseType<CodeBatchItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<CodeBatchItem>> CreateCodeBatch(
|
|
CreateCodeBatchDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.CreateCodeBatchAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("activation-codes")]
|
|
[EndpointSummary("查询兑换码")]
|
|
[ProducesResponseType<ActivationCodeList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<ActivationCodeList>> ActivationCodes(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetActivationCodesAsync(
|
|
ResolveActor(),
|
|
ToQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPost("activation-codes/redeem")]
|
|
[EndpointSummary("后台核销兑换码")]
|
|
[ProducesResponseType<ActivationCodeItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<ActivationCodeItem>> RedeemActivationCode(
|
|
RedeemActivationCodeDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.RedeemActivationCodeAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("point-activity-tasks")]
|
|
[EndpointSummary("查询积分活动任务")]
|
|
[ProducesResponseType<TenantPointTaskList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantPointTaskList>> PointTasks(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetPointTasksAsync(
|
|
ResolveActor(),
|
|
ToPointQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPut("point-activity-tasks")]
|
|
[EndpointSummary("新增或更新积分活动任务")]
|
|
[ProducesResponseType<object>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<object>> UpsertPointTask(
|
|
UpsertPointTaskDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.UpsertPointTaskAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("point-activity-claims")]
|
|
[EndpointSummary("查询积分任务领取记录")]
|
|
[ProducesResponseType<TenantPointClaimList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantPointClaimList>> PointClaims(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetPointClaimsAsync(
|
|
ResolveActor(),
|
|
ToPointQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("point-exchange-items")]
|
|
[EndpointSummary("查询积分兑换项")]
|
|
[ProducesResponseType<TenantPointExchangeItemList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantPointExchangeItemList>> PointExchangeItems(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetPointExchangeItemsAsync(
|
|
ResolveActor(),
|
|
ToPointQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPut("point-exchange-items")]
|
|
[EndpointSummary("新增或更新积分兑换项")]
|
|
[ProducesResponseType<object>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<object>> UpsertPointExchangeItem(
|
|
UpsertPointExchangeItemDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.UpsertPointExchangeItemAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("point-exchange-orders")]
|
|
[EndpointSummary("查询积分兑换订单")]
|
|
[ProducesResponseType<TenantPointExchangeOrderList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantPointExchangeOrderList>> PointExchangeOrders(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetPointExchangeOrdersAsync(
|
|
ResolveActor(),
|
|
ToPointQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPost("point-exchange-orders/status")]
|
|
[EndpointSummary("更新积分兑换订单状态")]
|
|
[ProducesResponseType<object>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<object>> UpdatePointExchangeOrderStatus(
|
|
UpdatePointExchangeOrderStatusDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.UpdatePointExchangeOrderStatusAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("coupons")]
|
|
[EndpointSummary("查询租户优惠券")]
|
|
[ProducesResponseType<TenantCouponList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantCouponList>> Coupons(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetCouponsAsync(
|
|
ResolveActor(),
|
|
ToQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPut("coupons")]
|
|
[EndpointSummary("新增或更新租户优惠券")]
|
|
[ProducesResponseType<object>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<object>> UpsertCoupon(
|
|
UpsertTenantCouponDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.UpsertCouponAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("coupons/redemptions")]
|
|
[EndpointSummary("查询优惠券领取和核销记录")]
|
|
[ProducesResponseType<TenantCouponRedemptionList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantCouponRedemptionList>> CouponRedemptions(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetCouponRedemptionsAsync(
|
|
ResolveActor(),
|
|
ToQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("coupons/report")]
|
|
[EndpointSummary("查询优惠券基础报表")]
|
|
[ProducesResponseType<TenantCouponReport>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantCouponReport>> CouponReport(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetCouponReportAsync(
|
|
ResolveActor(),
|
|
ToQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("refunds")]
|
|
[EndpointSummary("查询退款申请")]
|
|
[ProducesResponseType<TenantRefundList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantRefundList>> Refunds(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetRefundsAsync(
|
|
ResolveActor(),
|
|
ToQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPost("refunds")]
|
|
[EndpointSummary("创建退款申请")]
|
|
[ProducesResponseType<CommerceRefundRequest>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<CommerceRefundRequest>> CreateRefund(
|
|
CreateRefundRequestDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.CreateRefundRequestAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPost("refunds/status")]
|
|
[EndpointSummary("更新退款状态")]
|
|
[ProducesResponseType<CommerceRefundRequest>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<CommerceRefundRequest>> UpdateRefundStatus(
|
|
UpdateRefundStatusDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.UpdateRefundStatusAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("refunds/{refundRequestId:guid}/events")]
|
|
[EndpointSummary("查询退款事件")]
|
|
[ProducesResponseType<TenantRefundEventList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantRefundEventList>> RefundEvents(
|
|
Guid refundRequestId,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetRefundEventsAsync(
|
|
ResolveActor(),
|
|
refundRequestId,
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("reconciliation/batches")]
|
|
[EndpointSummary("查询对账批次")]
|
|
[ProducesResponseType<TenantReconciliationBatchList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantReconciliationBatchList>> ReconciliationBatches(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetReconciliationBatchesAsync(
|
|
ResolveActor(),
|
|
ToQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPost("reconciliation/batches")]
|
|
[EndpointSummary("创建对账批次")]
|
|
[ProducesResponseType<CommerceReconciliationBatch>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<CommerceReconciliationBatch>> CreateReconciliationBatch(
|
|
CreateReconciliationBatchDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.CreateReconciliationBatchAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpGet("reconciliation/issues")]
|
|
[EndpointSummary("查询对账异常")]
|
|
[ProducesResponseType<TenantReconciliationIssueList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantReconciliationIssueList>> ReconciliationIssues(
|
|
[FromQuery] TenantCommerceQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.GetReconciliationIssuesAsync(
|
|
ResolveActor(),
|
|
ToQuery(query),
|
|
cancellationToken));
|
|
}
|
|
|
|
[HttpPost("reconciliation/issues/status")]
|
|
[EndpointSummary("更新对账异常状态")]
|
|
[ProducesResponseType<CommerceReconciliationIssue>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<CommerceReconciliationIssue>> UpdateReconciliationIssue(
|
|
UpdateReconciliationIssueDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await commerceAdminService.UpdateReconciliationIssueAsync(
|
|
ResolveActor(),
|
|
request.ToCommand(),
|
|
cancellationToken));
|
|
}
|
|
|
|
private CommerceAdminActor ResolveActor()
|
|
{
|
|
if (currentTenant.TenantId is null || currentUser.UserId is null)
|
|
{
|
|
throw new CommerceException("Tenant commerce actor was not resolved.", "tenant_admin_access_denied");
|
|
}
|
|
|
|
return new CommerceAdminActor(currentTenant.TenantId.Value, currentUser.UserId.Value);
|
|
}
|
|
|
|
private static CommerceAdminQuery ToQuery(TenantCommerceQueryDto query)
|
|
{
|
|
return new CommerceAdminQuery(query.Provider, query.Status, query.Limit);
|
|
}
|
|
|
|
private static TenantPointQuery ToPointQuery(TenantCommerceQueryDto query)
|
|
{
|
|
return new TenantPointQuery(query.Status, query.Limit, query.UserId, query.RegionId);
|
|
}
|
|
}
|