初始化
Some checks failed
Some checks failed
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using HardwarePerformance.Application.Interfaces;
|
||||
using HardwarePerformance.Core.Entities;
|
||||
using HardwarePerformance.Infrastructure.Data;
|
||||
|
||||
namespace HardwarePerformance.Infrastructure.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// 产品Repository实现
|
||||
/// </summary>
|
||||
public class ProductRepository : Repository<Product>, IProductRepository
|
||||
{
|
||||
public ProductRepository(AppDbContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<Product> products, int totalCount)> GetByCategoryAsync(
|
||||
int categoryId,
|
||||
int pageNumber = 1,
|
||||
int pageSize = 20,
|
||||
string sortBy = "CurrentRank",
|
||||
bool ascending = true)
|
||||
{
|
||||
var query = _dbSet
|
||||
.Include(p => p.Category)
|
||||
.Include(p => p.PerformanceScores)
|
||||
.Where(p => p.CategoryId == categoryId);
|
||||
|
||||
// 排序
|
||||
query = ApplySorting(query, sortBy, ascending);
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
|
||||
var products = await query
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
return (products, totalCount);
|
||||
}
|
||||
|
||||
public async Task<Product?> GetByModelAsync(string model)
|
||||
{
|
||||
return await _dbSet
|
||||
.Include(p => p.Category)
|
||||
.Include(p => p.PerformanceScores)
|
||||
.FirstOrDefaultAsync(p => p.Model == model);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Product>> GetTopNByCategoryAsync(int categoryId, int n)
|
||||
{
|
||||
return await _dbSet
|
||||
.Include(p => p.Category)
|
||||
.Include(p => p.PerformanceScores)
|
||||
.Where(p => p.CategoryId == categoryId)
|
||||
.OrderBy(p => p.CurrentRank)
|
||||
.Take(n)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<Product> products, int totalCount)> SearchAsync(
|
||||
string searchTerm,
|
||||
int? categoryId = null,
|
||||
int pageNumber = 1,
|
||||
int pageSize = 20)
|
||||
{
|
||||
var query = _dbSet
|
||||
.Include(p => p.Category)
|
||||
.Include(p => p.PerformanceScores)
|
||||
.Where(p =>
|
||||
(string.IsNullOrEmpty(searchTerm) ||
|
||||
p.Name.Contains(searchTerm) ||
|
||||
p.Model.Contains(searchTerm) ||
|
||||
p.Manufacturer.Contains(searchTerm)) &&
|
||||
(!categoryId.HasValue || p.CategoryId == categoryId.Value));
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
|
||||
var products = await query
|
||||
.OrderBy(p => p.CurrentRank)
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
return (products, totalCount);
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<Product> products, int totalCount)> FilterAsync(
|
||||
int categoryId,
|
||||
int? minScore = null,
|
||||
int? maxScore = null,
|
||||
int? minYear = null,
|
||||
int? maxYear = null,
|
||||
string? manufacturer = null,
|
||||
int pageNumber = 1,
|
||||
int pageSize = 20)
|
||||
{
|
||||
var query = _dbSet
|
||||
.Include(p => p.Category)
|
||||
.Include(p => p.PerformanceScores)
|
||||
.Where(p => p.CategoryId == categoryId);
|
||||
|
||||
// 性能分数筛选
|
||||
if (minScore.HasValue)
|
||||
{
|
||||
query = query.Where(p => p.PerformanceScores.Any(ps => ps.Score >= minScore.Value));
|
||||
}
|
||||
|
||||
if (maxScore.HasValue)
|
||||
{
|
||||
query = query.Where(p => p.PerformanceScores.Any(ps => ps.Score <= maxScore.Value));
|
||||
}
|
||||
|
||||
// 发布年份筛选
|
||||
if (minYear.HasValue)
|
||||
{
|
||||
query = query.Where(p => p.ReleaseDate.HasValue && p.ReleaseDate.Value.Year >= minYear.Value);
|
||||
}
|
||||
|
||||
if (maxYear.HasValue)
|
||||
{
|
||||
query = query.Where(p => p.ReleaseDate.HasValue && p.ReleaseDate.Value.Year <= maxYear.Value);
|
||||
}
|
||||
|
||||
// 品牌筛选
|
||||
if (!string.IsNullOrEmpty(manufacturer))
|
||||
{
|
||||
query = query.Where(p => p.Manufacturer == manufacturer);
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
|
||||
var products = await query
|
||||
.OrderBy(p => p.CurrentRank)
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
return (products, totalCount);
|
||||
}
|
||||
|
||||
public async Task<Product?> GetWithDetailsAsync(int id)
|
||||
{
|
||||
return await _dbSet
|
||||
.Include(p => p.Category)
|
||||
.Include(p => p.Specifications)
|
||||
.Include(p => p.PerformanceScores)
|
||||
.ThenInclude(ps => ps.DataSource)
|
||||
.Include(p => p.RankingHistories
|
||||
.OrderByDescending(rh => rh.RecordDate)
|
||||
.Take(12)) // 最近12个月的排名历史
|
||||
.FirstOrDefaultAsync(p => p.Id == id);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Product>> GetByIdsAsync(IEnumerable<int> productIds)
|
||||
{
|
||||
return await _dbSet
|
||||
.Include(p => p.Category)
|
||||
.Include(p => p.Specifications)
|
||||
.Include(p => p.PerformanceScores)
|
||||
.ThenInclude(ps => ps.DataSource)
|
||||
.Where(p => productIds.Contains(p.Id))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> GetManufacturersAsync(int? categoryId = null)
|
||||
{
|
||||
var query = _dbSet.AsQueryable();
|
||||
|
||||
if (categoryId.HasValue)
|
||||
{
|
||||
query = query.Where(p => p.CategoryId == categoryId.Value);
|
||||
}
|
||||
|
||||
return await query
|
||||
.Where(p => !string.IsNullOrEmpty(p.Manufacturer))
|
||||
.Select(p => p.Manufacturer)
|
||||
.Distinct()
|
||||
.OrderBy(m => m)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RankingHistory>> GetRankingHistoryAsync(int productId, int months = 12)
|
||||
{
|
||||
var startDate = DateTime.UtcNow.AddMonths(-months);
|
||||
|
||||
return await _context.RankingHistories
|
||||
.Where(rh => rh.ProductId == productId && rh.RecordDate >= startDate)
|
||||
.OrderBy(rh => rh.RecordDate)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<Product> products, int totalCount)> GetByManufacturerAsync(
|
||||
string manufacturer,
|
||||
int? categoryId = null,
|
||||
int pageNumber = 1,
|
||||
int pageSize = 20)
|
||||
{
|
||||
var query = _dbSet
|
||||
.Include(p => p.Category)
|
||||
.Include(p => p.PerformanceScores)
|
||||
.Where(p => p.Manufacturer == manufacturer);
|
||||
|
||||
if (categoryId.HasValue)
|
||||
{
|
||||
query = query.Where(p => p.CategoryId == categoryId.Value);
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
|
||||
var products = await query
|
||||
.OrderBy(p => p.CurrentRank)
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
return (products, totalCount);
|
||||
}
|
||||
|
||||
private IQueryable<Product> ApplySorting(IQueryable<Product> query, string sortBy, bool ascending)
|
||||
{
|
||||
return sortBy.ToLower() switch
|
||||
{
|
||||
"name" => ascending ? query.OrderBy(p => p.Name) : query.OrderByDescending(p => p.Name),
|
||||
"manufacturer" => ascending ? query.OrderBy(p => p.Manufacturer) : query.OrderByDescending(p => p.Manufacturer),
|
||||
"releasedate" => ascending ? query.OrderBy(p => p.ReleaseDate) : query.OrderByDescending(p => p.ReleaseDate),
|
||||
"currentrank" => ascending ? query.OrderBy(p => p.CurrentRank) : query.OrderByDescending(p => p.CurrentRank),
|
||||
"score" => ascending ?
|
||||
query.OrderBy(p => p.PerformanceScores.Any() ? p.PerformanceScores.Average(ps => ps.Score) : 0) :
|
||||
query.OrderByDescending(p => p.PerformanceScores.Any() ? p.PerformanceScores.Average(ps => ps.Score) : 0),
|
||||
_ => ascending ? query.OrderBy(p => p.CurrentRank) : query.OrderByDescending(p => p.CurrentRank)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user