Skip to content

Commit

Permalink
Merge pull request #91 from DEPthes/develop
Browse files Browse the repository at this point in the history
V.3.0.0 Deploy
  • Loading branch information
phonil authored Aug 16, 2024
2 parents a6f1b9e + 3378277 commit 7f2d50b
Show file tree
Hide file tree
Showing 26 changed files with 344 additions and 101 deletions.
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ dependencies {
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0'


// DB
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/mvp/deplog/domain/member/WriterInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package mvp.deplog.domain.member;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import mvp.deplog.domain.member.domain.Part;
import mvp.deplog.domain.member.dto.Avatar;

@Data
@Builder
public class WriterInfo {

@Schema(type = "Avatar", description = "작성자의 아바타 이미지 객체입니다.")
private Avatar avatar;

@Schema(type = "String", example = "홍길동", description = "작성자의 이름입니다.")
private String name;

@Schema(type = "Integer", example = "3", description = "작성자의 기수입니다.")
private Integer generation;

@Schema(type = "Enum(Part)", example = "SERVER", description = "작성자의 파트입니다.", allowableValues = {"PLAN", "DESIGN", "ANDROID", "WEB", "SERVER"})
private Part part;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package mvp.deplog.domain.member.application;

import mvp.deplog.domain.member.dto.request.ModifyAvatarReq;
import mvp.deplog.domain.member.dto.response.MyInfoRes;
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
Expand All @@ -10,5 +11,5 @@ public interface MemberService {

SuccessResponse<MyInfoRes> getMyInfo(UserDetailsImpl userDetails);

SuccessResponse<Message> modifyAvatar(UserDetailsImpl userDetails, MultipartFile multipartFile);
SuccessResponse<Message> modifyAvatar(UserDetailsImpl userDetails, ModifyAvatarReq modifyAvatarReq);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import mvp.deplog.domain.member.domain.Member;
import mvp.deplog.domain.member.domain.repository.MemberRepository;
import mvp.deplog.domain.member.dto.mapper.MemberMapper;
import mvp.deplog.domain.member.dto.request.ModifyAvatarReq;
import mvp.deplog.domain.member.dto.response.MyInfoRes;
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
Expand Down Expand Up @@ -36,16 +37,14 @@ public SuccessResponse<MyInfoRes> getMyInfo(UserDetailsImpl userDetails) {

@Override
@Transactional
public SuccessResponse<Message> modifyAvatar(UserDetailsImpl userDetails, MultipartFile multipartFile) {
public SuccessResponse<Message> modifyAvatar(UserDetailsImpl userDetails, ModifyAvatarReq modifyAvatarReq) {
Member member = memberRepository.findById(userDetails.getMember().getId())
.orElseThrow(() -> new BadCredentialsException("잘못된 토큰 입력입니다."));

fileService.deleteFile(member.getAvatarImage(), DIRNAME);
String filePath = fileService.uploadFile(multipartFile, DIRNAME);
member.updateAvatarImage(filePath);
member.updateAvatar(modifyAvatarReq);

Message message = Message.builder()
.message("아바타 이미지 업로드가 완료되었습니다.")
.message("아바타 이미지 설정이 완료되었습니다.")
.build();

return SuccessResponse.of(message);
Expand Down
31 changes: 26 additions & 5 deletions src/main/java/mvp/deplog/domain/member/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import mvp.deplog.domain.common.BaseEntity;
import mvp.deplog.domain.member.dto.request.ModifyAvatarReq;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
Expand Down Expand Up @@ -39,15 +40,31 @@ public class Member extends BaseEntity {
@Min(value = 1)
private int generation;

@Column(name = "avatar_image", columnDefinition = "TEXT")
private String avatarImage;
@Column(name = "avatar_face")
private String avatarFace;

@Column(name = "avatar_body")
private String avatarBody;

@Column(name = "avatar_eyes")
private String avatarEyes;

@Column(name = "avatar_nose")
private String avatarNose;

@Column(name = "avatar_mouth")
private String avatarMouth;

public void updatePassword(String password) {
this.password = password;
}

public void updateAvatarImage(String avatarImage) {
this.avatarImage = avatarImage;
public void updateAvatar(ModifyAvatarReq modifyAvatarReq) {
this.avatarFace = modifyAvatarReq.getAvatarFace();
this.avatarBody = modifyAvatarReq.getAvatarBody();
this.avatarEyes = modifyAvatarReq.getAvatarEyes();
this.avatarNose = modifyAvatarReq.getAvatarNose();
this.avatarMouth = modifyAvatarReq.getAvatarMouth();
}

@Builder
Expand All @@ -58,6 +75,10 @@ public Member(String email, String password, String name, int generation, Part p
this.role = Role.MEMBER;
this.generation = generation;
this.part = part;
this.avatarImage = null;
this.avatarFace = null;
this.avatarBody = null;
this.avatarEyes = null;
this.avatarNose = null;
this.avatarMouth = null;
}
}
25 changes: 25 additions & 0 deletions src/main/java/mvp/deplog/domain/member/dto/Avatar.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package mvp.deplog.domain.member.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class Avatar {

@Schema(type = "String", example = "face1", description = "아바타 얼굴 파일명입니다.")
private String avatarFace;

@Schema(type = "String", example = "body1", description = "아바타 몸통 파일명입니다.")
private String avatarBody;

@Schema(type = "String", example = "eyes1", description = "아바타 눈 파일명입니다.")
private String avatarEyes;

@Schema(type = "String", example = "nose1", description = "아바타 코 파일명입니다.")
private String avatarNose;

@Schema(type = "String", example = "mouth1", description = "아바타 입 파일명입니다.")
private String avatarMouth;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
package mvp.deplog.domain.member.dto.mapper;

import mvp.deplog.domain.member.domain.Member;
import mvp.deplog.domain.member.dto.Avatar;
import mvp.deplog.domain.member.dto.response.MyInfoRes;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.ReportingPolicy;

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface MemberMapper {

@Mapping(source = "id", target = "memberId")
@Mapping(source = "name", target = "memberName")
@Mapping(source = "member", target = "avatar", qualifiedByName = "mapToAvatar")
MyInfoRes memberToMyInfo(Member member);

@Named("mapToAvatar")
default Avatar mapToAvatar(Member member) {
if (member == null) {
return null;
}

return Avatar.builder()
.avatarFace(member.getAvatarFace())
.avatarBody(member.getAvatarBody())
.avatarEyes(member.getAvatarEyes())
.avatarNose(member.getAvatarNose())
.avatarMouth(member.getAvatarMouth())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package mvp.deplog.domain.member.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

@Data
public class ModifyAvatarReq {

@Schema(type = "String", example = "face1", description = "아바타 얼굴 파일명입니다.")
private String avatarFace;

@Schema(type = "String", example = "body1", description = "아바타 몸통 파일명입니다.")
private String avatarBody;

@Schema(type = "String", example = "eyes1", description = "아바타 눈 파일명입니다.")
private String avatarEyes;

@Schema(type = "String", example = "nose1", description = "아바타 코 파일명입니다.")
private String avatarNose;

@Schema(type = "String", example = "mouth1", description = "아바타 입 파일명입니다.")
private String avatarMouth;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.Builder;
import lombok.Data;
import mvp.deplog.domain.member.domain.Part;
import mvp.deplog.domain.member.dto.Avatar;

@Data
@Builder
Expand All @@ -12,8 +13,8 @@ public class MyInfoRes {
@Schema(type = "Long", example = "1", description= "회원의 id입니다.")
private Long memberId;

@Schema(type = "String", example = "www.abcd.jpg", description= "회원의 아바타 이미지입니다.")
private String avatarImage;
@Schema(type = "Avatar", description = "작성자의 아바타 이미지 객체입니다.")
private Avatar avatar;

@Schema(type = "String", example = "홍길동", description= "회원의 이름입니다.")
private String memberName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import mvp.deplog.domain.member.dto.request.ModifyAvatarReq;
import mvp.deplog.domain.member.dto.response.MyInfoRes;
import mvp.deplog.domain.post.dto.request.CreatePostReq;
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
import mvp.deplog.global.exception.ErrorResponse;
Expand All @@ -16,6 +18,7 @@
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

Expand All @@ -38,20 +41,20 @@ ResponseEntity<SuccessResponse<MyInfoRes>> getMyInfo(
@Parameter(description = "Access Token을 입력해주세요.", required = true) @AuthenticationPrincipal UserDetailsImpl userDetails
);

@Operation(summary = "아바타 이미지 업로드 API", description = "아바타 이미지를 업로드합니다. 기존에 아바타가 있는 경우에는 url을 변경합니다.")
@Operation(summary = "아바타 이미지 설정 API", description = "아바타 이미지를 설정합니다. 기존에 아바타가 있는 경우에는 파일명을 변경합니다.")
@ApiResponses(value = {
@ApiResponse(
responseCode = "200", description = "아바타 이미지 업로드 성공",
responseCode = "200", description = "아바타 이미지 설정 성공",
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = MyInfoRes.class))}
),
@ApiResponse(
responseCode = "400", description = "아바타 이미지 업로드 실패",
responseCode = "400", description = "아바타 이미지 설정 실패",
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class))}
)
})
@PutMapping
ResponseEntity<SuccessResponse<Message>> modifyAvatar(
@Parameter(description = "Access Token을 입력해주세요.", required = true) @AuthenticationPrincipal UserDetailsImpl userDetails,
@Parameter(description = "업로드할 이미지 파일 (Multipart form-data 형식)") @RequestPart(value = "avatarImage") MultipartFile multipartFile
@Parameter(description = "Schemas의 ModifyAvatarReq를 참고해주세요.", required = true) @RequestBody ModifyAvatarReq modifyAvatarReq
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.RequiredArgsConstructor;
import mvp.deplog.domain.member.application.MemberService;
import mvp.deplog.domain.member.dto.request.ModifyAvatarReq;
import mvp.deplog.domain.member.dto.response.MyInfoRes;
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
Expand All @@ -27,7 +28,7 @@ public ResponseEntity<SuccessResponse<MyInfoRes>> getMyInfo(@AuthenticationPrinc
}

@Override
public ResponseEntity<SuccessResponse<Message>> modifyAvatar(@AuthenticationPrincipal UserDetailsImpl userDetails, MultipartFile multipartFile) {
return ResponseEntity.ok(memberService.modifyAvatar(userDetails, multipartFile));
public ResponseEntity<SuccessResponse<Message>> modifyAvatar(UserDetailsImpl userDetails, ModifyAvatarReq modifyAvatarReq) {
return ResponseEntity.ok(memberService.modifyAvatar(userDetails, modifyAvatarReq));
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package mvp.deplog.domain.post.application;

import lombok.RequiredArgsConstructor;
import mvp.deplog.domain.member.WriterInfo;
import mvp.deplog.domain.member.domain.Member;
import mvp.deplog.domain.member.domain.Role;
import mvp.deplog.domain.member.dto.Avatar;
import mvp.deplog.domain.post.domain.Post;
import mvp.deplog.domain.post.domain.repository.PostRepository;
import mvp.deplog.domain.post.dto.response.AnonymousPostDetailRes;
import mvp.deplog.domain.post.dto.response.MemberPostDetailRes;
import mvp.deplog.domain.post.exception.ResourceNotFoundException;
import mvp.deplog.domain.tagging.repository.TaggingRepository;
import mvp.deplog.global.common.SuccessResponse;
Expand Down Expand Up @@ -41,6 +45,8 @@ public SuccessResponse<AnonymousPostDetailRes> getPostDetail(UserDetailsImpl use

post.incrementViewCount(); // 조회수 증가

Member writer = post.getMember();

AnonymousPostDetailRes anonymousPostDetailRes = AnonymousPostDetailRes.builder()
.postId(post.getId())
.title(post.getTitle())
Expand All @@ -50,12 +56,20 @@ public SuccessResponse<AnonymousPostDetailRes> getPostDetail(UserDetailsImpl use
.viewCount(post.getViewCount())
.likeCount(post.getLikeCount())
.scrapCount(post.getScrapCount())
.writerInfo(AnonymousPostDetailRes.WriterInfo.builder()
.avatarImage(post.getMember().getAvatarImage())
.name(post.getMember().getName())
.generation(post.getMember().getGeneration())
.part(post.getMember().getPart())
.build())
.writerInfo(WriterInfo.builder()
.avatar(Avatar.builder()
.avatarFace(writer.getAvatarFace())
.avatarBody(writer.getAvatarBody())
.avatarEyes(writer.getAvatarEyes())
.avatarNose(writer.getAvatarNose())
.avatarMouth(writer.getAvatarMouth())
.build()
)
.name(writer.getName())
.generation(writer.getGeneration())
.part(writer.getPart())
.build()
)
.build();

return SuccessResponse.of(anonymousPostDetailRes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import lombok.RequiredArgsConstructor;
import mvp.deplog.domain.likes.domain.repository.LikesRepository;
import mvp.deplog.domain.member.WriterInfo;
import mvp.deplog.domain.member.domain.Member;
import mvp.deplog.domain.member.domain.Role;
import mvp.deplog.domain.member.domain.repository.MemberRepository;
import mvp.deplog.domain.member.dto.Avatar;
import mvp.deplog.domain.post.domain.Post;
import mvp.deplog.domain.post.domain.repository.PostRepository;
import mvp.deplog.domain.post.dto.response.AnonymousPostDetailRes;
import mvp.deplog.domain.post.dto.response.MemberPostDetailRes;
import mvp.deplog.domain.post.exception.ResourceNotFoundException;
import mvp.deplog.domain.scrap.domain.repository.ScrapRepository;
Expand Down Expand Up @@ -71,12 +74,20 @@ public SuccessResponse<MemberPostDetailRes> getPostDetail(UserDetailsImpl userDe
.scrapCount(post.getScrapCount())
.liked(liked)
.scraped(scraped)
.writerInfo(MemberPostDetailRes.WriterInfo.builder()
.avatarImage(post.getMember().getAvatarImage())
.name(post.getMember().getName())
.generation(post.getMember().getGeneration())
.part(post.getMember().getPart())
.build())
.writerInfo(WriterInfo.builder()
.avatar(Avatar.builder()
.avatarFace(writer.getAvatarFace())
.avatarBody(writer.getAvatarBody())
.avatarEyes(writer.getAvatarEyes())
.avatarNose(writer.getAvatarNose())
.avatarMouth(writer.getAvatarMouth())
.build()
)
.name(writer.getName())
.generation(writer.getGeneration())
.part(writer.getPart())
.build()
)
.build();

return SuccessResponse.of(memberPostDetailRes);
Expand Down
Loading

0 comments on commit 7f2d50b

Please sign in to comment.