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 @@ -328,26 +328,5 @@ public ResponseEntity<ApiResponse<Void>> updateProfileImage(
memberService.updateProfileImage(userDetails.getUsername(), profileImage);
return ApiResponse.success_only(SuccessStatus.UPDATE_PROFILE_IMAGE_SUCCESS);
}

/*
*
* 약관동의 API
*
* */
@Operation(
summary = "이용약관동의 API",
description = "이용약관 동의 여부를 저장합니다."
)
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "닉네임 중복 체크 성공")
})
@PostMapping("/agree-terms")
public ResponseEntity<ApiResponse<Void>> agreeToTerms(
@AuthenticationPrincipal UserDetails userDetails,
@RequestBody AgreeTermsRequestDTO agreeTermsRequestDTO) {

memberService.agreeToTerms(userDetails.getUsername(), agreeTermsRequestDTO);
return ApiResponse.success_only(SuccessStatus.TERMS_AGREE_SUCCESS);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
import com.moongeul.backend.api.member.dto.*;
import com.moongeul.backend.api.member.entity.*;
import com.moongeul.backend.api.member.jwt.dto.JwtTokenDTO;
import com.moongeul.backend.api.member.repository.AgreeRepository;
import com.moongeul.backend.api.member.repository.FollowRepository;
import com.moongeul.backend.api.member.repository.MemberRepository;
import com.moongeul.backend.api.member.repository.TermsRepository;
import com.moongeul.backend.api.member.util.NicknameGenerator;
import com.moongeul.backend.api.post.dto.CategoryPostListResponseDTO;
import com.moongeul.backend.api.post.dto.PostDTO;
Expand Down Expand Up @@ -51,8 +49,6 @@ public class MemberService {
private final GoogleOAuthService googleOAuthService;
private final KakaoOAuthService kakaoOAuthService;
private final NicknameGenerator nicknameGenerator;
private final TermsRepository termsRepository;
private final AgreeRepository agreeRepository;
private final FileUploadService fileUploadService;

// 인가코드 받아 JWT로 교환 및 회원가입/로그인 처리
Expand Down Expand Up @@ -441,51 +437,6 @@ private void validatePrivacyAccess(Member currentMember, Member targetMember) {
}
}

/*
*
* 약관동의 API
*
* */
@Transactional
public void agreeToTerms(String email, AgreeTermsRequestDTO agreeTermsRequestDTO){

Member member = getMemberByEmail(email);

// 예외처리: 필수 동의 여부 검증
if (!agreeTermsRequestDTO.isServiceTermsAgree() || !agreeTermsRequestDTO.isPrivatePolicyAgree()) {
throw new BadRequestException(ErrorStatus.DISAGREE_REQUIRED_TERM.getMessage());
}

// 1. 약관 타입과 DTO의 동의 여부 매핑
Map<TermsType, Boolean> agreementData = Map.of(
TermsType.SERVICE_TERMS_AGREE, agreeTermsRequestDTO.isServiceTermsAgree(),
TermsType.PRIVACY_POLICY_AGREE, agreeTermsRequestDTO.isPrivatePolicyAgree(),
TermsType.MARKETING_AGREE, agreeTermsRequestDTO.isMarketingAgree()
);

agreementData.forEach((type, isAgreed) -> {
// 1. 해당 타입의 약관 마스터 정보 조회
Terms terms = termsRepository.findByTermsType(type)
.orElseThrow(() -> new NotFoundException(ErrorStatus.TERMS_NOTFOUND_EXCEPTION.getMessage()));

// 2. 기존 동의 내역이 있는지 조회
agreeRepository.findByMemberAndTerms(member, terms)
.ifPresentOrElse(
// 이미 데이터가 있다면? -> 동의 여부 필드만 수정 (Dirty Checking 발생)
existingAgree -> existingAgree.updateAgreement(isAgreed),
// 데이터가 없다면? -> 새로 생성해서 저장
() -> {
Agree newAgree = Agree.builder()
.member(member)
.terms(terms)
.isAgreed(isAgreed)
.build();
agreeRepository.save(newAgree);
}
);
});
}

// 회원 조회 메서드
private Member getMemberByEmail(String email) {
return memberRepository.findByEmail(email)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.moongeul.backend.api.setting.controller;

import com.moongeul.backend.api.setting.dto.AgreeTermsRequestDTO;
import com.moongeul.backend.api.setting.dto.PrivacyLevelResponseDTO;
import com.moongeul.backend.api.setting.dto.PrivacyLevelUpdateRequestDTO;
import com.moongeul.backend.api.setting.service.AgreeTermsSettingService;
import com.moongeul.backend.api.setting.service.PrivacySettingService;
import com.moongeul.backend.common.response.ApiResponse;
import com.moongeul.backend.common.response.SuccessStatus;
Expand All @@ -13,19 +15,16 @@
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@Tag(name = "Setting", description = "설정 관련 API 입니다.")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/setting")
@RequestMapping("/api/v2/setting")
public class SettingController {

private final PrivacySettingService privacySettingService;
private final AgreeTermsSettingService agreeTermsSettingService;

@Operation(
summary = "계정 공개 범위 조회 API",
Expand Down Expand Up @@ -68,4 +67,20 @@ public ResponseEntity<ApiResponse<PrivacyLevelResponseDTO>> updatePrivacyLevel(
PrivacyLevelResponseDTO response = privacySettingService.updatePrivacyLevel(userDetails.getUsername(), request);
return ApiResponse.success(SuccessStatus.UPDATE_PRIVACY_LEVEL_SUCCESS, response);
}

@Operation(
summary = "이용약관동의 API",
description = "이용약관 동의 여부를 저장합니다."
)
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "닉네임 중복 체크 성공")
})
@PostMapping("/agree-terms")
public ResponseEntity<ApiResponse<Void>> agreeToTerms(
@AuthenticationPrincipal UserDetails userDetails,
@RequestBody AgreeTermsRequestDTO agreeTermsRequestDTO) {

agreeTermsSettingService.agreeToTerms(userDetails.getUsername(), agreeTermsRequestDTO);
return ApiResponse.success_only(SuccessStatus.TERMS_AGREE_SUCCESS);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.moongeul.backend.api.member.dto;
package com.moongeul.backend.api.setting.dto;

import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.moongeul.backend.api.member.entity;
package com.moongeul.backend.api.setting.entity;

import com.moongeul.backend.api.member.entity.Member;
import com.moongeul.backend.common.entity.BaseTimeEntity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.moongeul.backend.api.member.entity;
package com.moongeul.backend.api.setting.entity;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.moongeul.backend.api.member.entity;
package com.moongeul.backend.api.setting.entity;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.moongeul.backend.api.member.repository;
package com.moongeul.backend.api.setting.repository;

import com.moongeul.backend.api.member.entity.Agree;
import com.moongeul.backend.api.setting.entity.Agree;
import com.moongeul.backend.api.member.entity.Member;
import com.moongeul.backend.api.member.entity.Terms;
import com.moongeul.backend.api.setting.entity.Terms;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.moongeul.backend.api.member.repository;
package com.moongeul.backend.api.setting.repository;

import com.moongeul.backend.api.member.entity.Terms;
import com.moongeul.backend.api.member.entity.TermsType;
import com.moongeul.backend.api.setting.entity.Terms;
import com.moongeul.backend.api.setting.entity.TermsType;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.moongeul.backend.api.setting.service;

import com.moongeul.backend.api.member.repository.MemberRepository;
import com.moongeul.backend.api.setting.repository.AgreeRepository;
import com.moongeul.backend.api.setting.repository.TermsRepository;
import com.moongeul.backend.api.setting.dto.AgreeTermsRequestDTO;
import com.moongeul.backend.api.setting.entity.Agree;
import com.moongeul.backend.api.member.entity.Member;
import com.moongeul.backend.api.setting.entity.Terms;
import com.moongeul.backend.api.setting.entity.TermsType;
import com.moongeul.backend.common.exception.BadRequestException;
import com.moongeul.backend.common.exception.NotFoundException;
import com.moongeul.backend.common.response.ErrorStatus;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

@Service
@Slf4j
@RequiredArgsConstructor
public class AgreeTermsSettingService {

private final MemberRepository memberRepository;
private final TermsRepository termsRepository;
private final AgreeRepository agreeRepository;

/* 약관동의 API */
@Transactional
public void agreeToTerms(String email, AgreeTermsRequestDTO agreeTermsRequestDTO){

Member member = getMemberByEmail(email);

// 예외처리: 필수 동의 여부 검증
if (!agreeTermsRequestDTO.isServiceTermsAgree() || !agreeTermsRequestDTO.isPrivatePolicyAgree()) {
throw new BadRequestException(ErrorStatus.DISAGREE_REQUIRED_TERM.getMessage());
}

// 1. 약관 타입과 DTO의 동의 여부 매핑
Map<TermsType, Boolean> agreementData = Map.of(
TermsType.SERVICE_TERMS_AGREE, agreeTermsRequestDTO.isServiceTermsAgree(),
TermsType.PRIVACY_POLICY_AGREE, agreeTermsRequestDTO.isPrivatePolicyAgree(),
TermsType.MARKETING_AGREE, agreeTermsRequestDTO.isMarketingAgree()
);

agreementData.forEach((type, isAgreed) -> {
// 1. 해당 타입의 약관 마스터 정보 조회
Terms terms = termsRepository.findByTermsType(type)
.orElseThrow(() -> new NotFoundException(ErrorStatus.TERMS_NOTFOUND_EXCEPTION.getMessage()));

// 2. 기존 동의 내역이 있는지 조회
agreeRepository.findByMemberAndTerms(member, terms)
.ifPresentOrElse(
// 이미 데이터가 있다면? -> 동의 여부 필드만 수정 (Dirty Checking 발생)
existingAgree -> existingAgree.updateAgreement(isAgreed),
// 데이터가 없다면? -> 새로 생성해서 저장
() -> {
Agree newAgree = Agree.builder()
.member(member)
.terms(terms)
.isAgreed(isAgreed)
.build();
agreeRepository.save(newAgree);
}
);
});
}

private Member getMemberByEmail(String email) {
return memberRepository.findByEmail(email)
.orElseThrow(() -> new NotFoundException(ErrorStatus.USER_NOTFOUND_EXCEPTION.getMessage()));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.moongeul.backend.api.setting.service;

import com.moongeul.backend.api.member.entity.Member;
import com.moongeul.backend.api.member.entity.PrivacyLevel;
import com.moongeul.backend.api.member.entity.*;
import com.moongeul.backend.api.member.repository.MemberRepository;
import com.moongeul.backend.api.setting.dto.PrivacyLevelResponseDTO;
import com.moongeul.backend.api.setting.dto.PrivacyLevelUpdateRequestDTO;
Expand Down