Files
it/backend/HardwarePerformance.API/Controllers/ProductsController.cs
2025-11-03 17:03:57 +08:00

252 lines
9.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.AspNetCore.Mvc;
using HardwarePerformance.API.Models;
using HardwarePerformance.Infrastructure.Services;
namespace HardwarePerformance.API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private static readonly List<Product> _products = new()
{
new Product
{
Id = 1,
Name = "Apple A17 Pro",
Model = "A17 Pro",
Manufacturer = "Apple",
CategoryId = 1,
CurrentRank = 1,
ReleaseDate = new DateTime(2023, 9, 12),
Price = null
},
new Product
{
Id = 2,
Name = "Snapdragon 8 Gen 3",
Model = "SM8650-AB",
Manufacturer = "Qualcomm",
CategoryId = 1,
CurrentRank = 2,
ReleaseDate = new DateTime(2023, 10, 24),
Price = null
},
new Product
{
Id = 3,
Name = "Intel Core i9-13900K",
Model = "Core i9-13900K",
Manufacturer = "Intel",
CategoryId = 3,
CurrentRank = 1,
ReleaseDate = new DateTime(2022, 10, 20),
Price = 589.99m
},
new Product
{
Id = 4,
Name = "AMD Ryzen 9 7950X",
Model = "Ryzen 9 7950X",
Manufacturer = "AMD",
CategoryId = 3,
CurrentRank = 2,
ReleaseDate = new DateTime(2022, 9, 27),
Price = 699.99m
},
new Product
{
Id = 5,
Name = "NVIDIA GeForce RTX 4090",
Model = "RTX 4090",
Manufacturer = "NVIDIA",
CategoryId = 4,
CurrentRank = 1,
ReleaseDate = new DateTime(2022, 10, 12),
Price = 1599.99m
},
new Product
{
Id = 6,
Name = "AMD Radeon RX 7900 XTX",
Model = "RX 7900 XTX",
Manufacturer = "AMD",
CategoryId = 4,
CurrentRank = 2,
ReleaseDate = new DateTime(2022, 12, 3),
Price = 999.99m
}
};
private readonly IRedisCacheService _cacheService;
public ProductsController(IRedisCacheService cacheService)
{
_cacheService = cacheService;
}
[HttpGet]
public async Task<ActionResult<PagedResponse<Product>>> GetProducts(
[FromQuery] int? categoryId,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 10,
[FromQuery] string sortBy = "CurrentRank",
[FromQuery] string order = "asc")
{
// 创建缓存键
var cacheKey = $"products:list:{categoryId ?? 0}:{page}:{pageSize}:{sortBy}:{order}";
// 尝试从缓存获取数据
var cachedResult = await _cacheService.GetAsync<PagedResponse<Product>>(cacheKey);
if (cachedResult != null)
{
return Ok(cachedResult);
}
var query = _products.AsEnumerable();
if (categoryId.HasValue)
{
query = query.Where(p => p.CategoryId == categoryId.Value);
}
// 排序
query = sortBy.ToLower() switch
{
"name" => order.ToLower() == "desc" ? query.OrderByDescending(p => p.Name) : query.OrderBy(p => p.Name),
"manufacturer" => order.ToLower() == "desc" ? query.OrderByDescending(p => p.Manufacturer) : query.OrderBy(p => p.Manufacturer),
"releasedate" => order.ToLower() == "desc" ? query.OrderByDescending(p => p.ReleaseDate) : query.OrderBy(p => p.ReleaseDate),
"price" => order.ToLower() == "desc" ? query.OrderByDescending(p => p.Price) : query.OrderBy(p => p.Price),
_ => order.ToLower() == "desc" ? query.OrderByDescending(p => p.CurrentRank) : query.OrderBy(p => p.CurrentRank)
};
var totalCount = query.Count();
var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);
var items = query.Skip((page - 1) * pageSize).Take(pageSize).ToList();
var result = new PagedResponse<Product>
{
Items = items,
TotalCount = totalCount,
PageNumber = page,
PageSize = pageSize,
TotalPages = totalPages
};
// 将结果存入缓存设置5分钟过期时间
await _cacheService.SetAsync(cacheKey, result, TimeSpan.FromMinutes(5));
return Ok(result);
}
[HttpGet("{id}")]
public async Task<ActionResult<ApiResponse<Product>>> GetProduct(int id)
{
// 创建缓存键
var cacheKey = $"product:detail:{id}";
// 尝试从缓存获取数据
var cachedResult = await _cacheService.GetAsync<ApiResponse<Product>>(cacheKey);
if (cachedResult != null)
{
return Ok(cachedResult);
}
var product = _products.FirstOrDefault(p => p.Id == id);
if (product == null)
{
var notFoundResponse = new ApiResponse<Product>
{
Success = false,
Message = "未找到指定的产品"
};
// 缓存未找到的结果,设置较短过期时间
await _cacheService.SetAsync(cacheKey, notFoundResponse, TimeSpan.FromMinutes(1));
return NotFound(notFoundResponse);
}
var result = new ApiResponse<Product>
{
Data = product
};
// 将结果存入缓存设置15分钟过期时间
await _cacheService.SetAsync(cacheKey, result, TimeSpan.FromMinutes(15));
return Ok(result);
}
[HttpGet("search")]
public async Task<ActionResult<PagedResponse<Product>>> SearchProducts(
[FromQuery] string q,
[FromQuery] int? categoryId,
[FromQuery] string? manufacturer,
[FromQuery] int? minScore,
[FromQuery] int? maxScore,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 10)
{
// 创建缓存键
var cacheKey = $"products:search:{q ?? ""}:{categoryId ?? 0}:{manufacturer ?? ""}:{minScore ?? 0}:{maxScore ?? 0}:{page}:{pageSize}";
// 尝试从缓存获取数据
var cachedResult = await _cacheService.GetAsync<PagedResponse<Product>>(cacheKey);
if (cachedResult != null)
{
return Ok(cachedResult);
}
var query = _products.AsEnumerable();
if (!string.IsNullOrWhiteSpace(q))
{
query = query.Where(p =>
p.Name.Contains(q, StringComparison.OrdinalIgnoreCase) ||
p.Model.Contains(q, StringComparison.OrdinalIgnoreCase) ||
p.Manufacturer.Contains(q, StringComparison.OrdinalIgnoreCase));
}
if (categoryId.HasValue)
{
query = query.Where(p => p.CategoryId == categoryId.Value);
}
if (!string.IsNullOrWhiteSpace(manufacturer))
{
query = query.Where(p =>
p.Manufacturer.Equals(manufacturer, StringComparison.OrdinalIgnoreCase));
}
// 注意这里我们使用CurrentRank作为性能分数的替代因为实际产品中没有性能分数字段
if (minScore.HasValue)
{
query = query.Where(p => (100 - p.CurrentRank) >= minScore.Value);
}
if (maxScore.HasValue)
{
query = query.Where(p => (100 - p.CurrentRank) <= maxScore.Value);
}
var totalCount = query.Count();
var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);
var items = query.Skip((page - 1) * pageSize).Take(pageSize).ToList();
var result = new PagedResponse<Product>
{
Items = items,
TotalCount = totalCount,
PageNumber = page,
PageSize = pageSize,
TotalPages = totalPages
};
// 将结果存入缓存设置3分钟过期时间搜索结果变化较快
await _cacheService.SetAsync(cacheKey, result, TimeSpan.FromMinutes(3));
return Ok(result);
}
}
}