BUTTER STUDIO 발표 대본

안녕하세요 저희는 React JS와 CSS 및 PostgreSQL을 활용하여 영화 티켓 예매 사이트를 제작한 팀 Butter Studio의 윤지원, 김수빈, 한규민입니다.

<수빈>

저희는 먼저 관리자 권한으로의 영화관, 상영관, 영화, 상영시간표 정보 등록부터 사용자들의 영화 예매까지의 과정을 각자 맡은 부분을 중심으로 실행 화면을 보여드리며 설명하겠습니다. 그 다음으로 주요 기능별 어떤 방식으로 구현했는지를 중심으로 설명드리도록 하겠습니다.

첫 번째로, 관리자페이지에서 사용자들의 영화 예매를 위한 기본 정보 설정 과정을 UI 중심으로 보여드리며 설명하겠습니다. 기본 정보 설정 과정에는 먼저, 한 지점의 영화관에 대한 정보, 영화관 이름, 대중교통. 주차장 안내 등의 내용들을 관리하며, 상영관 종류에 따른 관람료 정보 또한 관리를 해줍니다. 다음으로 영화 정보 및 상영관 정보를 다룬 후, Butter DB의 각 영화에 대한 상영시간표 정보를 등록 및 삭제하는 과정을 거칩니다.

우선 영화관 관리 페이지입니다. 영화관 관리 페이지에서는 위에서 언급한 것처럼 한 지점의 영화관에 대한 정보, 즉 영화관 이름, 해당 영화관까지 운행하는 대중교통 정보, 주차장 안내 정보 등을 입력하고 수정할 수 있습니다. 또한 여기서 2D, 3D와 같은 상영관 종류에 따른 괌람료 정보의 입력 및 수정, 삭제가 가능합니다.

다음으로 영화 관리 페이지입니다. TMDB에서 가져온 영화 목록들 중 한 영화를 클릭했을 때, 해당 영화가 Butter DB에 존재하면 삭제 기능을 가진 삭제 버튼을, 존재하지 않는다면 DB에 저장할 수 있는 기능을 가진 등록 버튼이 띄워집니다. 또한 상단의 검색 기능을 사용해 검색한 결과를 목록으로 나타낼 수 있게 했습니다.

다음으로 상영관 관리 페이지입니다. 영화관 관리 페이지에서 작성했던 상영관별 관람료 정보를 통해 상영관타입을 지정해주었고, 이 상영관타입 정보를 1관, 2관, 특별관 등의 관리자가 정한 이름의 상영관과 연관시켜주고, 해당 상영관의 좌석 정보를 등록 및 수정해줍니다.

마지막으로 상영시간표 관리 페이지입니다. 앞에서 Butter DB에 등록한 영화들을 기준으로 하나의 영화를 선택해 해당 영화의 상영 예정일부터 상영 종료될 날짜, 어느 상영관에서 어느 시간에 상영할 예정인지에 대한 정보를 설정해줍니다. 상영시간표를 추가할 때의 과정은 뒤에 세부 기능에서 더 자세히 설명드릴 예정입니다. 설정해준 정보를 서버로 보내 Butter DB에 저장을 하고, Butter DB의 TimeTable Table에서 선택한 날짜의 정보들을 불러옵니다.

<규민>

저는 이번에 로그인과 회원가입 그리고 마이페이지 및 비회원 예매 확인 창을 만들었습니다. 예매를 하기 앞서 로그인을 해야합니다. 다른 방법으로는 비회원예매가 있지만 그건 나중에 하겠습니다.

-회원가입

로그인을 하려면 먼저 회원가입을 해야 합니다. 왜냐하면 사용자 정보가 서버에 없기 때문입니다. 먼저 회원가입 창을 클릭하고 사용자가 데이터를 알맞게 입력 합니다. 입력을 맞친 후 가입하기 버튼을 눌러서 서버로 전송을 시키는데 이때 서버로 넘어가기 전에 2가지 절차를 먼저 밟습니다. 첫번째는 비밀번호와 비밀번호 확인이 일치하는지. 두번째는 핸드폰 인증번호가 인증되었는지. 이렇게 2개를 먼저 승인이 되었음을 확인하고 서버로 보내주게 됩니다. 서버에서는 이렇게 받은 데이터를 유효성 검사를 해주고 형식에 맞지 않는 데이터 타입이면 경고창을 띄워줍니다. 유효성 검사도 승인이 되었다면 아이디 이메일 휴폰번호가 db에 똑같은게 있는지 각각 체크하고 없다면 중복되지 않는 데이터니깐 db에 드디어 사용자가 생기게 됩니다.

-로그인

이제 사용자가 db에 생겼으니 로그인을 해줍니다.

로그인은 사용자가 입력한 아이디 비밀번호를 서버로 넘겨주는데,

서버에서는 이를 받아 db랑 비교를 해줍니다. 일치하면 이 사용자의 정보를 클라이언트 쪽으로 다시 반환해주는데 이때 받은 사용자 정보로 각각 다른 화면이 나오겠금 설정해줍니다. 회원은 마이페이지 로그아웃,

비회원은 예매한 경우엔  예매확인 로그아웃, 관리자는 관리자페이지 로그아웃, 마지막으로 아무 권한이 없는 유저는 로그인 회원가입이 나오도록 구현했습니다.

여기서 어떻게 서버에서 처리해주는 지에 대해선

뒤에 기능부분 설명할 때 하겠습니다.

-마이페이지

회원으로 로그인하면 위에 nav가 바뀌는 걸 확인하실 수가 있는데 마이페이지로 들어가게 되면 프로필은 물론 회원가입할 때 입력하신 정보를 수정하실 수 있습니다.

프로필 변경은 파일을 받아서 db에 저장해 로그인 유지했던 방식으로

닉네임과 함께 UI에 표현했습니다.

회원정보 수정 기능은 기존 회원인지 먼저 검증하고 회원가입에서 했던 방식으로 휴대폰 인증, 데이터 유효성검사, 중복 검사를 합니다. 다만 이때는 회원정보 수정이므로, 업데이트만 해줍니다.

나의 예매 내역은 사용자가 예매한 내역을 db에서 찾아서 가져옵니다.

-비회원 예매 로그인

로그인과 마찬가지로 입력값을 넣고 로그인버튼을 누르면 서버로 전송해서 일치하면 비회원 정보를 쿠키에 담아 반환해줍니다.

그리고 예매 확인 창을 누르면 비회원이 예매한 예매 내역이 마이페이지와 동일하게 나옵니다.

이상입니다.

<지원>

다음으로 홈화면에서부터 영화 예매까지의 UI를 설명해드리겠습니다.

우선 홈화면입니다. 홈화면에는 박스오피스와 무비컬렉션이 있습니다. 박스오피스는 현재 저희 DB에 등록된 영화들 중에서 TMDB 인기도가 높은 순서대로 영화포스터가 보여집니다. 보이는 방식에는 카로셀을 이용하였습니다. 무비 컬렉션은 박스오피스 1위에 해당하는 영화의 포스터와 예고편을 보여줍니다.

다음으로 극장 화면입니다. 이곳은 극장정보, 상영시간표, 관람료 등의 정보를 볼 수 있는 곳입니다. 극장정보에는 총 상영관 수, 주소, 대중교통 안내, 주차 안내, 극장 위치가 표시된 지도를 볼 수 있습니다. 상영시간표에는 날짜와 상영관별로 영화의 상영시간표가 나오게 됩니다. 관람료는 상영관 종류, 주중/주말, 시간대, 나이대별로 나눠진 관람료를 표로 볼 수 있습니다.

다음은 영화 화면입니다. 이곳은 상영영화 목록을 볼 수 있는 곳으로 무비차트와, 상영예정작으로 이루어져 있습니다. 무비차트는 홈화면의 박스오피스와 마찬가지로 DB에 등록된 영화들 중에서 가장 TMDB 인기도가 높은 순서대로 정렬되어 보여집니다. 상영예정작은 개봉일이 오늘날짜보다 뒤에 있는 영화들이 보여지게 됩니다.

이중에 한 영화를 클릭하면 영화 상세정보 페이지로 넘어갑니다.

영화 상세정보 페이지에서는 제일 위에 스틸컷이 카로셀로 보이고, 그 아래 영화 포스터와 제목, 예매율, 감독, 출연, 장르, 개봉일 등의 정보가 보이게 됩니다. 그 아래는 영화의 줄거리 설명과, 영화의 예고편들이 나옵니다.

다음으로 빠른 예매를 클릭하거나 예매하기 버튼을 누르면 나오는 예매화면입니다. 영화와 극장을 선택하면 해당 영화에 해당하는 상영시간표를 불러오게 되고, 그 중 하나를 클릭하면 해당 시간과 상영관이 state에 저장되어 좌석선택페이지로 넘어갈 수 있게 됩니다.

좌석선택 페이지에서는 이미 예매된 선택불가 좌석을 제외하고 좌석을 선택할 수 있습니다. 먼저 일반/청소년/경로우대 인원을 정하고 해당 인원만큼의 좌석을 선택하면 좌석정보와, 총 결제금액이 뜨게 되고 결제하기로 넘어 갈 수 있습니다.

결제하기를 눌렀을 때 로그인이 되어있으면 바로 결제페이지로 넘어가고, 로그인이 안 된 상태이면 이러한 모달창이 뜬 후 비회원 예매를 클릭해야 결제페이지로 넘어가게 됩니다. 로그인이 된 상태에서의 결제페이지에는 해당 회원의 회원 정보가 미리 들어가 있고 수정은 불가능한 상태입니다. 수정은 마이페이지에서만 가능합니다. 비회원 예매를 클릭해서 넘어온 결제페이지에서는 비회원 정보를 입력할 수 있습니다. 비회원 정보를 모두 입력한 후 버튼을 눌러 저장해줍니다. 카카오페이 버튼을 클릭하여 결제 방법을 카카오페이로 지정한 다음, 결제하기를 누르면 다음의 화면으로 넘어가게 됩니다.

이 화면에서 휴대폰 번호와 생년월일을 입력하면 휴대폰에 알림톡이 오는데, 이 알림톡에서 결제를 진행한 후 완료버튼을 누르면 왼쪽의 예매완료페이지가 뜨게 됩니다. 만약 결제를 실패하면 예매실패페이지가 뜨게 됩니다. 예매완료페이지가 뜨면 결제페이지에서 입력된 이메일로 예매 내역이 발송되는 것으로 예매가 완료됩니다.

<수빈>

지금까지 UI를 통해 저희 프로젝트의 전체적인 흐름을 살펴보았습니다. 이후에는 더욱 자세히 주요 기능들을 살펴볼 예정입니다. 주로 관리자는 영화 정보를 등록하고, 시간표 및 상영관 정보들을 설정하는 일을 합니다. 다음으로 로그인 및 회원가입 기능을 통해 회원/비회원 로그인 및 마이페이지 또는 비회원 예매확인 페이지를 보여주게 됩니다. 마지막으로 가장 중요한 예매 및 결제 기능을 통해 예매하고자 하는 영화 및 좌석을 지정해 카카오페이 결제를 통해 영화를 예매할 수 있습니다.

처음으로 관리자페이지에서 영화 등록 및 기능입니다. 처음 화면에 보이는 리스트는 오늘 날짜를 기준으로 상영예정일이 한 달 전부터인 영화들을 TMDB에서 가져온 영화 목록들입니다. 한 영화를 클릭했을 때, 해당 영화가 Butter DB에 존재하면 삭제 기능을 가진 삭제 버튼을, 존재하지 않는다면 DB에 저장할 수 있는 기능을 가진 등록 버튼이 띄워집니다. 또한 상단의 검색 기능을 사용해 검색한 결과를 목록으로 나타낼 수 있게 했습니다. 이때, 검색 결과는 TMDB의 검색 결과에 따릅니다.

다음으로 상영시간표 등록 기능입니다. 먼저 Butter DB에 저장되어있는 영화들 중 하나를 선택합니다. 선택한 영화의 상영시간표에 한해 클라이언트에서 상영시간표를 추가할 때 이미 리스트에 추가한 상영시간대와 겹친다면 추가되지 않도록 설정해주었습니다. 클라이언트에 오류가 나지 않게 정보를 등록해준 상태에서 서버로 저장해달라고 요청을 보낼 때, 요청 보낸 상영시간대가 이미 Butter DB의 TimeTable Table에 저장되어있는 모든 상영시간대와 단 하나라도 겹친다면 유효하지 않은 데이터라는 에러를 발생시킵니다. 방금 전의 과정에서 에러가 발생하지 않는다면, Butter DB에 저장하게 됩니다.

클라이언트나 서버에서나 상영시간표를 비교하려 했을 때, 기존상영시간표가 이렇게 존재한다면 등록하고자 하는 상영시간표가 이렇게 겹치게 된다면 유효하지 않는거겠죠? 그리고 이것 또한 유효하지 않는 상영시간표가 될 것입니다. 이런 경우들을 피하게끔 상영시간표들을 비교해줍니다.

<규민>

휴대폰 인증

저는 네이버 sens라는 외부 api를 이용했습니다. 이 api는 제가 등록한 휴대폰이  수신번호로 메세지를 발송할 수 있게 해줍니다

먼저 어떠한 흐름으로 휴대폰이 인증되는지 살펴보겠습니다.

사용자는 클라이언트 쪽에서 인증하고자 하는 번호를 서버에 보냅니다. 서버는 인증번호를 만들고 인증번호 생성시간, 휴대폰 번호를 함께 db에 넣어줍니다.

그리고 네이버로 수신번호와 인증번호를 담아 보냅니다.

네이버는 사용자에게 인증번호를 발송합니다. 사용자는 발송된 인증번호를 입력하고 인증요청을 합니다. 서버는 이를 받아서db에 아까 담아둔 정보와 비교하고 클라이언트에 값을 반환해줍니다.

여기서 비교값은 총 3가지로 나뉘는데 1) 유효시간이 만료된 경우인데 이는 인증번호 생성시간과 인증번호 전송하는 시간 차가 5분이 지났다는 말인데 이러면 재전송을 해서 재인증을 해야합니다.  2) 인증번호가 잘못된 경우 제대로 입력하면 해결이 되고

3)인증이 되는 경우, 모두 승인이 되었기에 수행중인 다음 걸로 진행하시면 됩니다.

2번째는 로그인 상태 유지 및 그에 따른 UI입니다.

로그인은 사용자가 입력한 아이디 비밀번호를 서버로 넘겨주는데,

서버에서는 이를 db랑 비교해줍니다. 일치하면 이 사용자의 회원등급을 토큰에 담고 이를 다시 쿠키에 넣어 반환해줍니다. 그럼 클라이언트에서 암호화된 토큰으로 어떻게 사용자를 구분하는가.

저희는 이를 해결하기 위해 서버에서 복호화하는 방법을 택했습니다.

서버에서 쿠키안에 있는 토큰을 해석하고 사용자에게 반환한 뒤 이를 전역에서 이용했습니다.

react의 useContext를 이용해서  전역에서 state를 다뤘고 useEffect로 처음 렌더링시에 state를 변경해주었습니다.

이를 통해 페이지 이동이나 새로고침같은 경우에도 로그인 상태 유지를 할 수 있게 되었습니다.

<지원>

예매에서의 주요 기능은 우선 영화 선택에서부터 좌석을 지정하는 것까지의 흐름과, 카카오페이 결제 기능입니다.

먼저 예매페이지에선 DB에 있는 영화 목록을 모두 불러와 보여줍니다. 그리고 사용자가 영화를 선택하면 그 영화의 movieId를 통해 TMDB에서 해당영화의 정보를 불러와 state에 저장합니다. 영화와 극장을 모두 선택하면 해당 영화에 대한 상영시간표가 불러와지고, 어느 한 시간을 클릭하면 해당 상영시간표의 ID를 state에 저장합니다. 좌석선택 페이지로 넘어가면, 우선 state에 저장되었던 상영시간표ID를 통해 상영시간표DB를 불러오고 그것과 연동되어 있는 상영관DB를 불러와 전체 좌석정보를 저장합니다. 그 다음 예매내역DB에서 이미 예매된 좌석을 찾아와 예매 불가로 처리해줍니다. 그리고 이 상영관의 상영관 타입에 해당하는 관람료 정보를 불러와서 상영시간과 비교한 후 관람료를 책정해줍니다. 인원수에 맞도록 좌석을 선택해주면 최종 결제 금액이 결정되고 결제페이지로 넘어가게 됩니다. 결제페이지에선 회원 정보와 결제 수단을 입력하고 결제하기 버튼을 누르면 먼저 예매내역DB에 저장이 되고 카카오페이 결제를 요청하게 됩니다.

클라이언트는 서버를 통해 카카오서버와 소통하게 됩니다. 결제 요청 단계에서 클라이언트는 카카오서버로 각종 상품 정보와 cid, 결제 완료 후 리다이렉트할 url을 보내줍니다. 그것을 정상적으로 받은 카카오서버는 결제가 진행될 url과 결제 고유 번호인 tid를 보내줍니다. 저희는 우선 tid를 로컬스토리지에 저장한 다음 결제가 진행될 url을 열어주었습니다.

번호와 생년월일 입력후 핸드폰으로 카카오페이 결제가 완료될 때 까지 이 창에서 기다리고 있다가 결제가 완료되면 아까 클라이언트에서 카카오서버로 보내준 url로 리다이렉트 됩니다. 이 페이지가 보이게 되면 tid와 pg_token을 가지고 카카오페이 승인 요청을 보내고 이메일을 발송하게 됩니다. 승인요청은 최종적으로 결제 완료 처리를 하는 단계로, 로컬스토리지에 저장해놓은 tid와, 리다이렉트해줄 때 query string으로 전달된 pg_token을 받아와 카카오서버로 전송하여 최종 완료된 결제 정보를 받아옵니다. 이로써 결제가 완료되었습니다!

시연을 해보겠습니다.

-관리자페이지

-회원가입 및 로그인

-영화 예매하기

저희가 앞으로 해야할 일들입니다.

우선 클라이언트쪽에서는

1. 리액트 멀티카로셀 모듈을 이용하여 박스오피스 수정하기

2. 영화 상세정보 페이지에서 관람평 나타내기

3. 프라이빗 라우터 완성입니다.

서버 쪽에서는

1. 테이블을 삭제했을 경우, 관계된 테이블도 함께 삭제되는 기능

2. 예매 테이블에 고유한 예약번호 생성

3. 관람평 데이터베이스 구축이 있습니다.

QnA시간

이상으로 발표를 마치겠습니다. 감사합니다.