Skip to content

Commit

Permalink
Merge pull request #40 from kakao-tech-campus-2nd-step3/week8
Browse files Browse the repository at this point in the history
weekly: 8주차 작업 내용 머지
  • Loading branch information
5win authored Oct 25, 2024
2 parents 9d88769 + 149d6fc commit cbf6965
Show file tree
Hide file tree
Showing 17 changed files with 791 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/main/java/com/gamsa/history/constant/ActivityStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.gamsa.history.constant;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum ActivityStatus {
APPLIED("접수"),
WAITING("활동 대기"),
ACT("활동"),
FINISHED("활동 완료"),
REVIEWED("리뷰 완료");

private final String name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.gamsa.history.constant;

import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;

import java.util.stream.Stream;

@Converter
public class ActivityStatusConverter implements AttributeConverter<ActivityStatus, String> {

@Override
public String convertToDatabaseColumn(ActivityStatus activityStatus) {
if (activityStatus == null) {
return null;
}
return activityStatus.getName();
}

@Override
public ActivityStatus convertToEntityAttribute(String name) {
if (name == null) {
return null;
}
return Stream.of(ActivityStatus.values())
.filter(category -> category.getName().equals(name))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 활동 상태 접근."));
}
}
35 changes: 35 additions & 0 deletions src/main/java/com/gamsa/history/controller/HistoryController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.gamsa.history.controller;

import com.gamsa.history.dto.HistoryFindSliceResponse;
import com.gamsa.history.dto.HistorySaveRequest;
import com.gamsa.history.service.HistoryService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/history")
public class HistoryController {
private HistoryService historyService;

@PostMapping
public ResponseEntity<String> addHistory(@RequestBody HistorySaveRequest saveRequest) {
historyService.save(saveRequest);
return new ResponseEntity<>(HttpStatus.CREATED);
}

@GetMapping("{avatar-id}")
public Slice<HistoryFindSliceResponse> findSliceByUserId(@PathVariable("avatar-id") long avatarId, Pageable pageable) {
return historyService.findSliceByAvatarId(avatarId, pageable);
}

@DeleteMapping("{history-id}")
public ResponseEntity<String> deleteHistory(@PathVariable("history-id") long historyId) {
historyService.delete(historyId);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
37 changes: 37 additions & 0 deletions src/main/java/com/gamsa/history/domain/History.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.gamsa.history.domain;

import com.gamsa.activity.domain.Activity;
import com.gamsa.avatar.domain.Avatar;
import com.gamsa.history.constant.ActivityStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
@Builder
@AllArgsConstructor
public class History {
private long historyId;
private Avatar avatar;
private Activity activity;
private ActivityStatus activityStatus;
private boolean reviewed;

public void changeActivityStatusOnDate(LocalDateTime now) {
if ((this.activityStatus == ActivityStatus.APPLIED)
&& (now.isAfter(activity.getNoticeEndDate()))) {
this.activityStatus = ActivityStatus.WAITING;
} else if ((this.activityStatus == ActivityStatus.WAITING)
&& (now.isAfter(activity.getActStartDate()))) {
this.activityStatus = ActivityStatus.ACT;
} else if (now.isAfter(activity.getActEndDate())) {
this.activityStatus = ActivityStatus.FINISHED;
}
}

public void changeReviewed(boolean reviewed) {
this.reviewed = reviewed;
}
}
30 changes: 30 additions & 0 deletions src/main/java/com/gamsa/history/dto/HistoryFindSliceResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.gamsa.history.dto;

import com.gamsa.activity.dto.ActivityDetailResponse;
import com.gamsa.history.constant.ActivityStatus;
import com.gamsa.history.domain.History;
import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@Builder
@RequiredArgsConstructor
public class HistoryFindSliceResponse {

private final long historyId;
private final long avatarId;
private final ActivityDetailResponse activity;
private final ActivityStatus activityStatus;
private final boolean reviewed;

public static HistoryFindSliceResponse from(final History history) {
return HistoryFindSliceResponse.builder()
.historyId(history.getHistoryId())
.avatarId(history.getAvatar().getAvatarId())
.activityStatus(history.getActivityStatus())
.reviewed(history.isReviewed())
.activity(ActivityDetailResponse.from(history.getActivity()))
.build();
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/gamsa/history/dto/HistorySaveRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.gamsa.history.dto;

import com.gamsa.activity.domain.Activity;
import com.gamsa.avatar.domain.Avatar;
import com.gamsa.history.constant.ActivityStatus;
import com.gamsa.history.domain.History;
import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@Builder
@RequiredArgsConstructor
public class HistorySaveRequest {
private final long avatarId;
private final long actId;

public History toModel(Avatar avatar, Activity activity) {
return History.builder()
.activity(activity)
.avatar(avatar)
.activityStatus(ActivityStatus.APPLIED)
.reviewed(false)
.build();
}
}
59 changes: 59 additions & 0 deletions src/main/java/com/gamsa/history/entity/HistoryJpaEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.gamsa.history.entity;


import com.gamsa.activity.entity.ActivityJpaEntity;
import com.gamsa.avatar.entity.AvatarJpaEntity;
import com.gamsa.common.entity.BaseEntity;
import com.gamsa.history.constant.ActivityStatus;
import com.gamsa.history.constant.ActivityStatusConverter;
import com.gamsa.history.domain.History;
import jakarta.persistence.*;
import lombok.*;

@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Entity
@Table(name = "History")
public class HistoryJpaEntity extends BaseEntity {
@Id
@GeneratedValue()
@Column(name = "history_id")
private long historyId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "avatar_id")
private AvatarJpaEntity avatar;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "activity_id")
private ActivityJpaEntity activity;

@Convert(converter = ActivityStatusConverter.class)
@Column(name = "activity_status")
private ActivityStatus activityStatus;

@Column(name = "reviewed")
private boolean reviewed;

public static HistoryJpaEntity from(History history) {
return HistoryJpaEntity.builder()
.historyId(history.getHistoryId())
.avatar(AvatarJpaEntity.from(history.getAvatar()))
.activity(ActivityJpaEntity.from(history.getActivity()))
.activityStatus(history.getActivityStatus())
.reviewed(history.isReviewed())
.build();
}

public History toModel() {
return History.builder()
.historyId(historyId)
.avatar(avatar.toModel())
.activity(activity.toModel())
.activityStatus(activityStatus)
.reviewed(reviewed)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.gamsa.history.repository;

import com.gamsa.history.entity.HistoryJpaEntity;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;

public interface HistoryCustomRepository {
Slice<HistoryJpaEntity> findSliceByAvatarId(long avatarId, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.gamsa.history.repository;

import com.gamsa.history.entity.HistoryJpaEntity;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;

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

import static com.gamsa.history.entity.QHistoryJpaEntity.historyJpaEntity;

@RequiredArgsConstructor
public class HistoryCustomRepositoryImpl implements HistoryCustomRepository {
private final JPAQueryFactory jpaQueryFactory;

@Override
public Slice<HistoryJpaEntity> findSliceByAvatarId(long avatarId, Pageable pageable) {
List<OrderSpecifier> orders = getAllOrderSpecifiers(pageable);

List<HistoryJpaEntity> results = jpaQueryFactory
.selectFrom(historyJpaEntity)
.where(historyJpaEntity.avatar.avatarId.eq(avatarId))
.orderBy(orders.toArray(OrderSpecifier[]::new))
.offset(pageable.getOffset())
.limit(pageable.getOffset() + 1)
.fetch();

return checkLastPage(pageable, results);
}

private Slice<HistoryJpaEntity> checkLastPage(Pageable pageable, List<HistoryJpaEntity> results) {
boolean hasNest = false;
if (results.size() > pageable.getPageSize()) {
hasNest = true;
results.remove(pageable.getPageSize());
}
return new SliceImpl<>(results, pageable, hasNest);
}

private List<OrderSpecifier> getAllOrderSpecifiers(Pageable pageable) {
List<OrderSpecifier> orders = new ArrayList<>();

pageable.getSort().stream()
.forEach(order -> {
Order direction = order.getDirection().isAscending() ? Order.ASC : Order.DESC;
String property = order.getProperty();
PathBuilder orderPath = new PathBuilder(HistoryJpaEntity.class, "activityJpaEntity");
orders.add(new OrderSpecifier(direction, orderPath.get(property)));
}
);
return orders;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.gamsa.history.repository;

import com.gamsa.history.entity.HistoryJpaEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface HistoryJpaRepository extends JpaRepository<HistoryJpaEntity, Long>,
HistoryCustomRepository {
}
18 changes: 18 additions & 0 deletions src/main/java/com/gamsa/history/repository/HistoryRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.gamsa.history.repository;

import com.gamsa.history.domain.History;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;

import java.util.Optional;

public interface HistoryRepository {

void save(History history);

Optional<History> findById(long id);

void delete(History history);

Slice<History> findSliceByAvatarId(long avatarId, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.gamsa.history.repository;

import com.gamsa.history.domain.History;
import com.gamsa.history.entity.HistoryJpaEntity;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@RequiredArgsConstructor
@Repository
public class HistoryRepositoryImpl implements HistoryRepository {
private final HistoryJpaRepository historyJpaRepository;

@Override
public void save(History history) {
historyJpaRepository.save(HistoryJpaEntity.from(history));
}

@Override
public Slice<History> findSliceByAvatarId(long avatarId, Pageable pageable) {
return historyJpaRepository.findSliceByAvatarId(avatarId, pageable)
.map(entity -> entity.toModel());
}

@Override
public void delete(History history) {
historyJpaRepository.delete(HistoryJpaEntity.from(history));
}

@Override
public Optional<History> findById(long id) {
return historyJpaRepository.findById(id)
.map(entity -> entity.toModel());
}
}
Loading

0 comments on commit cbf6965

Please sign in to comment.