Skip to content

Commit

Permalink
Merge pull request #31 from TeamPINGLE/feat/26
Browse files Browse the repository at this point in the history
[feat] 핀 관련 api 생성
  • Loading branch information
Parkjyun authored Jan 9, 2024
2 parents 2066f7e + 00cbdcc commit e147c0b
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.pingle.pingleserver.controller;

import jakarta.annotation.Nullable;
import lombok.RequiredArgsConstructor;
import org.pingle.pingleserver.annotation.UserId;
import org.pingle.pingleserver.domain.enums.MCategory;
import org.pingle.pingleserver.dto.common.ApiResponse;
import org.pingle.pingleserver.dto.reponse.MeetingResponse;
import org.pingle.pingleserver.dto.reponse.PinResponse;
import org.pingle.pingleserver.dto.type.SuccessMessage;
import org.pingle.pingleserver.service.PinService;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/v1/teams/{teamId}/pins")
@RequiredArgsConstructor
public class PinController {

private final PinService pinService;

@GetMapping
public ApiResponse<List<PinResponse>> getPinList (@PathVariable("teamId") Long teamId, @Nullable @RequestParam("category")MCategory category) {
return ApiResponse.success(SuccessMessage.OK, pinService.getPinListFilterByCategory(teamId, category));

}

@GetMapping("/{pinId}/meetings")
public ApiResponse<List<MeetingResponse>> getMeetingList(@UserId Long userId, @PathVariable("pinId") Long pinId) {
return ApiResponse.success(SuccessMessage.OK, pinService.getMeetingDetailList(userId, pinId));
}
}
5 changes: 5 additions & 0 deletions src/main/java/org/pingle/pingleserver/domain/Pin.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -18,6 +20,9 @@ public class Pin extends BaseTimeEntity {
@ManyToOne(fetch = FetchType.LAZY)
private Team team;

@OneToMany(mappedBy = "pin")
private List<Meeting> meetingList;

@Embedded
private Point point;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package org.pingle.pingleserver.domain.enums;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@RequiredArgsConstructor
public enum MCategory {
PLAY("play"), STUDY("study"), MULTI("multi"), OTHERS("others");

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

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

@Builder
public record MeetingResponse(Long id, MCategory category, String name, String ownerName,
String location, String date, String startAt, String endAt, int maxParticipants,
int curParticipants, boolean isParticipating, String chatLink) {
}
27 changes: 27 additions & 0 deletions src/main/java/org/pingle/pingleserver/dto/reponse/PinResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.pingle.pingleserver.dto.reponse;

import org.pingle.pingleserver.domain.Meeting;
import org.pingle.pingleserver.domain.Pin;
import org.pingle.pingleserver.domain.enums.MCategory;

import java.util.Comparator;
import java.util.List;

public record PinResponse(Long id, Double x, Double y, MCategory category, int meetingCount) {
public static PinResponse of(Pin pin) {
return new PinResponse(pin.getId(),pin.getPoint().getX(), pin.getPoint().getY(),
getMostRecentMeetingCategoryOfPin(pin), getMeetingCount(pin));

}
private static MCategory getMostRecentMeetingCategoryOfPin (Pin pin) {
Comparator<Meeting> comparator = Comparator.comparing(Meeting::getStartAt);
List<Meeting> meetingList = pin.getMeetingList();
meetingList.sort(comparator);
return meetingList.get(0).getCategory();
}

private static int getMeetingCount(Pin pin) {
return pin.getMeetingList().size();
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package org.pingle.pingleserver.repository;

import org.pingle.pingleserver.domain.Pin;
import org.pingle.pingleserver.domain.Team;
import org.pingle.pingleserver.domain.Point;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface PinRepository extends JpaRepository<Pin, Long> {
List<Pin> findAllByTeam(Team team);
boolean existsByPoint(Point point);
Pin findByPoint(Point point);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@

import org.pingle.pingleserver.domain.Meeting;
import org.pingle.pingleserver.domain.UserMeeting;
import org.pingle.pingleserver.domain.enums.MRole;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;


import java.util.List;
import java.util.Optional;

public interface UserMeetingRepository extends JpaRepository<UserMeeting, Long> {
Optional<UserMeeting> findByMeetingAndMeetingRole(Meeting meeting, MRole role);
List<UserMeeting> findAllByMeeting(Meeting meeting);
boolean existsByUserIdAndMeeting(Long userId, Meeting meeting);
Optional<UserMeeting> findByUserIdAndMeetingId(Long userId, Long MeetingId);
Expand Down
84 changes: 82 additions & 2 deletions src/main/java/org/pingle/pingleserver/service/PinService.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,73 @@
package org.pingle.pingleserver.service;

import lombok.RequiredArgsConstructor;
import org.pingle.pingleserver.domain.Address;
import lombok.extern.slf4j.Slf4j;
import org.pingle.pingleserver.domain.Meeting;
import org.pingle.pingleserver.domain.Pin;
import org.pingle.pingleserver.domain.Point;
import org.pingle.pingleserver.domain.Team;
import org.pingle.pingleserver.domain.UserMeeting;
import org.pingle.pingleserver.domain.enums.MCategory;
import org.pingle.pingleserver.domain.enums.MRole;
import org.pingle.pingleserver.dto.reponse.MeetingResponse;
import org.pingle.pingleserver.dto.reponse.PinResponse;
import org.pingle.pingleserver.domain.Address;
import org.pingle.pingleserver.domain.Point;
import org.pingle.pingleserver.dto.request.MeetingRequest;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.BusinessException;
import org.pingle.pingleserver.repository.PinRepository;
import org.pingle.pingleserver.repository.TeamRepository;
import org.pingle.pingleserver.repository.UserMeetingRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class PinService {

private final PinRepository pinRepository;
private final TeamRepository teamRepository;
private final UserMeetingRepository userMeetingRepository;

public List<PinResponse> getPinListFilterByCategory(Long teamId, MCategory category) {
Team team = teamRepository.findById(teamId).orElseThrow(() -> new BusinessException(ErrorMessage.NOT_FOUND_RESOURCE));
List<Pin> pinList = pinRepository.findAllByTeam(team);
if(category == null) return pinList.stream().map(PinResponse::of).toList();
return pinList.stream().filter(pin -> checkMeetingsCategoryOfPin(pin, category)).map(PinResponse::of).toList();
}

public List<MeetingResponse> getMeetingDetailList(Long userId, Long pinId) {
Pin pin = pinRepository.findById(pinId).orElseThrow(() -> new BusinessException(ErrorMessage.NOT_FOUND_RESOURCE));
Comparator<Meeting> comparator = Comparator.comparing(Meeting::getStartAt);
List<Meeting> meetingList = pin.getMeetingList();
meetingList.sort(comparator);
List<MeetingResponse> responseList = new ArrayList<>();
for(Meeting meeting : meetingList) {
responseList.add(MeetingResponse.builder()
.id(meeting.getId())
.category(meeting.getCategory())
.name(meeting.getName())
.ownerName(getOwnerName(meeting))//만든사람
.location(pin.getName())
.date(getDateFromDateTime(meeting.getStartAt()))//meeting start 날짜 parsing
.startAt(getTimeFromDateTime(meeting.getStartAt()))//start 시간 parsing
.endAt(getTimeFromDateTime(meeting.getEndAt()))//end 시간 parsing
.maxParticipants(meeting.getMaxParticipants())
.curParticipants(getCurParticipants(meeting))
.isParticipating(isParticipating(userId, meeting))
.chatLink(meeting.getChatLink())
.build());
}
return responseList;
}

@Transactional
public Pin verifyAndReturnPin(MeetingRequest request, Long groupId) {
Expand All @@ -33,6 +82,37 @@ public Pin verifyAndReturnPin(MeetingRequest request, Long groupId) {
}
return pinRepository.findByPoint(new Point(request.x(), request.y()));
}

private boolean checkMeetingsCategoryOfPin(Pin pin, MCategory category) {
List<Meeting> meetingList = pin.getMeetingList();
for(Meeting meeting : meetingList) {
if(meeting.getCategory().getValue().equals(category.getValue()))
return true;
}
return false;
}

private String getOwnerName(Meeting meeting) {
UserMeeting userMeeting = userMeetingRepository.findByMeetingAndMeetingRole(meeting, MRole.OWNER).orElseThrow(() ->new BusinessException(ErrorMessage.NOT_FOUND_RESOURCE ));
return userMeeting.getUser().getName();
}

private int getCurParticipants(Meeting meeting) {
return userMeetingRepository.findAllByMeeting(meeting).size();
}

private boolean isParticipating(Long userId, Meeting meeting) {
return userMeetingRepository.existsByUserIdAndMeeting(userId, meeting);
}

private String getDateFromDateTime(LocalDateTime localDateTime) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
return localDateTime.format(formatter);
}
private String getTimeFromDateTime(LocalDateTime localDateTime) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
return localDateTime.format(formatter);
}

private boolean exist(Point point) {
return pinRepository.existsByPoint(point);
Expand Down

0 comments on commit e147c0b

Please sign in to comment.