ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Wee.T] 쿠폰페이지 개발(조회, 등록) ajax로 처리하기
    DEVELOP/Wee.T 2022. 8. 21. 21:26

     

     

    uri 매핑작업까지 다 마쳐셔, 본격적으로 기능구현을 시작했습니다.

    이번에 구현한 페이지는 쿠폰페이지입니다.

     

    이런식으로 동작하는 페이지를 만들었습니다.

     

    쿠폰페이지의 기능은 크게 다음과 같이 나눌 수 있는데,

    1. [쿠폰북]엔 다운로드 가능한 쿠폰들의 목록이 보여진다.
    2. [내 쿠폰] 탭을 통해 보유한 쿠폰들을 조회할 수 있다.
    3. [쿠폰북]의 쿠폰을 다운로드받으면 [내쿠폰] 탭에 추가된다.
    4. 쿠폰코드를 직접 입력해 쿠폰을 등록할 수 있다. 이렇게 등록한 쿠폰은 바로바로 [내쿠폰] 탭에 추가된다.

     

    2번 내쿠폰을 조회하는 부분과 4번 기능은 처음부터 ajax로 처리할 것을 염두에 두었습니다.

    아무래도 등록할 때마다 새로고침되는 것보단 바로바로 추가되는 것이 좀더 완성도 높은 페이지라 생각했기 때문입니다.

     

     

    쿠폰 DB관계

     

    DB설계 중 쿠폰과 관련된 테이블 구조입니다.

    쿠폰정보가 담긴 쿠폰테이블이 있고 쿠폰 사용내역 테이블에서 이 테이블의 기본키를 참조(FK)하여 user_id와 함께 PK로 사용하고 있습니다.

    userID는 일반회원 테이블인 t_mem테이블의 PK를 참조하고있고, 일반회원 테이블은 모든회원테이블인 t_user테이블의 PK를 참조하고 있는 관계입니다. 해당 프로젝트에서는 일반회원과 트레이너가 구분되지만, 쿠폰 발급과 사용은 일반회원만 가능하기 때문에 일반회원 테이블을 참조하였습니다.

     

     

    먼저 매퍼 xml파일에 전체쿠폰을 조회할 수 있는 sql쿼리를 작성하였습니다.

    WHERE절에 간이 만료된 쿠폰들은 아예 나타나지 않게끔 조건을 걸어두었고, visible속성이 공개인 쿠폰들만 가져왔습니다. 숨겨진 쿠폰은 사용자가 쿠폰번호를 직접 입력해 등록할 수 있게끔 만들기 위해 추가한 속성입니다. 마감기한이 없는 쿠폰은 기간이 무제한이라는 소리이므로 나중에 view단에서 따로 처리를 해줄 것입니다.

     

     

    내 쿠폰 조회 쿼리문은 쿠폰 사용내역 테이블을 조인하여 해당 유저가 보유하고있고, 아직 사용하지 않은 쿠폰들만 가져오도록 작성하였습니다.

     

     

     

    쿠폰등록 쿼리는 간단하게 쿠폰id와 유저id를 입력받도록 만들었습니다. 이 때 등록하는 쿠폰은 새로 등록하는 것이 아닌 사용자 입장의 쿼리로, 쿠폰테이블에 등록되어있는 쿠폰만 insert가 가능합니다(FK관계이기 때문에). 사용여부 컬럼은 default value로 'N'(사용하지 않음)을 설정해 두었고 적용일시 컬럼은 null을 허용하도록 설계했습니다.

     

     

    쿼리문 작성 후엔 매퍼인터페이스와 서비스 인터페이스, 구현클래스를 만들고, 각각의 단위 테스트를 진행했습니다.

     

     

    테스트가 모두 정상동작하는 것을 확인 후, 컨트롤러 메소드를 작성했습니다.

    매핑 URI는 이전에 작성해둔 표대로 작성하였습니다.

     


    1. 쿠폰북 조회하기

     

    Controller

    쿠폰북을 조회하는 GET방식 요청이 들어오면 서비스 메소드 수행 후 jsp로 이동합니다.

    수행 결과는 모델 공유속성으로 추가하였습니다.

     

    JSP

     

    jstl:core forEach태그를 사용해 모델에 등록된 속성들을 하나하나 빼서 jsp에 뿌려주었습니다. 

    기간을 표시하는 부분은 c:choose-when-otherwise태그를 사용하여 시작일과 종료일이 모두 null일 경우 기간 무제한이라고 명시해주고 아닐경우는 기간을 표시해주었습니다.

     

     


     

    2. 내쿠폰 조회

     

    Controller

     

    내 쿠폰 조회는 ajax로 처리할 것이기 때문에 컨트롤러에서 @ResponseBody로 리스트 자체를 리턴해주었습니다.

     

     

     

     

    JavaScript

     

     

    자바스크립트로 ajax통신을 처리하는 함수를 만들었습니다.

    매핑한 uri로 요청을 보내고, 파라미터로는 userId를 넘겨주었습니다. 이부분은 로그인파트 구현이 되지 않은 상태라 임의로 넣은 샘플데이터의 유저아이디를 전송했습니다. 나중에 로그인파트 구현이 완료되면 세션scope의 user_id를 넘겨주도록 수정해야 합니다.

     

    ajax통신 후 받은 리스트 객체를 jQuery의 each메소드로 반복합니다.

    기간에 null값이 들어오면 화면에 "null"이 그대로 찍히는 것을 방지하기 위해, null일 경우는 공백을 넣어주었습니다. 쿠폰영역의 html태그들을 str변수에 담고, 받아온 리스트 객체의 정보를 표시합니다. 기간이 모두 공백일 경우엔 "기간무제한"을 입력해주고, 아닐경우는 기간을 나타내 주었습니다.

     

     

    JSP

    <button class="nav-link" id="mycoupon-tab" data-bs-toggle="tab" data-bs-target="#mycoupon" type="button"
                        role="tab" aria-controls="mycoupon" aria-selected="false" onclick="getMyCoupon()">내 쿠폰</button>

     

    작성한 함수를 [내 쿠폰] 탭을 클릭했을 시 호출하도록 onclick이벤트를 걸어주어 마무리 하였습니다.

     

     


    3. 쿠폰 다운로드하기

     

    Controller

     

    쿠폰 등록 역시 ajax로 처리하였습니다. 등록은 POST방식으로 요청을 받고, 컨트롤러에 @ResponseBody로 boolean 타입을 리턴하도록 작성했습니다. 등록에 실패할 시 ControllerException으로 예외를 던지도록 래핑하였습니다.

     

    JavaScript

     

     

    쿠폰등록을 처리하는 함수를 만들어주고, 매핑한 uri로 ajax요청을 보냅니다. 함수의 매개변수로 쿠폰 아이디를 받고, 대소문자를 가리지 않게 하기위해 모두 대문자로 만들어줍니다. 쿠폰 아이디와 유저아이디를 전송 파라미터로 함께 보냅니다.(ajax의 data속성)

     

    성공했을 시 로직에는 내쿠폰을 보여주는 함수를 호출합니다. 이 역시 ajax로 요청을 보내기 때문에 쿠폰등록을 완료하면 바로바로 내쿠폰탭에 추가한 쿠폰이 보여지게 됩니다.

     

    실패했을 시에 사용자에게 구체적으로 메시지를 알려주고 싶어서 모달의 스타일을 동적으로 변경하였습니다. 스타일속성을 동적으로 변경하는 것은 부담이 크기 때문에 지양하는 것이 좋다고 알고있지만, 그렇게 하려면 모달을 하나 더 만들어 스타일 작업까지 해야하기에 그냥 동적으로 변경하는 방식을 선택했습니다.

     

    가장 처음에 모달의 스타일과 메시지를 초기화해준 이유는 한번 오류가 나고 다시 정상등록했을 때 이전에 변경된 모달이 뜨게하는 것을 막기 위해서 입니다.

     

    error시에 반환되는 request객체의 responseText에 오라클의 예외메시지 별로 나누어 모달창의 메시지가 다르게 나타날 수 있도록 처리해 주었습니다. ORA-02291은 부모키가 없을 시 발생하는 예외이고, ORA-00001은 무결성 제약조건에 위배될 시 발생하는 예외입니다. 사용자가 쉽게 이해할 수 있도록 예외메시지를 일반적인 말로 작성하였습니다.

     

    마지막으로 complete속성에 모달창을 나타나게 하여 각 상황별로 변경한 모달이 뜨게 만들었습니다.

     

    쿠폰을 직접 등록하는 것과 쿠폰북에 있는 쿠폰을 다운로드 받는 것은 로직이 동일하기 때문에, 두 기능에서 공유할 수 있도록 만들었습니다.

     

     

    JSP

     

    <form class="reg-coupon" onsubmit="createMyCoupon(couponId.value)" method="POST">
        <input type="text" placeholder="쿠폰코드를 입력하세요." pattern="^[a-zA-Z0-9]*$" name="couponId" id="couponId">
        <input type="submit" value="등록">
    </form>

    쿠폰코드를 입력하는 창을 form태그로 감싸고, onsubmit이벤트 속성에 작성한 함수를 걸어주었습니다. 함수의 매개변수부분 couponId.value는 해당 폼의 name에서 couponId를 찾아 그 값을 넘겨줍니다. 

    이것을 이용하면 forEach로 작성했던 쿠폰북의 파라미터를 넘기는 것도 가능합니다.

     

     

     

    forEach로 작성한 쿠폰북 영역의 input value를 querySelector를 이용해 가져오려 하면 같은 이름의 모든 value를 가져오기 때문에, 무조건 첫번째에 있는 value만 가져오게 되어 선택한 쿠폰에 대한 value를 가져올 수 없습니다. 이 때 다운로드 버튼을 폼태그로 감싸고, input name.value를 이용하면 전송된 폼의 input value만 전송할 수 있습니다.

     

    couponId는 사용자에게 보여줄 필요가 없으니 hidden으로 처리하고, onsubmit 이벤트로 작성한 함수를 걸어준 후 매개변수로 넣어주어 기능 구현을 완료하였습니다.

     

    본격적 기능 구현의 첫번째 단계라 맡은 부분 중 비교적 간단해보이는 쿠폰 페이지를 먼저 개발해보았는데, 예상대로 수월하게 구현할 수 있었습니다.

    댓글

Designed by Tistory.