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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ out/

# QueryDSL 자동 생성 Q 클래스 무시
/build/generated/querydsl/

# 로컬 환경 설정 파일
src/main/resources/application-local.yml
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ dependencies {
// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'

// Security
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'

// Jwt
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
implementation 'io.jsonwebtoken:jjwt-impl:0.12.3'
implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3'
implementation 'org.springframework.boot:spring-boot-configuration-processor'

}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,26 @@
import com.example.umc9th2.domain.mission.dto.req.MissionReqDTO;
import com.example.umc9th2.domain.mission.dto.res.MissionResDTO;
import com.example.umc9th2.domain.mission.service.MissionService;
import com.example.umc9th2.global.annotation.ValidPage;
import com.example.umc9th2.global.apiPayload.ApiResponse;
import com.example.umc9th2.global.apiPayload.code.GeneralSuccessCode;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import java.util.List;

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

private final MissionService missionService;

/**
* 미션 생성
*/

@PostMapping
public ApiResponse<MissionResDTO.CreateMission> createMission(
@RequestBody MissionReqDTO request
Expand All @@ -30,4 +35,17 @@ public ApiResponse<MissionResDTO.CreateMission> createMission(
)
);
}

//특정가게의미션을 조회
@GetMapping("/stores/{storeId}")
@Operation(summary = "특정 가게의 미션 목록 조회", description = "특정 가게에 등록된 미션 목록을 페이징하여 조회합니다.")
public ApiResponse<List<MissionResDTO.MissionList>> getStoreMissions(
@PathVariable Long storeId,
@ValidPage @RequestParam Integer page
) {
Pageable pageable = PageRequest.of(page - 1, 10);
Page<com.example.umc9th2.domain.mission.entity.Mission> missionPage = missionService.getStoreMissions(storeId, pageable);
List<MissionResDTO.MissionList> result = MissionConverter.toMissionListDTO(missionPage.getContent());
return ApiResponse.onSuccess(GeneralSuccessCode.OK, result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.example.umc9th2.domain.mission.entity.Mission;
import com.example.umc9th2.domain.store.entity.Store;

import java.util.List;

public class MissionConverter {

// DTO -> Entity 변환 (미션 생성)
Expand All @@ -29,4 +31,17 @@ public static MissionResDTO.CreateMission toCreateMissionDTO(Mission mission) {
mission.getStore().getStoreName()
);
}

// 미션목록반환
public static List<MissionResDTO.MissionList> toMissionListDTO(List<Mission> missionList) {
return missionList.stream()
.map(mission -> new MissionResDTO.MissionList(
mission.getMissionId(),
mission.getTitle(),
mission.getDescription(),
mission.getRewardPoints(),
mission.getIsActive()
))
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,12 @@ public record CreateMission(
Integer rewardPoints,
String storeName //store 에서
) {}
//미션 week 9
public record MissionList(
Long missionId,
String title,
String description,
Integer rewardPoints,
Boolean isActive
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.example.umc9th2.domain.store.entity.Store;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
Expand All @@ -11,6 +13,8 @@
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Mission {

@Id
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.example.umc9th2.domain.mission.repository;

import com.example.umc9th2.domain.mission.entity.Mission;
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_StoreId(Long storeId, Pageable pageable);

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import com.example.umc9th2.domain.store.entity.Store;
import com.example.umc9th2.domain.store.repository.StoreRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -26,4 +28,8 @@ public Mission createMission(MissionReqDTO request) {

return missionRepository.save(mission);
}

public Page<Mission> getStoreMissions(Long storeId, Pageable pageable) {
return missionRepository.findByStore_StoreId(storeId, pageable);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@
import com.example.umc9th2.domain.review.entity.Review;
import com.example.umc9th2.domain.review.service.ReviewCommandService;
import com.example.umc9th2.domain.review.service.ReviewQueryService;
import com.example.umc9th2.global.annotation.ValidPage;
import com.example.umc9th2.global.apiPayload.ApiResponse;
import com.example.umc9th2.global.apiPayload.code.GeneralSuccessCode;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import java.util.List;
Expand Down Expand Up @@ -45,4 +50,16 @@ public ApiResponse<ReviewResDTO.CreateReview> createReview(
ReviewResDTO.CreateReview result = reviewCommandService.createReview(request, userId);
return ApiResponse.onSuccess(code, result);
}
//작성한 리뷰 목록조회
@GetMapping("/my-reviews")
@Operation(summary = "내가 작성한 리뷰 목록 조회", description = "특정 사용자가 작성한 리뷰 목록을 페이징하여 조회합니다.")
public ApiResponse<List<ReviewResDTO.MyReviewList>> getMyReviews(
@RequestParam Long userId,
@ValidPage @RequestParam Integer page
) {
Pageable pageable = PageRequest.of(page - 1, 10);
Page<Review> reviewPage = reviewQueryService.getMyReviews(userId, pageable);
List<ReviewResDTO.MyReviewList> result = ReviewConverter.toMyReviewListDTO(reviewPage.getContent());
return ApiResponse.onSuccess(GeneralSuccessCode.OK, result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,19 @@ public static ReviewResDTO.CreateReview toCreateReviewResultDto(Review review) {
LocalDateTime.now()
);
}

//내가 작성한 리뷰 DTO 반환해
public static List<ReviewResDTO.MyReviewList> toMyReviewListDTO(List<Review> reviewList) {
return reviewList.stream()
.map(review -> new ReviewResDTO.MyReviewList(
review.getReviewId(),
review.getStore() != null ? review.getStore().getStoreName() : null,
review.getRating(),
review.getContent(),
review.getCreatedAt()
))
.toList();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,12 @@ public record CreateReview(
String storeName,
LocalDateTime createdAt
) {}
//내가 작성한 review 목ㄹ곻
public record MyReviewList(
Long reviewId,
String storeName,
Integer rating,
String content,
LocalDateTime createdAt
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.example.umc9th2.domain.user.entity.User;
import com.example.umc9th2.domain.store.entity.Store;
import com.example.umc9th2.global.BaseEntity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -13,8 +15,9 @@
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Review {
public class Review extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.example.umc9th2.domain.review.repository;

import com.example.umc9th2.domain.review.entity.Review;
import org.springframework.data.jpa.repository.*;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ReviewRepository extends JpaRepository<Review, Long>, ReviewQueryDsl {
//내가 작성한 리뷰 목록
Page<Review> findByUser_UserId(Long userId, Pageable pageable);

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.example.umc9th2.domain.review.service;

import com.example.umc9th2.domain.review.dto.res.ReviewSearchDTO;
import com.example.umc9th2.domain.review.entity.QReview;
import com.example.umc9th2.domain.review.entity.Review;
import com.example.umc9th2.domain.review.entity.QReview;
import com.example.umc9th2.domain.review.repository.ReviewRepository;
import com.example.umc9th2.domain.store.entity.QStore;
import com.querydsl.core.BooleanBuilder;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -23,7 +25,7 @@ public List<Review> searchReview(String type, String query) {
QReview review = QReview.review;
BooleanBuilder builder = new BooleanBuilder();

// 동적 쿼리 조건

if (type.equals("store")) {
builder.and(review.store.storeName.contains(query));
}
Expand All @@ -34,14 +36,16 @@ public List<Review> searchReview(String type, String query) {

if (type.equals("both")) {
String[] queries = query.split("&");
String firstQuery = queries[0]; // storeName
String secondQuery = queries[1]; // content

String firstQuery = queries[0];
String secondQuery = queries[1];
builder.and(review.store.storeName.contains(firstQuery));
builder.and(review.content.contains(secondQuery));
}

List<Review> reviewList = reviewRepository.searchReview(builder);
return reviewList;
}
public Page<Review> getMyReviews(Long userId, Pageable pageable) {
return reviewRepository.findByUser_UserId(userId, pageable);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public enum StoreErrorCode implements BaseErrorCode {
"가게를 찾을 수 없습니다."),
;

private final org.springframework.http.HttpStatus status;
private final HttpStatus status;
private final String code;
private final String message;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.example.umc9th2.domain.user.controller;

import com.example.umc9th2.domain.user.dto.req.UserReqDTO;
import com.example.umc9th2.domain.user.dto.res.UserResDTO;
import com.example.umc9th2.domain.user.service.UserService;
import com.example.umc9th2.global.apiPayload.ApiResponse;
import com.example.umc9th2.global.apiPayload.code.GeneralSuccessCode;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
public class UserController {

private final UserService userService;

// 회원가입
@PostMapping("/sign-up")
@Operation(summary = "회원가입", description = "새로운 사용자를 등록합니다.")
public ApiResponse<UserResDTO.JoinDTO> signup(
@RequestBody @Valid UserReqDTO.JoinDTO request
) {
UserResDTO.JoinDTO result = userService.signup(request);
return ApiResponse.onSuccess(GeneralSuccessCode.CREATED, result);
}

// 로그인
@PostMapping("/login")
@Operation(summary = "로그인", description = "사용자 로그인을 처리합니다.")
public ApiResponse<UserResDTO.LoginDTO> login(
@RequestBody @Valid UserReqDTO.LoginDTO dto
) {
UserResDTO.LoginDTO result = userService.login(dto);
return ApiResponse.onSuccess(GeneralSuccessCode.OK, result);
}

// 로그아웃
@PostMapping("/logout")
@Operation(summary = "로그아웃", description = "사용자 로그아웃을 처리합니다.")
public ApiResponse<String> logout() {
return ApiResponse.onSuccess(GeneralSuccessCode.OK, "로그아웃되었습니다.");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
import com.example.umc9th2.domain.user.dto.MyMissionDTO;
import com.example.umc9th2.domain.user.dto.res.UserMissionResDTO;
import com.example.umc9th2.domain.user.service.UserMissionService;
import com.example.umc9th2.global.annotation.ValidPage;
import com.example.umc9th2.global.apiPayload.ApiResponse;
import com.example.umc9th2.global.apiPayload.code.GeneralSuccessCode;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
Expand Down Expand Up @@ -36,4 +39,16 @@ public ApiResponse<UserMissionResDTO.ChallengeMission> challengeMission(
UserMissionResDTO.ChallengeMission result = userMissionService.challengeMission(missionId);
return ApiResponse.onSuccess(code, result);
}
//진행중인 미션목록죄회
@GetMapping("/in-progress")
@Operation(summary = "내가 진행중인 미션 목록 조회", description = "특정 사용자가 진행중인 미션 목록을 페이징하여 조회합니다.")
public ApiResponse<List<MyMissionDTO>> getInProgressMissions(
@RequestParam Long userId,
@ValidPage @RequestParam Integer page
) {
Pageable pageable = PageRequest.of(page - 1, 10);
Page<MyMissionDTO> missionPage = userMissionService.getInProgressMissions(userId, pageable);
return ApiResponse.onSuccess(GeneralSuccessCode.OK, missionPage.getContent());
}

}
Loading