본문 바로가기
web/Bakery Shop Project

쇼핑몰 구현 8 - 회원 기능

by su0a 2024. 2. 23.

1. MemberRepository

@Repository
public interface MemberRepository extends JpaRepository<Member,Long> {
    Optional<Member> findByEmail(String email); //email로 member 찾기 위해
    Boolean existsByEmail(String Email); //회원가입 시 중복 체크용으로 사용
}

 

2. MemberService

@Service
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;
    private final BCryptPasswordEncoder encoder;
    private final MailSendService mailSendService;

    //회원가입 시 유효성 검사
    public BindingResult joinValid(MemberJoinRequest req, BindingResult bindingResult){
        if(req.getEmail().isEmpty()){
            bindingResult.addError(new FieldError("req","email","아이디가 비어있습니다."));
        } else if(memberRepository.existsByEmail(req.getEmail())){
            bindingResult.addError(new FieldError("req","email","아이디가 중복됩니다."));
        }
        if(!mailSendService.checkAuthNum(req.getEmail(),req.getVerificationCode())){
            bindingResult.addError(new FieldError("req","verificationCode","인증번호를 확인하세요."));
        }
        if(req.getPassword().isEmpty()){
            bindingResult.addError(new FieldError("req","password","비밀번호가 비어있습니다."));
        } else if(!req.getPassword().equals(req.getPasswordCheck())){
            bindingResult.addError(new FieldError("req","passwordCheck","비밀번호가 일치하지 않습니다."));
        }
        if(req.getName().isEmpty()){
            bindingResult.addError(new FieldError("req","name","이름이 비어있습니다."));
        }
        return bindingResult;
    }

    //회원 가입
    @Transactional
    public Member join(MemberJoinRequest req){
        Member member = memberRepository.save(req.toEntity(encoder.encode(req.getPassword())));
        return member;
    }
    
    //내정보 조회 시 사용
    public Member myInfo(String email){
        return memberRepository.findByEmail(email).get();
    }

    //정보 수정 시 유효성 검사
    public BindingResult editValid(MemberDto dto, BindingResult bindingResult, String email){
        Member member = memberRepository.findByEmail(email).get();
        if(dto.getNowPassword().isEmpty()){
            bindingResult.addError(new FieldError("dto","nowPassword","현재 비밀번호가 비어있습니다."));
        } else if(!encoder.matches(dto.getNowPassword(),member.getPassword())){
            bindingResult.addError(new FieldError("dto","nowPassword","현재 비밀번호가 틀렸습니다."));
        }
        if(!dto.getNewPassword().equals(dto.getNewPasswordCheck())){
            bindingResult.addError(new FieldError("dto","newPasswordCheck","비밀번호가 일치하지 않습니다."));
        }
        if(dto.getName().isEmpty()){
            bindingResult.addError(new FieldError("dto","name","이름이 비어있습니다."));
        }
        return bindingResult;
    }

    //정보 수정
    @Transactional
    public void edit(MemberDto memberDto,String email){
        Member member = memberRepository.findByEmail(email).get();
        if(memberDto.getNewPassword().equals("")){
            member.edit(member.getPassword(),memberDto.getName());
        } else{
            member.edit(encoder.encode(memberDto.getNewPassword()),memberDto.getName());
        }
    }

    //회원 삭제
    public boolean delete(String email, String nowPassword) {
        Member member = memberRepository.findByEmail(email).get();
        if(encoder.matches(nowPassword,member.getPassword())){
            memberRepository.delete(member);
            return true;
        }
        else return false;
    }

}

 

3. MemberController

@Controller
@RequiredArgsConstructor
@RequestMapping("/members")
public class MemberController {

    private final MemberService memberService;
    private final ItemService itemService;
    private final DeliveryService deliveryService;
    private final OrderService orderService;
    private final CartService cartService;

    //회원가입 페이지 
    @GetMapping("/join")
    public String joinPage(Model model){
        model.addAttribute("memberJoinRequest",new MemberJoinRequest());
        return "members/join";
    }
    
    @PostMapping("/join")
    public String join(@Valid @ModelAttribute MemberJoinRequest req, BindingResult bindingResult,Model model){
        //Validation
        if(memberService.joinValid(req,bindingResult).hasErrors()){
            for (FieldError error : bindingResult.getFieldErrors()) {
                System.out.println(error.getDefaultMessage());
            }
            return "members/join";
        }
        memberService.join(req);
        model.addAttribute("message","회원가입에 성공했습니다!\n로그인 후 사용 가능합니다!");
        model.addAttribute("nextUrl","/members/login");
        return "printMessage";
    }
    @GetMapping("/login")
    public String loginPage(Model model, HttpServletRequest request) {
        // 로그인 성공 시 이전 페이지로 redirect 되게 하기 위해 세션에 저장
        String uri = request.getHeader("Referer");
        if (uri != null && !uri.contains("/login") && !uri.contains("/join")) {
            request.getSession().setAttribute("prevPage", uri);
        }

        model.addAttribute("memberLoginRequest", new MemberLoginRequest());
        return "members/login";
    }

    @GetMapping("/myPage/modify")
    public String memberEditPage(Authentication auth, Model model){
        Member member = memberService.myInfo(auth.getName());
        model.addAttribute("memberDto", MemberDto.of(member));
        return "members/modify";
    }

    @PostMapping("/myPage/modify")
    public String memberEdit(@Valid @ModelAttribute MemberDto dto, BindingResult bindingResult,
                             Authentication auth, Model model){
        //Validation
        if(memberService.editValid(dto,bindingResult, auth.getName()).hasErrors()){
            return "members/modify";
        }
        memberService.edit(dto, auth.getName());
        model.addAttribute("message","정보가 수정되었습니다");
        model.addAttribute("nextUrl","/members/myPage");
        return "printMessage";
    }
    @GetMapping("/myPage")
    public String myPage(Authentication auth,Model model){
        return "members/myPage";
    }

    @GetMapping("/myPage/wishlist")
    public String wishlistPage(Authentication auth, Model model,
                               @RequestParam(required = false,defaultValue = "1") int page){
        PageRequest pageRequest = PageRequest.of(page - 1, 10, Sort.by("id").descending());
        model.addAttribute("wishlists",itemService.findAllWishlist(auth,pageRequest));
        return "members/myWishlist";
    }

    @GetMapping("/myPage/delivery")
    public String myDeliveryPage(Authentication auth, Model model){
        Delivery delivery = memberService.myInfo(auth.getName()).getDelivery();
        model.addAttribute("deliveryDto",DeliveryDto.of(delivery));

        return "members/myDelivery";
    }
    @PostMapping("/myPage/delivery")
    public String myDelivery(Authentication auth, Model model, @ModelAttribute DeliveryDto dto,BindingResult bindingResult){
        Member loginMember = memberService.myInfo(auth.getName());
        if(deliveryService.editValid(dto, bindingResult).hasErrors()){
            return "members/myDelivery";
        }
        deliveryService.editDelivery(loginMember,dto);
        model.addAttribute("message","배송지가 등록되었습니다");
        model.addAttribute("nextUrl","/members/myPage");
        return "printMessage";
    }

    @GetMapping("/myPage/order")
    public String myOrderPage(Authentication auth, Model model,
                              @RequestParam(required = false,defaultValue = "1") int page){
        PageRequest pageRequest = PageRequest.of(page - 1, 10, Sort.by("id").descending());
        Page<OrderHistDto> orderHistDtoList = orderService.getOrderList(auth.getName(), pageRequest);

        model.addAttribute("orderHistDtoList",orderHistDtoList);
        return "members/myOrder";
    }

    @GetMapping("/myPage/cart")
    public String myCartPage(Authentication auth, Model model){
        List<CartDto> cartDtoList = cartService.cartList(auth.getName());
        model.addAttribute("cartDtoList",cartDtoList);
        return "members/myCart";
    }

}

 

4. MemberJoinRequest

  • 회원가입 시 사용되는 DTO
@Data
public class MemberJoinRequest {
    private String email;
    private String name;
    private String password;
    private String passwordCheck;
    private String verificationCode;

    public Member toEntity(String encodedPassword){
        return Member.builder()
                .email(email)
                .name(name)
                .password(encodedPassword)
                .delivery(null)
                .membership(Membership.FRIEND)
                .build();
    }
}

 

5. MemberDto

  • 회원정보 확인 및 수정 시 사용되는 DTO
@Data
@Builder
public class MemberDto {
    private String email;
    private String nowPassword;
    private String newPassword;
    private String newPasswordCheck;
    private String name;
    private DeliveryDto deliveryDto;

    public static MemberDto of(Member member){
        DeliveryDto deliveryDto1 = DeliveryDto.of(member.getDelivery());
        return MemberDto.builder()
                .email(member.getEmail())
                .name(member.getName())
                .deliveryDto(deliveryDto1)
                .build();
    }
}

 

6. MemberLoginRequest

  • 로그인에 사용되는 DTO
@Data
public class MemberLoginRequest {

    private String email;
    private String password;
}