test bilder
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
// src/Webshop.Application/Services/Public/ProductService.cs
|
// /src/Webshop.Application/Services/Public/ProductService.cs
|
||||||
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -12,6 +13,10 @@ using Webshop.Infrastructure.Data;
|
|||||||
|
|
||||||
namespace Webshop.Application.Services.Public
|
namespace Webshop.Application.Services.Public
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Service, der f<>r die Abfrage von Produktinformationen f<>r den <20>ffentlichen Shop-Bereich zust<73>ndig ist.
|
||||||
|
/// Alle hier zur<75>ckgegebenen Daten sind f<>r jeden Besucher sichtbar.
|
||||||
|
/// </summary>
|
||||||
public class ProductService : IProductService
|
public class ProductService : IProductService
|
||||||
{
|
{
|
||||||
private readonly ApplicationDbContext _context;
|
private readonly ApplicationDbContext _context;
|
||||||
@@ -21,53 +26,96 @@ namespace Webshop.Application.Services.Public
|
|||||||
_context = context;
|
_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruft eine Liste aller aktiven Produkte f<>r die allgemeine Produkt<6B>bersicht ab.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Eine Liste von ProductDto-Objekten.</returns>
|
||||||
public async Task<ServiceResult<IEnumerable<ProductDto>>> GetAllProductsAsync()
|
public async Task<ServiceResult<IEnumerable<ProductDto>>> GetAllProductsAsync()
|
||||||
{
|
{
|
||||||
|
// Startet eine Abfrage auf die 'Products'-Tabelle in der Datenbank.
|
||||||
var products = await _context.Products
|
var products = await _context.Products
|
||||||
.Include(p => p.Productcategories).ThenInclude(pc => pc.categorie)
|
// L<>dt die zugeh<65>rigen 'Productcategories'-Verkn<6B>pfungen mit.
|
||||||
|
.Include(p => p.Productcategories)
|
||||||
|
// L<>dt von dort aus die eigentliche 'categorie'-Entit<69>t.
|
||||||
|
.ThenInclude(pc => pc.categorie)
|
||||||
|
// L<>dt auch die zugeh<65>rigen Produktbilder mit.
|
||||||
.Include(p => p.Images)
|
.Include(p => p.Images)
|
||||||
|
// Filtert die Ergebnisse: Nur Produkte, die als 'IsActive' markiert sind.
|
||||||
.Where(p => p.IsActive)
|
.Where(p => p.IsActive)
|
||||||
|
// F<>hrt die Abfrage auf der Datenbank aus und l<>dt die Ergebnisse in eine Liste.
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
// Wandelt jede Product-Entit<69>t in ein ProductDto um.
|
||||||
|
// 'useShortDescription: true' sorgt daf<61>r, dass die k<>rzere Beschreibung f<>r die Listenansicht verwendet wird.
|
||||||
var dtos = products.Select(p => MapToDto(p, useShortDescription: true)).ToList();
|
var dtos = products.Select(p => MapToDto(p, useShortDescription: true)).ToList();
|
||||||
|
|
||||||
|
// Gibt das erfolgreiche Ergebnis mit der DTO-Liste zur<75>ck.
|
||||||
return ServiceResult.Ok<IEnumerable<ProductDto>>(dtos);
|
return ServiceResult.Ok<IEnumerable<ProductDto>>(dtos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruft ein einzelnes, aktives Produkt anhand seines eindeutigen Slugs ab (f<>r die Produktdetailseite).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="slug">Der URL-freundliche Slug des Produkts.</param>
|
||||||
|
/// <returns>Ein einzelnes ProductDto oder ein NotFound-Ergebnis.</returns>
|
||||||
public async Task<ServiceResult<ProductDto>> GetProductBySlugAsync(string slug)
|
public async Task<ServiceResult<ProductDto>> GetProductBySlugAsync(string slug)
|
||||||
{
|
{
|
||||||
|
// Startet eine Abfrage auf die 'Products'-Tabelle.
|
||||||
var product = await _context.Products
|
var product = await _context.Products
|
||||||
|
// L<>dt alle notwendigen verkn<6B>pften Daten f<>r die Detailansicht.
|
||||||
.Include(p => p.Productcategories).ThenInclude(pc => pc.categorie)
|
.Include(p => p.Productcategories).ThenInclude(pc => pc.categorie)
|
||||||
.Include(p => p.Images)
|
.Include(p => p.Images)
|
||||||
|
// Findet das erste Produkt, das dem Slug entspricht UND aktiv ist.
|
||||||
.FirstOrDefaultAsync(p => p.Slug == slug && p.IsActive);
|
.FirstOrDefaultAsync(p => p.Slug == slug && p.IsActive);
|
||||||
|
|
||||||
|
// Wenn kein Produkt gefunden wurde (oder es inaktiv ist), wird ein Fehler zur<75>ckgegeben.
|
||||||
if (product == null)
|
if (product == null)
|
||||||
{
|
{
|
||||||
return ServiceResult.Fail<ProductDto>(ServiceResultType.NotFound, $"Produkt mit dem Slug '{slug}' wurde nicht gefunden.");
|
return ServiceResult.Fail<ProductDto>(ServiceResultType.NotFound, $"Produkt mit dem Slug '{slug}' wurde nicht gefunden.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wandelt die gefundene Entit<69>t in ein DTO um.
|
||||||
|
// 'useShortDescription: false' sorgt daf<61>r, dass die vollst<73>ndige, lange Beschreibung verwendet wird.
|
||||||
return ServiceResult.Ok(MapToDto(product, useShortDescription: false));
|
return ServiceResult.Ok(MapToDto(product, useShortDescription: false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruft eine Liste der als "hervorgehoben" markierten Produkte ab (z.B. f<>r die Startseite).
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Eine Liste von ProductDto-Objekten, sortiert nach ihrer Anzeigereihenfolge.</returns>
|
||||||
public async Task<ServiceResult<IEnumerable<ProductDto>>> GetFeaturedProductsAsync()
|
public async Task<ServiceResult<IEnumerable<ProductDto>>> GetFeaturedProductsAsync()
|
||||||
{
|
{
|
||||||
|
// Startet eine Abfrage auf die 'Products'-Tabelle.
|
||||||
var products = await _context.Products
|
var products = await _context.Products
|
||||||
|
// Filtert nur Produkte, die sowohl aktiv als auch als "featured" markiert sind.
|
||||||
.Where(p => p.IsActive && p.IsFeatured)
|
.Where(p => p.IsActive && p.IsFeatured)
|
||||||
|
// Sortiert die Ergebnisse nach der vom Admin festgelegten Reihenfolge.
|
||||||
.OrderBy(p => p.FeaturedDisplayOrder)
|
.OrderBy(p => p.FeaturedDisplayOrder)
|
||||||
|
// L<>dt die zugeh<65>rigen Bilder und Kategorien.
|
||||||
.Include(p => p.Images)
|
.Include(p => p.Images)
|
||||||
.Include(p => p.Productcategories).ThenInclude(pc => pc.categorie)
|
.Include(p => p.Productcategories).ThenInclude(pc => pc.categorie)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
// Wandelt die Entit<69>ten in DTOs um (mit kurzer Beschreibung).
|
||||||
var dtos = products.Select(p => MapToDto(p, useShortDescription: true)).ToList();
|
var dtos = products.Select(p => MapToDto(p, useShortDescription: true)).ToList();
|
||||||
|
|
||||||
return ServiceResult.Ok<IEnumerable<ProductDto>>(dtos);
|
return ServiceResult.Ok<IEnumerable<ProductDto>>(dtos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private Hilfsmethode, um Codeduplizierung zu vermeiden
|
/// <summary>
|
||||||
|
/// Private Hilfsmethode, um eine Product-Entit<69>t in ein ProductDto zu konvertieren.
|
||||||
|
/// Dies vermeidet Codeduplizierung und stellt eine konsistente Datenstruktur sicher.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="product">Die Product-Entit<69>t aus der Datenbank.</param>
|
||||||
|
/// <param name="useShortDescription">Gibt an, ob die Kurz- oder Langbeschreibung verwendet werden soll.</param>
|
||||||
|
/// <returns>Ein bef<65>lltes ProductDto-Objekt.</returns>
|
||||||
private ProductDto MapToDto(Product product, bool useShortDescription)
|
private ProductDto MapToDto(Product product, bool useShortDescription)
|
||||||
{
|
{
|
||||||
return new ProductDto
|
return new ProductDto
|
||||||
{
|
{
|
||||||
Id = product.Id,
|
Id = product.Id,
|
||||||
Name = product.Name,
|
Name = product.Name,
|
||||||
|
// W<>hlt die passende Beschreibung basierend auf dem 'useShortDescription'-Flag.
|
||||||
Description = useShortDescription ? product.ShortDescription : product.Description,
|
Description = useShortDescription ? product.ShortDescription : product.Description,
|
||||||
Price = product.Price,
|
Price = product.Price,
|
||||||
OldPrice = product.OldPrice,
|
OldPrice = product.OldPrice,
|
||||||
@@ -75,12 +123,14 @@ namespace Webshop.Application.Services.Public
|
|||||||
IsInStock = product.IsInStock,
|
IsInStock = product.IsInStock,
|
||||||
StockQuantity = product.StockQuantity,
|
StockQuantity = product.StockQuantity,
|
||||||
Slug = product.Slug,
|
Slug = product.Slug,
|
||||||
|
// Mappt die verkn<6B>pften Kategorien auf eine Liste von CategorieDto.
|
||||||
categories = product.Productcategories.Select(pc => new CategorieDto
|
categories = product.Productcategories.Select(pc => new CategorieDto
|
||||||
{
|
{
|
||||||
Id = pc.categorie.Id,
|
Id = pc.categorie.Id,
|
||||||
Name = pc.categorie.Name,
|
Name = pc.categorie.Name,
|
||||||
Slug = pc.categorie.Slug
|
Slug = pc.categorie.Slug
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
|
// Mappt die verkn<6B>pften Bilder, sortiert nach DisplayOrder, auf eine Liste von ProductImageDto.
|
||||||
Images = product.Images.OrderBy(i => i.DisplayOrder).Select(img => new ProductImageDto
|
Images = product.Images.OrderBy(i => i.DisplayOrder).Select(img => new ProductImageDto
|
||||||
{
|
{
|
||||||
Id = img.Id,
|
Id = img.Id,
|
||||||
|
|||||||
Reference in New Issue
Block a user