Skip to content

Commit

Permalink
Merge branch 'dev' into feat/#72
Browse files Browse the repository at this point in the history
  • Loading branch information
koosco committed Nov 22, 2024
2 parents d04d7f6 + 347b3d4 commit 17fd068
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 10 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ dependencies {

// feign client
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'

// s3
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
}

tasks.named('test') {
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/com/groom/orbit/S3/S3UploadService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.groom.orbit.S3;

import java.io.IOException;
import java.util.UUID;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.groom.orbit.config.AmazonConfig;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class S3UploadService {

private final AmazonS3 amazonS3;
private final AmazonConfig amazonConfig;

public String uploadFile(MultipartFile file) {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize());
try {
amazonS3.putObject(
new PutObjectRequest(
amazonConfig.getBucket(), generateProfileKeyName(), file.getInputStream(), metadata));
} catch (IOException e) {
log.error("error at AmazonS3Manager uploadFile : {}", (Object) e.getStackTrace());
}

return amazonS3.getUrl(amazonConfig.getBucket(), generateProfileKeyName()).toString();
}

public String generateProfileKeyName() {
return "profile" + '/' + UUID.randomUUID().toString();
}
}
8 changes: 5 additions & 3 deletions src/main/java/com/groom/orbit/common/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ public enum ErrorCode {
NOT_FOUND_MEMBER(40402, HttpStatus.NOT_FOUND, "해당 사용자가 존재하지 않습니다."),
NOT_FOUND_RESUME(40403, HttpStatus.NOT_FOUND, "해당 이력이 존재하지 않습니다."),
NOT_FOUND_GOAL(40404, HttpStatus.NOT_FOUND, "해당 목표가 존재하지 않습니다."),
NOT_FOUND_QUEST(40405, HttpStatus.NOT_FOUND, "해당 퀘스트가 존재하지 않습니다."),
NOT_FOUND_SCHEDULE(40406, HttpStatus.NOT_FOUND, "해당 일정이 존재하지 않습니다."),
NOT_FOUND_SCHEDULE(40405, HttpStatus.NOT_FOUND, "해당 일정이 존재하지 않습니다."),
NOT_FOUND_S3(40406, HttpStatus.NOT_FOUND, "해당 파일을 찾을 수 없습니다."),
NOT_FOUND_QUEST(40407, HttpStatus.NOT_FOUND, "해당 퀘스트가 존재하지 않습니다."),

// Invalid Argument Error
MISSING_REQUEST_PARAMETER(40000, HttpStatus.BAD_REQUEST, "필수 요청 파라미터가 누락되었습니다."),
Expand All @@ -31,7 +32,8 @@ public enum ErrorCode {
BAD_REQUEST_PARAMETER(40005, HttpStatus.BAD_REQUEST, "잘못된 요청 파라미터입니다."),
BAD_REQUEST_JSON(40006, HttpStatus.BAD_REQUEST, "잘못된 JSON 형식입니다."),
SEARCH_SHORT_LENGTH_ERROR(40007, HttpStatus.BAD_REQUEST, "검색어는 2글자 이상이어야 합니다."),
INVALID_ACCESS_URL(40015, HttpStatus.BAD_REQUEST, "잘못된 사용자 접근입니다."),
INVALID_ACCESS_URL(40008, HttpStatus.BAD_REQUEST, "잘못된 사용자 접근입니다."),
INVALID_FILE(40009, HttpStatus.BAD_REQUEST, "잘못된 파일입니다."),

// Gone Error
GONE_SHARED_URL(41001, HttpStatus.GONE, "해당 공유 URL이 만료되었습니다."),
Expand Down
53 changes: 53 additions & 0 deletions src/main/java/com/groom/orbit/config/AmazonConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.groom.orbit.config;

import jakarta.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

import lombok.Getter;

@Configuration
@Getter
public class AmazonConfig {
@Value("${cloud.aws.credentials.access-key}")
private String accessKey;

@Value("${cloud.aws.credentials.secret-key}")
private String secretKey;

@Value("${cloud.aws.region.static}")
private String region;

@Value("${cloud.aws.s3.bucket}")
private String bucket;

private AWSCredentials awsCredentials;

@PostConstruct
public void init() {
this.awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
}

@Bean
public AmazonS3 amazonS3() {
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
}

@Bean
public AWSCredentialsProvider awsCredentialsProvider() {
return new AWSStaticCredentialsProvider(awsCredentials);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package com.groom.orbit.member.app.dto.response;
package com.groom.orbit.member.app;

import java.util.List;

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

import com.groom.orbit.S3.S3UploadService;
import com.groom.orbit.common.dto.CommonSuccessDto;
import com.groom.orbit.config.openai.AiFeedbackRequestDto;
import com.groom.orbit.config.openai.AiFeedbackResponseDto;
import com.groom.orbit.config.openai.OpenAiClient;
import com.groom.orbit.job.app.InterestJobService;
import com.groom.orbit.job.app.dto.JobDetailResponseDto;
import com.groom.orbit.member.app.MemberQueryService;
import com.groom.orbit.member.app.dto.request.UpdateMemberRequestDto;
import com.groom.orbit.member.dao.jpa.MemberRepository;
import com.groom.orbit.member.dao.jpa.entity.Member;
import com.groom.orbit.resume.app.ResumeQueryService;
Expand All @@ -27,6 +30,7 @@ public class MemberCommandService {
private final InterestJobService interestJobService;
private final ResumeQueryService resumeQueryService;
private final MemberQueryService memberQueryService;
private final S3UploadService s3UploadService;
private final OpenAiClient openAiClient;

private AiFeedbackRequestDto createAiFeedbackRequest(Long memberId) {
Expand Down Expand Up @@ -63,4 +67,18 @@ public String createAiFeedbackResponse(Long memberId) {

return responseDto.getAnswer();
}

public CommonSuccessDto updateMember(
Long memberId, UpdateMemberRequestDto requestDto, MultipartFile multipartFile) {

Member member = memberQueryService.findMember(memberId);

String newProfileUrl = s3UploadService.uploadFile(multipartFile);

member.updateMember(requestDto, newProfileUrl);

memberRepository.save(member);

return CommonSuccessDto.fromEntity(true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.groom.orbit.member.app.dto.request;

public record UpdateMemberRequestDto(
String nickname,
String knownPrompt,
String helpPrompt,
Boolean isNotification,
Boolean isProfile) {}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.groom.orbit.member.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.groom.orbit.common.annotation.AuthMember;
import com.groom.orbit.common.dto.CommonSuccessDto;
import com.groom.orbit.common.dto.ResponseDto;
import com.groom.orbit.member.app.dto.response.MemberCommandService;
import com.groom.orbit.member.app.MemberCommandService;
import com.groom.orbit.member.app.dto.request.UpdateMemberRequestDto;

import lombok.RequiredArgsConstructor;

Expand All @@ -21,4 +23,12 @@ public class MemberCommandController {
public ResponseDto<String> createAiFeedback(@AuthMember Long memberId) {
return ResponseDto.ok(memberCommandService.createAiFeedbackResponse(memberId));
}

@PatchMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseDto<CommonSuccessDto> updateMember(
@AuthMember Long memberId,
@RequestPart(value = "file", required = false) MultipartFile file,
@RequestPart(value = "requestDto") UpdateMemberRequestDto requestDto) {
return ResponseDto.ok(memberCommandService.updateMember(memberId, requestDto, file));
}
}
10 changes: 10 additions & 0 deletions src/main/java/com/groom/orbit/member/dao/jpa/entity/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import com.groom.orbit.job.dao.jpa.entity.InterestJob;
import com.groom.orbit.job.dao.jpa.entity.Job;
import com.groom.orbit.member.app.dto.request.UpdateMemberRequestDto;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
Expand Down Expand Up @@ -67,4 +68,13 @@ public void addInterestJobs(List<Job> jobs) {
jobs.stream().map(job -> InterestJob.create(this, job)).toList();
this.interestJobs.addAll(interestJobs);
}

public void updateMember(UpdateMemberRequestDto requestDto, String newProfileUrl) {
this.nickname = requestDto.nickname();
this.imageUrl = newProfileUrl;
this.knownPrompt = requestDto.knownPrompt();
this.helpPrompt = requestDto.helpPrompt();
this.isNotification = requestDto.isNotification();
this.isProfile = requestDto.isProfile();
}
}
15 changes: 14 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,17 @@ oauth:
api: https://kapi.kakao.com
---
openai:
api-key: ${OPENAI_API_KEY}
api-key: ${OPENAI_API_KEY}

---
cloud:
aws:
s3:
bucket: orbit-dev-env
credentials:
access-key: ${S3_ACCESS_KEY}
secret-key: ${S3_SECRET_KEY}
region:
static: ${REGION}
stack:
auto: false

0 comments on commit 17fd068

Please sign in to comment.