해당 포스팅에서는 배송지 관리 기능을 구현한 과정에 대해 간략하게 정리해 보고자 한다.
이전에는 회원 테이블에 배송지가 하나만 등록되어 있었다. 하지만 주문할 때 배송지가 자주 변경될 수 있기 때문에, 여러 배송지를 저장할 수 있도록 별도의 Address 테이블을 추가했다.
Address 테이블은 Member 테이블과 N:1 연관 관계를 맺어, 한 명의 회원이 여러 주소를 가질 수 있도록 했다.
이렇게 함으로써 사용자는 상품을 주문할 때, 회원의 모든 배송지 목록을 가져와서 원하는 배송지를 선택할 수 있다.
@Entity
public class Address extends BaseTimeEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "address_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
private String name; // 받는분 성함
private String zipcode; // 우편 번호
private String addr; // 받는분 주소
private String addrDetail; // 받는분 상세 주소
private String tel; // 받는분 전화 번호
private String req; // 배송 메시지
private boolean isDefault; // 기본 배송지 여부
}
/**
* 회원 가입
*/
public void createAccount(SignUpRequestDTO signUpRequestDTO) {
Member member = modelMapper.map(signUpRequestDTO, Member.class);
member.setPassword(passwordEncoder.encode(signUpRequestDTO.getPassword()));
member.setRole(Role.USER);
addressRepository.save(signUpRequestDTO.toAddress(member, signUpRequestDTO));
memberRepository.save(member);
}
/**
* 주문서 작성 화면 - 회원 기본 배송지 조회
*/
public Address getDefaultShippingAddress(Long memberId) {
return addressService.getAddressByMemberIdAndIsDefault(memberId, true);
}
/**
* 주문서 작성 화면 - 회원 배송지 목록 조회
*/
public List<Address> getAddressList(Long memberId) {
return addressService.getAllAddressByMemberId(memberId);
}
/**
* 상품 주문
*/
public Long order(OrderRequestDTO orderRequestDTO, Long memberId) {
// 생략
// 회원 배송지 관련 정보 업데이트
if (orderRequestDTO.isDefault()) {
// 기존의 주소 목록 가져오기
List<Address> existingAddresses = addressService.getAllAddressByMemberId(member.getId());
// 기본 배송지 모두 false로 초기화
existingAddresses.forEach(address -> {
address.setDefault(false);
addressService.saveAddress(address); // 기존 주소의 default 값을 변경한 후 저장
});
// 새로운 배송지 생성
Address newAddress = OrderRequestDTO.toAddress(member, orderRequestDTO);
// 새로운 배송지와 일치하는 기존 주소가 있는지 확인
boolean isDuplicate = existingAddresses.stream().anyMatch(address -> address.equals(newAddress));
// 중복되는 주소가 없는 경우 배송지 추가
if (!isDuplicate) {
// 새로운 배송지 추가
addressService.saveAddress(newAddress);
} else {
// 기존의 주소와 동일한 경우 isDefault 값을 true로 변경
existingAddresses.stream()
.filter(existingAddress -> existingAddress.equals(newAddress))
.findFirst()
.ifPresent(existingAddress -> {
existingAddress.setDefault(true);
existingAddress.setReq(orderRequestDTO.getReq());
addressService.saveAddress(existingAddress);
});
}
}
// 생략
}