Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 마이핑글 참여 완료/예정 번개 리스트 api 생성 #86

Merged
merged 5 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
@@ -1,27 +1,42 @@
package org.pingle.pingleserver.controller;

import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.pingle.pingleserver.annotation.GUserId;
import org.pingle.pingleserver.annotation.UserId;
import org.pingle.pingleserver.constant.Constants;
import org.pingle.pingleserver.dto.common.ApiResponse;
import org.pingle.pingleserver.dto.response.MyPingleResponse;
import org.pingle.pingleserver.dto.response.UserInfoResponse;
import org.pingle.pingleserver.dto.type.SuccessMessage;
import org.pingle.pingleserver.service.MeetingService;
import org.pingle.pingleserver.service.UserService;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/v1/users")
@RequiredArgsConstructor
public class UserController {

private final MeetingService meetingService;
private final UserService userService;

@GetMapping("/me")
public ApiResponse<UserInfoResponse> getLoginUserInfo(@UserId Long userId){
return ApiResponse.success(SuccessMessage.OK, userService.getUserInfo(userId));
}

//1. 유저 id를 통해 유저 번개 리스트를 받는다.
//2. 각각의 유저 번개 리스트에 대해 번개를 찾아가느 쿼리가 나간다.
@GetMapping("/me/meetings")
public ApiResponse<List<MyPingleResponse>> getMyPingles (@GUserId Long userId, @NotNull @RequestParam boolean participation,
@RequestHeader(Constants.TEAM_ID)Long teamId) {
return ApiResponse.success(SuccessMessage.OK, meetingService.getMyPingles(userId, teamId, participation));
}

@DeleteMapping("/leave")
public ApiResponse<Void> leave(@UserId Long userId, @Nullable @RequestHeader(Constants.APPLE_LOGOUT_HEADER) String code){
userService.leave(userId, code);
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/pingle/pingleserver/domain/Meeting.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.pingle.pingleserver.domain.enums.MCategory;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
Expand All @@ -21,6 +23,8 @@ public class Meeting extends BaseTimeEntity {
@JoinColumn(name = "pin_id")
private Pin pin;

@OneToMany(mappedBy = "meeting")
private List<UserMeeting> userMeetingList = new ArrayList<>();
@Enumerated(EnumType.STRING)
private MCategory category;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.pingle.pingleserver.dto.response;

import lombok.AccessLevel;
import lombok.Builder;
import org.pingle.pingleserver.domain.Meeting;
import org.pingle.pingleserver.domain.enums.MCategory;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

@Builder(access = AccessLevel.PRIVATE)
public record MyPingleResponse(Long id, MCategory category, String name, String ownerName, String location,
String dDay, String date, String startAt, String endAt, int maxParticipants,
int curParticipants, boolean isOwner) {

private static final String DDAYPREFIX = "D";
private static final String DDAY = "D-Day";
private static final String DONE = "Done";

public static MyPingleResponse of(Meeting meeting, String ownerName, boolean isOwner) {//유저아이디랑 번개 아이디가 필요.
return MyPingleResponse.builder()
.id(meeting.getId())
.category(meeting.getCategory())
.name(meeting.getName())
.ownerName(ownerName)
.location(meeting.getPin().getName())
.dDay(createDDay(meeting.getStartAt(), meeting.getEndAt()))
.date(getDateFromDateTime(meeting.getStartAt()))
.startAt(getTimeFromDateTime(meeting.getStartAt()))
.endAt(getTimeFromDateTime(meeting.getEndAt()))
.maxParticipants(meeting.getMaxParticipants())
.curParticipants(meeting.getUserMeetingList().size())
.isOwner(isOwner)
.build();
}

private static String createDDay(LocalDateTime startAt, LocalDateTime endAt) {
LocalDate startDate = startAt.toLocalDate();
if(LocalDateTime.now().isAfter(endAt)) //현재가 이후면 참
return DONE;
if(ChronoUnit.DAYS.between(startDate, LocalDate.now()) == 0)
return DDAY;
return DDAYPREFIX + ChronoUnit.DAYS.between(startDate, LocalDate.now());//12일 13일 -> 1
}

private static String getDateFromDateTime(LocalDateTime localDateTime) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
return localDateTime.format(formatter);
}
private static String getTimeFromDateTime(LocalDateTime localDateTime) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
return localDateTime.format(formatter);
Parkjyun marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@

import org.pingle.pingleserver.domain.Meeting;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.time.LocalDateTime;
import java.util.List;

public interface MeetingRepository extends JpaRepository<Meeting, Long> {
@Query("SELECT DISTINCT m FROM Meeting m " +//미팅 갖고 오는데
"JOIN FETCH m.pin p " +//핀 조인
"JOIN FETCH p.team t " +//팀 조인
"JOIN UserMeeting um ON um.meeting = m " +//
"WHERE um.user.id = :userId " +//유저 미팅 중에서 주어진 userid만 넣음
" AND (:teamId IS NULL OR t.id = :teamId) " + // 팀에서 팀만 넣음
" AND m.startAt > :currentDateTime " + //예정된 것들만
"ORDER BY m.startAt ASC") // 가까운 순으로
List<Meeting> findUnparticipatedMeetingsForUsersInTeamOrderByTime(Long userId, Long teamId, @Param("currentDateTime")LocalDateTime currentDateTime);
@Query("SELECT DISTINCT m FROM Meeting m " +//미팅 갖고 오는데
"JOIN FETCH m.pin p " +//핀 조인
"JOIN FETCH p.team t " +//팀 조인
"JOIN UserMeeting um ON um.meeting = m " +//
"WHERE um.user.id = :userId " +//유저 미팅 중에서 주어진 userid만 넣음
" AND (:teamId IS NULL OR t.id = :teamId) " + // 팀에서 팀만 넣음
" AND m.startAt <= :currentDateTime " + //참여완료
"ORDER BY m.startAt DESC") // 가까운 순으로
List<Meeting> findParticipatedMeetingsForUsersInTeamOrderByTime(Long userId, Long teamId, @Param("currentDateTime")LocalDateTime currentDateTime);
}
28 changes: 28 additions & 0 deletions src/main/java/org/pingle/pingleserver/service/MeetingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import org.pingle.pingleserver.domain.Meeting;
import org.pingle.pingleserver.domain.Pin;
import org.pingle.pingleserver.domain.UserMeeting;
import org.pingle.pingleserver.domain.enums.MRole;
import org.pingle.pingleserver.dto.request.MeetingRequest;
import org.pingle.pingleserver.dto.response.MyPingleResponse;
import org.pingle.pingleserver.dto.response.ParticipantsResponse;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.CustomException;
Expand All @@ -13,6 +15,8 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
Expand Down Expand Up @@ -44,4 +48,28 @@ public ParticipantsResponse getParticipants(Long meetingId) {
List<UserMeeting> userMeetings = userMeetingRepository.findAllByMeeting(meeting);
return ParticipantsResponse.of(userMeetings);
}

//유저 갖고와서 검증하고
//team도 있는지 검증하고
//usermeetings에서 유저가 포함된 유저 번개 전부 갖고옴
//각각의 유저번개의 번개 전부 갖고옴-> 리스트로 만들고 이때 핀의 Location도 갖고옴
public List<MyPingleResponse> getMyPingles(Long userId, Long teamId, boolean participation) {
List<Meeting> myMeetings = new ArrayList<>();
if(participation) // 참여 완려 -> 이미 시작 startAt이 현재보다
myMeetings = meetingRepository.findParticipatedMeetingsForUsersInTeamOrderByTime(userId, teamId, LocalDateTime.now());
if(!participation) // 참여하지 않은 것 == 나중에 일어날 것 -> startat이 현재보다 늦음
myMeetings = meetingRepository.findUnparticipatedMeetingsForUsersInTeamOrderByTime(userId, teamId, LocalDateTime.now());

return myMeetings.stream()
.map(meeting -> MyPingleResponse.of(meeting, getOwnerName(meeting), isOwner(userId, meeting.getId()))).toList();

}
private String getOwnerName(Meeting meeting) {
UserMeeting userMeeting = userMeetingRepository.findByMeetingAndMeetingRole(meeting, MRole.OWNER)
.orElseThrow(() ->new CustomException(ErrorMessage.RESOURCE_NOT_FOUND));
return userMeeting.getUser().getName();
}
private boolean isOwner(Long userId, Long meetingId) {
return userMeetingRepository.existsByUserIdAndMeetingIdAndMeetingRole(userId, meetingId, MRole.OWNER);
}
}