diff --git a/src/main/java/kz/konturai/parser/controller/MarketingController.java b/src/main/java/kz/konturai/parser/controller/MarketingController.java index 3fad309..fe52f24 100644 --- a/src/main/java/kz/konturai/parser/controller/MarketingController.java +++ b/src/main/java/kz/konturai/parser/controller/MarketingController.java @@ -847,6 +847,72 @@ public class MarketingController { .body(ApiResponse.error("Ошибка валидации", errorResponse)); } + @PostMapping("/strategy/{strategyId}/post/{postIndex}/regenerate-image") + public ResponseEntity regeneratePostImage( + @RequestHeader(value = "Authorization", required = false) String authHeader, + @PathVariable String strategyId, + @PathVariable int postIndex) { + + String userId = extractUserIdFromHeader(authHeader); + if (userId == null) { + return unauthorizedResponse(); + } + + // Проверяем существование стратегии и права доступа + Optional optStrategy = marketingStrategyService.getStrategyById(strategyId); + if (optStrategy.isEmpty()) { + ErrorResponse error = new ErrorResponse( + "NOT_FOUND", + "Стратегия с указанным ID не найдена"); + return ResponseEntity.status(404) + .body(ApiResponse.error("Стратегия не найдена", error)); + } + + MarketingStrategy strategy = optStrategy.get(); + if (!userId.equals(strategy.getUserId())) { + ErrorResponse error = new ErrorResponse( + "FORBIDDEN", + "У вас нет доступа к этой стратегии"); + return ResponseEntity.status(HttpStatus.FORBIDDEN) + .body(ApiResponse.error("Доступ запрещен", error)); + } + + try { + // Регенерируем изображение + MarketingStrategy.PostCalendarItem updatedItem = marketingStrategyService + .regeneratePostImage(strategyId, postIndex); + + if (updatedItem == null) { + ErrorResponse error = new ErrorResponse( + "INVALID_POST_INDEX", + "Пост с указанным индексом не найден в стратегии"); + return ResponseEntity.status(404) + .body(ApiResponse.error("Пост не найден", error)); + } + + // Формируем ответ с обновленными данными поста + Map responseData = new HashMap<>(); + responseData.put("strategyId", strategyId); + responseData.put("postIndex", postIndex); + responseData.put("imageUrl", updatedItem.getImageUrl()); + responseData.put("imageFilename", updatedItem.getImageFilename()); + responseData.put("theme", updatedItem.getTheme()); + responseData.put("platform", updatedItem.getPlatform()); + responseData.put("publishDate", updatedItem.getPublishDate()); + + return ResponseEntity.ok(ApiResponse.success( + "Изображение для поста успешно регенерировано", + responseData)); + } catch (Exception e) { + logger.error("Error regenerating post image: {}", e.getMessage(), e); + ErrorResponse error = new ErrorResponse( + "INTERNAL_SERVER_ERROR", + "Произошла ошибка при регенерации изображения"); + return ResponseEntity.status(500) + .body(ApiResponse.error("Внутренняя ошибка сервера", error)); + } + } + @ExceptionHandler(Exception.class) public ResponseEntity> handleGenericException(Exception e) { logger.error("Unhandled exception in MarketingController: {}", e.getMessage(), e); diff --git a/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java b/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java index 7aa6e1e..9563c5f 100644 --- a/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java +++ b/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java @@ -669,4 +669,47 @@ public class MarketingStrategyService { public Optional getStrategyById(String strategyId) { return repository.findById(strategyId); } + + /** + * Регенерирует изображение для указанного поста в стратегии + * + * @param strategyId ID стратегии + * @param postIndex Индекс поста в списке postCalendar (начиная с 0) + * @return Обновленный элемент календаря постов с новым изображением, или null + * если пост не найден + */ + public MarketingStrategy.PostCalendarItem regeneratePostImage(String strategyId, int postIndex) { + Optional optStrategy = repository.findById(strategyId); + if (optStrategy.isEmpty()) { + logger.error("Strategy not found: {}", strategyId); + return null; + } + + MarketingStrategy strategy = optStrategy.get(); + List postCalendar = strategy.getPostCalendar(); + + if (postCalendar == null || postIndex < 0 || postIndex >= postCalendar.size()) { + logger.error("Invalid post index {} for strategy {}. Calendar size: {}", + postIndex, strategyId, postCalendar != null ? postCalendar.size() : 0); + return null; + } + + MarketingStrategy.PostCalendarItem item = postCalendar.get(postIndex); + + // Get business context for image generation + String businessContext = getBusinessContextFromAnalysis(strategy.getAnalysisId()); + + // Note: Old image file is not deleted (MinIO doesn't have deleteFile method) + // New image will have a different filename, so old file will remain but won't + // be used + + // Generate new image + generateAndSaveImageForPost(item, businessContext); + + // Save updated strategy + repository.save(strategy); + + logger.info("Successfully regenerated image for post at index {} in strategy {}", postIndex, strategyId); + return item; + } }