diff --git a/.idea/modules.xml b/.idea/modules.xml index 7f32e8df..94f9a64b 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,7 +3,6 @@ - diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/dto/TokenDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/dto/TokenDto.java deleted file mode 100644 index 52008e93..00000000 --- a/server/008main_project/src/main/java/com/stockholm/main_project/auth/dto/TokenDto.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.stockholm.main_project.auth.dto; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -public class TokenDto { - - @AllArgsConstructor - @Getter - public static class Response { - private String accessToken; - private String refreshToken; - } -} \ No newline at end of file diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtAuthenticationFilter.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtAuthenticationFilter.java index 0837423c..4dcf75d2 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtAuthenticationFilter.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtAuthenticationFilter.java @@ -61,7 +61,6 @@ protected void successfulAuthentication(HttpServletRequest request, private String delegateAccessToken(Member member) { Map claims = new HashMap<>(); claims.put("memberId", member.getMemberId()); //Context에 member객체를 올려두기 위해 추가 - claims.put("email", member.getEmail()); claims.put("roles", member.getRoles()); String subject = member.getEmail(); @@ -75,11 +74,15 @@ private String delegateAccessToken(Member member) { } private String delegateRefreshToken(Member member) { + Map claims = new HashMap<>(); + claims.put("memberId", member.getMemberId()); + claims.put("roles", member.getRoles()); + String subject = member.getEmail(); Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getRefreshTokenExpirationMinutes()); String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); - String refreshToken = jwtTokenizer.generateRefreshToken(subject, expiration, base64EncodedSecretKey); + String refreshToken = jwtTokenizer.generateRefreshToken(claims, subject, expiration, base64EncodedSecretKey); return refreshToken; } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtVerificationFilter.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtVerificationFilter.java index 6a4a7886..24ac505f 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtVerificationFilter.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtVerificationFilter.java @@ -5,6 +5,7 @@ import com.stockholm.main_project.member.entity.Member; import com.stockholm.main_project.member.service.MemberService; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; @@ -16,10 +17,13 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; @Slf4j +@Configuration public class JwtVerificationFilter extends OncePerRequestFilter { private final JwtTokenizer jwtTokenizer; private final CustomAuthorityUtils authorityUtils; @@ -36,6 +40,7 @@ public JwtVerificationFilter(JwtTokenizer jwtTokenizer, @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { Map claims = verifyJws(request); + setAuthenticationToContext(claims); filterChain.doFilter(request, response); } @@ -63,4 +68,20 @@ private void setAuthenticationToContext(Map claims) { Authentication authentication = new UsernamePasswordAuthenticationToken(member, null, authorities); SecurityContextHolder.getContext().setAuthentication(authentication); } + + public String generateAccessTokenFromRefreshToken(Map claims) { + String subject = (String) claims.get("email"); + + Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getAccessTokenExpirationMinutes()); + String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); + + Map accessTokenClaims = new HashMap<>(); + accessTokenClaims.put("email", subject); + accessTokenClaims.put("memberId", claims.get("memberId")); + accessTokenClaims.put("roles", claims.get("roles")); + + String newAccessToken = jwtTokenizer.generateAccessToken(accessTokenClaims, subject, expiration, base64EncodedSecretKey); + + return newAccessToken; + } } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/OAuth2AuthenticationSuccessHandler.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/OAuth2AuthenticationSuccessHandler.java index ae42c29a..4d23d182 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/OAuth2AuthenticationSuccessHandler.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/OAuth2AuthenticationSuccessHandler.java @@ -48,7 +48,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo // 액세스 토큰 및 리프레시 토큰 생성 String accessToken = delegateAccessToken(email, authorities); - String refreshToken = delegateRefreshToken(email); + String refreshToken = delegateRefreshToken(email, authorities); // 헤더에 토큰 추가 response.addHeader("Authorization", "Bearer " + accessToken); @@ -60,7 +60,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo private void redirect(HttpServletRequest request, HttpServletResponse response, String username, List authorities) throws IOException { String accessToken = delegateAccessToken(username, authorities); - String refreshToken = delegateRefreshToken(username); + String refreshToken = delegateRefreshToken(username, authorities); String uri = createURI(accessToken, refreshToken).toString(); getRedirectStrategy().sendRedirect(request, response, uri); @@ -85,14 +85,19 @@ private String delegateAccessToken(String username, List authorities) { return accessToken; } - private String delegateRefreshToken(String username) { + private String delegateRefreshToken(String username, List authorities) { + int memberId = memberService.findMemberIdByEmail(username); + Map claims = new HashMap<>(); + claims.put("email", username); + claims.put("roles", authorities); + claims.put("memberId", memberId); String subject = username; Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getRefreshTokenExpirationMinutes()); String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); - String refreshToken = jwtTokenizer.generateRefreshToken(subject, expiration, base64EncodedSecretKey); + String refreshToken = jwtTokenizer.generateRefreshToken(claims, subject, expiration, base64EncodedSecretKey); return refreshToken; } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/JwtTokenizer.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/JwtTokenizer.java index 8049e974..0db27e68 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/JwtTokenizer.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/JwtTokenizer.java @@ -53,10 +53,11 @@ public String generateAccessToken(Map claims, .compact(); } - public String generateRefreshToken(String subject, Date expiration, String base64EncodedSecretKey){ + public String generateRefreshToken(Map claims, String subject, Date expiration, String base64EncodedSecretKey){ Key key = getKeyFromBase64EncodedKey(base64EncodedSecretKey); return Jwts.builder() + .setClaims(claims) .setSubject(subject) .setIssuedAt(Calendar.getInstance().getTime()) .setExpiration(expiration) diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/refreshToken/RefreshTokenService.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/refreshToken/RefreshTokenService.java new file mode 100644 index 00000000..19b47204 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/refreshToken/RefreshTokenService.java @@ -0,0 +1,49 @@ +package com.stockholm.main_project.auth.jwt.refreshToken; + +import com.stockholm.main_project.auth.filter.JwtVerificationFilter; +import com.stockholm.main_project.auth.jwt.JwtTokenizer; +import com.stockholm.main_project.exception.BusinessLogicException; +import com.stockholm.main_project.exception.ExceptionCode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service +public class RefreshTokenService { + + @Autowired + private JwtTokenizer jwtTokenizer; + + private final JwtVerificationFilter jwtVerificationFilter; + + public RefreshTokenService(JwtVerificationFilter jwtVerificationFilter) { + this.jwtVerificationFilter = jwtVerificationFilter; + } + + public String requestNewAccessToken(String refreshToken) throws Exception { + // 리프레시 토큰을 검증하고, 필요한 클레임을 추출합니다. + Map refreshTokenClaims = validateRefreshToken(refreshToken); + + // 새로운 액세스 토큰을 생성합니다. + String newAccessToken = jwtVerificationFilter.generateAccessTokenFromRefreshToken(refreshTokenClaims); + + return newAccessToken; + } + + private Map validateRefreshToken(String refreshToken) throws Exception { + try { + String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); + + // 리프레시 토큰을 검증하고 클레임을 추출합니다. + Map refreshTokenClaims = jwtTokenizer.getClaims(refreshToken, base64EncodedSecretKey).getBody(); + + // 여기에서 리프레시 토큰의 유효성을 추가적으로 검증하거나 필요한 클레임을 확인할 수 있습니다. + + return refreshTokenClaims; + } catch (Exception e) { + throw new BusinessLogicException(ExceptionCode.INVALID_REFRESH_TOKEN); + } + } + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/refreshToken/TokenController.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/refreshToken/TokenController.java new file mode 100644 index 00000000..6a26321a --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/refreshToken/TokenController.java @@ -0,0 +1,34 @@ +package com.stockholm.main_project.auth.jwt.refreshToken; + +import com.stockholm.main_project.member.dto.MemberResponseDto; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +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 org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/tokens") +public class TokenController { + + @Autowired + private RefreshTokenService refreshTokenService; + + @Operation(summary = "엑세스 토큰 재 발급", description = "엑세스 토큰을 재 발급합니다.", tags = { "Token" }) + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(schema = @Schema(implementation = TokenRefreshRequestDto.class))) + @ApiResponse(responseCode = "401", description = "INVALID REFRESH TOKEN") + @PostMapping("/refresh") + public ResponseEntity refreshAccessToken(@RequestBody TokenRefreshRequestDto tokenRefreshRequestDto) throws Exception { + + String newAccessToken = refreshTokenService.requestNewAccessToken(tokenRefreshRequestDto.getRefreshToken()); + return ResponseEntity.ok(newAccessToken); + + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/refreshToken/TokenRefreshRequestDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/refreshToken/TokenRefreshRequestDto.java new file mode 100644 index 00000000..12c8a4fd --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/refreshToken/TokenRefreshRequestDto.java @@ -0,0 +1,13 @@ +package com.stockholm.main_project.auth.jwt.refreshToken; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class TokenRefreshRequestDto { + @Schema(description = "refreshToken", defaultValue = "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJVU0VSIl0sIm1lbWJlcklkIjoxMDMsInN1YiI6InRlc3QwMTUxQG5hdmVyLmNvbSIsImlhdCI6MTY5NjkzNTA1NSwiZXhwIjoxNjk2OTYwMjU1fQ.F9IfWW_EKd7cFGYtd95B3_CcfSr2w1HLmIlEMK0fyN") + private String refreshToken; + +} \ No newline at end of file diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/controller/CommentController.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/controller/CommentController.java index 9e3f1092..1e6168ab 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/controller/CommentController.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/controller/CommentController.java @@ -9,7 +9,14 @@ import com.stockholm.main_project.board.entity.Board; import com.stockholm.main_project.board.service.BoardService; +import com.stockholm.main_project.member.dto.MemberPostDto; import com.stockholm.main_project.member.entity.Member; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -30,8 +37,11 @@ public CommentController(CommentService commentService, BoardService boardServic this.mapper = mapper; } + @Operation(summary = "댓글 생성", description = "새로운 댓글을 생성합니다.", tags = { "Comment" }) + @ApiResponse(responseCode = "201", description = "CREATED", + content = @Content(schema = @Schema(implementation = CommentResponseDto.class))) @PostMapping - public ResponseEntity postComment(@PathVariable long boardId, @RequestBody CommentRequestDto commentRequestDto, @AuthenticationPrincipal Member member){ + public ResponseEntity postComment(@Schema(implementation = CommentRequestDto.class)@PathVariable long boardId, @RequestBody CommentRequestDto commentRequestDto,@Parameter(hidden = true) @AuthenticationPrincipal Member member){ Comment comment = mapper.commentRequestDtoToComment(commentRequestDto); comment.setBoard(boardService.findBoard(boardId)); @@ -41,11 +51,15 @@ public ResponseEntity postComment(@PathVariable long boardId, @RequestBody Comme CommentResponseDto responseDto = mapper.commentToCommentResponseDto(createdComment); return new ResponseEntity<>(responseDto, HttpStatus.CREATED); } + @Operation(summary = "댓글 수정", description = "작성한 댓글을 수정합니다.", tags = { "Comment" }) + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(schema = @Schema(implementation = CommentResponseDto.class))) + @ApiResponse(responseCode = "404", description = "INVALID FAILED") @PatchMapping("{commentId}") public ResponseEntity updateComment(@PathVariable long boardId, @PathVariable long commentId, @RequestBody CommentRequestDto commentRequestDto, - @AuthenticationPrincipal Member member){ + @Parameter(hidden = true) @AuthenticationPrincipal Member member){ Comment comment = mapper.commentRequestDtoToComment(commentRequestDto); comment.setCommentId(commentId); @@ -56,8 +70,11 @@ public ResponseEntity updateComment(@PathVariable long boardId, return new ResponseEntity<>(responseDto, HttpStatus.OK); } + @Operation(summary = "댓글 삭제", description = "작성한 댓글를 삭제합니다.", tags = { "Comment" }) + @ApiResponse(responseCode = "204", description = "NO CONTENT") + @ApiResponse(responseCode = "404", description = "INVALID FAILED") @DeleteMapping("{commentId}") - public ResponseEntity deleteComment(@PathVariable long boardId, @PathVariable long commentId, @AuthenticationPrincipal Member member) { + public ResponseEntity deleteComment(@PathVariable long boardId, @PathVariable long commentId,@Parameter(hidden = true) @AuthenticationPrincipal Member member) { commentService.deleteComment(commentId, member); diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/dto/CommentRequestDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/dto/CommentRequestDto.java index 75f2a640..20e2faa3 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/dto/CommentRequestDto.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/dto/CommentRequestDto.java @@ -1,10 +1,12 @@ package com.stockholm.main_project.board.commnet.dto; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @Getter @Setter public class CommentRequestDto { + @Schema(description = "댓글 내용", defaultValue = "TestComments") private String content; } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/dto/CommentResponseDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/dto/CommentResponseDto.java index d8a36a84..4d44b070 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/dto/CommentResponseDto.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/commnet/dto/CommentResponseDto.java @@ -1,14 +1,20 @@ package com.stockholm.main_project.board.commnet.dto; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @Getter @Setter public class CommentResponseDto { + @Schema(description = "댓글 commentId", defaultValue = "1") private Long commentId; + @Schema(description = "댓글 작성자", defaultValue = "TestAccount") private String member; + @Schema(description = "댓글 내용", defaultValue = "TestComments") private String content; + @Schema(description = "댓글 생성 날짜", defaultValue = "2023-11-10T10:51:17.549Z") private String createdAt; + @Schema(description = "댓글 수정 날짜", defaultValue = "2023-12-10T10:51:17.549Z") private String ModifiedAt; } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/controller/BoardController.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/controller/BoardController.java index 0de6d76d..8180ac6a 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/board/controller/BoardController.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/controller/BoardController.java @@ -1,5 +1,6 @@ package com.stockholm.main_project.board.controller; +import com.stockholm.main_project.board.commnet.dto.CommentRequestDto; import com.stockholm.main_project.board.commnet.dto.CommentResponseDto; import com.stockholm.main_project.board.commnet.entity.Comment; import com.stockholm.main_project.board.commnet.service.CommentService; @@ -14,6 +15,7 @@ import com.stockholm.main_project.member.entity.Member; import com.stockholm.main_project.member.service.MemberService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -49,13 +51,9 @@ public BoardController(BoardService boardService, BoardMapper mapper, CommentSer // 게시물 생성 @PostMapping @Operation(summary = "게시물 생성", description = "새로운 게시물을 생성합니다.", tags = { "Board" }) - @ApiResponses({ - @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = Board.class))), - @ApiResponse(responseCode = "400", description = "Bad Request"), - @ApiResponse(responseCode = "405", description = "Method Not Allowed"), - @ApiResponse(responseCode = "500", description = "Internal Server Error") - }) - public ResponseEntity createBoard(@Valid @RequestBody BoardRequestDto boardPostDto, @AuthenticationPrincipal Member member) throws Exception { + @ApiResponse(responseCode = "201", description = "CREATED", + content = @Content(schema = @Schema(implementation = SingleBoardResponseDto.class))) + public ResponseEntity createBoard(@Schema(implementation = BoardRequestDto.class) @Valid @RequestBody BoardRequestDto boardPostDto, @Parameter(hidden = true) @AuthenticationPrincipal Member member) throws Exception { Board boardToCreate = mapper.boardRequestToBoard(boardPostDto); boardToCreate.setMember(member); @@ -67,13 +65,11 @@ public ResponseEntity createBoard(@Valid @RequestBody Bo @Operation(summary = "게시물 정보 변경", description = "게시물을 수정합니다.", tags = { "Board" }) @ApiResponse(responseCode = "200", description = "OK", - content = @Content(schema = @Schema(implementation = BoardRequestDto.class))) - @ApiResponse(responseCode = "400", description = "BAD REQUEST") - @ApiResponse(responseCode = "404", description = "NOT FOUND") - @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR") + content = @Content(schema = @Schema(implementation = SingleBoardResponseDto.class))) + @ApiResponse(responseCode = "404", description = "INVALID FAILED") @PatchMapping("{boardId}") - public ResponseEntity updateBoard(@Valid @PathVariable long boardId,@RequestBody BoardRequestDto boardRequestDto, - @AuthenticationPrincipal Member member) throws Exception { + public ResponseEntity updateBoard(@Schema(implementation = BoardRequestDto.class) @Valid @PathVariable long boardId,@RequestBody BoardRequestDto boardRequestDto, + @Parameter(hidden = true) @AuthenticationPrincipal Member member) throws Exception { Board boardToUpdate = mapper.boardRequestToBoard(boardRequestDto); Board board = boardService.updateBoard(boardId, boardToUpdate, member); @@ -86,9 +82,7 @@ public ResponseEntity updateBoard(@Valid @PathVariable l @Operation(summary = "게시물 정보 조회", description = "게시물을 조회합니다.", tags = { "Board" }) @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SingleBoardResponseDto.class))) - @ApiResponse(responseCode = "400", description = "BAD REQUEST") - @ApiResponse(responseCode = "404", description = "NOT FOUND") - @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR") + @ApiResponse(responseCode = "404", description = "BOARD NOT FOUND") @GetMapping("{boardId}") public ResponseEntity getBoard(@PathVariable long boardId){ Board response = boardService.findBoard(boardId); @@ -107,7 +101,6 @@ public ResponseEntity getBoard(@PathVariable long boardI @Operation(summary = "전체 게시물 조회", description = "모든 게시물을 조회합니다.", tags = { "Board" }) @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AllBoardResponseDto.class))) - @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR") @GetMapping public ResponseEntity> getBoards(){ List foundBoards = boardService.getAllBoards(); @@ -127,13 +120,12 @@ public ResponseEntity> getBoards(){ } @Operation(summary = "게시물 삭제", description = "게시물을 삭제합니다.", tags = { "Board" }) - @ApiResponses({ - @ApiResponse(responseCode = "204", description = "No Content"), - @ApiResponse(responseCode = "400", description = "Bad Request"), - @ApiResponse(responseCode = "404", description = "BOARD_NOT_FOUND"), - @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + @ApiResponse(responseCode = "204", description = "NO CONTENT") + @ApiResponse(responseCode = "400", description = "BAD REQUEST") + @ApiResponse(responseCode = "404", description = "INVALID FAILED") + @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR") @DeleteMapping("{boardId}") - public ResponseEntity deleteBoard(@PathVariable long boardId, @AuthenticationPrincipal Member member){ + public ResponseEntity deleteBoard(@PathVariable long boardId,@Parameter(hidden = true) @AuthenticationPrincipal Member member){ boardService.deleteBoard(boardId, member); return new ResponseEntity<>(HttpStatus.NO_CONTENT); diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/AllBoardResponseDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/AllBoardResponseDto.java index cbdb989d..a7b27f74 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/AllBoardResponseDto.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/AllBoardResponseDto.java @@ -1,6 +1,7 @@ package com.stockholm.main_project.board.dto.responseDto; import com.stockholm.main_project.board.commnet.dto.CommentResponseDto; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @@ -10,12 +11,20 @@ @Getter @Setter public class AllBoardResponseDto { + @Schema(description = "BoardId", defaultValue = "1") private Long boardId; + @Schema(description = "게시글 제목", defaultValue = "1") private String title; + @Schema(description = "게시글 내용", defaultValue = "TestContent") private String content; + @Schema(description = "게시글 작석자", defaultValue = "TestAccount") private String member; + @Schema(description = "게시글에 포함된 댓글", defaultValue = "TestComments") private List comments; + @Schema(description = "게시글 생성 날짜", defaultValue = "2023-10-10T10:51:17.549Z") private String createdAt; + @Schema(description = "게시글 수정 날짜", defaultValue = "2023-11-10T10:51:17.549Z") private String modifiedAt; + } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/BoardCommentDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/BoardCommentDto.java index 540b9093..6ca61887 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/BoardCommentDto.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/BoardCommentDto.java @@ -1,14 +1,20 @@ package com.stockholm.main_project.board.dto.responseDto; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @Getter @Setter public class BoardCommentDto { + @Schema(description = "commentId", defaultValue = "1") private long commentId; // 추가 + @Schema(description = "댓글 내용", defaultValue = "TestComment") private String content; + @Schema(description = "댓글 작성자", defaultValue = "TestAccount") private String member; + @Schema(description = "댓글 생성 날짜", defaultValue = "2023-11-10T10:51:17.549Z") private String createdAt; + @Schema(description = "댓글 수정 날짜", defaultValue = "2023-12-10T10:51:17.549Z") private String ModifiedAt; } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/SingleBoardResponseDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/SingleBoardResponseDto.java index 26d9bd2c..d1279aae 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/SingleBoardResponseDto.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/responseDto/SingleBoardResponseDto.java @@ -3,6 +3,7 @@ import com.stockholm.main_project.board.commnet.dto.CommentResponseDto; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @@ -12,12 +13,19 @@ @Getter @Setter public class SingleBoardResponseDto { + @Schema(description = "BoardId", defaultValue = "1") private Long boardId; + @Schema(description = "게시글 제목", defaultValue = "TestBoard") private String title; + @Schema(description = "게시글 내용", defaultValue = "TestContent") private String content; + @Schema(description = "게시글 작석자", defaultValue = "TestAccount") private String member; + @Schema(description = "게시글 생성 날짜", defaultValue = "2023-10-10T10:51:17.549Z") private String createdAt; + @Schema(description = "게시글 수정 날짜", defaultValue = "2023-11-10T10:51:17.549Z") private String modifiedAt; + @Schema(description = "게시글에 포함된 댓글", defaultValue = "TestComments") private List comments; diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/cash/controller/CashController.java b/server/008main_project/src/main/java/com/stockholm/main_project/cash/controller/CashController.java index 73b46d55..aab65a36 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/cash/controller/CashController.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/cash/controller/CashController.java @@ -11,6 +11,7 @@ import com.stockholm.main_project.stock.service.StockHoldService; import com.stockholm.main_project.stock.service.StockOrderService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -40,12 +41,12 @@ public CashController(CashMapper mapper, CashService cashService, MemberService } @PostMapping @Operation(summary = "현금 정보 생성", description = "새로운 현금 정보를 생성합니다.", tags = { "Cash" }) - @ApiResponse(responseCode = "201", description = "Created", + @ApiResponse(responseCode = "201", description = "CREATED", content = @Content(mediaType = "application/json", schema = @Schema(implementation = CashResponseDto.class))) @ApiResponse(responseCode = "400", description = "이미 보유한 현금이 있습니다.") - @ApiResponse(responseCode = "401", description = "Not Enough Money") + @ApiResponse(responseCode = "401", description = "NOT ENOUGH MONEY") public ResponseEntity postCash(@Schema(implementation = CashPostDto.class)@Valid @RequestBody CashPostDto cashPostDto, - @AuthenticationPrincipal Member member){ + @Parameter(hidden = true) @AuthenticationPrincipal Member member){ Cash cashToCreate = mapper.cashPostToCash(cashPostDto); @@ -61,11 +62,9 @@ public ResponseEntity postCash(@Schema(implementation = CashPostDto.class)@Valid @Operation(summary = "현금 정보 업데이트", description = "현금 정보를 업데이트합니다.", tags = { "Cash" }) @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", schema = @Schema(implementation = CashResponseDto.class))) - @ApiResponse(responseCode = "400", description = "Bad Request") - @ApiResponse(responseCode = "401", description = "Invalid Cash") - @ApiResponse(responseCode = "404", description = "Not Found") + @ApiResponse(responseCode = "401", description = "INVALID CASH") public ResponseEntity patchCash(@Schema(implementation = CashPatchDto.class)@PathVariable long cashId, @Valid @RequestBody CashPatchDto requestBody, - @AuthenticationPrincipal Member member){ + @Parameter(hidden = true) @AuthenticationPrincipal Member member){ Cash cashToUpdate = mapper.cashPatchToCash(requestBody); @@ -83,10 +82,9 @@ public ResponseEntity patchCash(@Schema(implementation = CashPatchDto.class)@Pat @Operation(summary = "현금 정보 조회", description = "현금 정보를 조회합니다.", tags = { "Cash" }) @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", schema = @Schema(implementation = CashResponseDto.class))) - @ApiResponse(responseCode = "401", description = "Invalid Cash") - @ApiResponse(responseCode = "404", description = "Not Found") + @ApiResponse(responseCode = "401", description = "INVALID CASH") @GetMapping - private ResponseEntity getCash(@AuthenticationPrincipal Member member){ + private ResponseEntity getCash(@Parameter(hidden = true) @AuthenticationPrincipal Member member){ Cash response = cashService.findCash(member); return new ResponseEntity<>(mapper.cashToCashResponseDto(response), HttpStatus.OK); diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/config/SwaggerConfig.java b/server/008main_project/src/main/java/com/stockholm/main_project/config/SwaggerConfig.java index cc3252ec..3f557b66 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/config/SwaggerConfig.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/config/SwaggerConfig.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.servers.Server; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.security.SecurityRequirement; @@ -23,12 +24,8 @@ public class SwaggerConfig { @Bean public OpenAPI openAPI() { - - // SecuritySecheme명 String jwtSchemeName = "jwtAuth"; - // API 요청헤더에 인증정보 포함 SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwtSchemeName); - // SecuritySchemes 등록 Components components = new Components() .addSecuritySchemes(jwtSchemeName, new SecurityScheme() .name(jwtSchemeName) diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/exception/ExceptionCode.java b/server/008main_project/src/main/java/com/stockholm/main_project/exception/ExceptionCode.java index 90f2c843..35723e81 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/exception/ExceptionCode.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/exception/ExceptionCode.java @@ -24,7 +24,8 @@ public enum ExceptionCode { AWS_CREDENTIALS_ERROR(401, "AWS 인증 오류"), S3_UPLOAD_ERROR(500, "S3 파일 업로드 중 오류 발생"), S3_DELETE_ERROR(500, "S3 파일 삭제 중 오류 발생"), - S3_URL_RETRIEVE_ERROR(500, "S3에서 파일 URL 검색 중 오류 발생"); + S3_URL_RETRIEVE_ERROR(500, "S3에서 파일 URL 검색 중 오류 발생"), + CRITERION_NOT_FOUND(404, "옳바른 정렬 기준이 아닙니다."); @Getter diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/controller/MemberController.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/controller/MemberController.java index fc63c964..30b7dc05 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/member/controller/MemberController.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/controller/MemberController.java @@ -8,6 +8,7 @@ import com.stockholm.main_project.member.service.MemberService; import com.stockholm.main_project.swaggersample.HelloResponse; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -37,7 +38,6 @@ public MemberController(MemberService memberService, MemberMapper mapper) { content = @Content(schema = @Schema(implementation = MemberResponseDto.class))) @ApiResponse(responseCode = "400", description = "EMAIL_DUPLICATION") @ApiResponse(responseCode = "404", description = "INVALID_PASSWORD") - @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR") @PostMapping public ResponseEntity postMember(@Schema(implementation = MemberPostDto.class)@Valid @RequestBody MemberPostDto memberPostDto){ Member member = mapper.memberPostToMember(memberPostDto); @@ -51,11 +51,9 @@ public ResponseEntity postMember(@Schema(implementation = MemberPostDto.class)@V @Operation(summary = "회원 정보 변경", description = "가입한 계정의 이름을 PATCH합니다.", tags = { "Member" }) @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = MemberResponseDto.class))) - @ApiResponse(responseCode = "400", description = "BAD REQUEST") @ApiResponse(responseCode = "404", description = "MEMBER NOT FOUND") - @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR") @PatchMapping - private ResponseEntity patchMember(@Schema(implementation = MemberPatchDto.class)@RequestBody MemberPatchDto memberPatchDto, @AuthenticationPrincipal Member member){ + private ResponseEntity patchMember(@Schema(implementation = MemberPatchDto.class)@Valid @RequestBody MemberPatchDto memberPatchDto,@Parameter(hidden = true) @AuthenticationPrincipal Member member){ memberPatchDto.setMemberId(member.getMemberId()); @@ -73,11 +71,9 @@ private ResponseEntity patchMember(@Schema(implementation = MemberPatchDto.class @Operation(summary = "회원 조회", description = "가입한 계정 중 하나가 GET됩니다.", tags = { "Member" }) @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = MemberResponseDto.class))) - @ApiResponse(responseCode = "400", description = "BAD REQUEST") - @ApiResponse(responseCode = "404", description = "NOT FOUND") - @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR") + @ApiResponse(responseCode = "404", description = "INVALID FAILED") @GetMapping - private ResponseEntity getMember(@AuthenticationPrincipal Member member){ + private ResponseEntity getMember(@Parameter(hidden = true) @AuthenticationPrincipal Member member){ Member response = memberService.findMember(member.getMemberId()); return new ResponseEntity<>(mapper.memberToMemberResponseDto(response), HttpStatus.OK); @@ -89,7 +85,7 @@ private ResponseEntity getMember(@AuthenticationPrincipal Member member){ @ApiResponse(responseCode = "400", description = "BAD REQUEST") @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR") @DeleteMapping - private ResponseEntity deleteMember(@AuthenticationPrincipal Member member){ + private ResponseEntity deleteMember(@Parameter(hidden = true) @AuthenticationPrincipal Member member){ memberService.deleteMember(member.getMemberId()); return new ResponseEntity(HttpStatus.NO_CONTENT); diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java b/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java index b080e51f..5415b29d 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java @@ -79,10 +79,15 @@ public void myScheduledStockMinMethod2() throws InterruptedException { } -// @Scheduled(fixedRate = 1000) -// public void run() throws InterruptedException { -// webSocketController.check(); -// } + // 회사 정보 호출 + @Scheduled(cron = "0 0 8 * * MON-FRI") + public void myScheduledUpdateCompanyInfMethod() throws InterruptedException { + LocalDateTime start = LocalDateTime.now(); + companyService.updateCompanyInf(); + LocalDateTime end = LocalDateTime.now(); + Duration duration = Duration.between(start, end); + System.out.println(duration.getSeconds()); + } // @Scheduled(fixedRate = 10000000) // public void secondSchedule() throws InterruptedException { diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/controller/CompanyController.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/controller/CompanyController.java index a76e6eb6..98f17670 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/controller/CompanyController.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/controller/CompanyController.java @@ -1,10 +1,13 @@ package com.stockholm.main_project.stock.controller; import com.stockholm.main_project.stock.dto.CompanyResponseDto; +import com.stockholm.main_project.stock.dto.StockInfResponseDto; import com.stockholm.main_project.stock.dto.StockMinResponseDto; import com.stockholm.main_project.stock.entity.Company; import com.stockholm.main_project.stock.mapper.StockMapper; +import com.stockholm.main_project.stock.service.ApiCallService; import com.stockholm.main_project.stock.service.CompanyService; +import com.stockholm.main_project.stock.service.StockInfService; import com.stockholm.main_project.stock.service.StockMinService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.ArraySchema; @@ -31,12 +34,16 @@ public class CompanyController { private final CompanyService companyService; private final StockMapper stockMapper; - private StockMinService stockMinService; + private final StockMinService stockMinService; + private final ApiCallService apiCallService; + private final StockInfService stockInfService; - public CompanyController(CompanyService companyService, StockMapper stockMapper, StockMinService stockMinService) { + public CompanyController(CompanyService companyService, StockMapper stockMapper, StockMinService stockMinService, ApiCallService apiCallService, StockInfService stockInfService) { this.companyService = companyService; this.stockMapper = stockMapper; this.stockMinService = stockMinService; + this.apiCallService = apiCallService; + this.stockInfService = stockInfService; } // swagger 추가 @Operation(summary = "CompanyList 가져오기", description = "CompanyList를 Get해 옵니다", tags = { "Company" }) @@ -89,4 +96,11 @@ public ResponseEntity getCompanyChart(@PathVariable("companyId") long companyId) return new ResponseEntity(stockMinList, HttpStatus.OK); } + + @GetMapping("/sort/{criterion}") + public ResponseEntity getStockInfSortByCriterion(@PathVariable("criterion") String criterion) { + List stockInfResponseDtos = stockInfService.stockInfSortByCriterion(criterion); + + return new ResponseEntity(stockInfResponseDtos, HttpStatus.OK); + } } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/CompanyInfDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/CompanyInfDto.java new file mode 100644 index 00000000..c61d8612 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/CompanyInfDto.java @@ -0,0 +1,25 @@ +package com.stockholm.main_project.stock.dto; + +import lombok.*; + +@Setter +@Getter +@NoArgsConstructor +public class CompanyInfDto { + private CompanyInfOutput output; + + @Getter + @Setter + @NoArgsConstructor + public class CompanyInfOutput { + // 상장 주수 + private String lstn_stcn; + // 시가 총액 + private String hts_avls; + // 52주 최고가 + private String w52_hgpr; + // 52주 최저가 + private String w52_lwpr; + } + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java index 68d9a4d6..84de7a50 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java @@ -22,10 +22,16 @@ public class Company extends Auditable { @Column private String korName; + @Column + private String imageUrl; + @OneToOne(mappedBy = "company", cascade = CascadeType.ALL) private StockAsBi stockAsBi; @OneToOne(mappedBy = "company", cascade = CascadeType.ALL) private StockInf stockInf; + @OneToOne(mappedBy ="company", cascade = CascadeType.ALL) + private CompanyInf companyInf; + } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/CompanyInf.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/CompanyInf.java new file mode 100644 index 00000000..ef3c63f2 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/CompanyInf.java @@ -0,0 +1,71 @@ +package com.stockholm.main_project.stock.entity; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class CompanyInf { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long companyInfId; + + @Column + // 상장 주수 + private String lstn_stcn; + + @Column + // 시가 총액 + private String hts_avls; + + @Column + // 52주 최고가 + private String w52_hgpr; + + @Column + // 52주 최저가 + private String w52_lwpr; + + @Column + // 산업군 + private String industry; + + @Column + // 세부 산업군 + private String detailed_Industry; + + @Column + // 기업 개요 + private String company_Overview; + + @OneToOne + @JoinColumn(name = "COMPANY_ID") + private Company company; + + @Builder + public CompanyInf(long companyInfId, String lstn_stcn, String hts_avls, String w52_hgpr, String w52_lwpr, String industry, String detailed_Industry, String company_Overview, Company company) { + this.companyInfId = companyInfId; + this.lstn_stcn = lstn_stcn; + this.hts_avls = hts_avls; + this.w52_hgpr = w52_hgpr; + this.w52_lwpr = w52_lwpr; + this.industry = industry; + this.detailed_Industry = detailed_Industry; + this.company_Overview = company_Overview; + this.company = company; + } + + public CompanyInfBuilder updateCompanyInf() { + return builder() + .companyInfId(this.companyInfId) + .company(this.company) + .company_Overview(this.company_Overview) + .industry(this.industry) + .detailed_Industry(this.detailed_Industry); + } +} \ No newline at end of file diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Star.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Star.java index 12ea5421..8ed2858e 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Star.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Star.java @@ -27,4 +27,6 @@ public class Star extends Auditable { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "COMPANY_ID") private Company company; + + } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/mapper/StockMapper.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/mapper/StockMapper.java index 804b37d7..5a65ae02 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/mapper/StockMapper.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/mapper/StockMapper.java @@ -36,6 +36,8 @@ default CompanyResponseDto companyToCompanyResponseDto(Company company) { @Mapping(source = "company.companyId", target = "companyId") StockInfResponseDto stockInfToStockInfResponseDto(StockInf stockInf); @Mapping(source = "company.companyId", target = "companyId") + List stockInfsToStockInfResponseDtos(List stockInf); + @Mapping(source = "company.companyId", target = "companyId") StockAsBiResponseDto stockAsBiToStockAsBiResponseDto(StockAsBi stockAsBi); @Mapping(source = "company.companyId", target = "companyId") StockMinResponseDto stockMinToStockMinResponseDto(StockMin stockMin); @@ -88,4 +90,6 @@ default List starsToStarResponseDtos(List stars) { } return starResponseDtos; } + + CompanyInf companyInfDtoToCompanyInf(CompanyInfDto companyInfDto); } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyInfRepository.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyInfRepository.java new file mode 100644 index 00000000..57021665 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyInfRepository.java @@ -0,0 +1,7 @@ +package com.stockholm.main_project.stock.repository; + +import com.stockholm.main_project.stock.entity.CompanyInf; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CompanyInfRepository extends JpaRepository { +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyRepository.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyRepository.java index ace6e976..1d0ac8b9 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyRepository.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyRepository.java @@ -9,11 +9,11 @@ public interface CompanyRepository extends JpaRepository { - @Query("SELECT c FROM Company c JOIN FETCH c.stockAsBi JOIN FETCH c.stockInf WHERE c.code = :code") + @Query("SELECT c FROM Company c JOIN FETCH c.stockAsBi JOIN FETCH c.stockInf JOIN FETCH c.companyInf WHERE c.code = :code") Company findByCode(@Param("code") String code); - @Query("SELECT c FROM Company c JOIN FETCH c.stockAsBi JOIN FETCH c.stockInf WHERE c.companyId = :companyId") + @Query("SELECT c FROM Company c JOIN FETCH c.stockAsBi JOIN FETCH c.stockInf JOIN FETCH c.companyInf WHERE c.companyId = :companyId") Company findByCompanyId(@Param("companyId") long companyId); - @Query("SELECT c from Company c join fetch c.stockAsBi JOIN FETCH c.stockInf") + @Query("SELECT c from Company c join fetch c.stockAsBi JOIN FETCH c.stockInf JOIN FETCH c.companyInf") List findAll(); } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StockInfRepository.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StockInfRepository.java new file mode 100644 index 00000000..60e12592 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StockInfRepository.java @@ -0,0 +1,14 @@ +package com.stockholm.main_project.stock.repository; + +import com.stockholm.main_project.stock.entity.StockInf; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface StockInfRepository extends JpaRepository { + @Query("SELECT s FROM StockInf s JOIN FETCH s.company ORDER BY s.stck_prpr DESC ") + List findAllByOrderByStck_prpr(); + + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/ApiCallService.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/ApiCallService.java index 5e165814..f2cb7f12 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/ApiCallService.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/ApiCallService.java @@ -1,7 +1,9 @@ package com.stockholm.main_project.stock.service; +import com.stockholm.main_project.stock.dto.CompanyInfDto; import com.stockholm.main_project.stock.dto.StockasbiDataDto; import com.stockholm.main_project.stock.dto.StockMinDto; +import com.stockholm.main_project.stock.entity.CompanyInf; import com.stockholm.main_project.stock.repository.CompanyRepository; import com.stockholm.main_project.utils.Time; import lombok.Getter; @@ -44,6 +46,10 @@ public class ApiCallService { @Value("${stock-url.kospi}") private String KOSPI_URL; + @Getter + @Value("${stock-url.companyInf}") + private String COMPANY_URL; + private final String FID_ETC_CLS_CODE = ""; private final String FID_COND_MRKT_DIV_CODE = "J"; @@ -142,4 +148,30 @@ public String getKospiMonthFromApi(){ } + public CompanyInfDto getCompayInfFromApi(String stockCode){ + String token = tokenService.getAccessToken(); + + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", "Bearer " + token); + headers.add("appkey", APP_KEY); + headers.add("appsecret", APP_SECRET); + headers.add("tr_id", "FHKST01010100"); + + String uri = COMPANY_URL + "?FID_COND_MRKT_DIV_CODE=J&FID_INPUT_ISCD=" + stockCode; + + HttpEntity entity = new HttpEntity<>("parameters", headers); + + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference() {}); + + if (response.getStatusCode().is2xxSuccessful()) { + CompanyInfDto companyInfDto = response.getBody(); + log.info("실행"); + return companyInfDto; + } else { + log.info("error"); + return null; + } + + } + } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/CompanyService.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/CompanyService.java index f506e914..fb93af78 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/CompanyService.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/CompanyService.java @@ -1,24 +1,32 @@ package com.stockholm.main_project.stock.service; +import com.stockholm.main_project.stock.dto.CompanyInfDto; import com.stockholm.main_project.stock.dto.StockasbiDataDto; import com.stockholm.main_project.stock.entity.Company; +import com.stockholm.main_project.stock.entity.CompanyInf; import com.stockholm.main_project.stock.entity.StockAsBi; import com.stockholm.main_project.stock.mapper.ApiMapper; +import com.stockholm.main_project.stock.repository.CompanyInfRepository; import com.stockholm.main_project.stock.repository.CompanyRepository; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.transaction.Transactional; import java.util.List; +@Slf4j @Service @Transactional public class CompanyService { private final CompanyRepository companyRepository; + private final CompanyInfRepository companyInfRepository; private final ApiCallService apiCallService; private final ApiMapper apiMapper; - public CompanyService(CompanyRepository companyRepository, ApiCallService apiCallService, ApiMapper apiMapper) { + + public CompanyService(CompanyRepository companyRepository, CompanyInfRepository companyInfRepository, ApiCallService apiCallService, ApiMapper apiMapper) { this.companyRepository = companyRepository; + this.companyInfRepository = companyInfRepository; this.apiCallService = apiCallService; this.apiMapper = apiMapper; } @@ -80,6 +88,24 @@ public void fillCompaines() throws InterruptedException { } } + public void updateCompanyInf() throws InterruptedException { + List companies = companyRepository.findAll(); + log.info(String.valueOf(companies.size())); + for(Company company : companies) { + CompanyInfDto companyInfDto = apiCallService.getCompayInfFromApi(company.getCode()); + CompanyInf companyInf = company.getCompanyInf(); + companyInf = companyInf.updateCompanyInf() + .lstn_stcn(companyInfDto.getOutput().getLstn_stcn()) + .hts_avls(companyInfDto.getOutput().getHts_avls()) + .w52_hgpr(companyInfDto.getOutput().getW52_hgpr()) + .w52_lwpr(companyInfDto.getOutput().getW52_lwpr()) + .build(); + company.setCompanyInf(companyInf); + companyRepository.save(company); + Thread.sleep(500); + } + } + } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockInfService.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockInfService.java new file mode 100644 index 00000000..7be1bc49 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockInfService.java @@ -0,0 +1,41 @@ +package com.stockholm.main_project.stock.service; + +import com.stockholm.main_project.exception.BusinessLogicException; +import com.stockholm.main_project.exception.ExceptionCode; +import com.stockholm.main_project.stock.dto.StockInfResponseDto; +import com.stockholm.main_project.stock.mapper.StockMapper; +import com.stockholm.main_project.stock.repository.StockInfRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@Transactional(readOnly = true) +public class StockInfService { + private final StockInfRepository stockInfRepository; + private final StockMapper stockMapper; + + public StockInfService(StockInfRepository stockInfRepository, StockMapper stockMapper) { + this.stockInfRepository = stockInfRepository; + this.stockMapper = stockMapper; + } + + // 스웨거에 criterion 알려주기 + public List stockInfSortByCriterion(String criterion) { + + // 종목명 별 +// if(criterion.equals("kor_Name")) +// return stockMapper.stockInfsToStockInfResponseDtos(stockInfRepository.findAllByOrderByCompany_Company_KorName()); +// // 현재가 별 +// else if(criterion.equals("stck_Prpr")) +// return stockMapper.stockInfsToStockInfResponseDtos(stockInfRepository.findAllByOrderByStck_prpr()); +// else if(criterion.equals("prdy_Ctrt")) +// return stockMapper.stockInfsToStockInfResponseDtos(stockInfRepository.findAllByOrderByPrdy_ctrt()); +// else if(criterion.equals("acml_tr_pbmn")) +// return stockMapper.stockInfsToStockInfResponseDtos(stockInfRepository.findAllByOrderByAcml_tr_pbmn()); +// else +// throw new BusinessLogicException(ExceptionCode.CRITERION_NOT_FOUND); + return null; + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockOrderService.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockOrderService.java index 9b8e9c72..f612b92c 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockOrderService.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockOrderService.java @@ -123,7 +123,7 @@ public StockOrder reserveStock(Member member, long price, int stockCount, long c // 보유 주식 설정 StockHold stockHold = stockHoldService.findStockHold(companyId, member.getMemberId()); stockHold.setStockCount(stockHold.getStockCount() - stockCount); - stockHold.setReserveStockCount(stockCount); + stockHold.setReserveStockCount(stockHold.getReserveStockCount() + stockCount); } StockOrder stockOrder = new StockOrder(); diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloController.java b/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloController.java index e478d320..eb9822ac 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloController.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloController.java @@ -14,7 +14,7 @@ @RequestMapping("/stockholm") public class HelloController { - @Operation(summary = "hello post 요청", description = "post됩니다.", tags = { "Member" }) + @Operation(summary = "hello post 요청", description = "post됩니다.", tags = { "Test" }) @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = HelloResponse.class))), @@ -33,7 +33,7 @@ public ResponseEntity helloPost( return new ResponseEntity<>(helloResponse, HttpStatus.OK); } - @Operation(summary = "hello get 요청", description = "get됩니다.", tags = { "Member" }) + @Operation(summary = "hello get 요청", description = "get됩니다.", tags = { "Test" }) @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = HelloResponse.class))), diff --git a/server/008main_project/src/main/resources/application.yml b/server/008main_project/src/main/resources/application.yml index 0e1f8de1..aa9fb1fe 100644 --- a/server/008main_project/src/main/resources/application.yml +++ b/server/008main_project/src/main/resources/application.yml @@ -106,6 +106,7 @@ stock-url: stockasbi: "https://openapivts.koreainvestment.com:29443/uapi/domestic-stock/v1/quotations/inquire-asking-price-exp-ccn" stockhour: "https://openapivts.koreainvestment.com:29443/uapi/domestic-stock/v1/quotations/inquire-time-itemchartprice" kospi: "https://openapivts.koreainvestment.com:29443/uapi/domestic-stock/v1/quotations/inquire-daily-indexchartprice" + companyInf: "https://openapivts.koreainvestment.com:29443/uapi/domestic-stock/v1/quotations/inquire-price" jwt: key: ${JWT_SECRET_KEY} diff --git a/server/008main_project/src/main/resources/templates/my-page.html b/server/008main_project/src/main/resources/templates/my-page.html deleted file mode 100644 index de155ea5..00000000 --- a/server/008main_project/src/main/resources/templates/my-page.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Title - - - - - \ No newline at end of file diff --git a/server/008main_project/src/test/java/com/stockholm/main_project/stock/StockOrderService.java b/server/008main_project/src/test/java/com/stockholm/main_project/stock/StockOrderService.java new file mode 100644 index 00000000..fc80eec3 --- /dev/null +++ b/server/008main_project/src/test/java/com/stockholm/main_project/stock/StockOrderService.java @@ -0,0 +1,28 @@ +package com.stockholm.main_project.stock; + +import com.stockholm.main_project.member.entity.Member; +import com.stockholm.main_project.member.repository.MemberRepository; +import com.stockholm.main_project.stock.dto.CompanyResponseDto; +import com.stockholm.main_project.stock.repository.CompanyRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +public class StockOrderService { + private MemberRepository memberRepository; + private StockOrderService stockOrderService; + + public StockOrderService(StockOrderService stockOrderService) { + this.stockOrderService = stockOrderService; + } + + + @Test + public void buyStock() { + //given + //when + + //then + } +}