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

Update Version 2.0.3 #95

Merged
merged 16 commits into from
Mar 25, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public boolean saveManualBadge(String userEmail, BadgeType badgeType, boolean re
Badge badge = Badge.createBadge(user, badgeType);
badgeRepository.save(badge);
if (registerMessage) {
user.addNewBadgeNotification(badgeType.name());
user.addNewBadgeNotification(badgeType);
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
package com.playkuround.playkuroundserver.domain.common;

public abstract class AppVersion {
import java.util.Map;
import java.util.stream.Stream;

private AppVersion() {
}
import static java.util.stream.Collectors.toMap;

public enum AppVersion {

ANDROID("2.0.2"),
IOS("2.0.0");

private static String CURRENT_VERSION = "2.0.2";
private static final Map<String, AppVersion> stringToEnum =
Stream.of(values())
.collect(toMap(Object::toString, e -> e));
private String latest_updated_version;

AppVersion(String latest_updated_version) {
this.latest_updated_version = latest_updated_version;
}

public static boolean isCurrentVersion(String version) {
return CURRENT_VERSION.equals(version);
public static boolean isLatestUpdatedVersion(String os, String version) {
AppVersion appVersion = stringToEnum.get(os.toUpperCase());
if (appVersion == null) {
throw new NotSupportOSException();
}
return appVersion.latest_updated_version.equals(version);
}

public static void changeAppVersion(String version) {
CURRENT_VERSION = version;
public static void changeLatestUpdatedVersion(String os, String version) {
AppVersion appVersion = stringToEnum.get(os.toUpperCase());
if (appVersion == null) {
throw new NotSupportOSException();
}
appVersion.latest_updated_version = version;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.playkuround.playkuroundserver.domain.common;

import com.playkuround.playkuroundserver.global.error.ErrorCode;
import com.playkuround.playkuroundserver.global.error.exception.BusinessException;

public class NotSupportOSException extends BusinessException {

public NotSupportOSException() {
super(ErrorCode.NOT_SUPPORT_OS);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
Expand All @@ -23,18 +22,12 @@ public ScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId)
ScoreRankingResponse response = ScoreRankingResponse.createEmptyResponse();

List<NicknameAndScore> nicknameAndScores = adventureRepository.findRankTop100DescByLandmarkId(landmarkId);
nicknameAndScores
.forEach(nicknameAndScore ->
response.addRank(nicknameAndScore.nickname(), nicknameAndScore.score()));
nicknameAndScores.forEach(nicknameAndScore ->
response.addRank(nicknameAndScore.nickname(), nicknameAndScore.score()));

Optional<RankAndScore> optionalMyScore = adventureRepository.findMyRankByLandmarkId(user, landmarkId);
if (optionalMyScore.isPresent()) {
RankAndScore myScore = optionalMyScore.get();
response.setMyRank(myScore.ranking(), myScore.score());
}
else {
response.setMyRank(0, 0);
}
RankAndScore rankAndScore = adventureRepository.findMyRankByLandmarkId(user, landmarkId)
.orElseGet(() -> new RankAndScore(0, 0));
response.setMyRank(rankAndScore.ranking(), rankAndScore.score());
return response;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,32 @@
import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse;
import com.playkuround.playkuroundserver.domain.user.dao.UserRepository;
import com.playkuround.playkuroundserver.domain.user.domain.User;
import lombok.RequiredArgsConstructor;
import com.playkuround.playkuroundserver.domain.user.dto.EmailAndNickname;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class TotalScoreService {

private final String redisSetKey = "ranking";
private final String redisSetKey;
private final UserRepository userRepository;
private final RedisTemplate<String, String> redisTemplate;
private final ZSetOperations<String, String> zSetOperations;

public TotalScoreService(UserRepository userRepository, RedisTemplate<String, String> redisTemplate) {
this.redisSetKey = "ranking";
this.userRepository = userRepository;
this.zSetOperations = redisTemplate.opsForZSet();
}

@Transactional
public Long incrementTotalScore(User user, Long score) {
ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
zSetOperations.incrementScore(redisSetKey, user.getEmail(), score);

Double myTotalScore = zSetOperations.score(redisSetKey, user.getEmail());
Expand All @@ -38,7 +42,7 @@ public Long incrementTotalScore(User user, Long score) {
@Transactional(readOnly = true)
public ScoreRankingResponse getRankTop100(User user) {
Set<ZSetOperations.TypedTuple<String>> typedTuples
= redisTemplate.opsForZSet().reverseRangeWithScores(redisSetKey, 0, 99);
= zSetOperations.reverseRangeWithScores(redisSetKey, 0, 99);
if (typedTuples == null) {
return ScoreRankingResponse.createEmptyResponse();
}
Expand All @@ -54,33 +58,36 @@ public ScoreRankingResponse getRankTop100(User user) {
}

private Map<String, String> getNicknameBindingEmailMapList(List<String> emails) {
List<Map<String, String>> nicknameBindingEmailMapList = userRepository.findNicknameByEmailIn(emails);
return nicknameBindingEmailMapList.stream()
.collect(HashMap::new, (m, v) -> m.put(v.get("email"), v.get("nickname")), HashMap::putAll);
List<EmailAndNickname> nicknameByEmailIn = userRepository.findNicknameByEmailIn(emails);
return nicknameByEmailIn.stream()
.collect(Collectors.toMap(EmailAndNickname::email, EmailAndNickname::nickname));
}

private RankAndScore getMyRank(User user) {
ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();

Double myTotalScore = zSetOperations.score(redisSetKey, user.getEmail());
if (myTotalScore == null) {
return new RankAndScore(0, 0);
}

Set<String> emailSet = zSetOperations.reverseRangeByScore(redisSetKey, myTotalScore, myTotalScore, 0, 1);
if (emailSet == null) {
return new RankAndScore(0, 0);
return new RankAndScore(0, 0); // 발생하지 않음
}
int myRank = getMyRank(emailSet);

return new RankAndScore(myRank, myTotalScore.intValue());
}

private int getMyRank(Set<String> emailSet) {
int myRank = -1;
// emailSet의 크기는 항상 1일 것이다.
for (String email : emailSet) {
Long rank = zSetOperations.reverseRank(redisSetKey, email);
if (rank == null) {
continue;
continue; // 발생하지 않음
}
myRank = rank.intValue();
}

return new RankAndScore(myRank + 1, myTotalScore.intValue());
return myRank + 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ public void setMyRank(int ranking, int score) {

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public static class RankList {
private String nickname;
private int score;
}

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public static class MyRank {
private int ranking;
private int score;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.playkuround.playkuroundserver.global.common.response.ApiResponse;
import com.playkuround.playkuroundserver.global.util.ApiUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
Expand All @@ -23,9 +24,15 @@ public class AdminApi {
private final BadgeService badgeService;

@PostMapping("/app-version")
@Operation(summary = "앱 버전 올리기(관리자모드)", description = "앱 버전을 올립니다. 이전버전 사용자에게 공지 메시지를 보냅니다.")
public ApiResponse<Void> updateAppVersion(@RequestParam("version") String appVersion) {
AppVersion.changeAppVersion(appVersion);
@Operation(summary = "앱 버전 올리기(관리자모드)", description = "앱 버전을 올립니다. 이전버전 사용자에게 공지 메시지를 보냅니다.",
parameters = {
@Parameter(name = "version", description = "최신 앱 버전", example = "2.0.2", required = true),
@Parameter(name = "os", description = "모바일 운영체제(android 또는 ios)", example = "android", required = true)
}
)
public ApiResponse<Void> updateAppVersion(@RequestParam("version") String appVersion,
@RequestParam("os") String os) {
AppVersion.changeLatestUpdatedVersion(os, appVersion);
return ApiUtils.success(null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
import com.playkuround.playkuroundserver.domain.user.api.response.UserProfileResponse;
import com.playkuround.playkuroundserver.domain.user.application.UserProfileService;
import com.playkuround.playkuroundserver.domain.user.domain.HighestScore;
import com.playkuround.playkuroundserver.domain.user.dto.UserNotification;
import com.playkuround.playkuroundserver.domain.user.domain.Notification;
import com.playkuround.playkuroundserver.domain.user.domain.NotificationEnum;
import com.playkuround.playkuroundserver.global.common.response.ApiResponse;
import com.playkuround.playkuroundserver.global.security.UserDetailsImpl;
import com.playkuround.playkuroundserver.global.util.ApiUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
Expand Down Expand Up @@ -51,18 +53,30 @@ public ApiResponse<Boolean> isAvailableNickname(@RequestParam("nickname") String
}

@GetMapping("/notification")
@Operation(summary = "유저 알림 얻기", description = "유저 개인 알림을 얻습니다. 저장된 메시지는 (정상적인) 호출 이후 삭제됩니다.")
@Operation(summary = "유저 알림 얻기",
description = "유저 개인 알림을 얻습니다. 저장된 메시지는 (정상적인) 호출 이후 삭제됩니다.<br>" +
"=== name 명 리스트(new_badge는 description도 중요) ===<br>" +
"1. 시스템 점검 중일 때(단독으로만 반환): system_check<br>" +
"2. 앱 버전 업데이트가 필요할 때(단독으로만 반환): update<br>" +
"3. 새로운 뱃지 획득: new_badge(MONTHLY_RANKING_1, MONTHLY_RANKING_2, MONTHLY_RANKING_3, COLLEGE_OF_BUSINESS_ADMINISTRATION_100_AND_FIRST_PLACE)<br>" +
"4. 개인 알림: alarm",
parameters = {
@Parameter(name = "version", description = "현재 앱 버전", example = "2.0.2", required = true),
@Parameter(name = "os", description = "모바일 운영체제(android 또는 ios)", example = "android")
}
)
public ApiResponse<List<UserNotificationResponse>> getNotification(@AuthenticationPrincipal UserDetailsImpl userDetails,
@RequestParam("version") String appVersion) {
@RequestParam("version") String appVersion,
@RequestParam(name = "os", required = false, defaultValue = "android") String os) {
List<UserNotificationResponse> response;
if (!SystemCheck.isSystemAvailable()) {
response = UserNotificationResponse.from(UserNotificationResponse.NotificationEnum.SYSTEM_CHECK);
response = UserNotificationResponse.from(NotificationEnum.SYSTEM_CHECK);
}
else if (!AppVersion.isCurrentVersion(appVersion)) {
response = UserNotificationResponse.from(UserNotificationResponse.NotificationEnum.UPDATE);
else if (!AppVersion.isLatestUpdatedVersion(os, appVersion)) {
response = UserNotificationResponse.from(NotificationEnum.UPDATE);
}
else {
List<UserNotification> notificationList = userProfileService.getNotification(userDetails.getUser());
List<Notification> notificationList = userProfileService.getNotification(userDetails.getUser());
response = UserNotificationResponse.from(notificationList);
}
return ApiUtils.success(response);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.playkuround.playkuroundserver.domain.user.api.response;

import com.playkuround.playkuroundserver.domain.user.dto.UserNotification;
import com.playkuround.playkuroundserver.domain.user.domain.Notification;
import com.playkuround.playkuroundserver.domain.user.domain.NotificationEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -18,25 +19,12 @@ public class UserNotificationResponse {
private String description;

public static List<UserNotificationResponse> from(NotificationEnum notificationEnum) {
return List.of(new UserNotificationResponse(notificationEnum.name, notificationEnum.description));
return List.of(new UserNotificationResponse(notificationEnum.getName(), notificationEnum.getDefaultMessage()));
}

public static List<UserNotificationResponse> from(List<UserNotification> notificationList) {
public static List<UserNotificationResponse> from(List<Notification> notificationList) {
return notificationList.stream()
.map(notification -> new UserNotificationResponse(notification.name(), notification.description()))
.map(notification -> new UserNotificationResponse(notification.getName(), notification.getDescription()))
.toList();
}

public enum NotificationEnum {
UPDATE("update", "application is must update"),
SYSTEM_CHECK("system_check", "system is not available");

private final String name;
private final String description;

NotificationEnum(String name, String description) {
this.name = name;
this.description = description;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

import com.playkuround.playkuroundserver.domain.user.dao.UserRepository;
import com.playkuround.playkuroundserver.domain.user.domain.HighestScore;
import com.playkuround.playkuroundserver.domain.user.domain.Notification;
import com.playkuround.playkuroundserver.domain.user.domain.User;
import com.playkuround.playkuroundserver.domain.user.dto.UserNotification;
import com.playkuround.playkuroundserver.global.util.BadWordFilterUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

@Service
Expand All @@ -34,21 +34,16 @@ public HighestScore getUserGameHighestScore(User user) {
}

@Transactional
public List<UserNotification> getNotification(User user) {
String str_notification = user.getNotification();
if (str_notification == null) {
public List<Notification> getNotification(User user) {
Set<Notification> notificationSet = user.getNotification();
if (notificationSet == null || notificationSet.isEmpty()) {
return new ArrayList<>();
}

List<Notification> userNotifications = notificationSet.stream().toList();
user.clearNotification();
userRepository.save(user);
return convertToUserNotificationList(str_notification);
}

private List<UserNotification> convertToUserNotificationList(String str_notification) {
return Arrays.stream(str_notification.split("@"))
.map(notifications -> notifications.split("#"))
.filter(nameAndDescription -> nameAndDescription.length == 2)
.map(nameAndDescription -> new UserNotification(nameAndDescription[0], nameAndDescription[1]))
.toList();
return userNotifications;
}
}
Loading
Loading