Skip to content
Open
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
7 changes: 7 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ dependencies {
// Spring Test 의존성 추가
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'

//QueryDsl 의존성 추가
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

}

tasks.named('test') {
Expand Down
89 changes: 89 additions & 0 deletions src/main/java/one/kiosk/controller/MenuController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package one.kiosk.controller;

import lombok.RequiredArgsConstructor;
import one.kiosk.dto.ApiResponse;
import one.kiosk.dto.MenuReturnDto;
import one.kiosk.dto.MenuUpdateDto;
import one.kiosk.dto.MenuUploadDto;
import one.kiosk.entity.MenuEntity;
import one.kiosk.exception.GlobalExceptionHandler;
import one.kiosk.service.MenuService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/menu")
public class MenuController {

private final MenuService menuService;

//메뉴 등록
@PostMapping("/upload")
public ResponseEntity<ApiResponse<String>> upload(@RequestHeader("Authorization") String token, @RequestBody MenuUploadDto menuUploadDto) {

//토큰의 "Bearer " 지우기
String tokenId = token.replace("Bearer ", "");

menuService.upload(menuUploadDto, tokenId);
//메뉴 등록 성공
return ResponseEntity.status(HttpStatus.CREATED)
.body(new ApiResponse<>(true,"메뉴가 등록되었습니다.",null));
}

//메뉴 검색
@GetMapping("search/{id}")
public ResponseEntity<ApiResponse<MenuReturnDto>> upload(@RequestHeader("Authorization") String token,@PathVariable Long id) {

//토큰의 "Bearer " 지우기
String tokenId = token.replace("Bearer ", "");

MenuReturnDto menuReturnDto = menuService.find(id,tokenId);

if (menuReturnDto == null) {
throw new GlobalExceptionHandler.MenuNotFoundException("메뉴를 찾을 수 없습니다");
}

//메뉴 검색 성공
return ResponseEntity.status(HttpStatus.OK)
.body(new ApiResponse<>(true,"메뉴 정보를 조회합니다",menuReturnDto));
}

//메뉴 전체조회
@GetMapping("/total")
public ResponseEntity<ApiResponse<List<MenuReturnDto>>> total(@RequestHeader("Authorization") String token) {
//토큰의 "Bearer " 지우기
String tokenId = token.replace("Bearer ", "");
List<MenuReturnDto> menuDtos = menuService.findAll(tokenId);

return ResponseEntity.status(HttpStatus.OK)
.body(new ApiResponse<>(true,"전체 메뉴를 조회합니다",menuDtos));
}

//메뉴 수정
@PutMapping("/update")
public ResponseEntity<ApiResponse<String>> update(@RequestHeader("Authorization") String token, @RequestBody MenuUpdateDto menuUpdateDto) {
//토큰의 "Bearer " 지우기
String tokenId = token.replace("Bearer ", "");
menuService.update(menuUpdateDto,tokenId);
//수정 완료
return ResponseEntity.status(HttpStatus.OK)
.body(new ApiResponse<>(true,"메뉴정보 수정이 완료되었습니다.",null));
}

//메뉴 삭제
@DeleteMapping("/delete/{id}")
public ResponseEntity<ApiResponse<String>> delete(@RequestHeader("Authorization") String token, @PathVariable Long id) {
//토큰의 "Bearer " 지우기
String tokenId = token.replace("Bearer ", "");
menuService.delete(id,tokenId);
//삭제 성공
return ResponseEntity.status(HttpStatus.OK)
.body(new ApiResponse<>(true,"메뉴를 삭제하였습니다.",null));
}
}
12 changes: 12 additions & 0 deletions src/main/java/one/kiosk/dto/ApiResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package one.kiosk.dto;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class ApiResponse<T> {
private boolean success;
private String message;
private T data;
}
13 changes: 13 additions & 0 deletions src/main/java/one/kiosk/dto/InfoDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package one.kiosk.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import one.kiosk.jwt.MemberRole;

@Data
@AllArgsConstructor
public class InfoDto {
private String username;
private String company;
private MemberRole role;
}
19 changes: 19 additions & 0 deletions src/main/java/one/kiosk/dto/MenuOptionReturnDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package one.kiosk.dto;

import lombok.*;
import one.kiosk.entity.MenuOptionEntity;

@Data
@NoArgsConstructor
@Getter
@Setter
public class MenuOptionReturnDto {
private String optionname;
private int price;

public MenuOptionReturnDto(String optionname, int price) {
this.optionname = optionname;
this.price = price;
}
}

42 changes: 42 additions & 0 deletions src/main/java/one/kiosk/dto/MenuReturnDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package one.kiosk.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import one.kiosk.entity.MenuEntity;
import one.kiosk.jwt.JWTUtil;

import java.util.List;

@Data
@NoArgsConstructor
public class MenuReturnDto {

private String menuname;
private int price;
private String category;
private String imageUrl;
private List<MenuOptionReturnDto> option;

// 생성자(전체조회용)
public MenuReturnDto(String menuname, int price, String category, String imgUrl, List<MenuOptionReturnDto> menuOptions) {
this.menuname = menuname;
this.price = price;
this.category = category;
this.imageUrl = imgUrl;
this.option = menuOptions;
}
//메뉴 entity와 검색을 통해 나온 이미지의 url을 함께 dto에 저장. 전체 메뉴옵션을 함께 리턴(단일조회용)
public static MenuReturnDto toMenuReturnDto(MenuEntity menuEntity, String imageUrl, List<MenuOptionReturnDto> optionReturnDto) {
MenuReturnDto dto = new MenuReturnDto();
dto.setMenuname(menuEntity.getMenuname());
dto.setPrice(menuEntity.getPrice());
dto.setCategory(menuEntity.getCategory());
dto.setImageUrl(imageUrl);
dto.setOption(optionReturnDto);
return dto;
}

}

18 changes: 18 additions & 0 deletions src/main/java/one/kiosk/dto/MenuUpdateDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package one.kiosk.dto;

import lombok.*;
import one.kiosk.entity.MenuEntity;

@Data
@AllArgsConstructor
@Getter
@Builder
public class MenuUpdateDto {

private Long id;
private String menuname;
private int price;
private String category;
private Long imageId;

}
32 changes: 32 additions & 0 deletions src/main/java/one/kiosk/dto/MenuUploadDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package one.kiosk.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import one.kiosk.entity.Image;
import one.kiosk.entity.MenuEntity;
import one.kiosk.jwt.JWTUtil;

@Data
@AllArgsConstructor
@Builder
public class MenuUploadDto {
private String menuname;
private int price;
private String category;
private Long adminId;
private Image imageId;


public MenuEntity toMenuEntity() {
return MenuEntity.builder()
.menuname(this.menuname)
.price(this.price)
.category(this.category)
.adminId(this.adminId)
.imageId(this.imageId).build();
}

}

47 changes: 47 additions & 0 deletions src/main/java/one/kiosk/entity/MenuEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package one.kiosk.entity;

import jakarta.persistence.*;
import lombok.*;
import one.kiosk.jwt.MemberRole;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;

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

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@Getter
@Setter
@Table(name = "tbl_menu")
public class MenuEntity extends DateEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "menu_id")
private Long menuId;

@Column(name = "menuname", nullable = false)
private String menuname;

@Column(name = "price", nullable = false)
private int price;

@Column(name = "category", nullable = false)
private String category;

//jwt 토큰에서 추출한 id를 저장
@Column(name = "admin_id", nullable = false)
private Long adminId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "image_id") // 외래키 설정
private Image imageId;




}
23 changes: 23 additions & 0 deletions src/main/java/one/kiosk/entity/MenuOptionEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package one.kiosk.entity;

import jakarta.persistence.*;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Data
@Entity
@Table(name = "tbl_menuoption")
public class MenuOptionEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "menuop_id")
private Long menuopid;

@Column(name = "optionname")
private String optionname;

@Column(name = "price")
private int price;

}
61 changes: 61 additions & 0 deletions src/main/java/one/kiosk/exception/GlobalExceptionHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,31 @@ public CustomAuthenticationException(String message) {
}
}

// 내부 클래스 : 메뉴 crud 예외들
public static class MenuUplaodException extends RuntimeException {
public MenuUplaodException(String message) {super(message);}
}

public static class MenuNotFoundException extends RuntimeException {
public MenuNotFoundException(String message) {super(message);}
}

public static class MenuNotExistException extends RuntimeException {
public MenuNotExistException(String message) {super(message);}
}

public static class MenuUpdateException extends RuntimeException {
public MenuUpdateException(String message) {super(message);}
}

public static class MenuDeleteException extends RuntimeException {
public MenuDeleteException(String message) {super(message);}
}

public static class UserUnmatchException extends RuntimeException {
public UserUnmatchException(String message) {super(message);}
}

// 예외 처리 메서드들
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ApiMessageResponse> handleUserNotFoundException(UserNotFoundException ex) {
Expand Down Expand Up @@ -105,4 +130,40 @@ public ResponseEntity<ApiMessageResponse> handleGeneralException(Exception ex) {
logger.error("Unhandled Exception: ", ex);
return createResponse(HttpStatus.INTERNAL_SERVER_ERROR, "서버 내부 오류가 발생했습니다.");
}

@ExceptionHandler(MenuUplaodException.class)
public ResponseEntity<ApiMessageResponse> handleMenuUplaodException(MenuUplaodException ex) {
logger.error("MenuUplaodException: ", ex);
return createResponse(HttpStatus.BAD_REQUEST,"메뉴 등록에 실패하였습니다.");
}

@ExceptionHandler(MenuNotFoundException.class)
public ResponseEntity<ApiMessageResponse> handleMenuNotFoundException(MenuNotFoundException ex) {
logger.error("MenuNotFoundException: ", ex);
return createResponse(HttpStatus.NOT_FOUND,ex.getMessage());
}

@ExceptionHandler(MenuNotExistException.class)
public ResponseEntity<ApiMessageResponse> handleMenuNotExistException(MenuNotExistException ex) {
logger.error("MenuNotExistException: ", ex);
return createResponse(HttpStatus.NOT_FOUND,"등록된 메뉴가 없습니다.");
}

@ExceptionHandler(MenuUpdateException.class)
public ResponseEntity<ApiMessageResponse> handleMenuUpdateException(MenuUpdateException ex) {
logger.error("MenuUpdateException: ", ex);
return createResponse(HttpStatus.BAD_REQUEST, "메뉴를 수정하지 못했습니다");
}

@ExceptionHandler(MenuDeleteException.class)
public ResponseEntity<ApiMessageResponse> handleMenuDeleteException(MenuDeleteException ex) {
logger.error("MenuDeleteException: ", ex);
return createResponse(HttpStatus.BAD_REQUEST,"메뉴를 삭제하지 못했습니다.");
}

@ExceptionHandler(UserUnmatchException.class)
public ResponseEntity<ApiMessageResponse> handleUserUnmatchException(UserUnmatchException ex) {
logger.error("UserUnmatchException : ", ex);
return createResponse(HttpStatus.BAD_REQUEST,"해당 메뉴에 접근 권한이 없습니다.");
}
}
Loading