using Sharp.NetServer.Attributes;
using Sharp.NetServer.Controllers;
using Sharp.NetServer.Models;
namespace NetServer.Test.Examples.Controllers;
///
/// 产品管理控制器示例
///
[ApiController]
[Route("api/products")]
public class ProductController : BaseController
{
private static readonly List Products = new()
{
new Product { Id = 1, Name = "笔记本电脑", Price = 5999.00m, Stock = 50, Category = "电子产品" },
new Product { Id = 2, Name = "无线鼠标", Price = 99.00m, Stock = 200, Category = "电子产品" },
new Product { Id = 3, Name = "机械键盘", Price = 399.00m, Stock = 100, Category = "电子产品" },
new Product { Id = 4, Name = "显示器", Price = 1299.00m, Stock = 30, Category = "电子产品" }
};
///
/// 获取所有产品(公开接口,带缓存和限流)
/// GET /api/products
///
[AllowAnonymous]
[RateLimit(200, RateLimitScope.Ip)]
[ResponseCache(60, VaryByQueryKeys = true)]
[HttpGet]
public async Task GetAllProductsAsync(HttpContext context)
{
var category = GetQueryParam(context, "category", "");
var products = string.IsNullOrEmpty(category)
? Products
: Products.Where(p => p.Category.Equals(category, StringComparison.OrdinalIgnoreCase)).ToList();
await WriteSuccessResponseAsync(context, products);
}
///
/// 获取产品详情
/// GET /api/products/1
///
[AllowAnonymous]
[ResponseCache(30)]
[HttpGet("{id}")]
public async Task GetProductByIdAsync(HttpContext context)
{
var idStr = context.Request.Url.Segments.LastOrDefault()?.TrimEnd('/');
if (int.TryParse(idStr, out var id))
{
var product = Products.FirstOrDefault(p => p.Id == id);
if (product != null)
{
await WriteSuccessResponseAsync(context, product);
return;
}
}
await NotFoundAsync(context, "产品未找到");
}
///
/// 创建产品(需要认证)
/// POST /api/products
/// Body: { "name": "新产品", "price": 199.00, "stock": 100, "category": "类别" }
///
[Authorize(Roles = "Admin")]
[RateLimit(20, RateLimitScope.User)]
[HttpPost]
public async Task CreateProductAsync(HttpContext context)
{
var productData = await ReadJsonBodyAsync(context);
if (productData == null || string.IsNullOrEmpty(productData.Name) || productData.Price <= 0)
{
await BadRequestAsync(context, "无效的产品数据");
return;
}
productData.Id = Products.Max(p => p.Id) + 1;
Products.Add(productData);
await WriteSuccessResponseAsync(context, productData, "产品创建成功");
}
///
/// 更新库存
/// PATCH /api/products/1/stock
/// Body: { "quantity": 10 }
///
[Authorize]
[HttpPatch("{id}/stock")]
public async Task UpdateStockAsync(HttpContext context)
{
var idStr = context.Request.Url.Segments[^2].TrimEnd('/');
if (!int.TryParse(idStr, out var id))
{
await BadRequestAsync(context, "无效的产品ID");
return;
}
var product = Products.FirstOrDefault(p => p.Id == id);
if (product == null)
{
await NotFoundAsync(context, "产品未找到");
return;
}
var stockUpdate = await ReadJsonBodyAsync>(context);
if (stockUpdate != null && stockUpdate.TryGetValue("quantity", out var quantityObj))
if (int.TryParse(quantityObj.ToString(), out var quantity))
{
product.Stock = quantity;
await WriteSuccessResponseAsync(context, product, "库存更新成功");
return;
}
await BadRequestAsync(context, "无效的库存数量");
}
///
/// 删除产品
/// DELETE /api/products/1
///
[Authorize(Roles = "Admin")]
[HttpDelete("{id}")]
public async Task DeleteProductAsync(HttpContext context)
{
var idStr = context.Request.Url.Segments.LastOrDefault()?.TrimEnd('/');
if (!int.TryParse(idStr, out var id))
{
await BadRequestAsync(context, "无效的产品ID");
return;
}
var product = Products.FirstOrDefault(p => p.Id == id);
if (product == null)
{
await NotFoundAsync(context, "产品未找到");
return;
}
Products.Remove(product);
await WriteSuccessResponseAsync(context, new { id }, "产品删除成功");
}
///
/// 搜索产品
/// GET /api/products/search?q=键盘&minPrice=100&maxPrice=500
///
[AllowAnonymous]
[RateLimit(150, RateLimitScope.Ip)]
[HttpGet("search")]
public async Task SearchProductsAsync(HttpContext context)
{
var query = GetQueryParam(context, "q", "");
var minPriceStr = GetQueryParam(context, "minPrice", "0");
var maxPriceStr = GetQueryParam(context, "maxPrice", decimal.MaxValue.ToString());
decimal.TryParse(minPriceStr, out var minPrice);
decimal.TryParse(maxPriceStr, out var maxPrice);
var results = Products.Where(p =>
(string.IsNullOrEmpty(query) || p.Name.Contains(query, StringComparison.OrdinalIgnoreCase)) &&
p.Price >= minPrice &&
p.Price <= maxPrice
).ToList();
await WriteSuccessResponseAsync(context, new
{
query,
minPrice,
maxPrice,
count = results.Count,
products = results
});
}
}
///
/// 产品数据模型
///
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
public int Stock { get; set; }
public string Category { get; set; } = string.Empty;
}