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 @@ -24,7 +24,7 @@ public class DateCourseLogQueryController {

private final DateCourseLogQueryService dateCourseLogQueryService;

@Operation(summary = "최근 1개월 WithTime 사용자의 데이트 평균 횟수와 나의 데이트 횟수 조회 API by 피우", description = "메인 페이지의 데이트 나침반에 해당하는 API입니다. 최근 1개월 WithTime 사용자의 데이트 평균 횟수와 나의 데이트 횟수 조회하는 API입니다.")
@Operation(summary = "최근 1개월 WithTime 사용자의 데이트 평균 횟수와 나의 데이트 횟수 조회 API by 피우", description = "메인 페이지의 데이트 나침반에 해당하는 API입니다. 최근 1개월 WithTime 사용자의 데이트 평균 횟수와 나의 데이트 횟수 조회하는 API입니다. 비회원은 나의 데이트 횟수가 0회로 표시됩니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공입니다.")
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.withtime.be.withtimebe.domain.member.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.withtime.be.withtimebe.domain.member.annotation.enums.PointAction;

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GetPoint {
PointAction action();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.withtime.be.withtimebe.domain.member.annotation.enums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum PointAction {

KEYWORD_SEARCH("키워드 검색", 3),
VIEW_DATE_COURSE("데이트 코스 조회", 5),
SAVE_DATE_COURSE("데이트 코스 저장", 10),
CREATE_DATE_COURSE("데이트 코스 생성", 30),
WRITE_REVIEW("리뷰 작성", 20),
COMPLETE_TEST("취향 테스트 완료", 20),
INPUT_PROFILE("프로필 입력", 10),
// COMPLETE_MISSION("미션 완료", 0),
;

private final String label;
private final Integer point;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.withtime.be.withtimebe.domain.member.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.withtime.be.withtimebe.domain.member.annotation.GetPoint;
import org.withtime.be.withtimebe.domain.member.annotation.enums.PointAction;
import org.withtime.be.withtimebe.domain.member.service.command.MemberCommandService;
import org.withtime.be.withtimebe.global.security.domain.CustomUserDetails;

import lombok.RequiredArgsConstructor;

@Aspect
@Component
@RequiredArgsConstructor
public class GetPointAspect {

private final MemberCommandService memberCommandService;

@AfterReturning("@annotation(getPoint)")
public void addPoint(GetPoint getPoint) {

// 행동 및 포인트 추출
PointAction action = getPoint.action();
Integer point = action.getPoint();

// 인증 객체 추출
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication == null || !authentication.isAuthenticated()) {
return;
}

// 포인트 적립
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
if(userDetails instanceof CustomUserDetails customUserDetails) {
Long memberId = customUserDetails.getMember().getId();
memberCommandService.addPoint(memberId, point);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.withtime.be.withtimebe.domain.member.controller;

import org.namul.api.payload.response.DefaultResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.withtime.be.withtimebe.domain.member.converter.MemberConverter;
import org.withtime.be.withtimebe.domain.member.dto.GradeResponseDTO;
import org.withtime.be.withtimebe.domain.member.dto.MemberResponseDTO;
import org.withtime.be.withtimebe.domain.member.entity.Member;
import org.withtime.be.withtimebe.domain.member.service.query.GradeQueryService;
import org.withtime.be.withtimebe.global.security.annotation.AuthenticatedMember;

import io.swagger.v3.oas.annotations.Operation;
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 lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/members/grade")
@Tag(name = "사용자 등급 관련 API")
public class GradeController {

private final GradeQueryService gradeQueryService;

@Operation(summary = "나의 등급 조회 API by 피우", description = "나의 등급을 조회하는 API 입니다. 로그인한 사용자만 조회 가능합니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "등급 반환 성공"),
@ApiResponse(
responseCode = "404",
description = """
다음과 같은 이유로 실패할 수 있습니다:
- GRADE404_1: 등급을 찾지 못했습니다.
"""
)
})
@GetMapping
public DefaultResponse<GradeResponseDTO.FindMyGrade> findMyGrade(@AuthenticatedMember Member member) {
GradeResponseDTO.FindMyGrade response = gradeQueryService.findMyGrade(member);
return DefaultResponse.ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.namul.api.payload.response.DefaultResponse;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.withtime.be.withtimebe.domain.member.converter.MemberConverter;
import org.withtime.be.withtimebe.domain.member.dto.MemberRequestDTO;
import org.withtime.be.withtimebe.domain.member.dto.MemberResponseDTO;
import org.withtime.be.withtimebe.domain.member.entity.Member;
import org.withtime.be.withtimebe.domain.member.service.command.MemberCommandService;
import org.withtime.be.withtimebe.domain.member.service.query.MemberQueryService;
import org.withtime.be.withtimebe.global.security.annotation.AuthenticatedMember;

@RestController
Expand All @@ -21,6 +27,7 @@
public class MemberController {

private final MemberCommandService memberCommandService;
private final MemberQueryService memberQueryService;

@Operation(summary = "비밀번호 변경 API", description = "현재 비밀번호가 맞으면 새로운 비밀번호로 변경")
@ApiResponses({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.withtime.be.withtimebe.domain.member.converter;

import org.withtime.be.withtimebe.domain.member.dto.GradeResponseDTO;
import org.withtime.be.withtimebe.domain.member.entity.Grade;
import org.withtime.be.withtimebe.domain.member.entity.Member;

public class GradeConverter {

public static GradeResponseDTO.FindMyGrade toFindMyGrade(Member member, Grade current, Grade next) {

int nextRequiredPoint = (next == null) ? 0 : next.getRequiredPoint() - member.getPoint();

return GradeResponseDTO.FindMyGrade.builder()
.username(member.getUsername())
.grade(current.getGradeType().name())
.level(current.getLevel())
.description(current.getDescription())
.nextRequiredPoint(nextRequiredPoint)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.withtime.be.withtimebe.domain.member.dto;

import lombok.Builder;

public record GradeResponseDTO() {

@Builder
public record FindMyGrade(
String username,
String grade,
String level,
String description,
Integer nextRequiredPoint
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,5 @@ public record MemberResponseDTO() {
@Builder
public record ChangeInfo(
String username
) {

}
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.withtime.be.withtimebe.domain.member.entity;

import org.withtime.be.withtimebe.domain.member.entity.enums.GradeType;
import org.withtime.be.withtimebe.global.common.BaseEntity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Table(name = "grade")
public class Grade extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "grade_id")
private Long id;

@Enumerated(EnumType.STRING)
@Column(nullable = false, unique = true)
private GradeType gradeType;

@Column(nullable = false)
private String level;

@Column(nullable = false)
private String description;

@Column(nullable = false)
private Integer requiredPoint;
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ public class Member extends BaseEntity {
@Column(name = "role", nullable = false)
private Role role;

@Column(name = "point", nullable = false)
@Builder.Default
private Integer point = 0;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "region_id")
private Region region;
Expand All @@ -98,6 +102,10 @@ public void updateAlarmSetting(Boolean pushAlarm, Boolean emailAlarm, Boolean sm
this.smsAlarm = smsAlarm;
}

public void addPoint(Integer point) {
this.point += point;
}

public void updateRegion(Region region) {
this.region = region;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.withtime.be.withtimebe.domain.member.entity.enums;

public enum GradeType {
FLIRT,
EXPLORER,
SEEKER,
NAVIGATOR,
JOURNEYMAN,
TRAILBLAZER,
TIMEKEEPER,
ROMANTIC_NOMAD,
MASTER_OF_MOMENTS,
WITHTIME
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.withtime.be.withtimebe.domain.member.repository;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.withtime.be.withtimebe.domain.member.entity.Grade;

public interface GradeRepository extends JpaRepository<Grade, Long> {

@Query("SELECT g FROM Grade g " +
"WHERE g.requiredPoint <= :point " +
"ORDER BY g.requiredPoint DESC")
Optional<Grade> findCurrentGrade(@Param("point") int point);

@Query("SELECT g FROM Grade g " +
"WHERE g.requiredPoint > :point " +
"ORDER BY g.requiredPoint ASC")
Optional<Grade> findNextGrade(@Param("point") int point);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public interface MemberCommandService {
void changePassword(Member member, MemberRequestDTO.ChangePassword request);
void changePassword(String email, String password);
Member changeInfo(Long memberId, MemberRequestDTO.ChangeInfo request);
void addPoint(Long memberId, Integer point);
void deleteMember(Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ public Member changeInfo(Long memberId, MemberRequestDTO.ChangeInfo request) {
}

@Override
public void addPoint(Long memberId, Integer point) {
Member member = memberRepository.findById(memberId).orElseThrow(() ->
new MemberException(MemberErrorCode.NOT_FOUND));
member.addPoint(point);
}

public void deleteMember(Long memberId) {
memberRepository.deleteById(memberId);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.withtime.be.withtimebe.domain.member.service.query;

import org.withtime.be.withtimebe.domain.member.dto.GradeResponseDTO;
import org.withtime.be.withtimebe.domain.member.entity.Member;

public interface GradeQueryService {
GradeResponseDTO.FindMyGrade findMyGrade(Member member);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.withtime.be.withtimebe.domain.member.service.query;

import org.springframework.stereotype.Service;
import org.springframework.web.ErrorResponseException;
import org.withtime.be.withtimebe.domain.member.converter.GradeConverter;
import org.withtime.be.withtimebe.domain.member.dto.GradeResponseDTO;
import org.withtime.be.withtimebe.domain.member.entity.Grade;
import org.withtime.be.withtimebe.domain.member.entity.Member;
import org.withtime.be.withtimebe.domain.member.repository.GradeRepository;
import org.withtime.be.withtimebe.global.error.code.GradeErrorCode;
import org.withtime.be.withtimebe.global.error.exception.GradeException;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class GradeQueryServiceImpl implements GradeQueryService {

private final GradeRepository gradeRepository;

@Override
public GradeResponseDTO.FindMyGrade findMyGrade(Member member) {

int currentPoint = member.getPoint();

Grade currentGrade = gradeRepository.findCurrentGrade(currentPoint)
.orElseThrow(() -> new GradeException(GradeErrorCode.GRADE_NOT_FOUND));

Grade nextGrade = gradeRepository.findNextGrade(currentPoint)
.orElse(null);

return GradeConverter.toFindMyGrade(member, currentGrade, nextGrade);
}
}
Loading