using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Tiku.Api.Contracts; using Tiku.Application.Points; using Tiku.Application.Security; namespace Tiku.Api.Controllers; [ApiController] [Authorize(Policy = TikuPolicies.CurrentTenantMember)] [Produces("application/json")] [Route("api/points")] public sealed class PointsController( IPointService pointService, ICurrentUser currentUser, ITenantContext currentTenant) : ControllerBase { [HttpGet("summary")] [EndpointSummary("查询当前用户积分摘要")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> Summary(CancellationToken cancellationToken) { return Ok(await pointService.GetSummaryAsync(ResolveActor(), cancellationToken)); } [HttpGet("tasks")] [EndpointSummary("查询当前可领取积分任务")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> Tasks( [FromQuery] PointQueryDto query, CancellationToken cancellationToken) { return Ok(await pointService.GetTasksAsync( ResolveActor(), query.ToQuery(), cancellationToken)); } [HttpPost("tasks/claim")] [EndpointSummary("领取积分任务奖励")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> ClaimTask( ClaimPointTaskDto request, CancellationToken cancellationToken) { return Ok(await pointService.ClaimTaskAsync( ResolveActor(), request.ToCommand(), cancellationToken)); } [HttpGet("exchange-items")] [EndpointSummary("查询积分兑换项")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> ExchangeItems( [FromQuery] PointQueryDto query, CancellationToken cancellationToken) { return Ok(await pointService.GetExchangeItemsAsync( ResolveActor(), query.ToQuery(), cancellationToken)); } [HttpPost("exchange-orders")] [EndpointSummary("创建积分兑换订单")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> CreateExchangeOrder( CreatePointExchangeOrderDto request, CancellationToken cancellationToken) { return Ok(await pointService.CreateExchangeOrderAsync( ResolveActor(), request.ToCommand(), cancellationToken)); } [HttpGet("exchange-orders")] [EndpointSummary("查询当前用户积分兑换订单")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> ExchangeOrders( [FromQuery] PointQueryDto query, CancellationToken cancellationToken) { return Ok(await pointService.GetExchangeOrdersAsync( ResolveActor(), query.ToQuery(), cancellationToken)); } private PointActor ResolveActor() { if (currentTenant.TenantId is null || currentUser.UserId is null) { throw new PointException("Current point actor was not resolved.", "point_access_denied"); } return new PointActor(currentTenant.TenantId.Value, currentUser.UserId.Value); } }