-
Notifications
You must be signed in to change notification settings - Fork 0
Feat/#63 스탬프 기능 구현 #64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 13 commits
1389fd8
17baa9a
d38cf0f
bf68938
7f722b8
d6cf754
d83fc38
fd1aabe
f3e06ca
ec0594c
4e4e68f
ca51498
315da79
d94d70c
2f1e8e8
599a53a
6dd074c
ea9f0d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package com.campus.campus.domain.manager.application.dto.request; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import jakarta.validation.constraints.NotBlank; | ||
|
|
||
| public record RewardRequest( | ||
| @NotBlank | ||
| @Schema(description = "보상으로 지급 이미지 url", example = "https://www.example.com.png") | ||
| String rewardImageUrl | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package com.campus.campus.domain.manager.application.dto.response; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
|
|
||
| public record StampRewardNeededUserListResponse( | ||
| @Schema(description = "보상 지급이 필요한 사용자 ID", example = "1") | ||
| Long userId, | ||
|
|
||
| @Schema(description = "보상 지급이 필요한 사용자 이름", example = "한승현") | ||
| String nickname, | ||
|
|
||
| @Schema(description = "사용자의 스탬프 수", example = "10") | ||
| int stampCount, | ||
|
|
||
| @Schema(description = "사용자가 보상이 필요한지 여부", example = "true") | ||
| boolean rewardNeeded | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,15 +14,23 @@ | |
| import com.campus.campus.domain.council.domain.repository.StudentCouncilRepository; | ||
| import com.campus.campus.domain.manager.application.dto.request.CouncilApproveOrDenyRequest; | ||
| import com.campus.campus.domain.manager.application.dto.request.ManagerLoginRequest; | ||
| import com.campus.campus.domain.manager.application.dto.request.RewardRequest; | ||
| import com.campus.campus.domain.manager.application.dto.response.CertifyRequestCouncilResponse; | ||
| import com.campus.campus.domain.manager.application.dto.response.CouncilApproveOrDenyResponse; | ||
| import com.campus.campus.domain.manager.application.dto.response.CertifyRequestCouncilListResponse; | ||
| import com.campus.campus.domain.manager.application.dto.response.ManagerLoginResponse; | ||
| import com.campus.campus.domain.manager.application.dto.response.StampRewardNeededUserListResponse; | ||
| import com.campus.campus.domain.manager.application.exception.ManagerNotFoundException; | ||
| import com.campus.campus.domain.manager.application.exception.PasswordNotCorrectException; | ||
| import com.campus.campus.domain.manager.application.mapper.ManagerMapper; | ||
| import com.campus.campus.domain.manager.domain.entity.Manager; | ||
| import com.campus.campus.domain.manager.domain.repository.ManagerRepository; | ||
| import com.campus.campus.domain.stamp.domain.entity.Reward; | ||
| import com.campus.campus.domain.stamp.domain.repository.RewardRepository; | ||
| import com.campus.campus.domain.stamp.domain.repository.StampRepository; | ||
| import com.campus.campus.domain.user.application.exception.UserNotFoundException; | ||
| import com.campus.campus.domain.user.domain.entity.User; | ||
| import com.campus.campus.domain.user.domain.repository.UserRepository; | ||
| import com.campus.campus.global.util.jwt.JwtProvider; | ||
| import com.campus.campus.global.util.jwt.application.service.RedisTokenService; | ||
|
|
||
|
|
@@ -34,6 +42,9 @@ | |
| public class ManagerService { | ||
| private final StudentCouncilRepository studentCouncilRepository; | ||
| private final ManagerRepository managerRepository; | ||
| private final UserRepository userRepository; | ||
| private final StampRepository stampRepository; | ||
| private final RewardRepository rewardRepository; | ||
| private final PasswordEncoder passwordEncoder; | ||
| private final JwtProvider jwtProvider; | ||
| private final RedisTokenService redisTokenService; | ||
|
|
@@ -96,6 +107,29 @@ public CertifyRequestCouncilResponse getCertifyRequestCouncil(Long councilId) { | |
| return managerMapper.toCertifyRequestCouncilResponse(studentCouncil); | ||
| } | ||
|
|
||
| public List<StampRewardNeededUserListResponse> getStampRewardNeededUserList() { | ||
| List<User> rewardNeededUsers = userRepository.findAllByRewardNeededIsTrueAndDeletedAtIsNull(); | ||
|
|
||
| return rewardNeededUsers.stream() | ||
| .map(user -> { | ||
| int stampCount = stampRepository.countByUser(user); | ||
|
||
| return managerMapper.toStampRewardNeededUserListResponse(user, stampCount); | ||
| } | ||
| ).toList(); | ||
| } | ||
|
|
||
| @Transactional | ||
| public void grantRewardToUser(Long userId, RewardRequest rewardRequest) { | ||
| User user = userRepository.findByIdAndDeletedAtIsNull(userId) | ||
| .orElseThrow(UserNotFoundException::new); | ||
|
|
||
| Reward reward = managerMapper.createReward(user, rewardRequest); | ||
|
|
||
| rewardRepository.save(reward); | ||
|
|
||
| user.updateRewardNeeded(false); | ||
| } | ||
|
Comment on lines
+121
to
+131
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 보상 지급 전 현재 구현은 🛠️ 권장 수정 예시 `@Transactional`
public void grantRewardToUser(Long userId, RewardRequest rewardRequest) {
User user = userRepository.findByIdAndDeletedAtIsNull(userId)
.orElseThrow(UserNotFoundException::new);
+ if (!user.isRewardNeeded()) {
+ throw new IllegalStateException("해당 사용자는 보상 대상이 아닙니다.");
+ }
+
Reward reward = managerMapper.createReward(user, rewardRequest);
rewardRepository.save(reward);
user.updateRewardNeeded(false);
}🤖 Prompt for AI Agents |
||
|
|
||
| private void sendCouncilApprovedMail(String to) { | ||
| SimpleMailMessage message = new SimpleMailMessage(); | ||
| message.setTo(to); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,10 +13,12 @@ | |
|
|
||
| import com.campus.campus.domain.manager.application.dto.request.CouncilApproveOrDenyRequest; | ||
| import com.campus.campus.domain.manager.application.dto.request.ManagerLoginRequest; | ||
| import com.campus.campus.domain.manager.application.dto.request.RewardRequest; | ||
| import com.campus.campus.domain.manager.application.dto.response.CertifyRequestCouncilResponse; | ||
| import com.campus.campus.domain.manager.application.dto.response.CouncilApproveOrDenyResponse; | ||
| import com.campus.campus.domain.manager.application.dto.response.CertifyRequestCouncilListResponse; | ||
| import com.campus.campus.domain.manager.application.dto.response.ManagerLoginResponse; | ||
| import com.campus.campus.domain.manager.application.dto.response.StampRewardNeededUserListResponse; | ||
| import com.campus.campus.domain.manager.application.service.ManagerService; | ||
| import com.campus.campus.global.common.response.CommonResponse; | ||
|
|
||
|
|
@@ -68,4 +70,22 @@ public CommonResponse<List<CertifyRequestCouncilListResponse>> getCertifyRequest | |
|
|
||
| return CommonResponse.success(ManagerResponseCode.CERTIFY_REQUEST_LIST_SUCCESS, responses); | ||
| } | ||
|
|
||
| @GetMapping("/reward/need/users") | ||
|
||
| @PreAuthorize("hasRole('MANAGER')") | ||
| @Operation(summary = "스탬프 보상이 필요한 유저 목록 조회") | ||
| public CommonResponse<List<StampRewardNeededUserListResponse>> getStampRewardNeededUserList() { | ||
| List<StampRewardNeededUserListResponse> responses = managerService.getStampRewardNeededUserList(); | ||
|
|
||
| return CommonResponse.success(ManagerResponseCode.REWARD_NEEDED_USER_LIST_SUCCESS, responses); | ||
| } | ||
|
|
||
| @PostMapping("reward/grant/{userId}") | ||
| @PreAuthorize("hasRole('MANAGER')") | ||
| @Operation(summary = "스탬프 보상 지급") | ||
| public CommonResponse<Void> grantRewardToUser(@PathVariable Long userId, RewardRequest rewardRequest) { | ||
| managerService.grantRewardToUser(userId, rewardRequest); | ||
|
|
||
| return CommonResponse.success(ManagerResponseCode.GRANT_REWARD_SUCCESS); | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package com.campus.campus.domain.stamp.application.dto.response; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
|
|
||
| public record RewardResponse( | ||
| @Schema(description = "보상 id", example = "1") | ||
| Long rewardId, | ||
|
|
||
| @Schema(description = "보상 이미지 url", example = "https://www.example.com.png") | ||
| String rewardImageUrl, | ||
|
|
||
| @Schema(description = "지급일") | ||
| LocalDateTime rewardDate | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.campus.campus.domain.stamp.application.dto.response; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
|
|
||
| public record StampInfoResponse( | ||
| @Schema(description = "스탬프 개수", example = "3") | ||
| int stampCount, | ||
|
|
||
| @Schema(description = "스탬프에 해당하는 리뷰 목록") | ||
| List<StampReviewResponse> reviews | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package com.campus.campus.domain.stamp.application.dto.response; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
|
|
||
| public record StampReviewResponse( | ||
| @Schema(description = "리뷰 id", example = "1") | ||
| Long reviewId, | ||
|
|
||
| @Schema(description = "리뷰 장소 이름", example = "투썸 플레이스") | ||
| String placeName, | ||
|
|
||
| @Schema(description = "리뷰 작성 시간", example = "2024-01-10T18:00:00") | ||
| LocalDateTime reviewCreatedAt | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package com.campus.campus.domain.stamp.application.mapper; | ||
|
|
||
| import org.springframework.stereotype.Component; | ||
|
|
||
| import com.campus.campus.domain.review.domain.entity.Review; | ||
| import com.campus.campus.domain.stamp.application.dto.response.RewardResponse; | ||
| import com.campus.campus.domain.stamp.application.dto.response.StampReviewResponse; | ||
| import com.campus.campus.domain.stamp.domain.entity.Reward; | ||
| import com.campus.campus.domain.stamp.domain.entity.Stamp; | ||
| import com.campus.campus.domain.user.domain.entity.User; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @Component | ||
| @RequiredArgsConstructor | ||
| public class StampMapper { | ||
| public RewardResponse toRewardResponse(Reward reward) { | ||
| return new RewardResponse( | ||
| reward.getRewardId(), | ||
| reward.getRewardImageUrl(), | ||
| reward.getCreatedAt() | ||
| ); | ||
| } | ||
|
|
||
| public StampReviewResponse toStampReviewResponse(Stamp stamp) { | ||
| Review review = stamp.getReview(); | ||
|
|
||
| return new StampReviewResponse( | ||
| review.getId(), | ||
| review.getPlace().getPlaceName(), | ||
| review.getCreatedAt() | ||
| ); | ||
| } | ||
|
|
||
| public Stamp createStamp(User user, Review review) { | ||
| return Stamp.builder() | ||
| .user(user) | ||
| .review(review) | ||
| .build(); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.