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; }