|
|
@@ -1,20 +1,63 @@
|
|
|
package pl.dmss.vmaneliuk.database.controllers;
|
|
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
import org.springframework.http.ResponseEntity;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+import pl.dmss.vmaneliuk.database.model.Developer;
|
|
|
import pl.dmss.vmaneliuk.database.model.Game;
|
|
|
+import pl.dmss.vmaneliuk.database.model.User;
|
|
|
+import pl.dmss.vmaneliuk.database.model.BugReport;
|
|
|
import pl.dmss.vmaneliuk.database.services.GameService;
|
|
|
+import pl.dmss.vmaneliuk.database.services.BugReportService;
|
|
|
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Path;
|
|
|
+import java.nio.file.Paths;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.UUID;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@RestController
|
|
|
@RequestMapping("/api/games")
|
|
|
+@CrossOrigin(origins = "http://localhost:4200")
|
|
|
public class GameController {
|
|
|
|
|
|
private final GameService gameService;
|
|
|
|
|
|
- public GameController(GameService gameService) {
|
|
|
+ private final BugReportService bugReportService;
|
|
|
+ private final String UPLOAD_DIRECTORY = "uploads";
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public GameController(GameService gameService, BugReportService bugReportService) {
|
|
|
this.gameService = gameService;
|
|
|
+ this.bugReportService = bugReportService;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @GetMapping("/{gameId}/reports")
|
|
|
+ public ResponseEntity<List<BugReport>> getReportsByGame(@PathVariable Long gameId) {
|
|
|
+ // Student Note: We grab all reports and filter out only those matching our gameId
|
|
|
+ List<BugReport> gameReports = bugReportService.getAllReports().stream()
|
|
|
+ .filter(report -> report.getGame() != null && report.getGame().getGameId().equals(gameId))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ return ResponseEntity.ok(gameReports);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @PutMapping("/{gameId}/reports/{reportId}/status")
|
|
|
+ public ResponseEntity<BugReport> updateReportStatusFromGameContext(
|
|
|
+ @PathVariable Long gameId,
|
|
|
+ @PathVariable Long reportId,
|
|
|
+ @RequestParam String status) {
|
|
|
+
|
|
|
+ BugReport updatedReport = bugReportService.updateReportStatus(reportId, status);
|
|
|
+ return ResponseEntity.ok(updatedReport);
|
|
|
}
|
|
|
|
|
|
@GetMapping
|
|
|
@@ -22,9 +65,114 @@ public class GameController {
|
|
|
return ResponseEntity.ok(gameService.getAllGames());
|
|
|
}
|
|
|
|
|
|
- @PostMapping
|
|
|
- public ResponseEntity<Game> createGame(@RequestBody Game game) {
|
|
|
- Game savedGame = gameService.createGame(game);
|
|
|
- return ResponseEntity.ok(savedGame);
|
|
|
+ @PostMapping(consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
|
|
|
+ public ResponseEntity<?> createGame(
|
|
|
+ @RequestPart("game") String gameJson,
|
|
|
+ @RequestPart(value = "image", required = false) MultipartFile file) {
|
|
|
+ try {
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+ objectMapper.registerModule(new com.fasterxml.jackson.datatype.jsr310.JavaTimeModule());
|
|
|
+
|
|
|
+ Game game = objectMapper.readValue(gameJson, Game.class);
|
|
|
+
|
|
|
+ if (game.getDeveloper() == null || game.getDeveloper().getDeveloperId() == null) {
|
|
|
+ Developer defaultDev = new Developer();
|
|
|
+ defaultDev.setDeveloperId(1L);
|
|
|
+ game.setDeveloper(defaultDev);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (file != null && !file.isEmpty()) {
|
|
|
+ File directory = new File(UPLOAD_DIRECTORY);
|
|
|
+ if (!directory.exists()) {
|
|
|
+ directory.mkdirs();
|
|
|
+ }
|
|
|
+
|
|
|
+ String uniqueFilename = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
|
|
|
+ Path filePath = Paths.get(UPLOAD_DIRECTORY, uniqueFilename);
|
|
|
+ Files.copy(file.getInputStream(), filePath);
|
|
|
+
|
|
|
+ game.setImagePath("/uploads/" + uniqueFilename);
|
|
|
+ }
|
|
|
+
|
|
|
+ Game savedGame = gameService.createGame(game);
|
|
|
+ return ResponseEntity.ok(savedGame);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.err.println("CRITICAL PERSISTENCE FAULT DETECTED:");
|
|
|
+ e.printStackTrace();
|
|
|
+ return ResponseEntity.status(500).body("Server internal mapping fault: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @PutMapping(value = "/{id}", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
|
|
|
+ public ResponseEntity<Game> updateGame(
|
|
|
+ @PathVariable("id") Long id,
|
|
|
+ @RequestPart("game") String gameJson,
|
|
|
+ @RequestPart(value = "image", required = false) MultipartFile file) {
|
|
|
+ try {
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+ objectMapper.registerModule(new com.fasterxml.jackson.datatype.jsr310.JavaTimeModule());
|
|
|
+ objectMapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
|
|
+
|
|
|
+ Game updatedGame = objectMapper.readValue(gameJson, Game.class);
|
|
|
+ Game currentDatabaseState = gameService.getGameById(id)
|
|
|
+ .orElseThrow(() -> new RuntimeException("Target record execution fault. Missing target link: " + id));
|
|
|
+
|
|
|
+ if (file != null && !file.isEmpty()) {
|
|
|
+ File directory = new File(UPLOAD_DIRECTORY);
|
|
|
+ if (!directory.exists()) directory.mkdirs();
|
|
|
+
|
|
|
+ String uniqueFilename = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
|
|
|
+ Path filePath = Paths.get(UPLOAD_DIRECTORY, uniqueFilename);
|
|
|
+ Files.copy(file.getInputStream(), filePath);
|
|
|
+
|
|
|
+ updatedGame.setImagePath("/uploads/" + uniqueFilename);
|
|
|
+ } else {
|
|
|
+ updatedGame.setImagePath(currentDatabaseState.getImagePath());
|
|
|
+ }
|
|
|
+
|
|
|
+ Game finalizedResult = gameService.updateGame(id, updatedGame);
|
|
|
+ return ResponseEntity.ok(finalizedResult);
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.err.println("Execution fault inside alteration network sequence: " + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ return ResponseEntity.internalServerError().build();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/{gameId}/developer")
|
|
|
+ public ResponseEntity<Developer> getGameDeveloper(@PathVariable Long gameId) {
|
|
|
+ return gameService.getGameById(gameId)
|
|
|
+ .map(game -> ResponseEntity.ok(game.getDeveloper()))
|
|
|
+ .orElse(ResponseEntity.notFound().build());
|
|
|
+ }
|
|
|
+
|
|
|
+ @DeleteMapping("/{id}")
|
|
|
+ public ResponseEntity<Void> deleteGame(@PathVariable("id") Long id) {
|
|
|
+ try {
|
|
|
+ gameService.deleteGame(id);
|
|
|
+ return ResponseEntity.noContent().build();
|
|
|
+ } catch (Exception e) {
|
|
|
+ return ResponseEntity.notFound().build();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/{id}")
|
|
|
+ public ResponseEntity<Game> getGameById(@PathVariable Long id) {
|
|
|
+ return gameService.getGameById(id)
|
|
|
+ .map(ResponseEntity::ok)
|
|
|
+ .orElse(ResponseEntity.notFound().build());
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping("/{id}/buy")
|
|
|
+ public ResponseEntity<?> buyGame(@PathVariable Long id, @RequestParam Long userId) {
|
|
|
+ try {
|
|
|
+ User updatedUser = gameService.processGamePurchase(id, userId);
|
|
|
+ return ResponseEntity.ok(new pl.dmss.vmaneliuk.database.model.UserProfileResponse(updatedUser));
|
|
|
+ } catch (IllegalArgumentException e) {
|
|
|
+ return ResponseEntity.badRequest().body(Map.of("error", e.getMessage(), "reason", "INSUFFICIENT_FUNDS"));
|
|
|
+ } catch (RuntimeException e) {
|
|
|
+ return ResponseEntity.status(404).body(Map.of("error", e.getMessage(), "reason", "NOT_FOUND"));
|
|
|
+ }
|
|
|
}
|
|
|
}
|