bild update
This commit is contained in:
@@ -1,13 +1,12 @@
|
||||
// src/Webshop.Api/Controllers/Admin/AdminProductsController.cs
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http; // F<>r IFormFile
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Webshop.Application.DTOs.Products;
|
||||
using Webshop.Application.Services.Admin.Interfaces;
|
||||
|
||||
namespace Webshop.Api.Controllers.Admin
|
||||
{
|
||||
[ApiController]
|
||||
@@ -38,20 +37,29 @@ namespace Webshop.Api.Controllers.Admin
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<AdminProductDto>> CreateAdminProduct([FromBody] CreateAdminProductDto productDto) // << ZUR<55>CK ZU [FromBody] >>
|
||||
[Consumes("multipart/form-data")]
|
||||
public async Task<ActionResult<AdminProductDto>> CreateAdminProduct([FromForm] CreateAdminProductDto productDto)
|
||||
{
|
||||
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||
|
||||
var createdProduct = await _adminProductService.CreateAdminProductAsync(productDto);
|
||||
if (createdProduct == null) return BadRequest("Produkt konnte nicht erstellt werden.");
|
||||
|
||||
return CreatedAtAction(nameof(GetAdminProduct), new { id = createdProduct.Id }, createdProduct);
|
||||
}
|
||||
|
||||
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> UpdateAdminProduct(Guid id, [FromBody] UpdateAdminProductDto productDto) // << ZUR<55>CK ZU [FromBody] >>
|
||||
[Consumes("multipart/form-data")]
|
||||
public async Task<IActionResult> UpdateAdminProduct(Guid id, [FromForm] UpdateAdminProductDto productDto)
|
||||
{
|
||||
if (id != productDto.Id) return BadRequest();
|
||||
if (id != productDto.Id) return BadRequest("ID in URL und Body stimmen nicht <20>berein.");
|
||||
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||
|
||||
var success = await _adminProductService.UpdateAdminProductAsync(productDto);
|
||||
|
||||
if (!success) return NotFound();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// src/Webshop.Application/DTOs/Products/CreateAdminProductDto.cs
|
||||
using Microsoft.AspNetCore.Http; // FÜR IFormFile
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
@@ -15,14 +16,13 @@ namespace Webshop.Application.DTOs.Products
|
||||
[Required]
|
||||
public decimal Price { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsInStock { get; set; } = true;
|
||||
public int StockQuantity { get; set; }
|
||||
[Required]
|
||||
public string Slug { get; set; }
|
||||
|
||||
// << KORREKTUR: Felder für Bild-URLs, keine IFormFile >>
|
||||
public string? MainImageUrl { get; set; }
|
||||
public List<string>? AdditionalImageUrls { get; set; }
|
||||
// << ZURÜCK ZU IFormFile >>
|
||||
public IFormFile? MainImageFile { get; set; }
|
||||
public List<IFormFile>? AdditionalImageFiles { get; set; }
|
||||
|
||||
public List<Guid> CategorieIds { get; set; } = new List<Guid>();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// src/Webshop.Application/DTOs/Products/UpdateAdminProductDto.cs
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
@@ -17,14 +18,14 @@ namespace Webshop.Application.DTOs.Products
|
||||
[Required]
|
||||
public decimal Price { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public bool IsInStock { get; set; }
|
||||
public int StockQuantity { get; set; }
|
||||
[Required]
|
||||
public string Slug { get; set; }
|
||||
|
||||
// << KORREKTUR: Felder für Bild-URLs >>
|
||||
public string? MainImageUrl { get; set; }
|
||||
public List<string>? AdditionalImageUrls { get; set; }
|
||||
// << ZURÜCK ZU IFormFile >>
|
||||
public IFormFile? MainImageFile { get; set; }
|
||||
public List<IFormFile>? AdditionalImageFiles { get; set; }
|
||||
public List<Guid>? ImagesToDelete { get; set; }
|
||||
|
||||
public List<Guid> CategorieIds { get; set; } = new List<Guid>();
|
||||
|
||||
|
||||
@@ -15,13 +15,16 @@ namespace Webshop.Application.Services.Admin
|
||||
public class AdminProductService : IAdminProductService
|
||||
{
|
||||
private readonly IProductRepository _productRepository;
|
||||
private readonly IFileStorageService _fileStorageService;
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public AdminProductService(
|
||||
IProductRepository productRepository,
|
||||
IFileStorageService fileStorageService,
|
||||
ApplicationDbContext context)
|
||||
{
|
||||
_productRepository = productRepository;
|
||||
_fileStorageService = fileStorageService;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
@@ -102,15 +105,21 @@ namespace Webshop.Application.Services.Admin
|
||||
{
|
||||
var images = new List<ProductImage>();
|
||||
|
||||
if (!string.IsNullOrEmpty(productDto.MainImageUrl))
|
||||
// Hauptbild hochladen
|
||||
if (productDto.MainImageFile != null)
|
||||
{
|
||||
images.Add(new ProductImage { Url = productDto.MainImageUrl, IsMainImage = true, DisplayOrder = 1 });
|
||||
await using var stream = productDto.MainImageFile.OpenReadStream();
|
||||
var url = await _fileStorageService.SaveFileAsync(stream, productDto.MainImageFile.FileName, productDto.MainImageFile.ContentType);
|
||||
images.Add(new ProductImage { Url = url, IsMainImage = true, DisplayOrder = 1 });
|
||||
}
|
||||
if (productDto.AdditionalImageUrls != null)
|
||||
// Weitere Bilder hochladen
|
||||
if (productDto.AdditionalImageFiles != null)
|
||||
{
|
||||
int order = 2;
|
||||
foreach (var url in productDto.AdditionalImageUrls)
|
||||
foreach (var file in productDto.AdditionalImageFiles)
|
||||
{
|
||||
await using var stream = file.OpenReadStream();
|
||||
var url = await _fileStorageService.SaveFileAsync(stream, file.FileName, file.ContentType);
|
||||
images.Add(new ProductImage { Url = url, IsMainImage = false, DisplayOrder = order++ });
|
||||
}
|
||||
}
|
||||
@@ -146,6 +155,34 @@ namespace Webshop.Application.Services.Admin
|
||||
|
||||
if (existingProduct == null) return false;
|
||||
|
||||
// Bilder l<>schen
|
||||
if (productDto.ImagesToDelete != null && productDto.ImagesToDelete.Any())
|
||||
{
|
||||
var imagesToRemove = existingProduct.Images.Where(img => productDto.ImagesToDelete.Contains(img.Id)).ToList();
|
||||
_context.ProductImages.RemoveRange(imagesToRemove);
|
||||
}
|
||||
// Hauptbild aktualisieren/hochladen
|
||||
if (productDto.MainImageFile != null)
|
||||
{
|
||||
var existingMainImage = existingProduct.Images.FirstOrDefault(img => img.IsMainImage);
|
||||
if (existingMainImage != null) _context.ProductImages.Remove(existingMainImage);
|
||||
|
||||
await using var stream = productDto.MainImageFile.OpenReadStream();
|
||||
var url = await _fileStorageService.SaveFileAsync(stream, productDto.MainImageFile.FileName, productDto.MainImageFile.ContentType);
|
||||
existingProduct.Images.Add(new ProductImage { Url = url, IsMainImage = true, DisplayOrder = 1 });
|
||||
}
|
||||
// Weitere Bilder hinzuf<75>gen
|
||||
if (productDto.AdditionalImageFiles != null && productDto.AdditionalImageFiles.Any())
|
||||
{
|
||||
int displayOrder = (existingProduct.Images.Any() ? existingProduct.Images.Max(i => i.DisplayOrder) : 0) + 1;
|
||||
foreach (var file in productDto.AdditionalImageFiles)
|
||||
{
|
||||
await using var stream = file.OpenReadStream();
|
||||
var url = await _fileStorageService.SaveFileAsync(stream, file.FileName, file.ContentType);
|
||||
existingProduct.Images.Add(new ProductImage { Url = url, IsMainImage = false, DisplayOrder = displayOrder++ });
|
||||
}
|
||||
}
|
||||
|
||||
// Basisdaten aktualisieren
|
||||
existingProduct.Name = productDto.Name;
|
||||
existingProduct.Description = productDto.Description;
|
||||
@@ -170,21 +207,6 @@ namespace Webshop.Application.Services.Admin
|
||||
}
|
||||
}
|
||||
|
||||
// Bilder synchronisieren
|
||||
existingProduct.Images.Clear();
|
||||
if (!string.IsNullOrEmpty(productDto.MainImageUrl))
|
||||
{
|
||||
existingProduct.Images.Add(new ProductImage { Url = productDto.MainImageUrl, IsMainImage = true, DisplayOrder = 1 });
|
||||
}
|
||||
if (productDto.AdditionalImageUrls != null)
|
||||
{
|
||||
int order = 2;
|
||||
foreach (var url in productDto.AdditionalImageUrls)
|
||||
{
|
||||
existingProduct.Images.Add(new ProductImage { Url = url, IsMainImage = false, DisplayOrder = order++ });
|
||||
}
|
||||
}
|
||||
|
||||
await _productRepository.UpdateProductAsync(existingProduct);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user