Skip to content

Commit

Permalink
Merge pull request #65 from Solucitation/feature/favorites_friends
Browse files Browse the repository at this point in the history
LGTM~πŸ‘ 거의 λ‹€ μ™”λ„€μš” 개발 λκΉŒμ§€ νŒŒμ΄νŒ…πŸ₯³
  • Loading branch information
khee2 authored Jul 31, 2024
2 parents be725be + c314655 commit 7d2fb04
Show file tree
Hide file tree
Showing 7 changed files with 373 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ out/
!**/src/test/**/out/
src/main/resources/application.yml
src/main/resources/application.properties
src/main/resources/application.yml

### NetBeans ###
/nbproject/private/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package com.solucitation.midpoint_backend.domain.FavFriend.api;

import com.solucitation.midpoint_backend.domain.FavFriend.dto.FavFriendRequest;
import com.solucitation.midpoint_backend.domain.FavFriend.entity.FavFriend;
import com.solucitation.midpoint_backend.domain.FavFriend.service.FavFriendService;
import jakarta.validation.Valid;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

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

@RestController
@RequestMapping("/api/favs/friends")
@RequiredArgsConstructor
public class FavFriendController {
private final FavFriendService favFriendService;

@PostMapping("/save")
public ResponseEntity<?> saveFavFriend(Authentication authentication, @Valid @RequestBody FavFriendRequest favFriendRequest, BindingResult result) {
String email = authentication.getName();
if (result.hasErrors()) {
String errorMessage = result.getAllErrors().stream()
.map(error -> error.getDefaultMessage())
.collect(Collectors.joining(", "));
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new ApiResponse(false, "μž…λ ₯ 값이 잘λͺ»λ˜μ—ˆμŠ΅λ‹ˆλ‹€: " + errorMessage));
}

try {
FavFriend savedFriend = favFriendService.saveFavoriteFriend(
favFriendRequest.getAddress(),
favFriendRequest.getName(),
favFriendRequest.getLatitude(),
favFriendRequest.getLongitude(),
email
);
return ResponseEntity
.status(HttpStatus.CREATED)
.body(new ApiResponse(true, "μ¦κ²¨μ°ΎλŠ” 친ꡬ μ €μž₯에 μ„±κ³΅ν–ˆμŠ΅λ‹ˆλ‹€.", savedFriend.getFavFriendId()));
} catch (RuntimeException e) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new ApiResponse(false, "이미 μ‘΄μž¬ν•˜λŠ” μΉœκ΅¬μž…λ‹ˆλ‹€."));
} catch (Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ApiResponse(false, "μ„œλ²„ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. " + e.getMessage()));
}
}

@GetMapping("/details")
public ResponseEntity<?> getFavFriendDetails(Authentication authentication, @RequestParam Long favFriendId) {
String email = authentication.getName();
try {
FavFriend favFriend = favFriendService.getFavoriteFriendByFavFriendId(favFriendId, email);
return ResponseEntity.ok(new FavFriendResponse(favFriend.getFavFriendId(), favFriend.getName(), favFriend.getAddress()));
} catch (RuntimeException e) {
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(new ApiResponse(false, e.getMessage()));
} catch (Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ApiResponse(false, "μ„œλ²„ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. " + e.getMessage()));
}
}

@DeleteMapping("/delete")
public ResponseEntity<?> deleteFavFriend(Authentication authentication, @RequestParam Long favFriendId) {
String email = authentication.getName();
try {
favFriendService.deleteFavoriteFriendByName(favFriendId, email);
return ResponseEntity.ok(new ApiResponse(true, "μ¦κ²¨μ°ΎλŠ” 친ꡬ μ‚­μ œμ— μ„±κ³΅ν–ˆμŠ΅λ‹ˆλ‹€."));
} catch (RuntimeException e) {
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(new ApiResponse(false, e.getMessage()));
} catch (Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ApiResponse(false, "μ„œλ²„ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. " + e.getMessage()));
}
}

@GetMapping("/list")
public ResponseEntity<?> getFavFriendsList(Authentication authentication) {
String email = authentication.getName();
try {
List<FavFriend> favFriends = favFriendService.getFavoriteFriends(email);
return ResponseEntity.ok(favFriends.stream()
.map(favFriend -> new FavFriendResponse(favFriend.getFavFriendId(), favFriend.getName(), favFriend.getAddress()))
.collect(Collectors.toList()));
} catch (RuntimeException e) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new ApiResponse(false, e.getMessage()));
} catch (Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ApiResponse(false, "μ„œλ²„ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. " + e.getMessage()));
}
}

@PatchMapping("/update")
public ResponseEntity<?> updateFavFriend(Authentication authentication, @RequestParam Long favFriendId, @RequestParam(required = false) String name, @RequestParam(required = false) String address) {
String email = authentication.getName();
try {
FavFriend updatedFriend = favFriendService.updateFavoriteFriend(favFriendId, name, address, email);
return ResponseEntity.ok(new ApiResponse(true, "μ¦κ²¨μ°ΎλŠ” 친ꡬ μˆ˜μ •μ— μ„±κ³΅ν–ˆμŠ΅λ‹ˆλ‹€.", updatedFriend.getFavFriendId()));
} catch (IllegalArgumentException e) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new ApiResponse(false, e.getMessage()));
} catch (RuntimeException e) {
return ResponseEntity
.status(HttpStatus.FORBIDDEN)
.body(new ApiResponse(false, e.getMessage()));
} catch (Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ApiResponse(false, "μ„œλ²„ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. " + e.getMessage()));
}
}

@Getter
@Setter
public static class FavFriendResponse {
private Long favFriendId;
private String name;
private String address;

public FavFriendResponse(Long favFriendId, String name, String address) {
this.favFriendId = favFriendId;
this.name = name;
this.address = address;
}
}

public static class ApiResponse {
private boolean success;
private String message;
private Long favFriendId;

public ApiResponse(boolean success, String message, Long favFriendId) {
this.success = success;
this.message = message;
this.favFriendId = favFriendId;
}

public ApiResponse(boolean success, String message) {
this(success, message, null);
}

public boolean isSuccess() {
return success;
}

public void setSuccess(boolean success) {
this.success = success;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public Long getFavFriendId() {
return favFriendId;
}

public void setFavFriendId(Long favFriendId) {
this.favFriendId = favFriendId;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.solucitation.midpoint_backend.domain.FavFriend.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class FavFriendRequest {

@NotBlank(message = "Address is required")
@Size(max = 255, message = "Address must be less than 255 characters")
private String address;

@NotBlank(message = "Name is required")
@Size(max = 100, message = "Name must be less than 100 characters")
private String name;

@NotNull(message = "Latitude is required")
private Float latitude;

@NotNull(message = "Longitude is required")
private Float longitude;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.solucitation.midpoint_backend.domain.FavFriend.entity;

import com.solucitation.midpoint_backend.domain.member.entity.Member;
import jakarta.persistence.*;
import lombok.*;

@Builder
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Table(name = "fav_friend")
public class FavFriend {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "fav_friend_id")
private Long favFriendId;

@ManyToOne
@JoinColumn(name = "member_id", nullable = false)
private Member member;

@Column(name = "address", nullable = false, length = 255)
private String address;

@Column(name = "name", nullable = false, unique = true, length = 100)
private String name; // 친ꡬ 이름은 쀑볡 μ €μž₯ λΆˆκ°€λŠ₯

@Column(name = "latitude", nullable = false)
private Float latitude;

@Column(name = "longitude", nullable = false)
private Float longitude;

public void setAddress(String address) {
this.address = address;
}

public void setName(String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.solucitation.midpoint_backend.domain.FavFriend.repository;

import com.solucitation.midpoint_backend.domain.FavFriend.entity.FavFriend;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

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

@Repository
public interface FavoriteFriendRepository extends JpaRepository<FavFriend, Long> {
Optional<FavFriend> findByNameAndMemberId(String name, Long memberId);
List<FavFriend> findByMemberId(Long memberId);
Optional<FavFriend> findByFavFriendIdAndMemberId(Long favFriendId, Long member_id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.solucitation.midpoint_backend.domain.FavFriend.service;

import com.solucitation.midpoint_backend.domain.FavFriend.entity.FavFriend;
import com.solucitation.midpoint_backend.domain.FavFriend.repository.FavoriteFriendRepository;
import com.solucitation.midpoint_backend.domain.member.entity.Member;
import com.solucitation.midpoint_backend.domain.member.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class FavFriendService {
private final FavoriteFriendRepository favoriteFriendRepository;
private final MemberRepository memberRepository;

@Transactional
public FavFriend saveFavoriteFriend(String address, String name, Float latitude, Float longitude, String email) {
Member member = memberRepository.findByEmail(email)
.orElseThrow(() -> new IllegalArgumentException("ν•΄λ‹Ή μ΄λ©”μΌμ˜ νšŒμ›μ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."));

favoriteFriendRepository.findByNameAndMemberId(name, member.getId())
.ifPresent(favFriend -> {
throw new RuntimeException("이미 μ‘΄μž¬ν•˜λŠ” μΉœκ΅¬μž…λ‹ˆλ‹€.");
});

FavFriend favFriend = FavFriend.builder()
.member(member)
.address(address)
.name(name)
.latitude(latitude)
.longitude(longitude)
.build();

return favoriteFriendRepository.save(favFriend);
}

@Transactional(readOnly = true)
public FavFriend getFavoriteFriendByFavFriendId(Long favFriendId, String email) {
Member member = memberRepository.findByEmail(email)
.orElseThrow(() -> new IllegalArgumentException("ν•΄λ‹Ή μ΄λ©”μΌμ˜ νšŒμ›μ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."));

return favoriteFriendRepository.findByFavFriendIdAndMemberId(favFriendId, member.getId())
.orElseThrow(() -> new RuntimeException("μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μΉœκ΅¬μž…λ‹ˆλ‹€."));
}

@Transactional
public void deleteFavoriteFriendByName(Long favFriendId, String email) {
Member member = memberRepository.findByEmail(email)
.orElseThrow(() -> new IllegalArgumentException("ν•΄λ‹Ή μ΄λ©”μΌμ˜ νšŒμ›μ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."));

FavFriend favFriend = favoriteFriendRepository.findByFavFriendIdAndMemberId(favFriendId, member.getId())
.orElseThrow(() -> new RuntimeException("μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μΉœκ΅¬μž…λ‹ˆλ‹€."));

favoriteFriendRepository.delete(favFriend);
}

@Transactional(readOnly = true)
public List<FavFriend> getFavoriteFriends(String email) {
Member member = memberRepository.findByEmail(email)
.orElseThrow(() -> new IllegalArgumentException("ν•΄λ‹Ή μ΄λ©”μΌμ˜ νšŒμ›μ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."));

return favoriteFriendRepository.findByMemberId(member.getId());
}

@Transactional
public FavFriend updateFavoriteFriend(Long favFriendId, String name, String address, String email) {
Member member = memberRepository.findByEmail(email)
.orElseThrow(() -> new IllegalArgumentException("ν•΄λ‹Ή μ΄λ©”μΌμ˜ νšŒμ›μ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."));

FavFriend favFriend = favoriteFriendRepository.findByFavFriendIdAndMemberId(favFriendId, member.getId())
.orElseThrow(() -> new IllegalArgumentException("μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μ¦κ²¨μ°ΎλŠ” μΉœκ΅¬μž…λ‹ˆλ‹€."));

if (name == null || name.trim().isEmpty() || name.length() > 100) {
throw new IllegalArgumentException("이름은 μ΅œμ†Œ 1κΈ€μž 이상 μ΅œλŒ€ 100κΈ€μž μ΄ν•˜λ‘œ μž…λ ₯ν•΄μ•Ό ν•©λ‹ˆλ‹€.");
}
if (address == null || address.trim().isEmpty() || address.length() > 255) {
throw new IllegalArgumentException("μ£Όμ†ŒλŠ” μ΅œμ†Œ 1κΈ€μž 이상 μ΅œλŒ€ 255κΈ€μž μ΄ν•˜λ‘œ μž…λ ₯ν•΄μ•Ό ν•©λ‹ˆλ‹€.");
}

if (!address.equals(favFriend.getAddress())) {
favFriend.setAddress(address);
}

if (!name.equals(favFriend.getName())) {
if (favoriteFriendRepository.findByNameAndMemberId(name, member.getId()).isPresent()) {
throw new IllegalArgumentException("이미 μ‘΄μž¬ν•˜λŠ” 친ꡬ μ΄λ¦„μž…λ‹ˆλ‹€.");
}
favFriend.setName(name);
}

return favoriteFriendRepository.save(favFriend);
}
}
Loading

0 comments on commit 7d2fb04

Please sign in to comment.