Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.example.RealMatch.user.infrastructure.ScrapMockDataProvider;
import com.example.RealMatch.user.presentation.code.UserErrorCode;
import com.example.RealMatch.user.presentation.dto.request.MyEditInfoRequestDto;
import com.example.RealMatch.user.presentation.dto.request.MyInstagramUpdateRequestDto;
import com.example.RealMatch.user.presentation.dto.request.MyProfileCardUpdateRequestDto;
import com.example.RealMatch.user.presentation.dto.response.MyEditInfoResponseDto;
import com.example.RealMatch.user.presentation.dto.response.MyLoginResponseDto;
Expand Down Expand Up @@ -171,6 +172,27 @@ public MyProfileCardResponseDto updateMyProfileImage(
return MyProfileCardResponseDto.from(user, detail, categories);
}

// 인스타 아이디 수정
@Transactional
public MyProfileCardResponseDto updateSns(
Long userId,
MyInstagramUpdateRequestDto request
) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new CustomException(UserErrorCode.USER_NOT_FOUND));

UserMatchingDetail detail = userMatchingDetailRepository
.findByUserIdAndIsDeprecatedFalse(userId)
.orElseThrow(() -> new CustomException(UserErrorCode.PROFILE_CARD_NOT_FOUND));

detail.updateSns(request.getSnsAccount());

List<UserContentCategory> categories =
userContentCategoryRepository.findByUserId(userId);

return MyProfileCardResponseDto.from(user, detail, categories);
}

@Transactional(readOnly = true)
public boolean isNicknameAvailable(String nickname) {
return nicknameValidator.isAvailable(nickname);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,20 @@ public void setMatchingResult(String creatorType) {
public void deprecated() {
this.isDeprecated = true;
}

// 인스타 아이디 업데이트 메서드
public void updateSns(String snsAccount) {
if (snsAccount == null || snsAccount.isBlank()) {
this.snsUrl = null;
return;
}

String cleanAccount = snsAccount.trim()
.replace("@", "")
.replaceAll("[^a-zA-Z0-9._]", ""); // 허용된 문자만 남김

this.snsUrl = cleanAccount.isEmpty()
? null
: "https://www.instagram.com/" + cleanAccount + "/";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.example.RealMatch.user.application.service.UserService;
import com.example.RealMatch.user.application.service.UserWithdrawService;
import com.example.RealMatch.user.presentation.dto.request.MyEditInfoRequestDto;
import com.example.RealMatch.user.presentation.dto.request.MyInstagramUpdateRequestDto;
import com.example.RealMatch.user.presentation.dto.request.MyProfileCardUpdateRequestDto;
import com.example.RealMatch.user.presentation.dto.response.FavoriteBrandListResponseDto;
import com.example.RealMatch.user.presentation.dto.response.FavoriteCampaignListResponseDto;
Expand Down Expand Up @@ -167,6 +168,8 @@ public CustomResponse<FavoriteCampaignListResponseDto> getMyFavoriteCampaigns(
)
);
}

@Override
@PatchMapping("/me/profile-image")
public CustomResponse<MyProfileCardResponseDto> updateMyProfileImage(
@AuthenticationPrincipal CustomUserDetails userDetails,
Expand All @@ -176,4 +179,15 @@ public CustomResponse<MyProfileCardResponseDto> updateMyProfileImage(
userService.updateMyProfileImage(userDetails.getUserId(), request)
);
}

@Override
@PatchMapping("/me/instagram")
public CustomResponse<MyProfileCardResponseDto> updateMySns(
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestBody @Valid MyInstagramUpdateRequestDto request
) {
return CustomResponse.ok(
userService.updateSns(userDetails.getUserId(), request)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.RealMatch.user.presentation.dto.request;

import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class MyInstagramUpdateRequestDto {

@Size(max = 30, message = "인스타그램 아이디는 30자를 초과할 수 없습니다")
@Pattern(regexp = "^[a-zA-Z0-9._]*$", message = "인스타그램 아이디는 영문, 숫자, ., _ 만 사용 가능합니다")
private String snsAccount;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.example.RealMatch.match.domain.entity.enums.CampaignSortType;
import com.example.RealMatch.match.presentation.dto.request.MatchRequestDto;
import com.example.RealMatch.user.presentation.dto.request.MyEditInfoRequestDto;
import com.example.RealMatch.user.presentation.dto.request.MyInstagramUpdateRequestDto;
import com.example.RealMatch.user.presentation.dto.request.MyProfileCardUpdateRequestDto;
import com.example.RealMatch.user.presentation.dto.response.FavoriteBrandListResponseDto;
import com.example.RealMatch.user.presentation.dto.response.FavoriteCampaignListResponseDto;
Expand Down Expand Up @@ -209,10 +210,35 @@ CustomResponse<FavoriteCampaignListResponseDto> getMyFavoriteCampaigns(
CampaignSortType sort
);

@Operation(summary = "프로필 이미지 수정 API By 고경수",
description = "Attachment API로 업로드된 이미지 URL을 받아 프로필 이미지를 변경합니다")
@Operation(
summary = "프로필 이미지 수정 API By 고경수",
description = """
프로필 카드의 profileImageUrl을 변경합니다.
- 이미 업로드된 이미지 URL을 전달받아 저장합니다.
- 파일 업로드/용량 검증은 업로드 API에서 처리합니다.
"""
)
@ApiResponses({
@ApiResponse(responseCode = "200", description = "프로필 이미지 수정 성공"),
@ApiResponse(responseCode = "404", description = "USER_NOT_FOUND / PROFILE_CARD_NOT_FOUND")
})
@PatchMapping("/me/profile-image")
CustomResponse<MyProfileCardResponseDto> updateMyProfileImage(
@Parameter(hidden = true) CustomUserDetails userDetails,
@RequestBody MyProfileCardUpdateRequestDto request
@Parameter(hidden = true) @AuthenticationPrincipal CustomUserDetails userDetails,
@Valid @RequestBody MyProfileCardUpdateRequestDto request
);

@Operation(
summary = "인스타그램 아이디 수정 API By 고경수",
description = "인스타그램 계정 아이디를 변경합니다. (예: @myaccount -> https://www.instagram.com/myaccount/ 형태로 DB에 저장))"
)
@ApiResponses({
@ApiResponse(responseCode = "200", description = "인스타 아이디 수정 성공"),
@ApiResponse(responseCode = "404", description = "USER_NOT_FOUND / PROFILE_CARD_NOT_FOUND")
})
@PatchMapping("/me/instagram")
CustomResponse<MyProfileCardResponseDto> updateMySns(
@Parameter(hidden = true) @AuthenticationPrincipal CustomUserDetails userDetails,
@Valid @RequestBody MyInstagramUpdateRequestDto request
);
}
Loading