Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Binary file added 0주차미션/0주차미션_고경수.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2,976 changes: 2,976 additions & 0 deletions 0주차미션/hello.vuerd.json

Large diffs are not rendered by default.

Binary file added 10주차미션/.DS_Store
Binary file not shown.
Binary file added 10주차미션/src/.DS_Store
Binary file not shown.
Binary file added 10주차미션/src/main/.DS_Store
Binary file not shown.
Binary file added 10주차미션/src/main/java/.DS_Store
Binary file not shown.
Binary file added 10주차미션/src/main/java/com/.DS_Store
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.umc9th;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;


@SpringBootApplication
@EnableJpaAuditing
public class Umc9thApplication {
public static void main(String[] args) {
SpringApplication.run(Umc9thApplication.class, args);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.example.umc9th.domain.mission.controller;

import com.example.umc9th.domain.mission.dto.res.MissionResDTO;
import com.example.umc9th.domain.mission.service.MissionQueryService;
import com.example.umc9th.global.validator.ValidPage;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/missions")
public class MissionController {

private final MissionQueryService missionQueryService;

@Operation(summary = "특정 가게의 미션 목록 조회", description = "Store ID로 미션 리스트를 페이징하여 조회합니다.")
@GetMapping("/{storeId}")
public MissionResDTO.MissionPreviewListDTO getMissions(
@PathVariable Long storeId,
@ValidPage @RequestParam Integer page
) {
return missionQueryService.getMissionsByStore(storeId, page);
}

@Operation(summary = "내가 진행 중인 미션 목록 조회", description = "User ID로 진행 중인 미션 리스트를 페이징하여 조회합니다.")
@GetMapping("/user/{userId}")
public MissionResDTO.MissionPreviewListDTO getUserMissions(
@PathVariable Long userId,
@ValidPage @RequestParam(defaultValue = "1") Integer page
) {
return missionQueryService.getMissionsByUser(userId, page);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.example.umc9th.domain.mission.converter;

import com.example.umc9th.domain.mission.dto.res.MissionResDTO;
import com.example.umc9th.domain.mission.entity.Mission;
import com.example.umc9th.domain.user.entity.mapping.UserMission;
import org.springframework.data.domain.Page;

public class MissionConverter {

public static MissionResDTO.MissionPreviewListDTO toMissionPreviewListDTOFromUserMission(Page<UserMission> userMissionPage) {

return MissionResDTO.MissionPreviewListDTO.builder()
.missionList(
userMissionPage.getContent().stream()
.map(um -> {
Mission m = um.getMission();
return MissionResDTO.MissionPreviewDTO.builder()
.missionId(m.getId())
.title(m.getTitle())
.description(m.getDescription())
.rewardPoint(m.getPoint())
.build();
}).toList()
)
.currentPage(userMissionPage.getNumber() + 1)
.totalPage(userMissionPage.getTotalPages())
.totalElements(userMissionPage.getTotalElements())
.isFirst(userMissionPage.isFirst())
.isLast(userMissionPage.isLast())
.build();
}

// Mission 전용
public static MissionResDTO.MissionPreviewListDTO toMissionPreviewListDTOFromMission(Page<Mission> missionPage) {

return MissionResDTO.MissionPreviewListDTO.builder()
.missionList(
missionPage.getContent().stream()
.map(m ->
MissionResDTO.MissionPreviewDTO.builder()
.missionId(m.getId())
.title(m.getTitle())
.description(m.getDescription())
.rewardPoint(m.getPoint())
.build()
).toList()
)
.currentPage(missionPage.getNumber() + 1)
.totalPage(missionPage.getTotalPages())
.totalElements(missionPage.getTotalElements())
.isFirst(missionPage.isFirst())
.isLast(missionPage.isLast())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.umc9th.domain.mission.dto.res;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

public class MissionResDTO {

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class MissionPreviewDTO {
private Long missionId;
private String title;
private String description;
private Integer rewardPoint;
}

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class MissionPreviewListDTO {
private List<MissionPreviewDTO> missionList;
private Integer currentPage;
private Integer totalPage;
private Long totalElements;
private Boolean isFirst;
private Boolean isLast;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.example.umc9th.domain.mission.entity;

import com.example.umc9th.domain.store.entity.Store;
import com.example.umc9th.domain.user.entity.mapping.UserMission;
import com.example.umc9th.global.entity.BaseEntity;
import jakarta.persistence.*;
import lombok.*;

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

@Entity
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
@Table(name = "mission")
public class Mission extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "mission_id")
private Long id;

@Column(nullable = false, length = 100)
private String title;

@Column(columnDefinition = "TEXT")
private String description;

@Column(nullable = false)
private Integer point;

@Column(length = 50)
private String verification;

// Store와의 연관 관계 (N:1) - 연관 관계의 주인
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "store_id")
private Store store;

// UserMission과의 연관 관계 (1:N)
@OneToMany(mappedBy = "mission", cascade = CascadeType.ALL)
@Builder.Default
private List<UserMission> userMissionList = new ArrayList<>();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.umc9th.domain.mission.exception;

import com.example.umc9th.global.apiPayload.code.BaseErrorCode;
import com.example.umc9th.global.apiPayload.exception.GeneralException;

public class MissionException extends GeneralException {

public MissionException(BaseErrorCode code) {
super(code);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.umc9th.domain.mission.repository;

import com.example.umc9th.domain.mission.entity.Mission;
import com.example.umc9th.domain.store.entity.Store;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MissionRepository extends JpaRepository<Mission, Long> {
Page<Mission> findByStore(Store store, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.example.umc9th.domain.mission.service;

import com.example.umc9th.domain.mission.converter.MissionConverter;
import com.example.umc9th.domain.mission.dto.res.MissionResDTO;
import com.example.umc9th.domain.mission.entity.Mission;
import com.example.umc9th.domain.mission.repository.MissionRepository;
import com.example.umc9th.domain.store.entity.Store;
import com.example.umc9th.domain.store.repository.StoreRepository;
import com.example.umc9th.domain.user.entity.mapping.UserMission;
import com.example.umc9th.domain.user.enums.UserMissionStatus;
import com.example.umc9th.domain.user.repository.UserMissionRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

private final MissionRepository missionRepository;
private final StoreRepository storeRepository;
private final UserMissionRepository userMissionRepository;

public MissionResDTO.MissionPreviewListDTO getMissionsByStore(Long storeId, Integer page) {

Store store = storeRepository.findById(storeId)
.orElseThrow(() -> new RuntimeException("Store not found"));

PageRequest pageable = PageRequest.of(page - 1, 10);

Page<Mission> missionPage = missionRepository.findByStore(store, pageable);

return MissionConverter.toMissionPreviewListDTOFromMission(missionPage);
}

public MissionResDTO.MissionPreviewListDTO getMissionsByUser(Long userId, Integer page) {
PageRequest pageable = PageRequest.of(page - 1, 10);

Page<UserMission> missionPage = userMissionRepository.findByUserIdAndStatus(
userId,
UserMissionStatus.CHALLENGING,
pageable
);

return MissionConverter.toMissionPreviewListDTOFromUserMission(missionPage);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.example.umc9th.domain.review.controller;

import com.example.umc9th.domain.review.converter.ReviewConverter;
import com.example.umc9th.domain.review.dto.ReviewResponse;
import com.example.umc9th.domain.review.dto.req.ReviewReqDTO;
import com.example.umc9th.domain.review.dto.res.ReviewResDTO;
import com.example.umc9th.domain.review.entity.Review;
import com.example.umc9th.domain.review.exception.code.ReviewSuccessCode;
import com.example.umc9th.domain.review.service.command.ReviewCommandService;
import com.example.umc9th.domain.review.service.query.ReviewQueryService;
import com.example.umc9th.global.apiPayload.ApiResponse;
import com.example.umc9th.global.apiPayload.code.GeneralSuccessCode;
import com.example.umc9th.global.validator.ValidPage;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

import org.springframework.data.domain.Page;

import org.springframework.web.bind.annotation.*;

@RequiredArgsConstructor
@RestController
@RequestMapping("/reviews")
public class ReviewController {

private final ReviewQueryService reviewQueryService;
private final ReviewCommandService reviewCommandService;

/**
* 내가 작성한 리뷰 조회 API
*/
@Operation(summary = "내가 작성한 리뷰 조회", description = "사용자가 작성한 리뷰를 필터링하여 페이징 조회합니다.")
@GetMapping("/user/{userId}")
public ApiResponse<ReviewResDTO.ReviewListDTO> getMyReviews(
@PathVariable Long userId,
@RequestParam(required = false) Long storeId,
@RequestParam(required = false) Integer minStar,
@RequestParam(required = false) Integer maxStar,
@ValidPage @RequestParam(defaultValue = "1") Integer page
) {

Page<ReviewResponse> reviews = reviewQueryService.getReviewsByUserWithFilters(
userId, storeId, minStar, maxStar, page
);

return ApiResponse.onSuccess(
GeneralSuccessCode.OK,
ReviewConverter.toReviewListDTO(reviews)
);
}

/**
* 2. 가게에 리뷰 추가하기 API
* POST /reviews
*/
@PostMapping
public ApiResponse<ReviewResDTO.CreateReviewResultDTO> createReview(
@RequestBody @Valid ReviewReqDTO.CreateReviewDTO request
) {
ReviewResDTO.CreateReviewResultDTO result = reviewCommandService.createReview(request);
return ApiResponse.onSuccess(GeneralSuccessCode.CREATED, result);
}

// 가게의 리뷰 목록 조회
@Operation(summary = "가게의 리뷰 목록 조회", description = "가게 이름으로 리뷰 리스트를 페이징하여 조회합니다.")
@GetMapping
public ApiResponse<ReviewResDTO.ReviewPreviewListDTO> getReviews(
@RequestParam String storeName,
@RequestParam(defaultValue = "1") Integer page
) {
ReviewResDTO.ReviewPreviewListDTO result =
reviewQueryService.findReview(storeName, page);

return ApiResponse.onSuccess(
ReviewSuccessCode.REVIEW_FOUND,
result
);
}
}
Loading