Skip to content

Commit

Permalink
Merge pull request #92 from softeerbootcamp4th/feat/#87-get-lottery
Browse files Browse the repository at this point in the history
Feat/#87 get lottery
  • Loading branch information
wjddn2165 authored Aug 12, 2024
2 parents 8438b20 + b2b4b5b commit 2dfbd4a
Show file tree
Hide file tree
Showing 13 changed files with 106 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import JGS.CasperEvent.domain.event.dto.RequestDto.AdminRequestDto;
import JGS.CasperEvent.domain.event.dto.RequestDto.LotteryEventRequestDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.LotteryEventDetailResponseDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.LotteryEventResponseDto;
import JGS.CasperEvent.domain.event.service.adminService.AdminService;
import JGS.CasperEvent.global.response.ResponseDto;
Expand All @@ -11,6 +12,8 @@
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/admin")
public class AdminController {
Expand All @@ -28,11 +31,19 @@ public ResponseEntity<ResponseDto> postAdmin(@RequestBody @Valid AdminRequestDto
.body(adminService.postAdmin(adminRequestDto));
}

@GetMapping("/event/lottery")
public ResponseEntity<List<LotteryEventDetailResponseDto>> getLotteryEvent() {
return ResponseEntity
.status(HttpStatus.OK)
.body(adminService.getLotteryEvent());
}

@PostMapping("/event/lottery")
public ResponseEntity<LotteryEventResponseDto> createLotteryEvent(
@Valid @RequestBody LotteryEventRequestDto lotteryEventRequestDto) {
return ResponseEntity
.status(HttpStatus.CREATED)
.body(adminService.createLotteryEvent(lotteryEventRequestDto));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package JGS.CasperEvent.domain.event.dto.ResponseDto;

import JGS.CasperEvent.domain.event.entity.event.LotteryEvent;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public record LotteryEventDetailResponseDto(LocalDateTime startDateTime, LocalDateTime endDateTime,
AtomicInteger appliedCount, int winnerCount,
LocalDateTime createdAt, LocalDateTime updatedAt) {
public static ArrayList<LotteryEventDetailResponseDto> of(List<LotteryEvent> lotteryEvent) {
ArrayList<LotteryEventDetailResponseDto> lotteryEventDtoList = new ArrayList<>();
for (LotteryEvent event : lotteryEvent) {
lotteryEventDtoList.add(new LotteryEventDetailResponseDto(
event.getStartDateTime(),
event.getEndDateTime(),
event.getAppliedCount(),
event.getWinnerCount(),
event.getCreatedAt(),
event.getUpdatedAt()));
}
return lotteryEventDtoList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

public record LotteryEventResponseDto(LocalDateTime serverDateTime, LocalDateTime eventStartDate, LocalDateTime eventEndDate,
public record LotteryEventResponseDto(LocalDateTime serverDateTime, LocalDateTime eventStartDate,
LocalDateTime eventEndDate,
long activePeriod) {
public static LotteryEventResponseDto of(LotteryEvent lotteryEvent, LocalDateTime serverDateTime) {
return new LotteryEventResponseDto(
Expand All @@ -15,5 +16,4 @@ public static LotteryEventResponseDto of(LotteryEvent lotteryEvent, LocalDateTim
ChronoUnit.DAYS.between(lotteryEvent.getStartDateTime(), lotteryEvent.getEndDateTime())
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,20 @@

import JGS.CasperEvent.domain.event.dto.RequestDto.CasperBotRequestDto;
import JGS.CasperEvent.global.entity.BaseEntity;
import JGS.CasperEvent.global.util.UserUtil;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.ToString;


@Entity
@Getter
@ToString
public class CasperBot extends BaseEntity {
public CasperBot(CasperBotRequestDto postCasperBot, String phoneNumber) {
this.casperId = UserUtil.generateId();
this.phoneNumber = phoneNumber;
this.eyeShape = postCasperBot.getEyeShape();
this.eyePosition = postCasperBot.getEyePosition();
this.mouthShape = postCasperBot.getMouthShape();
this.color = postCasperBot.getColor();
this.sticker = postCasperBot.getSticker();
this.name = postCasperBot.getName();
this.expectation = postCasperBot.getExpectation();
}

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long casperId;

private String phoneNumber;

private int eyeShape;
Expand All @@ -36,56 +30,14 @@ public CasperBot() {

}

public Long getCasperId() {
return casperId;
}

public String getPhoneNumber() {
return phoneNumber;
}

public int getEyeShape() {
return eyeShape;
}

public int getEyePosition() {
return eyePosition;
}

public int getMouthShape() {
return mouthShape;
}

public int getColor() {
return color;
}

public int getSticker() {
return sticker;
}

public String getName() {
return name;
}

public String getExpectation() {
return expectation;
}

@Override
public String toString() {
return "CasperBot{" +
"casperId=" + casperId +
", phoneNumber='" + phoneNumber + '\'' +
", eyeShape=" + eyeShape +
", eyePosition=" + eyePosition +
", mouthShape=" + mouthShape +
", color=" + color +
", sticker=" + sticker +
", name='" + name + '\'' +
", expectation='" + expectation + '\'' +
", createdAt='" + getCreatedAt() + '\'' +
", updatedAt='" + getUpdatedAt() + '\'' +
'}';
public CasperBot(CasperBotRequestDto requestDto, String phoneNumber) {
this.phoneNumber = phoneNumber;
this.eyeShape = requestDto.getEyeShape();
this.eyePosition = requestDto.getEyePosition();
this.mouthShape = requestDto.getMouthShape();
this.color = requestDto.getColor();
this.sticker = requestDto.getSticker();
this.name = requestDto.getName();
this.expectation = requestDto.getExpectation();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import lombok.Getter;

import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicInteger;

@Getter
@MappedSuperclass
Expand All @@ -21,12 +22,14 @@ public class BaseEvent extends BaseEntity {
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
protected LocalDateTime endDateTime;
protected int winnerCount;
protected AtomicInteger appliedCount;

// 기본 생성자에서 디폴트 값 설정
public BaseEvent() {
this.startDateTime = LocalDateTime.now();
this.endDateTime = LocalDateTime.now().plusMinutes(10);
this.winnerCount = 0; // 기본 우승자 수를 0으로 설정
this.appliedCount = new AtomicInteger(0);
}

// 특정 값을 설정할 수 있는 생성자
Expand All @@ -35,4 +38,8 @@ public BaseEvent(LocalDateTime startDateTime, LocalDateTime endDateTime, int win
this.endDateTime = endDateTime;
this.winnerCount = winnerCount;
}

public void addAppliedCount(){
this.appliedCount.addAndGet(1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ public class LotteryEvent extends BaseEvent {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long lotteryEventId;

public LotteryEvent(LocalDateTime eventStartDateTime, LocalDateTime eventEndDateTime, int winnerCount){
this.startDateTime = eventStartDateTime;
this.endDateTime = eventEndDateTime;
public LotteryEvent(LocalDateTime startDateTime, LocalDateTime endDateTime, int winnerCount) {
this.startDateTime = startDateTime;
this.endDateTime = endDateTime;
this.winnerCount = winnerCount;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import JGS.CasperEvent.domain.event.dto.RequestDto.AdminRequestDto;
import JGS.CasperEvent.domain.event.dto.RequestDto.LotteryEventRequestDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.LotteryEventDetailResponseDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.LotteryEventResponseDto;
import JGS.CasperEvent.domain.event.entity.admin.Admin;
import JGS.CasperEvent.domain.event.entity.event.LotteryEvent;
Expand All @@ -11,11 +12,13 @@
import JGS.CasperEvent.global.enums.CustomErrorCode;
import JGS.CasperEvent.global.enums.Role;
import JGS.CasperEvent.global.error.exception.CustomException;
import JGS.CasperEvent.global.error.exception.TooManyLotteryEventException;
import JGS.CasperEvent.global.response.ResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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

@RequiredArgsConstructor
Expand Down Expand Up @@ -44,6 +47,8 @@ public ResponseDto postAdmin(AdminRequestDto adminRequestDto) {
}

public LotteryEventResponseDto createLotteryEvent(LotteryEventRequestDto lotteryEventRequestDto) {
if(lotteryEventRepository.count() >= 1) throw new TooManyLotteryEventException();

LotteryEvent lotteryEvent = lotteryEventRepository.save(new LotteryEvent(
lotteryEventRequestDto.getEventStartDateTime(),
lotteryEventRequestDto.getEventEndDateTime(),
Expand All @@ -52,4 +57,10 @@ public LotteryEventResponseDto createLotteryEvent(LotteryEventRequestDto lottery

return LotteryEventResponseDto.of(lotteryEvent, LocalDateTime.now());
}

public List<LotteryEventDetailResponseDto> getLotteryEvent() {
return LotteryEventDetailResponseDto.of(
lotteryEventRepository.findAll()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import JGS.CasperEvent.domain.event.dto.ResponseDto.LotteryEventResponseDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.LotteryParticipantResponseDto;
import JGS.CasperEvent.domain.event.entity.casperBot.CasperBot;
import JGS.CasperEvent.domain.event.entity.event.LotteryEvent;
import JGS.CasperEvent.domain.event.entity.participants.LotteryParticipants;
import JGS.CasperEvent.domain.event.repository.CasperBotRepository;
import JGS.CasperEvent.domain.event.repository.eventRepository.LotteryEventRepository;
Expand All @@ -13,6 +14,7 @@
import JGS.CasperEvent.global.entity.BaseUser;
import JGS.CasperEvent.global.enums.CustomErrorCode;
import JGS.CasperEvent.global.error.exception.CustomException;
import JGS.CasperEvent.global.error.exception.LotteryEventNotExists;
import JGS.CasperEvent.global.jwt.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -45,18 +47,23 @@ public LotteryEventService(LotteryEventRepository lotteryEventRepository,
this.userRepository = userRepository;
}

public CasperBotResponseDto postCasperBot(BaseUser user, CasperBotRequestDto postCasperBot) throws CustomException {
public CasperBotResponseDto postCasperBot(BaseUser user, CasperBotRequestDto casperBotRequestDto) throws CustomException {
LotteryParticipants participants = registerUserIfNeed(user);
LotteryEvent lotteryEvent = lotteryEventRepository.findById(1L).orElseThrow(LotteryEventNotExists::new);

CasperBot casperBot = casperBotRepository.save(new CasperBot(casperBotRequestDto, user.getId()));
lotteryEvent.addAppliedCount();

CasperBot casperBot = new CasperBot(postCasperBot, participants.getBaseUser().getId());
participants.updateCasperId(casperBot.getCasperId());

if (!casperBot.getExpectation().isEmpty()) participants.expectationAdded();
lotteryParticipantsRepository.save(participants);
casperBotRepository.save(casperBot);
if (!casperBot.getExpectation().isEmpty()) {
participants.expectationAdded();
lotteryEvent.addAppliedCount();
}

CasperBotResponseDto casperBotDto = CasperBotResponseDto.of(casperBot);
redisService.addData(casperBotDto);

return casperBotDto;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum CustomErrorCode {
JWT_MISSING("인증 토큰이 존재하지 않습니다.", 401),
MULTIPLE_RUSH_EVENTS_FOUND("해당 날짜에 여러 개의 이벤트가 존재합니다.", 409),
TODAY_RUSH_EVENT_NOT_FOUND("오늘의 이벤트를 찾을 수 없습니다.", 404),
LOTTERY_EVENT_ALREADY_EXISTS("추첨 이벤트가 이미 존재합니다.", 409),
INVALID_RUSH_EVENT_OPTIONS_COUNT("이벤트의 옵션 수가 올바르지 않습니다.", 500),
INVALID_RUSH_EVENT_OPTION_ID("옵션 ID는 1 또는 2여야 합니다.", 400);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import JGS.CasperEvent.global.enums.CustomErrorCode;
import JGS.CasperEvent.global.error.exception.CustomException;
import JGS.CasperEvent.global.error.exception.TooManyLotteryEventException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
Expand Down Expand Up @@ -33,10 +34,17 @@ public ResponseEntity<ErrorResponse> missingCookieHandler(){
@ExceptionHandler(UserPrincipalNotFoundException.class)
public ResponseEntity<ErrorResponse> userPrincipalNotFoundHandler(){
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.status(HttpStatus.CONFLICT)
.body(ErrorResponse.of(CustomErrorCode.USER_NOT_FOUND));
}

@ExceptionHandler(TooManyLotteryEventException.class)
public ResponseEntity<ErrorResponse> tooManyLotteryEventExceptionHandler(){
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(ErrorResponse.of(CustomErrorCode.LOTTERY_EVENT_ALREADY_EXISTS));
}

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e){
BindingResult bindingResult = e.getBindingResult();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package JGS.CasperEvent.global.error.exception;

public class LotteryEventNotExists extends RuntimeException{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package JGS.CasperEvent.global.error.exception;

public class TooManyLotteryEventException extends RuntimeException {

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package JGS.CasperEvent.domain.event.controller.eventController;

import jakarta.servlet.http.Cookie;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
Expand Down

0 comments on commit 2dfbd4a

Please sign in to comment.