Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.controller;

import jakarta.validation.Valid;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.data;

import java.util.Arrays;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.data;

import java.util.Arrays;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.data;

import java.util.Arrays;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.data;

import java.util.Arrays;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.data;

import java.util.Arrays;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.dto.request;

import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.dto.response;

import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.entity;

import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.exception;

import org.springframework.http.HttpStatus;

import com.pbl.insaroad.global.exception.model.BaseErrorCode;

import lombok.AllArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.animalmission.service;

import java.util.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.game.controller;

import jakarta.validation.Valid;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import com.pbl.insaroad.domain.game.dto.request.GameRequest.CompleteRequest;
import com.pbl.insaroad.domain.game.dto.request.GameRequest.UnvisitedRequest;
import com.pbl.insaroad.domain.game.dto.response.GameResponse.GameProgressResponse;
import com.pbl.insaroad.domain.game.dto.response.GameResponse.UnvisitedResponse;
import com.pbl.insaroad.global.response.BaseResponse;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

@Tag(name = "Game", description = "게임 관련 API")
@RequestMapping("/api/games")
public interface GameController {

@PostMapping("/unvisited")
@Operation(
summary = "미방문 Location 전체 조회",
description = "사용자 기준으로 아직 방문하지 않은 Location 목록 전체를 반환합니다.")
ResponseEntity<BaseResponse<UnvisitedResponse>> unvisited(
@RequestBody @Valid UnvisitedRequest request);

@PostMapping("/complete")
@Operation(
summary = "게임 진행/완료 처리",
description =
"""
현재 Location 방문을 처리합니다.

- 미션이 아직 남아있는 경우:
사용자 방문 이력을 갱신하고, 아직 방문하지 않은 Location 목록을 반환합니다.

- 이번 방문으로 모든 Location을 방문한 경우:
미션을 완료 처리하고, 교환권 발급 정보를 함께 반환합니다.
""")
ResponseEntity<BaseResponse<GameProgressResponse>> complete(
@RequestBody @Valid CompleteRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.game.controller;

import jakarta.validation.Valid;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.pbl.insaroad.domain.game.dto.request.GameRequest.CompleteRequest;
import com.pbl.insaroad.domain.game.dto.request.GameRequest.UnvisitedRequest;
import com.pbl.insaroad.domain.game.dto.response.GameResponse.GameProgressResponse;
import com.pbl.insaroad.domain.game.dto.response.GameResponse.UnvisitedResponse;
import com.pbl.insaroad.domain.user.service.UserService;
import com.pbl.insaroad.global.response.BaseResponse;

import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
public class GameControllerImpl implements GameController {

private final UserService userService;

@Override
public ResponseEntity<BaseResponse<UnvisitedResponse>> unvisited(
@RequestBody @Valid UnvisitedRequest request) {
return ResponseEntity.ok(
BaseResponse.success(userService.getUnvisitedLocations(request.getUserCode())));
}

@Override
public ResponseEntity<BaseResponse<GameProgressResponse>> complete(
@RequestBody @Valid CompleteRequest request) {
return ResponseEntity.ok(BaseResponse.success(userService.completeGame(request)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.game.dto.request;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/** Game 관련 요청 DTO 모음 */
public class GameRequest {

/** 미방문 Location 전체 조회 요청 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class UnvisitedRequest {

@NotBlank private String userCode;
}

/** 게임 1회 완료 처리 요청 - 첫 시작이면 userCode = null 허용 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class CompleteRequest {

private String userCode;

@NotNull private Long currentLocationId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.game.dto.response;

import java.time.LocalDateTime;
import java.util.List;

import com.pbl.insaroad.domain.location.dto.LocationResponse;

import lombok.Builder;
import lombok.Getter;

/** Game 관련 응답 DTO 모음 */
public class GameResponse {

/** 미방문 Location 전체 조회 응답 */
@Getter
@Builder
public static class UnvisitedResponse {

private List<LocationResponse> unvisitedLocations;
}

/** 게임 1회 완료 처리 응답 - 사용자 코드 - 아직 방문하지 않은 Location 전체 */
@Getter
@Builder
public static class CompleteResponse {

private String userCode;
private List<LocationResponse> unvisitedLocations;
}

/** 전체 미션 완료 응답 (교환권 발급) */
@Getter
@Builder
public static class FinishResponse {

/** QR로 사용할 교환권 URL */
private String exchangeUrl;

/** 교환권 발급 시각 */
private LocalDateTime issuedAt;
}

@Getter
@Builder
public static class GameProgressResponse {

/** 이번 complete 처리로 전체 미션이 완료되었는지 여부 */
private boolean completed;

/** 미완료 시 채움 */
private CompleteResponse complete;

/** 완료 시 채움 (교환권 발급 정보) */
private FinishResponse finish;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.game.exception;

import org.springframework.http.HttpStatus;

import com.pbl.insaroad.global.exception.model.BaseErrorCode;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum GameErrorCode implements BaseErrorCode {
USER_CODE_REQUIRED("GAME001", "사용자 번호가 필요합니다.", HttpStatus.BAD_REQUEST),
USER_NOT_FOUND("GAME002", "사용자를 찾을 수 없습니다.", HttpStatus.NOT_FOUND),

LOCATION_NOT_FOUND("GAME010", "위치 정보를 찾을 수 없습니다.", HttpStatus.NOT_FOUND),

NOT_ALL_LOCATIONS_VISITED("GAME020", "아직 방문하지 않은 위치가 남아있습니다.", HttpStatus.CONFLICT);

private final String code;
private final String message;
private final HttpStatus status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.location.controller;

import jakarta.validation.Valid;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import com.pbl.insaroad.domain.location.dto.LocationResponse;
import com.pbl.insaroad.domain.location.dto.request.LocationRequest;
import com.pbl.insaroad.global.response.BaseResponse;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

@Tag(name = "Location", description = "Location 관련 API")
@RequestMapping("/api/locations")
public interface LocationController {

@PostMapping
@Operation(summary = "Location 생성", description = "Location을 생성합니다.")
ResponseEntity<BaseResponse<LocationResponse>> create(
@RequestBody @Valid LocationRequest.CreateLocationRequest request);

@DeleteMapping("/{id}")
@Operation(summary = "Location 삭제", description = "Location을 삭제합니다.")
ResponseEntity<BaseResponse<Void>> deleteById(@PathVariable("id") Long locationId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) SKU PBL Team4
*/
package com.pbl.insaroad.domain.location.controller;

import jakarta.validation.Valid;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.pbl.insaroad.domain.location.dto.LocationResponse;
import com.pbl.insaroad.domain.location.dto.request.LocationRequest.CreateLocationRequest;
import com.pbl.insaroad.domain.location.service.LocationService;
import com.pbl.insaroad.global.response.BaseResponse;

import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
public class LocationControllerImpl implements LocationController {

private final LocationService locationService;

@Override
public ResponseEntity<BaseResponse<LocationResponse>> create(
@RequestBody @Valid CreateLocationRequest request) {
return ResponseEntity.ok(BaseResponse.success(locationService.create(request)));
}

@Override
public ResponseEntity<BaseResponse<Void>> deleteById(@PathVariable("id") Long locationId) {
locationService.deleteById(locationId);
return ResponseEntity.ok(BaseResponse.success("Location이 성공적으로 삭제되었습니다.", null));
}
}
Loading
Loading