Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into fix/#57-sse
Browse files Browse the repository at this point in the history
  • Loading branch information
yonghwankim-dev committed Dec 5, 2023
2 parents 242ac35 + 7d00f2f commit 6d9de4d
Show file tree
Hide file tree
Showing 18 changed files with 358 additions and 41 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ dependencies {
implementation "com.querydsl:querydsl-jpa:${queryDslVersion}"
implementation "com.querydsl:querydsl-apt:${queryDslVersion}"

// AWS S3
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ public interface MemberRepository extends JpaRepository<Member, Long> {
Optional<Member> findMemberByEmailAndProvider(String email, String provider);

Optional<Member> findMemberByEmail(String email);

boolean existsByEmail(String email);

boolean existsByNickname(String nickname);
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,10 @@ public Integer calculateDailyGainRate(PortfolioGainHistory prevHistory) {
}

// 포트폴리오 당월 예상 배당금 = 각 종목들에 해당월의 배당금 합계
public long calculateCurrentMonthDividend(){
public long calculateCurrentMonthDividend() {
return portfolioHoldings.stream()
.mapToLong(PortfolioHolding::calculateCurrentMonthDividend)
.sum();
.mapToLong(PortfolioHolding::calculateCurrentMonthDividend)
.sum();
}

public Integer getNumberOfShares() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,25 +150,32 @@ public Integer calculateAnnualDividendYield() {

// 연간 배당금 = 종목의 배당금 합계
public long calculateAnnualDividend() {
long annualDividend = stock.getStockDividends().stream()
.mapToLong(StockDividend::getDividend)
.sum();
return annualDividend * calculateNumShares();
List<StockDividend> stockDividends = stock.getCurrentYearDividends();

long totalDividend = 0;
for (PurchaseHistory history : purchaseHistory) {
for (StockDividend stockDividend : stockDividends) {
if (history.getPurchaseDate().isBefore(stockDividend.getExDividendDate().atStartOfDay())) {
totalDividend += history.getNumShares() * stockDividend.getDividend();
}
}
}
return totalDividend;
}

public void changeCurrentPrice(long currentPrice) {
this.currentPrice = currentPrice;
}

public long calculateCurrentMonthDividend(){
public long calculateCurrentMonthDividend() {
List<StockDividend> stockDividends = stock.getCurrentMonthDividends();
return stockDividends.stream()
.flatMapToLong(stockDividend ->
LongStream.of(purchaseHistory.stream()
.filter(history ->
history.getPurchaseDate().isBefore(stockDividend.getExDividendDate().atStartOfDay()))
.mapToLong(PurchaseHistory::getNumShares)
.sum() * stockDividend.getDividend()))
.sum();
.flatMapToLong(stockDividend ->
LongStream.of(purchaseHistory.stream()
.filter(history ->
history.getPurchaseDate().isBefore(stockDividend.getExDividendDate().atStartOfDay()))
.mapToLong(PurchaseHistory::getNumShares)
.sum() * stockDividend.getDividend()))
.sum();
}
}
8 changes: 8 additions & 0 deletions src/main/java/codesquad/fineants/domain/stock/Stock.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,12 @@ public List<StockDividend> getCurrentMonthDividends() {
dividend.getPaymentDate().getMonth() == today.getMonth())
.collect(Collectors.toList());
}

public List<StockDividend> getCurrentYearDividends() {
LocalDate today = LocalDate.now();
return stockDividends.stream()
.filter(dividend -> dividend.getPaymentDate() != null)
.filter(dividend -> dividend.getPaymentDate().getYear() == today.getYear())
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package codesquad.fineants.spring.api.S3.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Optional;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.PutObjectRequest;

import codesquad.fineants.spring.api.errors.errorcode.MemberErrorCode;
import codesquad.fineants.spring.api.errors.exception.BadRequestException;
import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class AmazonS3Service {
private final AmazonS3 amazonS3;
@Value("${aws.s3.bucket}")
private String bucketName;

@Transactional
public String upload(MultipartFile multipartFile) {
File file = convertMultiPartFileToFile(multipartFile).orElseThrow(
() -> new BadRequestException(MemberErrorCode.PROFILE_IMAGE_UPLOAD_FAIL));
// random file name
String key = UUID.randomUUID() + file.getName();
// put S3
amazonS3.putObject(new PutObjectRequest(bucketName, key, file).withCannedAcl(
CannedAccessControlList.PublicRead));
// get S3
String path = amazonS3.getUrl(bucketName, key).toString();
// delete object
file.delete();
return path;
}

private Optional<File> convertMultiPartFileToFile(MultipartFile file) {
File convertedFile = new File(file.getOriginalFilename());
try (FileOutputStream fos = new FileOutputStream(convertedFile)) {
fos.write(file.getBytes());
} catch (IOException e) {
throw new BadRequestException(MemberErrorCode.PROFILE_IMAGE_UPLOAD_FAIL);
}
return Optional.of(convertedFile);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@
public enum MemberErrorCode implements ErrorCode {

NOT_FOUND_MEMBER(HttpStatus.NOT_FOUND, "회원을 찾지 못하였습니다."),
ALREADY_EXIST_ID(HttpStatus.CONFLICT, "중복된 아이디입니다.");
ALREADY_EXIST_ID(HttpStatus.CONFLICT, "중복된 아이디입니다."),
REDUNDANT_NICKNAME(HttpStatus.BAD_REQUEST, "닉네임이 중복되었습니다"),
REDUNDANT_EMAIL(HttpStatus.BAD_REQUEST, "이메일이 중복되었습니다."),
PASSWORD_CHECK_FAIL(HttpStatus.BAD_REQUEST, "비밀번호가 일치하지 않습니다."),
VERIFICATION_CODE_CHECK_FAIL(HttpStatus.BAD_REQUEST, "검증코드가 일치하지 않습니다."),
SEND_EMAIL_VERIF_FAIL(HttpStatus.BAD_REQUEST, "이메일 전송이 실패하였습니다"),
PROFILE_IMAGE_UPLOAD_FAIL(HttpStatus.BAD_REQUEST, "이미지 파일 업로드가 실패하였습니다."),
BAD_SIGNUP_INPUT(HttpStatus.BAD_REQUEST, "잘못된 입력형식입니다."),
LOGIN_FAIL(HttpStatus.BAD_REQUEST, "로그인에 실패하였습니다.");

private final HttpStatus httpStatus;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,30 @@

import java.time.LocalDateTime;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import codesquad.fineants.spring.api.member.request.LoginRequest;
import codesquad.fineants.spring.api.member.request.OauthMemberLogoutRequest;
import codesquad.fineants.spring.api.member.request.OauthMemberRefreshRequest;
import codesquad.fineants.spring.api.member.request.SignUpRequest;
import codesquad.fineants.spring.api.member.request.VerifyEmailRequest;
import codesquad.fineants.spring.api.member.response.LoginResponse;
import codesquad.fineants.spring.api.member.response.OauthCreateUrlResponse;
import codesquad.fineants.spring.api.member.response.OauthMemberLoginResponse;
import codesquad.fineants.spring.api.member.response.OauthMemberRefreshResponse;
import codesquad.fineants.spring.api.member.service.MemberService;
import codesquad.fineants.spring.api.response.ApiResponse;
import codesquad.fineants.spring.api.success.code.MemberSuccessCode;
import codesquad.fineants.spring.api.success.code.OauthSuccessCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -65,4 +73,37 @@ public ApiResponse<OauthMemberRefreshResponse> refreshAccessToken(
return ApiResponse.success(OauthSuccessCode.OK_REFRESH_TOKEN, response);
}

@PostMapping("signup")
public ApiResponse<Void> signup(@RequestPart(required = false) MultipartFile profileImageFile,
@RequestPart("signupData") SignUpRequest request) {
memberService.signup(profileImageFile, request);
return ApiResponse.success(MemberSuccessCode.OK_SIGNUP);
}

@PostMapping("/signup/verifyEmail")
public ApiResponse<Void> sendEmailVerif(
@RequestBody final VerifyEmailRequest request) {
memberService.sendEmailVerif(request);
return ApiResponse.success(MemberSuccessCode.OK_SEND_EMAIL_VERIF);
}

@GetMapping("/signup/duplicationcheck/nickname/{nickname}")
public ApiResponse<Void> nicknameDuplicationCheck(
@PathVariable final String nickname) {
memberService.checkNickname(nickname);
return ApiResponse.success(MemberSuccessCode.OK_NICKNAME_CHECK);
}

@GetMapping("/signup/duplicationcheck/email/{email}")
public ApiResponse<Void> emailDuplicationCheck(
@PathVariable final String email) {
memberService.checkEmail(email);
return ApiResponse.success(MemberSuccessCode.OK_EMAIL_CHECK);
}

@PostMapping("/login")
public ApiResponse<LoginResponse> login(
@RequestBody final LoginRequest request) {
return ApiResponse.success(MemberSuccessCode.OK_LOGIN, memberService.login(request));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package codesquad.fineants.spring.api.member.request;

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

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class LoginRequest {
private String email;
private String password;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package codesquad.fineants.spring.api.member.request;

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

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class SignUpRequest {
private String nickname;
private String email;
private String password;
private String passwordConfirm;
private String verificationCode;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package codesquad.fineants.spring.api.member.request;

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

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class VerifyEmailRequest {
private String email;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package codesquad.fineants.spring.api.member.response;

import codesquad.fineants.domain.jwt.Jwt;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class LoginResponse {
private Jwt jwt;
private OauthMemberResponse user;

public static LoginResponse from(Jwt jwt, OauthMemberResponse user) {
return new LoginResponse(jwt, user);
}
}
Loading

0 comments on commit 6d9de4d

Please sign in to comment.