Skip to content
Merged
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 build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ dependencies {

// aop
implementation 'org.springframework.boot:spring-boot-starter-aop'

// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.umc9th.domain.category.repository;

import com.example.umc9th.domain.category.entity.Category;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CategoryRepository extends JpaRepository<Category, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.example.umc9th.domain.mission.controller;

import com.example.umc9th.domain.mission.dto.MissionRequestDto;
import com.example.umc9th.domain.mission.dto.MissionResponseDto;
import com.example.umc9th.domain.mission.service.MissionService;
import com.example.umc9th.domain.review.dto.ReviewRequestDto;
import com.example.umc9th.domain.review.dto.ReviewResponseDto;
import com.example.umc9th.global.apiPayload.ApiResponse;
import com.example.umc9th.global.apiPayload.code.status.GeneralSuccessCode;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/missions")
@Tag(name = "๋ฏธ์…˜")
public class MissionController {
private final MissionService missionService;

@Operation(
summary = "๋ฏธ์…˜ ์ถ”๊ฐ€",
description = "๊ด€๋ฆฌ์ž์šฉ")
@PostMapping("/admin")
public ApiResponse<String> addMission(@RequestBody MissionRequestDto.CreateMission req) {
return ApiResponse.onSuccess(GeneralSuccessCode._CREATED, missionService.createMission(req));
}

@Operation(
summary = "์‚ฌ์šฉ์ž ๋ฏธ์…˜ ์ถ”๊ฐ€",
description = "์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ€๊ฒŒ ๋ฏธ์…˜์„ ๋ณธ์ธ์˜ ๋„์ „ ๋ฏธ์…˜์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.")
@PostMapping("/{mission-id}")
public ApiResponse<MissionResponseDto.AddUserMission> addMission(@RequestParam @PathVariable("mission-id")Long missionId) {
return ApiResponse.onSuccess(GeneralSuccessCode._CREATED, missionService.addUserMission(missionId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.umc9th.domain.mission.dto;

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

public class MissionRequestDto {
private MissionRequestDto() {}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NoArgsConstructor ์—ฌ๊ธฐ์— access PROTECTED ๊ฑธ๋ฉด ๋˜๋Š”๋ฐ์šฉ


@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class CreateMission{
private Integer point;
private String content;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.example.umc9th.domain.mission.dto;

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

public class MissionResponseDto {
private MissionResponseDto() {}

@Builder
@Getter
@AllArgsConstructor
public static class AddUserMission{
private Long missionId;
private String content;
private String createdAt;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.umc9th.domain.mission.service;

import com.example.umc9th.domain.mission.dto.MissionRequestDto;
import com.example.umc9th.domain.mission.dto.MissionResponseDto;

public interface MissionService {
String createMission(MissionRequestDto.CreateMission req);
MissionResponseDto.AddUserMission addUserMission(Long missionId);
}
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.dto.MissionRequestDto;
import com.example.umc9th.domain.mission.dto.MissionResponseDto;
import com.example.umc9th.domain.mission.entity.Mission;
import com.example.umc9th.domain.mission.entity.UserMission;
import com.example.umc9th.domain.mission.repository.MissionRepository;
import com.example.umc9th.domain.mission.repository.UserMissionRepository;
import com.example.umc9th.domain.store.repository.StoreRepository;
import com.example.umc9th.domain.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class MissionServiceImpl implements MissionService{
private final MissionRepository missionRepository;
private final StoreRepository storeRepository;
private final UserRepository userRepository;
private final UserMissionRepository userMissionRepository;

@Override
public String createMission(MissionRequestDto.CreateMission req) {
Mission mission = Mission.builder()
.store(storeRepository.getReferenceById(1L))
.content(req.getContent())
.point(req.getPoint())
.build();

missionRepository.save(mission);

return mission.getId().toString();
}

@Override
public MissionResponseDto.AddUserMission addUserMission(Long missionId) {
UserMission um = UserMission.builder()
.user(userRepository.getReferenceById(1L))
.mission(missionRepository.getReferenceById(missionId))
.build();

userMissionRepository.save(um);

return MissionResponseDto.AddUserMission.builder()
.missionId(missionId)
.content(um.getMission().getContent())
.createdAt(um.getMission().getCreatedAt().toString())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.umc9th.domain.review.controller;

import com.example.umc9th.domain.review.dto.ReviewRequestDto;
import com.example.umc9th.domain.review.dto.ReviewResponseDto;
import com.example.umc9th.domain.review.service.ReviewService;
import com.example.umc9th.global.apiPayload.ApiResponse;
Expand All @@ -8,10 +9,7 @@
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
Expand Down Expand Up @@ -39,4 +37,14 @@ public ApiResponse<CursorResponseDto<ReviewResponseDto.Review>> getReviews(
size));
}

@Operation(
summary = "๋ฆฌ๋ทฐ ์ž‘์„ฑ",
description = "ํ•ด๋‹น ๊ฐ€๊ฒŒ์— ๋ฆฌ๋ทฐ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.")
@PostMapping
public ApiResponse<ReviewResponseDto.Created> addReview(@RequestBody ReviewRequestDto.Create req) {
return ApiResponse.onSuccess(GeneralSuccessCode._CREATED,reviewService.createReview(req));
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.umc9th.domain.review.dto;

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

import java.util.List;

public class ReviewRequestDto {
private ReviewRequestDto() {}

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Create{
private Long storeId;
private String content;
private Float star;
private List<String> reviewImages;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,14 @@ public static class Review{
private String reviewReplyContent;
private String reviewReplyCreatedAt;
}

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Created{
private Long id;
private Long storeId;
private String createdAt;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.example.umc9th.domain.review.service;

import com.example.umc9th.domain.review.dto.ReviewRequestDto;
import com.example.umc9th.domain.review.dto.ReviewResponseDto;
import com.example.umc9th.global.dto.CursorResponseDto;

public interface ReviewService {
void createReview(String content, Long userId, Long storeId);
ReviewResponseDto.Created createReview(ReviewRequestDto.Create dto);

CursorResponseDto<ReviewResponseDto.Review> getReviews(String storeName,
Float minStar,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.umc9th.domain.review.service;

import com.example.umc9th.domain.review.dto.ReviewRequestDto;
import com.example.umc9th.domain.review.dto.ReviewResponseDto;
import com.example.umc9th.domain.review.entity.Review;
import com.example.umc9th.domain.review.repository.ReviewPredicate;
Expand Down Expand Up @@ -30,14 +31,21 @@ public class ReviewServiceImpl implements ReviewService{


@Override
public void createReview(String content, Long userId, Long storeId) {
public ReviewResponseDto.Created createReview(ReviewRequestDto.Create dto) {
Review review = Review.builder()
.content(content)
.user(userRepository.getReferenceById(userId))
.store(storeRepository.getReferenceById(storeId))
.user(userRepository.getReferenceById(1L))
.store(storeRepository.getReferenceById(dto.getStoreId()))
.content(dto.getContent())
.star(dto.getStar())
//.reviewImages(dto.getReviewImages()) todo: ์ด๋ฏธ์ง€ ๋ฆฌ์ŠคํŠธ
.build();

reviewRepository.save(review);
return ReviewResponseDto.Created.builder()
.id(review.getId())
.storeId(review.getStore().getId())
.createdAt(review.getCreatedAt().toString())
.build();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.umc9th.global.annotation;

import com.example.umc9th.global.validator.CategoryValidator;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.*;

/**
* @Documented : ์‚ฌ์šฉ์ž ์ •์˜ ์–ด๋…ธํ…Œ์ด์…˜
* @Target : ์–ด๋…ธํ…Œ์ด์…˜ ์ ์šฉ ๋ฒ”์œ„
* @Retention : ์–ด๋…ธํ…Œ์ด์…˜ ์ƒ๋ช…์ฃผ๊ธฐ
*/
@Documented
@Constraint(validatedBy = CategoryValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface ExistCategories {
//์—ฌ๊ธฐ์„œ ๋””ํดํŠธ ๋ฉ”์‹œ์ง€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
String message() default "ํ•ด๋‹น ์Œ์‹์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.umc9th.global.apiPayload.code.status;

import com.example.umc9th.global.apiPayload.code.BaseErrorCode;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor
public enum CategoryErrorCode implements BaseErrorCode {
CATEGORY_NOT_EXISTED(HttpStatus.NOT_FOUND,"CATEGORY_400","์กด์žฌํ•˜์ง€ ์•Š๋Š” ์นดํ…Œ๊ณ ๋ฆฌ์ž…๋‹ˆ๋‹ค.");

private final HttpStatus httpStatus;
private final String code;
private final String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.umc9th.global.validator;

import com.example.umc9th.domain.category.repository.CategoryRepository;
import com.example.umc9th.global.annotation.ExistCategories;
import com.example.umc9th.global.apiPayload.code.status.CategoryErrorCode;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@RequiredArgsConstructor
public class CategoryValidator implements ConstraintValidator<ExistCategories, List<Long>> {

private final CategoryRepository categoryRepository;

@Override
public void initialize(ExistCategories constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}

@Override
public boolean isValid(List<Long> values, ConstraintValidatorContext context) {
boolean isValid = values.stream().allMatch(categoryRepository::existsById);

if(!isValid){
context.disableDefaultConstraintViolation(); // ๋””ํดํŠธ ๋ฉ”์„ธ์ง€ ์ดˆ๊ธฐํ™”
context.buildConstraintViolationWithTemplate(CategoryErrorCode.CATEGORY_NOT_EXISTED.getMessage())
.addConstraintViolation(); // ์ƒˆ๋กœ์šด ๋ฉ”์„ธ์ง€๋กœ ๋ฎ์–ด์“ฐ๊ธฐ
}
return isValid;
}
}
Loading