Skip to content

Commit

Permalink
Merge pull request #215 from BudgetBuddiesTeam/feat/#198
Browse files Browse the repository at this point in the history
[feat] 유저 추가 API 수정 + 어드민 설정의 해시태그 보유 유저 조회 API 구현
  • Loading branch information
ryogaeng authored Nov 28, 2024
2 parents 1d7d2f7 + 19e44af commit 64c696c
Show file tree
Hide file tree
Showing 19 changed files with 349 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,10 @@ public void update(DiscountRequest.UpdateDiscountDto discountRequestDto) {
this.isInCalendar = discountRequestDto.getIsInCalendar();
}

public static DiscountInfo withId(Long id) {
DiscountInfo discountInfo = new DiscountInfo();
discountInfo.setId(id);
return discountInfo;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.bbteam.budgetbuddies.domain.favoritehashtag.controller;

import com.bbteam.budgetbuddies.apiPayload.ApiResponse;
import com.bbteam.budgetbuddies.domain.favoritehashtag.dto.FavoriteHashtagResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

public interface FavoriteHashtagApi {

@Operation(summary = "[User] 해당되는 해시태그를 설정한 유저 조회 API", description = "특정 할인정보 또는 지원정보에 등록된 해시태그를 설정한 유저를 조회합니다.")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공"),
})
@Parameters({
@Parameter(name = "discountInfoId", description = "조회할 할인정보 ID", required = false),
@Parameter(name = "supportInfoId", description = "조회할 지원정보 ID", required = false),
})
ApiResponse<List<FavoriteHashtagResponseDto>> getUsersByHashtags(
@RequestParam(required = false) Long discountInfoId,
@RequestParam(required = false) Long supportInfoId
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.bbteam.budgetbuddies.domain.favoritehashtag.controller;

import com.bbteam.budgetbuddies.apiPayload.ApiResponse;
import com.bbteam.budgetbuddies.domain.favoritehashtag.dto.FavoriteHashtagResponseDto;
import com.bbteam.budgetbuddies.domain.favoritehashtag.service.FavoriteHashtagService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/favoriteHashtags")
public class FavoriteHashtagController implements FavoriteHashtagApi {

private final FavoriteHashtagService favoriteHashtagService;

@Override
@GetMapping("/applicable-users")
public ApiResponse<List<FavoriteHashtagResponseDto>> getUsersByHashtags(
@RequestParam(required = false) Long discountInfoId,
@RequestParam(required = false) Long supportInfoId
) {
List<FavoriteHashtagResponseDto> users = favoriteHashtagService.findUsersByHashtag(discountInfoId, supportInfoId);
return ApiResponse.onSuccess(users);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.bbteam.budgetbuddies.domain.favoritehashtag.dto;

import com.bbteam.budgetbuddies.domain.user.entity.User;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor

public class FavoriteHashtagResponseDto {
private Long userId;

public FavoriteHashtagResponseDto(User user) {
this.userId = user.getId();
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.bbteam.budgetbuddies.domain.favoritehashtag.repository;

import com.bbteam.budgetbuddies.domain.favoritehashtag.entity.FavoriteHashtag;
import com.bbteam.budgetbuddies.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface FavoriteHashtagRepository extends JpaRepository<FavoriteHashtag, Long> {
import java.util.List;

public interface FavoriteHashtagRepository extends JpaRepository<FavoriteHashtag, Long> {
List<FavoriteHashtag> findByUser(User user);

}
List<FavoriteHashtag> findByHashtagIdIn(List<Long> hashtagIds);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.bbteam.budgetbuddies.domain.favoritehashtag.service;

import com.bbteam.budgetbuddies.domain.favoritehashtag.dto.FavoriteHashtagResponseDto;

import java.util.List;

public interface FavoriteHashtagService {
List<Long> getUsersForHashtag(Long discountInfoId, Long supportInfoId);

List<FavoriteHashtagResponseDto> findUsersByHashtag(Long discountInfoId, Long supportInfoId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.bbteam.budgetbuddies.domain.favoritehashtag.service;

import com.bbteam.budgetbuddies.domain.connectedinfo.entity.ConnectedInfo;
import com.bbteam.budgetbuddies.domain.connectedinfo.repository.ConnectedInfoRepository;
import com.bbteam.budgetbuddies.domain.discountinfo.entity.DiscountInfo;
import com.bbteam.budgetbuddies.domain.favoritehashtag.dto.FavoriteHashtagResponseDto;
import com.bbteam.budgetbuddies.domain.favoritehashtag.entity.FavoriteHashtag;
import com.bbteam.budgetbuddies.domain.favoritehashtag.repository.FavoriteHashtagRepository;
import com.bbteam.budgetbuddies.domain.supportinfo.entity.SupportInfo;
import com.bbteam.budgetbuddies.domain.user.entity.User;
import com.bbteam.budgetbuddies.domain.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class FavoriteHashtagServiceImpl implements FavoriteHashtagService {

private final ConnectedInfoRepository connectedInfoRepository;
private final FavoriteHashtagRepository favoriteHashtagRepository;
private final UserRepository userRepository;

@Override
public List<Long> getUsersForHashtag(Long discountInfoId, Long supportInfoId) {
List<ConnectedInfo> connectedInfos;

if (discountInfoId != null) {
DiscountInfo discountInfo = DiscountInfo.withId(discountInfoId);
connectedInfos = connectedInfoRepository.findAllByDiscountInfo(discountInfo);
} else if (supportInfoId != null) {
SupportInfo supportInfo = SupportInfo.withId(supportInfoId);
connectedInfos = connectedInfoRepository.findAllBySupportInfo(supportInfo);
} else {
throw new IllegalArgumentException("discountInfoId 또는 supportInfoId 중 하나는 필수입니다.");
}

List<Long> hashtagIds = connectedInfos.stream()
.map(connectedInfo -> connectedInfo.getHashtag().getId())
.collect(Collectors.toList());
System.out.println("Connected Hashtags IDs: " + hashtagIds);


List<FavoriteHashtag> favoriteHashtags = favoriteHashtagRepository.findByHashtagIdIn(hashtagIds);
System.out.println("Favorite Hashtags: " + favoriteHashtags);

return favoriteHashtags.stream()
.map(favoriteHashtag -> favoriteHashtag.getUser().getId())
.distinct()
.collect(Collectors.toList());
}

@Override
public List<FavoriteHashtagResponseDto> findUsersByHashtag(Long discountInfoId, Long supportInfoId) {
List<Long> userIds = getUsersForHashtag(discountInfoId, supportInfoId);

return userIds.stream()
.map(userId -> {
Optional<User> optionalUser = userRepository.findById(userId);
optionalUser.ifPresent(user -> System.out.println("User found: " + user)); // 여기에 추가
return optionalUser.map(FavoriteHashtagResponseDto::new)
.orElseGet(() -> {
System.out.println("User not found with id: " + userId);
return null;
});
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,9 @@ public void update(SupportRequest.UpdateSupportDto supportRequestDto) {
this.thumbnailUrl = supportRequestDto.getThumbnailUrl();
this.isInCalendar = supportRequestDto.getIsInCalendar();
}

public static SupportInfo withId(Long id) {
SupportInfo supportInfo = new SupportInfo();
supportInfo.setId(id);
return supportInfo;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import java.util.List;

public interface UserApi {
@Operation(summary = "[Admin] 기본 카테고리 생성 API ", description = "기본 카테고리가 없는 사용자에게 기본 카테고리를 생성합니다.")
@Operation(summary = "[Admin] 기본 카테고리 생성 API ", description = "(회원 가입시 필수적으로 자동 생성되어야 합니다!)기본 카테고리가 없는 사용자에게 기본 카테고리를 생성합니다.")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공"),
})
Expand All @@ -30,13 +30,16 @@ public interface UserApi {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공"),
})
@Parameters({
@Parameter(name = "phoneNumber", description = "휴대폰 번호. requestBody"),
@Parameter(name = "name", description = "사용자 이름. requestBody"),
@Parameter(name = "age", description = "사용자 나이. requestBody"),
@Parameter(name = "gender", description = "사용자 성별 / MALE, FEMALE, NONE requestBody"),
@Parameter(name = "email", description = "메일 주소. requestBody"),
@Parameter(name = "photoUrl", description = "사진 Url. 아마 사용 x requestBody"),
@Parameter(name = "consumptionPattern", description = "소비 패턴. 아마 사용 x requestBody")
@Parameter(name = "phoneNumber", description = "휴대폰 번호"),
@Parameter(name = "name", description = "사용자 이름"),
@Parameter(name = "age", description = "사용자 나이"),
@Parameter(name = "mobileCarrier", description = "통신사"),
@Parameter(name = "region", description = "지역"),
@Parameter(name = "gender", description = "사용자 성별 / MALE, FEMALE, NONE"),
@Parameter(name = "email", description = "메일 주소"),
@Parameter(name = "hashtagIds", description = "사용자가 선택한 해시태그 ID 리스트(제공되는 리스트 기반으로 Id 매칭 필요(통신사, 지역 포함))")
// @Parameter(name = "photoUrl", description = "사진 Url. 아마 사용 x requestBody"),
// @Parameter(name = "consumptionPattern", description = "소비 패턴. 아마 사용 x requestBody")
})
ApiResponse<UserDto.ResponseUserDto> registerUser(@RequestBody UserDto.RegisterUserDto dto);
@Operation(summary = "[Admin] User 찾기 ", description = "ID를 기반으로 해당 사용자를 찾습니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ public ResponseEntity<List<UserConsumptionGoalResponse>> createConsumptionGoals(

@PostMapping("/register")
public ApiResponse<UserDto.ResponseUserDto> registerUser(@RequestBody UserDto.RegisterUserDto dto) {
// 유저 정보 저장
UserDto.ResponseUserDto savedUser = userService.saveUser(dto);

// 유저가 선택한 해시태그를 저장
userService.saveFavoriteHashtags(savedUser.getId(), dto.getHashtagIds());

return ApiResponse.onSuccess(userService.saveUser(dto));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public static UserDto.ResponseUserDto toDto(User user) {
.phoneNumber(user.getPhoneNumber())
.lastLoginAt(user.getLastLoginAt())
.gender(user.getGender())
.region(user.getRegion())
.mobileCarrier(user.getMobileCarrier())
// .consumptionPattern(user.getConsumptionPattern())
// .photoUrl(user.getPhotoUrl())
.email(user.getEmail())
.age(user.getAge())
.build();
Expand All @@ -23,7 +27,11 @@ public static User toUser(UserDto.RegisterUserDto dto) {
.email(dto.getEmail())
.age(dto.getAge())
.name(dto.getName())
.region(dto.getRegion())
.mobileCarrier(dto.getMobileCarrier())
.gender(dto.getGender())
// .consumptionPattern(dto.getConsumptionPattern())
// .photoUrl(dto.getPhotoUrl())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.hibernate.validator.constraints.Length;

import java.time.LocalDateTime;
import java.util.List;

public class UserDto {

Expand All @@ -19,10 +20,13 @@ public static class RegisterUserDto {
private String name;
@Min(value = 1, message = "나이는 0또는 음수가 될 수 없습니다.")
private Integer age;
private String mobileCarrier;
private String region;
private Gender gender;
private String email;
private String photoUrl;
private String consumptionPattern;
private List<Long> hashtagIds; // 사용자가 선택한 해시태그 ID 목록
// private String photoUrl;
// private String consumptionPattern;
}

@Getter
Expand All @@ -33,9 +37,11 @@ public static class ResponseUserDto {
private String name;
private String email;
private Integer age;
private String mobileCarrier;
private String region;
private Gender gender;
private String photoUrl;
private String consumptionPattern;
// private String photoUrl;
// private String consumptionPattern;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "Asia/Seoul")
private LocalDateTime lastLoginAt;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ public class User extends BaseEntity {
@Column(nullable = false, length = 50, unique = true)
private String email;

@Column(nullable = false)
private String mobileCarrier; // 통신사
@Column(nullable = true)
private String mobileCarrier; // 통신사

@Column(nullable = true)
private String region; // 거주지

private LocalDateTime lastLoginAt;

private LocalDateTime lastLoginAt;

public void changeUserDate(String email, String name) {
this.name = name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
public interface UserService {
List<UserConsumptionGoalResponse> createConsumptionGoalWithDefaultGoals(Long userId);

void saveFavoriteHashtags(Long userId, List<Long> hashtagIds);

UserDto.ResponseUserDto saveUser(UserDto.RegisterUserDto dto);

UserDto.ResponseUserDto findUser(Long userId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.UserConsumptionGoalResponse;
import com.bbteam.budgetbuddies.domain.consumptiongoal.entity.ConsumptionGoal;
import com.bbteam.budgetbuddies.domain.consumptiongoal.repository.ConsumptionGoalRepository;
import com.bbteam.budgetbuddies.domain.favoritehashtag.entity.FavoriteHashtag;
import com.bbteam.budgetbuddies.domain.favoritehashtag.repository.FavoriteHashtagRepository;
import com.bbteam.budgetbuddies.domain.hashtag.entity.Hashtag;
import com.bbteam.budgetbuddies.domain.hashtag.repository.HashtagRepository;
import com.bbteam.budgetbuddies.domain.user.converter.UserConverter;
import com.bbteam.budgetbuddies.domain.user.dto.UserDto;
import com.bbteam.budgetbuddies.domain.user.entity.User;
Expand All @@ -28,6 +32,8 @@ public class UserServiceImpl implements UserService {
private final CategoryRepository categoryRepository;
private final ConsumptionGoalRepository consumptionGoalRepository;
private final ConsumptionGoalConverter consumptionGoalConverter;
private final HashtagRepository hashtagRepository;
private final FavoriteHashtagRepository favoriteHashtagRepository;

@Override
@Transactional
Expand All @@ -53,6 +59,26 @@ public List<UserConsumptionGoalResponse> createConsumptionGoalWithDefaultGoals(L
.collect(Collectors.toList());
}

@Override
@Transactional
public void saveFavoriteHashtags(Long userId, List<Long> hashtagIds) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new NoSuchElementException("User not found"));

List<FavoriteHashtag> favoriteHashtags = hashtagIds.stream()
.map(hashtagId -> {
Hashtag hashtag = hashtagRepository.findById(hashtagId)
.orElseThrow(() -> new NoSuchElementException("Hashtag not found"));
return FavoriteHashtag.builder()
.user(user)
.hashtag(hashtag)
.build();
})
.collect(Collectors.toList());

favoriteHashtagRepository.saveAll(favoriteHashtags);
}

@Override
@Transactional
public UserDto.ResponseUserDto saveUser(UserDto.RegisterUserDto dto) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,6 @@ void toggleLikeTest() {
.age(30)
.gender(Gender.MALE)
.email("[email protected]")
.photoUrl("http://example.com/photo.jpg")
.consumptionPattern("Regular")
.lastLoginAt(LocalDateTime.now())
.build();

Expand Down
Loading

0 comments on commit 64c696c

Please sign in to comment.