Skip to content
Merged
12 changes: 8 additions & 4 deletions back/src/main/java/com/back/domain/job/job/entity/Job.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "job")
@Getter @Setter
@Getter
@NoArgsConstructor
public class Job extends BaseEntity {
@Column(name = "name", nullable = false, unique = true)
Expand All @@ -20,15 +20,19 @@ public class Job extends BaseEntity {
private String description;

@OneToMany(mappedBy = "job", cascade = CascadeType.ALL)
private List<JobAlias> aliases;
private List<JobAlias> aliases = new ArrayList<>();

public Job(String name, String description) {
this.name = name;
this.description = description;
this.aliases = new ArrayList<>();
}

public void addAlias(JobAlias alias) {
if (aliases == null) {
aliases = new ArrayList<>();
}
aliases.add(alias);
alias.setJob(this);
alias.linkToJob(this);
}
}
11 changes: 9 additions & 2 deletions back/src/main/java/com/back/domain/job/job/entity/JobAlias.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Table(name = "job_alias")
@Getter @Setter
@Getter
@NoArgsConstructor
public class JobAlias extends BaseEntity {
@Column(name = "name", nullable = false, unique = true)
Expand All @@ -22,4 +21,12 @@ public JobAlias(String name) {
this.name = name;
this.job = null; // 기본적으로 연결된 Job이 없음 (pending 상태)
}

public void linkToJob(Job job) {
this.job = job;
}

public boolean isPending() {
return this.job == null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public Job create(String name, String description) {
@Transactional
public JobAlias createAlias(Job job, String aliasName) {
JobAlias alias = new JobAlias(aliasName);
alias.setJob(job);
job.addAlias(alias);
return jobAliasRepository.save(alias);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
@RequiredArgsConstructor
public class MemberStorage {
Expand All @@ -24,12 +26,15 @@ public Mentor findMentorByMember(Member member) {
}

public Mentor findMentorByMemberId(Long memberId) {
return mentorRepository.findByMemberId(memberId)
return mentorRepository.findByMemberIdWithMember(memberId)
.orElseThrow(() -> new ServiceException(MemberErrorCode.NOT_FOUND_MENTOR));
}
public Optional<Mentor> findMentorByMemberOptional(Member member) {
return mentorRepository.findByMemberIdWithMember(member.getId());
}

public Mentee findMenteeByMember(Member member) {
return menteeRepository.findByMemberId(member.getId())
return menteeRepository.findByMemberIdWithMember(member.getId())
.orElseThrow(() -> new ServiceException(MemberErrorCode.NOT_FOUND_MENTEE));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
public record MenteeDto(
@Schema(description = "멘티 ID")
Long menteeId,
@Schema(description = "멘티명")
String name
@Schema(description = "멘티 닉네임")
String nickname
) {
public static MenteeDto from(Mentee mentee) {
return new MenteeDto(
mentee.getId(),
mentee.getMember().getName()
mentee.getMember().getNickname()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ public interface MenteeRepository extends JpaRepository<Mentee, Long> {
@Query("SELECT m FROM Mentee m WHERE m.member.id = :memberId AND m.isDeleted = false")
Optional<Mentee> findByMemberId(@Param("memberId") Long memberId);

@Query("SELECT m FROM Mentee m JOIN FETCH m.member WHERE m.member.id = :memberId AND m.isDeleted = false")
Optional<Mentee> findByMemberIdWithMember(@Param("memberId") Long memberId);

@Query("SELECT m FROM Mentee m WHERE m.id = :id AND m.isDeleted = false")
Optional<Mentee> findById(@Param("id") Long id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
public record MentorDetailDto(
@Schema(description = "멘토 ID")
Long mentorId,
@Schema(description = "멘토명")
String name,
@Schema(description = "멘토 닉네임")
String nickname,
@Schema(description = "평점")
Double rate,
// TODO: Job id, name
Expand All @@ -17,7 +17,7 @@ public record MentorDetailDto(
public static MentorDetailDto from(Mentor mentor) {
return new MentorDetailDto(
mentor.getId(),
mentor.getMember().getName(),
mentor.getMember().getNickname(),
mentor.getRate(),
mentor.getCareerYears()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
public record MentorDto(
@Schema(description = "멘토 ID")
Long mentorId,
@Schema(description = "멘토명")
String name
@Schema(description = "멘토 닉네임")
String nickname
) {
public static MentorDto from(Mentor mentor) {
return new MentorDto(
mentor.getId(),
mentor.getMember().getName()
mentor.getMember().getNickname()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ public interface MentorRepository extends JpaRepository<Mentor, Long> {
@Query("SELECT m FROM Mentor m WHERE m.member.id = :memberId AND m.isDeleted = false")
Optional<Mentor> findByMemberId(@Param("memberId") Long memberId);

@Query("SELECT m FROM Mentor m JOIN FETCH m.member WHERE m.member.id = :memberId AND m.isDeleted = false")
Optional<Mentor> findByMemberIdWithMember(@Param("memberId") Long memberId);

@Query("SELECT m FROM Mentor m WHERE m.id = :id AND m.isDeleted = false")
Optional<Mentor> findById(@Param("id") Long id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ public Page<Mentoring> searchMentorings(String keyword, Pageable pageable) {

BooleanBuilder builder = new BooleanBuilder();

// 제목, 멘토 이름 검색 조건
// 제목, 멘토 닉네임 검색 조건
if (keyword != null && !keyword.isBlank()) {
builder.and(
mentoring.title.containsIgnoreCase(keyword)
.or(mentor.member.name.containsIgnoreCase(keyword))
.or(mentor.member.nickname.containsIgnoreCase(keyword))
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.back.domain.mentoring.mentoring.entity.Mentoring;
import com.back.domain.mentoring.mentoring.error.MentoringErrorCode;
import com.back.domain.mentoring.mentoring.repository.MentoringRepository;
import com.back.domain.mentoring.reservation.entity.Reservation;
import com.back.domain.mentoring.reservation.error.ReservationErrorCode;
import com.back.domain.mentoring.reservation.repository.ReservationRepository;
import com.back.domain.mentoring.slot.entity.MentorSlot;
import com.back.domain.mentoring.slot.error.MentorSlotErrorCode;
Expand Down Expand Up @@ -52,6 +54,11 @@ public MentorSlot findMentorSlot(Long slotId) {
.orElseThrow(() -> new ServiceException(MentorSlotErrorCode.NOT_FOUND_MENTOR_SLOT));
}

public Reservation findReservation(Long reservationId) {
return reservationRepository.findById(reservationId)
.orElseThrow(() -> new ServiceException(ReservationErrorCode.NOT_FOUND_RESERVATION));
}


// ==== exists 메서드 =====

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,21 @@ public enum ReservationStatus {
APPROVED, // 승인됨
REJECTED, // 거절됨
CANCELED, // 취소됨
COMPLETED // 완료됨
COMPLETED; // 완료됨

public boolean canApprove() {
return this == PENDING;
}

public boolean canReject() {
return this == PENDING;
}

public boolean canCancel() {
return this == PENDING || this == APPROVED;
}

public boolean canComplete() {
return this == APPROVED;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.back.domain.mentoring.reservation.controller;

import com.back.domain.member.member.entity.Member;
import com.back.domain.member.member.service.MemberStorage;
import com.back.domain.member.mentee.entity.Mentee;
import com.back.domain.member.mentor.entity.Mentor;
import com.back.domain.mentoring.reservation.dto.request.ReservationRequest;
import com.back.domain.mentoring.reservation.dto.response.ReservationResponse;
import com.back.domain.mentoring.reservation.service.ReservationService;
Expand All @@ -12,10 +14,9 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
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.*;

import java.util.Optional;

@RestController
@RequestMapping("/reservations")
Expand Down Expand Up @@ -43,4 +44,61 @@ public RsData<ReservationResponse> createReservation(
resDto
);
}

@PatchMapping("/{reservationId}/approve")
@PreAuthorize("hasRole('MENTOR')")
@Operation(summary = "예약 수락", description = "멘토가 멘티의 예약 신청을 수락합니다. 로그인한 멘토만 예약 수락할 수 있습니다.")
public RsData<ReservationResponse> approveReservation(
@PathVariable Long reservationId
) {
Mentor mentor = memberStorage.findMentorByMember(rq.getActor());

ReservationResponse resDto = reservationService.approveReservation(mentor, reservationId);

return new RsData<>(
"200",
"예약이 수락되었습니다.",
resDto
);
}

@PatchMapping("/{reservationId}/reject")
@PreAuthorize("hasRole('MENTOR')")
@Operation(summary = "예약 거절", description = "멘토가 멘티의 예약 신청을 거절합니다. 로그인한 멘토만 예약 거절할 수 있습니다.")
public RsData<ReservationResponse> rejectReservation(
@PathVariable Long reservationId
) {
Mentor mentor = memberStorage.findMentorByMember(rq.getActor());

ReservationResponse resDto = reservationService.rejectReservation(mentor, reservationId);

return new RsData<>(
"200",
"예약이 거절되었습니다.",
resDto
);
}

@PatchMapping("/{reservationId}/cancel")
@Operation(summary = "예약 취소", description = "멘토 또는 멘티가 예약을 취소합니다. 로그인 후 예약 취소할 수 있습니다.")
public RsData<ReservationResponse> cancelReservation(
@PathVariable Long reservationId
) {
Member member = rq.getActor();
ReservationResponse resDto;

Optional<Mentor> mentor = memberStorage.findMentorByMemberOptional(member);
if (mentor.isPresent()) {
resDto = reservationService.cancelReservation(mentor.get(), reservationId);
} else {
Mentee mentee = memberStorage.findMenteeByMember(member);
resDto = reservationService.cancelReservation(mentee, reservationId);
}

return new RsData<>(
"200",
"예약이 취소되었습니다.",
resDto
);
}
}
Loading