测试
This commit is contained in:
271
MinimalAPI/Services/ComparisonService.cs
Normal file
271
MinimalAPI/Services/ComparisonService.cs
Normal file
@@ -0,0 +1,271 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MinimalAPI.Data;
|
||||
using MinimalAPI.Models;
|
||||
using MinimalAPI.Models.DTOs;
|
||||
|
||||
namespace MinimalAPI.Services
|
||||
{
|
||||
public class ComparisonService : IComparisonService
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public ComparisonService(AppDbContext context, IMapper mapper)
|
||||
{
|
||||
_context = context;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public async Task<object> CompareProductsAsync(List<int> productIds)
|
||||
{
|
||||
// 验证输入
|
||||
if (productIds == null || productIds.Count < 2 || productIds.Count > 4)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取产品
|
||||
var products = await _context.Products
|
||||
.Include(p => p.Category)
|
||||
.Where(p => productIds.Contains(p.Id))
|
||||
.ToListAsync();
|
||||
|
||||
if (products.Count != productIds.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 检查是否所有产品属于同一类别
|
||||
var categoryIds = products.Select(p => p.CategoryId).Distinct().ToList();
|
||||
if (categoryIds.Count > 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取性能分数
|
||||
var productIdsList = products.Select(p => p.Id).ToList();
|
||||
var performanceScores = await _context.PerformanceScores
|
||||
.Where(ps => productIdsList.Contains(ps.ProductId))
|
||||
.ToListAsync();
|
||||
|
||||
// 获取规格参数
|
||||
var specifications = await _context.Specifications
|
||||
.Where(s => productIdsList.Contains(s.ProductId))
|
||||
.ToListAsync();
|
||||
|
||||
// 创建产品DTO列表
|
||||
var productDtos = products.Select(p => {
|
||||
var dto = _mapper.Map<ProductDto>(p);
|
||||
dto.PerformanceScores = performanceScores
|
||||
.Where(ps => ps.ProductId == p.Id)
|
||||
.ToList();
|
||||
dto.Specifications = specifications
|
||||
.Where(s => s.ProductId == p.Id)
|
||||
.ToList();
|
||||
return dto;
|
||||
}).ToList();
|
||||
|
||||
// 生成对比矩阵
|
||||
var comparisonMatrix = GenerateComparisonMatrix(productDtos);
|
||||
|
||||
return new
|
||||
{
|
||||
Products = productDtos,
|
||||
Comparison = comparisonMatrix
|
||||
};
|
||||
}
|
||||
|
||||
private List<Dictionary<string, object>> GenerateComparisonMatrix(List<ProductDto> products)
|
||||
{
|
||||
var matrix = new List<Dictionary<string, object>>();
|
||||
|
||||
// 添加基本信息行
|
||||
matrix.Add(new Dictionary<string, object> { ["指标"] = "产品名称", ["类型"] = "基本信息" });
|
||||
foreach (var product in products)
|
||||
{
|
||||
matrix[0][$"{product.Name}"] = product.Name;
|
||||
}
|
||||
|
||||
// 添加制造商行
|
||||
matrix.Add(new Dictionary<string, object> { ["指标"] = "制造商", ["类型"] = "基本信息" });
|
||||
foreach (var product in products)
|
||||
{
|
||||
matrix[1][$"{product.Name}"] = product.Manufacturer;
|
||||
}
|
||||
|
||||
// 添加型号行
|
||||
matrix.Add(new Dictionary<string, object> { ["指标"] = "型号", ["类型"] = "基本信息" });
|
||||
foreach (var product in products)
|
||||
{
|
||||
matrix[2][$"{product.Name}"] = product.Model;
|
||||
}
|
||||
|
||||
// 添加排名行
|
||||
matrix.Add(new Dictionary<string, object> { ["指标"] = "当前排名", ["类型"] = "性能指标" });
|
||||
foreach (var product in products)
|
||||
{
|
||||
matrix[3][$"{product.Name}"] = product.CurrentRank;
|
||||
}
|
||||
|
||||
// 添加发布日期行
|
||||
matrix.Add(new Dictionary<string, object> { ["指标"] = "发布日期", ["类型"] = "基本信息" });
|
||||
foreach (var product in products)
|
||||
{
|
||||
matrix[4][$"{product.Name}"] = product.ReleaseDate.ToString("yyyy-MM-dd");
|
||||
}
|
||||
|
||||
// 添加价格行
|
||||
matrix.Add(new Dictionary<string, object> { ["指标"] = "价格", ["类型"] = "基本信息" });
|
||||
foreach (var product in products)
|
||||
{
|
||||
matrix[5][$"{product.Name}"] = product.Price?.ToString("C") ?? "N/A";
|
||||
}
|
||||
|
||||
// 添加性能分数行
|
||||
var benchmarkTypes = products
|
||||
.SelectMany(p => p.PerformanceScores)
|
||||
.Select(ps => ps.BenchmarkType)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
foreach (var benchmarkType in benchmarkTypes)
|
||||
{
|
||||
var rowIndex = matrix.Count;
|
||||
matrix.Add(new Dictionary<string, object> { ["指标"] = benchmarkType, ["类型"] = "性能指标" });
|
||||
|
||||
foreach (var product in products)
|
||||
{
|
||||
var score = product.PerformanceScores
|
||||
.FirstOrDefault(ps => ps.BenchmarkType == benchmarkType)?.Score;
|
||||
matrix[rowIndex][$"{product.Name}"] = score?.ToString() ?? "N/A";
|
||||
}
|
||||
}
|
||||
|
||||
// 添加规格参数行
|
||||
var specNames = products
|
||||
.SelectMany(p => p.Specifications)
|
||||
.Select(s => s.Name)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
foreach (var specName in specNames)
|
||||
{
|
||||
var rowIndex = matrix.Count;
|
||||
matrix.Add(new Dictionary<string, object> { ["指标"] = specName, ["类型"] = "规格参数" });
|
||||
|
||||
foreach (var product in products)
|
||||
{
|
||||
var specValue = product.Specifications
|
||||
.FirstOrDefault(s => s.Name == specName)?.Value;
|
||||
matrix[rowIndex][$"{product.Name}"] = specValue ?? "N/A";
|
||||
}
|
||||
}
|
||||
|
||||
// 标记最优和最差值
|
||||
MarkBestAndWorstValues(matrix, products);
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
private void MarkBestAndWorstValues(List<Dictionary<string, object>> matrix, List<ProductDto> products)
|
||||
{
|
||||
// 对于排名,越小越好
|
||||
var rankRow = matrix.FirstOrDefault(m => m["指标"].ToString() == "当前排名");
|
||||
if (rankRow != null)
|
||||
{
|
||||
var ranks = products.Select(p => p.CurrentRank).ToList();
|
||||
var minRank = ranks.Min();
|
||||
var maxRank = ranks.Max();
|
||||
|
||||
foreach (var product in products)
|
||||
{
|
||||
var rank = product.CurrentRank;
|
||||
if (rank == minRank)
|
||||
{
|
||||
rankRow[$"{product.Name}_isBest"] = true;
|
||||
}
|
||||
else if (rank == maxRank)
|
||||
{
|
||||
rankRow[$"{product.Name}_isWorst"] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 对于价格,越小越好
|
||||
var priceRow = matrix.FirstOrDefault(m => m["指标"].ToString() == "价格");
|
||||
if (priceRow != null)
|
||||
{
|
||||
var prices = products.Where(p => p.Price.HasValue).Select(p => p.Price!.Value).ToList();
|
||||
if (prices.Any())
|
||||
{
|
||||
var minPrice = prices.Min();
|
||||
var maxPrice = prices.Max();
|
||||
|
||||
foreach (var product in products)
|
||||
{
|
||||
if (product.Price.HasValue)
|
||||
{
|
||||
if (product.Price == minPrice)
|
||||
{
|
||||
priceRow[$"{product.Name}_isBest"] = true;
|
||||
}
|
||||
else if (product.Price == maxPrice)
|
||||
{
|
||||
priceRow[$"{product.Name}_isWorst"] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 对于性能分数,越大越好
|
||||
var performanceRows = matrix.Where(m => m["类型"].ToString() == "性能指标" &&
|
||||
m["指标"].ToString() != "当前排名").ToList();
|
||||
|
||||
foreach (var row in performanceRows)
|
||||
{
|
||||
var benchmarkType = row["指标"].ToString();
|
||||
var scores = new List<decimal?>();
|
||||
|
||||
foreach (var product in products)
|
||||
{
|
||||
var scoreStr = row[$"{product.Name}"]?.ToString();
|
||||
if (decimal.TryParse(scoreStr, out var score))
|
||||
{
|
||||
scores.Add(score);
|
||||
}
|
||||
else
|
||||
{
|
||||
scores.Add(null);
|
||||
}
|
||||
}
|
||||
|
||||
var validScores = scores.Where(s => s.HasValue).Select(s => s!.Value).ToList();
|
||||
if (validScores.Any())
|
||||
{
|
||||
var maxScore = validScores.Max();
|
||||
var minScore = validScores.Min();
|
||||
|
||||
for (int i = 0; i < products.Count; i++)
|
||||
{
|
||||
if (scores[i].HasValue)
|
||||
{
|
||||
if (scores[i] == maxScore)
|
||||
{
|
||||
row[$"{products[i].Name}_isBest"] = true;
|
||||
}
|
||||
else if (scores[i] == minScore)
|
||||
{
|
||||
row[$"{products[i].Name}_isWorst"] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user