Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat : 회원 정보 수정 #81

Merged
merged 1 commit into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/groom/orbit/common/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public enum ErrorCode {
NOT_FOUND_RESUME(40403, HttpStatus.NOT_FOUND, "해당 이력이 존재하지 않습니다."),
NOT_FOUND_GOAL(40404, HttpStatus.NOT_FOUND, "해당 목표가 존재하지 않습니다."),
NOT_FOUND_SCHEDULE(40405, HttpStatus.NOT_FOUND, "해당 일정이 존재하지 않습니다."),
NOT_FOUND_S3(40406, HttpStatus.NOT_FOUND, "해당 파일을 찾을 수 없습니다."),

// Invalid Argument Error
MISSING_REQUEST_PARAMETER(40000, HttpStatus.BAD_REQUEST, "필수 요청 파라미터가 누락되었습니다."),
Expand All @@ -31,6 +32,7 @@ public enum ErrorCode {
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_FILE(40008, 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 @@ -14,6 +14,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.Getter;
Expand Down Expand Up @@ -62,4 +63,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
Loading