HaniBlindBox/server/C#/HoneyBox/src/HoneyBox.Api/Controllers/WarehouseController.cs
2026-01-03 22:23:21 +08:00

502 lines
16 KiB
C#

using System.Security.Claims;
using HoneyBox.Core.Interfaces;
using HoneyBox.Model.Base;
using HoneyBox.Model.Models;
using HoneyBox.Model.Models.Order;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace HoneyBox.Api.Controllers;
/// <summary>
/// 仓库控制器 - 处理用户仓库和发货功能
/// </summary>
/// <remarks>
/// 提供仓库查询、奖品回收、发货申请、物流查询等功能
/// </remarks>
[ApiController]
[Route("api")]
public class WarehouseController : ControllerBase
{
private readonly IWarehouseService _warehouseService;
private readonly ILogger<WarehouseController> _logger;
public WarehouseController(
IWarehouseService warehouseService,
ILogger<WarehouseController> logger)
{
_warehouseService = warehouseService;
_logger = logger;
}
#region
/// <summary>
/// 仓库首页查询
/// </summary>
/// <remarks>
/// GET /api/warehouse_index
///
/// 获取用户仓库中的奖品列表
/// Requirements: 10.1-10.3
/// </remarks>
/// <param name="page">页码</param>
/// <param name="type">类型: 1赏品 2预售 3卡册 4保险柜 5无限赏</param>
/// <param name="keyword">搜索关键词</param>
/// <returns>仓库奖品列表</returns>
[HttpGet("warehouse_index")]
[Authorize]
[ProducesResponseType(typeof(ApiResponse<WarehouseIndexResponseDto>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ApiResponse<WarehouseIndexResponseDto>), StatusCodes.Status401Unauthorized)]
public async Task<ApiResponse<WarehouseIndexResponseDto>> GetWarehouseIndex(
[FromQuery] int page = 1,
[FromQuery] int type = 1,
[FromQuery] string? keyword = null)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return ApiResponse<WarehouseIndexResponseDto>.Unauthorized();
}
try
{
var request = new WarehouseIndexRequest
{
Page = page < 1 ? 1 : page,
Type = type,
Keyword = keyword,
PageSize = 10
};
var result = await _warehouseService.GetWarehouseIndexAsync(userId.Value, request);
return ApiResponse<WarehouseIndexResponseDto>.Success(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get warehouse index: UserId={UserId}", userId);
return ApiResponse<WarehouseIndexResponseDto>.Fail("获取仓库列表失败");
}
}
#endregion
#region
/// <summary>
/// 奖品回收
/// POST /api/warehouse_recovery
/// Requirements: 11.1-11.5
/// </summary>
[HttpPost("warehouse_recovery")]
[Authorize]
public async Task<ApiResponse<RecoveryResultDto>> RecoveryPrizes([FromBody] RecoveryRequest? request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return ApiResponse<RecoveryResultDto>.Unauthorized();
}
try
{
if (request == null || string.IsNullOrWhiteSpace(request.RecoveryInfo))
{
return ApiResponse<RecoveryResultDto>.Fail("请选择要回收的奖品");
}
var result = await _warehouseService.RecoveryPrizesAsync(userId.Value, request);
return ApiResponse<RecoveryResultDto>.Success(result);
}
catch (InvalidOperationException ex)
{
_logger.LogWarning("Recovery prizes failed: UserId={UserId}, Error={Error}",
userId, ex.Message);
return ApiResponse<RecoveryResultDto>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to recovery prizes: UserId={UserId}", userId);
return ApiResponse<RecoveryResultDto>.Fail("回收奖品失败");
}
}
#endregion
#region
/// <summary>
/// 奖品发货申请
/// </summary>
/// <remarks>
/// POST /api/warehouse_send
///
/// 申请将仓库中的奖品发货到指定地址
/// Requirements: 12.1-12.5
/// </remarks>
/// <param name="request">发货申请请求参数</param>
/// <returns>发货申请结果</returns>
[HttpPost("warehouse_send")]
[Authorize]
[ProducesResponseType(typeof(ApiResponse<SendResultDto>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ApiResponse<SendResultDto>), StatusCodes.Status401Unauthorized)]
public async Task<ApiResponse<SendResultDto>> SendPrizes([FromBody] SendRequest? request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return ApiResponse<SendResultDto>.Unauthorized();
}
try
{
if (request == null || string.IsNullOrWhiteSpace(request.RecoveryInfo))
{
return ApiResponse<SendResultDto>.Fail("请选择要发货的奖品");
}
if (string.IsNullOrWhiteSpace(request.Name))
{
return ApiResponse<SendResultDto>.Fail("请填写收货人姓名");
}
if (string.IsNullOrWhiteSpace(request.Mobile))
{
return ApiResponse<SendResultDto>.Fail("请填写收货人手机号");
}
if (string.IsNullOrWhiteSpace(request.Address))
{
return ApiResponse<SendResultDto>.Fail("请填写收货地址");
}
var result = await _warehouseService.SendPrizesAsync(userId.Value, request);
return ApiResponse<SendResultDto>.Success(result);
}
catch (InvalidOperationException ex)
{
_logger.LogWarning("Send prizes failed: UserId={UserId}, Error={Error}",
userId, ex.Message);
return ApiResponse<SendResultDto>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to send prizes: UserId={UserId}", userId);
return ApiResponse<SendResultDto>.Fail("发货申请失败");
}
}
/// <summary>
/// 确认发货
/// POST /api/warehouse_send_confirm
/// Requirements: 13.1-13.2
/// </summary>
[HttpPost("warehouse_send_confirm")]
[Authorize]
public async Task<ApiResponse> ConfirmSend([FromBody] ConfirmSendRequest? request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return ApiResponse.Unauthorized();
}
try
{
if (request == null || request.Id <= 0)
{
return ApiResponse.Fail("发货记录ID不能为空");
}
var result = await _warehouseService.ConfirmSendAsync(userId.Value, request.Id);
if (result)
{
return ApiResponse.Success("确认成功");
}
return ApiResponse.Fail("确认失败");
}
catch (InvalidOperationException ex)
{
_logger.LogWarning("Confirm send failed: UserId={UserId}, Id={Id}, Error={Error}",
userId, request?.Id, ex.Message);
return ApiResponse.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to confirm send: UserId={UserId}, Id={Id}",
userId, request?.Id);
return ApiResponse.Fail("确认发货失败");
}
}
#endregion
#region
/// <summary>
/// 发货记录查询
/// POST /api/warehouse_send_record
/// Requirements: 14.1-14.3
/// </summary>
[HttpPost("warehouse_send_record")]
[Authorize]
public async Task<ApiResponse<PageResponse<SendRecordDto>>> GetSendRecords([FromBody] SendRecordRequest? request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return ApiResponse<PageResponse<SendRecordDto>>.Unauthorized();
}
try
{
request ??= new SendRecordRequest();
if (request.Page < 1) request.Page = 1;
if (request.Status < 1) request.Status = 1;
var result = await _warehouseService.GetSendRecordsAsync(userId.Value, request.Page, request.Status);
return ApiResponse<PageResponse<SendRecordDto>>.Success(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get send records: UserId={UserId}", userId);
return ApiResponse<PageResponse<SendRecordDto>>.Fail("获取发货记录失败");
}
}
/// <summary>
/// 发货记录详情查询
/// POST /api/warehouse_send_record_detail
/// Requirements: 15.1-15.3
/// </summary>
[HttpPost("warehouse_send_record_detail")]
[Authorize]
public async Task<ApiResponse<SendRecordDetailDto>> GetSendRecordDetail([FromBody] SendRecordDetailRequest? request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return ApiResponse<SendRecordDetailDto>.Unauthorized();
}
try
{
if (request == null || request.Id <= 0)
{
return ApiResponse<SendRecordDetailDto>.Fail("发货记录ID不能为空");
}
var result = await _warehouseService.GetSendRecordDetailAsync(userId.Value, request.Id);
return ApiResponse<SendRecordDetailDto>.Success(result);
}
catch (InvalidOperationException ex)
{
_logger.LogWarning("Get send record detail failed: UserId={UserId}, Id={Id}, Error={Error}",
userId, request?.Id, ex.Message);
return ApiResponse<SendRecordDetailDto>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get send record detail: UserId={UserId}, Id={Id}",
userId, request?.Id);
return ApiResponse<SendRecordDetailDto>.Fail("获取发货记录详情失败");
}
}
/// <summary>
/// 回收记录查询
/// POST /api/warehouse_recovery_record
/// Requirements: 16.1-16.2
/// </summary>
[HttpPost("warehouse_recovery_record")]
[Authorize]
public async Task<ApiResponse<PageResponse<RecoveryRecordDto>>> GetRecoveryRecords([FromBody] RecoveryRecordRequest? request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return ApiResponse<PageResponse<RecoveryRecordDto>>.Unauthorized();
}
try
{
request ??= new RecoveryRecordRequest();
if (request.Page < 1) request.Page = 1;
var result = await _warehouseService.GetRecoveryRecordsAsync(userId.Value, request.Page);
return ApiResponse<PageResponse<RecoveryRecordDto>>.Success(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get recovery records: UserId={UserId}", userId);
return ApiResponse<PageResponse<RecoveryRecordDto>>.Fail("获取回收记录失败");
}
}
#endregion
#region
/// <summary>
/// 物流信息查询
/// POST /api/warehouse_order_logistics
/// Requirements: 17.1-17.3
/// </summary>
[HttpPost("warehouse_order_logistics")]
[Authorize]
public async Task<ApiResponse<LogisticsDto>> GetLogistics([FromBody] LogisticsRequest? request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return ApiResponse<LogisticsDto>.Unauthorized();
}
try
{
if (request == null || request.Id <= 0)
{
return ApiResponse<LogisticsDto>.Fail("发货记录ID不能为空");
}
var result = await _warehouseService.GetLogisticsAsync(userId.Value, request.Id);
return ApiResponse<LogisticsDto>.Success(result);
}
catch (InvalidOperationException ex)
{
_logger.LogWarning("Get logistics failed: UserId={UserId}, Id={Id}, Error={Error}",
userId, request?.Id, ex.Message);
return ApiResponse<LogisticsDto>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get logistics: UserId={UserId}, Id={Id}",
userId, request?.Id);
return ApiResponse<LogisticsDto>.Fail("获取物流信息失败");
}
}
#endregion
#region
/// <summary>
/// 移入保险柜
/// </summary>
/// <remarks>
/// POST /api/warehouse_movein
///
/// 将仓库中的奖品移入保险柜
/// Requirements: 12.1
/// </remarks>
/// <param name="request">移入请求参数</param>
/// <returns>操作结果</returns>
[HttpPost("warehouse_movein")]
[Authorize]
[ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ApiResponse), StatusCodes.Status401Unauthorized)]
public async Task<ApiResponse> MoveIntoSafe([FromBody] SafeOperationRequest? request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return ApiResponse.Unauthorized();
}
try
{
if (request == null || string.IsNullOrWhiteSpace(request.RecoveryInfo))
{
return ApiResponse.Fail("请选择兑换的赏品");
}
var result = await _warehouseService.MoveIntoSafeAsync(userId.Value, request);
if (result)
{
return ApiResponse.Success("移入成功");
}
return ApiResponse.Fail("移入失败");
}
catch (InvalidOperationException ex)
{
_logger.LogWarning("Move into safe failed: UserId={UserId}, Error={Error}",
userId, ex.Message);
return ApiResponse.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to move into safe: UserId={UserId}", userId);
return ApiResponse.Fail("移入失败");
}
}
/// <summary>
/// 移出保险柜
/// </summary>
/// <remarks>
/// POST /api/warehouse_remove
///
/// 将保险柜中的奖品移出到仓库
/// Requirements: 12.2
/// </remarks>
/// <param name="request">移出请求参数</param>
/// <returns>操作结果</returns>
[HttpPost("warehouse_remove")]
[Authorize]
[ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ApiResponse), StatusCodes.Status401Unauthorized)]
public async Task<ApiResponse> RemoveFromSafe([FromBody] SafeOperationRequest? request)
{
var userId = GetCurrentUserId();
if (userId == null)
{
return ApiResponse.Unauthorized();
}
try
{
if (request == null || string.IsNullOrWhiteSpace(request.RecoveryInfo))
{
return ApiResponse.Fail("请选择兑换的赏品");
}
var result = await _warehouseService.RemoveFromSafeAsync(userId.Value, request);
if (result)
{
return ApiResponse.Success("移出成功");
}
return ApiResponse.Fail("移出失败");
}
catch (InvalidOperationException ex)
{
_logger.LogWarning("Remove from safe failed: UserId={UserId}, Error={Error}",
userId, ex.Message);
return ApiResponse.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to remove from safe: UserId={UserId}", userId);
return ApiResponse.Fail("移出失败");
}
}
#endregion
#region Private Helper Methods
/// <summary>
/// 获取当前登录用户ID
/// </summary>
private int? GetCurrentUserId()
{
var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier);
if (userIdClaim == null || !int.TryParse(userIdClaim.Value, out var userId))
{
return null;
}
return userId;
}
#endregion
}