Skip to content
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

[FEAT] user stat 결과 경험치를 %로 치환해서 응답 #90

Merged
merged 6 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ public boolean getDayOfWeekValue(DayOfWeek dayOfWeek) {
}

public AlarmType determineAlarmType() {
return Objects.isNull(room) ? AlarmType.PERSONAL : AlarmType.GROUP;
return isRoomAlarm() ? AlarmType.GROUP : AlarmType.PERSONAL;
}
Comment on lines 129 to +131
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 👍


public boolean isRoomAlarm() {
return Objects.nonNull(room);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.wakeUpTogetUp.togetUp.api.users.UserAvatarService;
import com.wakeUpTogetUp.togetUp.api.users.UserService;
import com.wakeUpTogetUp.togetUp.api.users.model.User;
import com.wakeUpTogetUp.togetUp.api.users.vo.UserStat;
import com.wakeUpTogetUp.togetUp.utils.JwtService;
import java.io.IOException;
import java.util.List;
Expand Down Expand Up @@ -56,7 +57,7 @@ public LoginRes socialLogin(SocialLoginReq socialLoginReq) {
.email(socialUserRes.getEmail())
.accessToken(accessToken)
.avatarId(userAvatarService.getUserAvatarId(user.getId()))
.userStat(userService.getUserStat(user))
.userStat(UserStat.from(user))
Copy link
Contributor

Choose a reason for hiding this comment

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

함수이름을 from이라고 지은 이유가 궁금해요!

Copy link
Member Author

Choose a reason for hiding this comment

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

정적 팩토리 메소드로 인수인 user에서 정보를 가져와 생성한다는 의미를 담았습니다.
from은 주로 하나의 매개변수를 받을 때 사용하는 네이밍 입니다.

https://velog.io/@saint6839/%EC%A0%95%EC%A0%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9C-%EB%84%A4%EC%9D%B4%EB%B0%8D-%EB%B0%A9%EC%8B%9D

Copy link
Contributor

Choose a reason for hiding this comment

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

그렇군요 👍

.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@
import com.google.cloud.vision.v1.FaceAnnotation;
import com.wakeUpTogetUp.togetUp.api.auth.AuthUser;
import com.wakeUpTogetUp.togetUp.api.file.FileService;
import com.wakeUpTogetUp.togetUp.api.mission.dto.request.MissionLogCreateReq;
import com.wakeUpTogetUp.togetUp.api.mission.dto.request.MissionCompleteReq;
import com.wakeUpTogetUp.togetUp.api.mission.dto.response.GetMissionLogRes;
import com.wakeUpTogetUp.togetUp.api.mission.dto.response.GetMissionWithObjectListRes;
import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionLogCreateRes;
import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionCompleteRes;
import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionPerfomRes;
import com.wakeUpTogetUp.togetUp.api.mission.service.MissionImageService;
import com.wakeUpTogetUp.togetUp.api.notification.NotificationService;
import com.wakeUpTogetUp.togetUp.api.users.vo.UserStat;
import com.wakeUpTogetUp.togetUp.common.Status;
import com.wakeUpTogetUp.togetUp.common.dto.BaseResponse;
import com.wakeUpTogetUp.togetUp.exception.BaseException;
Expand Down Expand Up @@ -44,8 +42,6 @@ public class MissionController {
private final MissionService missionService;
private final MissionImageService missionImageService;
private final FileService fileService;
private final NotificationService notificationService;


@Operation(summary = "미션 목록 가져오기")
@GetMapping("/{missionId}")
Expand Down Expand Up @@ -98,13 +94,12 @@ public BaseResponse<MissionPerfomRes> recognizeFaceExpression(
@Operation(summary = "미션 수행 기록 생성 및 경험치, 레벨, 포인트 정산")
@PostMapping("/complete")
@ResponseStatus(HttpStatus.CREATED)
public BaseResponse<MissionLogCreateRes> postMissionLog(
public BaseResponse<MissionCompleteRes> processMissionCompletion(
@Parameter(hidden = true) @AuthUser Integer userId,
@RequestBody @Valid MissionLogCreateReq missionLogCreateReq
@RequestBody @Valid MissionCompleteReq missionCompleteReq
) {
UserStat userStat = missionService.afterMissionComplete(userId, missionLogCreateReq);
notificationService.sendNotificationToUsersInRoom(missionLogCreateReq.getAlarmId(), userId);
return new BaseResponse<>(Status.SUCCESS_CREATED, new MissionLogCreateRes(userStat));
return new BaseResponse<>(Status.SUCCESS_CREATED,
missionService.afterMissionComplete(userId, missionCompleteReq));
}

// TODO : 달별 검색
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
import com.google.cloud.vision.v1.Likelihood;
import com.wakeUpTogetUp.togetUp.api.alarm.AlarmRepository;
import com.wakeUpTogetUp.togetUp.api.alarm.model.Alarm;
import com.wakeUpTogetUp.togetUp.api.mission.dto.request.MissionLogCreateReq;
import com.wakeUpTogetUp.togetUp.api.mission.dto.request.MissionCompleteReq;
import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionCompleteRes;
import com.wakeUpTogetUp.togetUp.api.mission.model.Emotion;
import com.wakeUpTogetUp.togetUp.api.mission.model.MissionLog;
import com.wakeUpTogetUp.togetUp.api.mission.service.AzureAiService;
import com.wakeUpTogetUp.togetUp.api.mission.service.GoogleVisionService;
import com.wakeUpTogetUp.togetUp.api.mission.service.ObjectDetectionService;
import com.wakeUpTogetUp.togetUp.api.notification.NotificationService;
import com.wakeUpTogetUp.togetUp.api.room.RoomRepository;
import com.wakeUpTogetUp.togetUp.api.room.model.Room;
import com.wakeUpTogetUp.togetUp.api.users.UserRepository;
import com.wakeUpTogetUp.togetUp.api.users.UserService;
import com.wakeUpTogetUp.togetUp.api.users.model.User;
Expand All @@ -22,15 +22,16 @@
import com.wakeUpTogetUp.togetUp.exception.BaseException;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

@Service
@RequiredArgsConstructor
@Slf4j
public class MissionService {

private final ObjectDetectionService objectDetectionService;
Expand All @@ -49,28 +50,26 @@ public List<DetectedObject> getObjectDetectionResult(String object, MultipartFil
List<DetectedObject> detectedObjects = azureAiService.detectObjectByVer40(missionImage);

// TODO: 디버그용 삭제
System.out.println();
System.out.println("탐지할 객체 = " + object);
System.out.println("[감지된 객체]");
log.info("탐지할 객체 = " + object);
log.info("[감지된 객체]");
Comment on lines 52 to +54
Copy link
Contributor

Choose a reason for hiding this comment

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

훨씬 좋네요!

detectedObjects.stream()
.map(DetectedObject::getName)
.forEach(System.out::println);
.forEach(log::info);

if (detectedObjects.size() == 0) {
if (detectedObjects.isEmpty()) {
throw new BaseException(Status.MISSION_OBJECT_NOT_FOUND);
}

// todo: 객체 정리하고 비교할 자료구조 찾기

List<DetectedObject> highestConfidenceObjects = detectedObjects.stream()
.filter(objetDetected -> objetDetected.getName().toLowerCase().equals(object))
.sorted(Comparator.comparing(DetectedObject::getConfidence).reversed())
.limit(3)
.collect(Collectors.toList());

// TODO: 디버그용 삭제
System.out.println("[감지된 객체 중 목표 객체 정확도순 최대 3개]");
highestConfidenceObjects.forEach(System.out::println);
log.info("[감지된 객체 중 목표 객체 정확도순 최대 3개]");
highestConfidenceObjects.forEach(obj -> log.info(obj.toString()));

if (highestConfidenceObjects.isEmpty()) {
throw new BaseException(Status.MISSION_FAILURE);
Expand Down Expand Up @@ -119,7 +118,7 @@ private Likelihood getLikelihood(Emotion emotion, FaceAnnotation face) {
// 모델로 객체 인식하기
public void recognizeObjectByModel(String object, MultipartFile missionImage) {
for (String objectDetected : objectDetectionService.detectObject(missionImage)) {
System.out.println("objectDetected = " + objectDetected);
log.info("objectDetected = " + objectDetected);

if (objectDetected.equals(object)) {
return;
Expand All @@ -130,34 +129,43 @@ public void recognizeObjectByModel(String object, MultipartFile missionImage) {
}

@Transactional
public UserStat afterMissionComplete(int userId, MissionLogCreateReq req) {
createMissionLog(userId, req);
return userService.userProgress(userId);
}

// TODO : 미션 수행 기록 추가 + REQUEST 수정하기
public void createMissionLog(int userId, MissionLogCreateReq req) {
public MissionCompleteRes afterMissionComplete(int userId, MissionCompleteReq req) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BaseException(Status.USER_NOT_FOUND));

Alarm alarm = alarmRepository.findById(req.getAlarmId())
.orElseThrow(() -> new BaseException(Status.ALARM_NOT_FOUND));

Room room = Objects.isNull(req.getRoomId())
? null
: roomRepository.findById(req.getRoomId())
.orElseThrow(() -> new BaseException(Status.ROOM_NOT_FOUND));
createMissionLog(user, req);
userService.userProgress(user);
sendNotificationIfRoomExists(alarm, user);

return new MissionCompleteRes(UserStat.from(user));
}

private void sendNotificationIfRoomExists(Alarm alarm, User user) {
if (alarm.isRoomAlarm()) {
// 미션 성공 후 처리 로직과 알림 보내기 로직을 독립적으로 분리
// 알림을 보내는데 실패해도 모든 과정이 롤백되지 않음
try {
notificationService.sendNotificationToUsersInRoom(alarm.getId(), user.getId());
} catch (BaseException e) {
log.error(e.getMessage());
}
}
}

private void createMissionLog(User user, MissionCompleteReq req) {
Alarm alarm = alarmRepository.findById(req.getAlarmId())
.orElseThrow(() -> new BaseException(Status.ALARM_NOT_FOUND));

MissionLog missionLog = MissionLog.builder()
.alarmName(alarm.getName())
.missionPicLink(req.getMissionPicLink())
.user(user)
.room(room)
.room(alarm.getRoom())
.build();

missionLogRepository.save(missionLog);


}
}

Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.wakeUpTogetUp.togetUp.api.mission.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -15,14 +13,11 @@
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class MissionLogCreateReq {
public class MissionCompleteReq {
@NotNull(message = "알람 id는 null일 수 없습니다.")
@Schema(description = "알람 id", example = "1")
private Integer alarmId;

@Schema(description = "그룹 id")
private Integer roomId;

@NotBlank(message = "미션 수행 사진은 공백일 수 없습니다.")
@Schema(description = "미션 수행 사진")
private String missionPicLink;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

@Getter
@AllArgsConstructor
public class MissionLogCreateRes {
public class MissionCompleteRes {
@Schema(description = "경험치, 레벨, 포인트 정산 결과")
private UserStat userStat;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@

import com.wakeUpTogetUp.togetUp.api.notification.vo.NotificationSendVo;
import com.wakeUpTogetUp.togetUp.api.notification.vo.RoomMissionLogNotificationVo;
import com.wakeUpTogetUp.togetUp.api.room.RoomRepository;
import com.wakeUpTogetUp.togetUp.api.room.model.Room;
import com.wakeUpTogetUp.togetUp.api.room.model.RoomUser;
import com.wakeUpTogetUp.togetUp.api.users.UserRepository;
import com.wakeUpTogetUp.togetUp.api.users.UserService;
import com.wakeUpTogetUp.togetUp.api.users.fcmToken.FcmTokenRepository;
import com.wakeUpTogetUp.togetUp.api.users.model.User;
import com.wakeUpTogetUp.togetUp.common.Status;
import com.wakeUpTogetUp.togetUp.exception.BaseException;
import com.wakeUpTogetUp.togetUp.api.room.RoomRepository;
import com.wakeUpTogetUp.togetUp.api.users.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
Expand All @@ -39,7 +38,6 @@ public void sendNotificationToAllUsers(String title, String body) {
}

public void sendNotificationToUsersInRoom(Integer alarmId, Integer missionCompleteUserId) {

User user = userRepository.findById(missionCompleteUserId)
.orElseThrow(() -> new BaseException(Status.USER_NOT_FOUND));
Room room = roomRepository.findByAlarmId(alarmId)
Expand All @@ -51,15 +49,15 @@ public void sendNotificationToUsersInRoom(Integer alarmId, Integer missionComple
.filter(userId -> userId != user.getId())
.collect(Collectors.toList());

if (userIdsInRoom.size() > 0)
if (userIdsInRoom.size() > 0) {
fcmService.sendMessageToTokens(
new RoomMissionLogNotificationVo(
user,
room,
fcmTokenRepository.findAllByUser_IdIn(userIdsInRoom)

)
);
}
}

}
34 changes: 6 additions & 28 deletions src/main/java/com/wakeUpTogetUp/togetUp/api/users/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@
import com.wakeUpTogetUp.togetUp.api.users.fcmToken.FcmToken;
import com.wakeUpTogetUp.togetUp.api.users.fcmToken.FcmTokenRepository;
import com.wakeUpTogetUp.togetUp.api.users.model.User;
import com.wakeUpTogetUp.togetUp.api.users.vo.UserStat;
import com.wakeUpTogetUp.togetUp.common.Status;
import com.wakeUpTogetUp.togetUp.exception.BaseException;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -47,8 +43,8 @@ public User getSignedUser(SocialUserRes socialUserRes, LoginType loginType) {
.name(socialUserRes.getName())
.email(socialUserRes.getEmail())
.level(DEFAULT_USER_LEVEL)
.experience(DEFAULT_USER_EXPERIENCE)
.point(DEFAULT_USER_POINT)
.expPoint(DEFAULT_USER_EXPERIENCE)
.coin(DEFAULT_USER_POINT)
Copy link
Contributor

Choose a reason for hiding this comment

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

DEFAULT_USER_POINT -> DEFAULT_USER_COIN 부탁해요!

Copy link
Member Author

Choose a reason for hiding this comment

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

네 고치고 머지하겠습니다!

.build());
userAvatarService.setUserDefaultAvatar(user);

Expand Down Expand Up @@ -97,30 +93,12 @@ public void deleteById(Integer userId) {
if (roomUserNumber > 0) {
roomUserRepository.deleteByUserId(userId);
}

}

public UserStat userProgress(int userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BaseException(Status.USER_NOT_FOUND));

user.gainExperience(10);
int threshold = 10 + 16 * (user.getLevel() - 1);

if (user.checkUserLevelUpAvailable(threshold)) {
user.levelUp(threshold);
}
public void userProgress(User user) {
user.gainExpPoint(10);
user.progress();
userRepository.save(user);

return new UserStat(user.getLevel(), user.getExperience(), user.getPoint());
}

public UserStat getUserStat(User user) {
return UserStat.builder()
.level(user.getLevel())
.experience(user.getExperience())
.point(user.getPoint())
.build();
}

public List<Integer> getAgreedNotiUsersIds() {
Expand Down
Loading