세미프로젝트-kHotel

냐아암·2023년 10월 18일
0

국비

목록 보기
113/114
post-thumbnail

세미 프로젝트 중 본인이 구현한 기능들 위주로 서술하겠다.
Servlet, Jsp 주로 사용

📍 로그인(쿠키를 이용한 아이디 저장)및 로그아웃

  • 로그인 성공 시 세션에 loginMember를 저장한다.
session.setAttribute("loginMember", loginMember);
session.setMaxInactiveInterval(3600);
  • 쿠키를 이용하여 아이디 저장 기능 구현
Cookie c = new Cookie("saveId", inputId);
					
// 아이디 저장이 체크된 경우
if(req.getParameter("K-saveId") != null) {
	// 쿠키 파일을 30일 동안 유지
	c.setMaxAge(60*60*24*30);
						
} else {
						
	c.setMaxAge(0);
}
					
c.setPath(req.getContextPath());
// -> /kHotel로 시작하는 주소에서만 쿠키 적용
					
resp.addCookie(c);
  • 로그아웃 시 세션 무효화
session.invalidate();

📍 아이디 찾기

  • AJAX 사용하여 아이디 찾기 구현
 $.ajax({
        url : "idSearch",
        data : {
                "nmInput":nmInput.value,
                "pnoInput":pnoInput.value
            },
        type : "POST",
        dataType : "JSON",

        success : function(result){
            if(result!=null){
                id.innerHTML="아이디 : " + result;
            } else {
                id.innerText="일치하는 회원이 없습니다.";
                nmInput.value="";
                nmInput.focus();
                pnoInput.value="";
            }
        },
        error : function(){
            console.log("오류발생");

            console.log("상태코드 : " + request.status); // 404, 500

            console.log(request.responseText); // 에러 메세지

            console.log(error); // 에러 객체 출력

        }
    })

📍 비밀번호 재설정

  • AJAX 사용하여 비밀번호 재설정 기능 구현
    • 입력한 정보와 회원정보 일치 시 재설정 화면으로 이동
    • 입력한 정보와 회원정보 불일치 시 일치하는 회원이 없다는 alert창 띄우기

📍 회원 정보 확인

  • Session에 담겨있는 회원정보들을 하나씩 꺼내어 jsp에서 input value값에 작성

📍 예약하기(최종)

  • 예약 시 입력한 정보를 바탕으로 예약, 결제, 쿠폰 테이블들의 값을 INSERT/UPDATE함

📍 게시판(QnA 목록, FAQ 목록)

  • QnA 목록 조회_페이지네이션, 검색기능
    • 현재 페이지의 숫자를 담고 있는 'cp'파라미터의 값을 가져와서 조회
      (만약 cp가 없다면 1페이지이기 때문에 cp에 1을 대입한다.)
    • 검색을 했을 때와 아닐 때를 구분하여 조회
int type = Integer.parseInt(req.getParameter("type"));
			
			
int cp = 1;

if(req.getParameter("cp") != null) { // 쿼리스트링에 "cp"가 존재한다면
	cp = Integer.parseInt(req.getParameter("cp"));
}

KBoardService service = new KBoardService();

Map<String, Object> map = null;
//Map<String, Object> map = service.qna(type,cp);


if(req.getParameter("select") == null) { // 일반 목록 조회
	map = service.qna(type,cp);

} else {
	String select = req.getParameter("select");
	String content = req.getParameter("sContent");


	map = service.qnaSearch(select, content, type, cp);

}

📍 FAQ 삭제

  • AJAX를 사용하여 비동기로 게시글 삭제 구현
 if(confirm("정말 삭제하시겠습니까?")){
        $.ajax({

            url : contextPath + "/admin/faqDelete",

            data : {"boardNo" : boardNo},

            success : function(result){

                if(result>0){
                    alert("삭제되었습니다.");
                    selectFaqList();
                } else {
                    alert("삭제 실패")
                }

            } , 

            error : function(req, status, error){
                console.log("faq 삭제 실패");
                console.log(req.responseText);
            }

        })
    } 

selectFaqList();

const sDiv = document.createElement("div");
sDiv.classList.add("k-faq-slide");

// 제목, 작성자, 화살표
const tSpan = document.createElement("span");
const dSpan = document.createElement("span");
const aDiv  = document.createElement("div");
aDiv.classList.add("k-arrow-img");

tSpan.innerText=f.boardTitle;
dSpan.innerText=f.boardDate;

sDiv.append(tSpan, dSpan, aDiv);

.
.
이렇게 요소들을 create, append하여 삭제 기능을 구현하였다.


📍 빙고게임

  • 빙고에 랜덤 숫자 25개를 넣어준다
const set = new Set(); 

while(true){

    let random = Math.floor(Math.random()*50+1);

    set.add(random);

    if(set.size == 25){
        break;
    }
}

let list = "";
list = Array.from(set); // 생성한 난수 배열에 담음

for(let t = 0; t<25; t++){ // 테이블 안에 배열 넣기
    
    tds[t].innerHTML = list[t];
}
  • 입력한 숫자와 빙고 칸의 숫자가 일치하면 칸을 분홍색으로 바꾼다
for(let f = 0; f<25; f++){
        if(input.value === tds[f].innerHTML){
            //console.log(input.value)
            tds[f].innerHTML = "";
            tds[f].classList.add("pink"); // 배경 색상 변경
        }
    }
    input.value=""
    input.focus();
  • bing이라는 변수를 만들어 빙고의 개수를 누적하고, 가로/세로/대각선을 각각 비교하여 빙고일 시 bing에 숫자 1씩 더해준다.
 let bing = 0;
    
    
    for(let q=0; q<25; q=q+5){ // 가로 빙고
        let count = 0;
        for(let c = 0+q; c<5+q; c++){
            if(getComputedStyle(tds[c]).backgroundColor == "rgb(255, 192, 203)"){
                count++;
                //console.log("count: "+count)
                if(count == 5){
                    bing++;
                }
                //console.log("bing : "+bing);
                span.innerHTML = bing;
                
            }
        }
        

    }

    for(let q= 0; q<5; q++){ // 세로 빙고
        
        let count = 0
        for(let c=0+q; c<21+q; c=c+5){
            if(getComputedStyle(tds[c]).backgroundColor == "rgb(255, 192, 203)"){
                count++;
                if(count == 5){
                    bing++
                }
                span.innerHTML = bing;
               
            }
        }
       
    }
// 대각선..
  • 빙고 성공 시 쿠폰을 지급하고, 실패 시 이벤트 목록 페이지로 이동한다.

  • 하루에 한 번만 참여할 수 있도록 Oracle 스케줄러를 사용하였다.

    • Fl(참여 여부 확인 컬럼)을 하루에 한 번씩 N으로 바꾸는 구문
      BEGIN
       DBMS_SCHEDULER.CREATE_JOB (
          job_name        => 'UPDATE_FL_JOB',
          job_type        => 'PLSQL_BLOCK',
          job_action      => 'BEGIN 
                                UPDATE EVENT_FL 
                                SET UPDOWN_FL = ''N'',
                                    BINGO_FL = ''N''; 
                                COMMIT; 
                             END;',
          start_date      => SYSTIMESTAMP,
          repeat_interval => 'FREQ=DAILY; INTERVAL=1', -- 매일 1회 실행
          enabled         => TRUE
       );
      END;

📍 업다운 게임

  • 1~50 사이의 난수 생성 후 입력한 수와 일치 시 쿠폰 지급
if (input.value == random) {
                
  $.ajax({

    url : contextPath + "/event/updown/coupon",



    success : function(result){
      alert("정답입니다! 쿠폰함을 확인해주세요.");
    },

    error : function(){
      console.log("오류발생");
    }

  });
                

  return true;
}
  • 기회 모두 소진 시 실패
if (input.value != random &&count == 5) { // 5번 입력했을 경우
  // function 실행
  alert("기회 5번 모두 소진하였습니다. 게임 실패");
  return true;
}

📍 이벤트 글 작성 CRUD

(썸네일 사진은 목록에서만 보이게 처리했다.)

  • 사진 첨부 시 미리보기 기능
inputImg[i].addEventListener("change", function () {

        if (this.files[0] != undefined) {

            const reader = new FileReader(); // 파일 읽는 객체 생성

            reader.readAsDataURL(this.files[0]); // 파일 읽고 result에 저장 -> url 통해서 이미지 볼 수 있음

            reader.onload = function (e) {

                preview[i].setAttribute("src", e.target.result); // 미리보기 img 태그 src 세팅

                deleteSet.delete(i);
            }


        } else { // 파일이 선택되지 않음 == 파일 선택했다가 확인이 아닌 취소가 눌렸을 때
            preview[i].removeAttribute("src");
        }



    });
  • 글 등록/수정 시 MultipartRequest 객체 사용
    (객체 사용을 위해 form태그를 enctype="multipart/form-data" 이렇게 작성했다)
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		try {

			// multiPartRequest
			// 최대 용량, 이미지 저장 경로, 파일명, 인코딩 설정
			int maxSize = 1024 * 1024 * 80;

			HttpSession session = req.getSession();
			String root = session.getServletContext().getRealPath("/");
			String folderPath = "/resources/images/event/";
			String filePath = root + folderPath;

			String encoding = "UTF-8";

			MultipartRequest mpReq = new MultipartRequest(req, filePath, maxSize, encoding, new MyRenamePolicy());

			Enumeration<String> files = mpReq.getFileNames();

			List<EventImage> imageList = new ArrayList<>();

			while (files.hasMoreElements()) { // 다음 요소가 있을 때

				String name = files.nextElement();

				String rename = mpReq.getFilesystemName(name);

				String original = mpReq.getOriginalFileName(name);

				if (original != null) { // 실제로 파일이 담겨있는 경우
					EventImage image = new EventImage();

					image.setImageRename(folderPath + rename);
					image.setImageLevel(Integer.parseInt(name));

					imageList.add(image);
				}

			}

			// 글 제목, 내용, 회원번호(관리자이지만 혹시 몰라서)
			String title = mpReq.getParameter("K-title");
			String content = mpReq.getParameter("K-content");
			String date = mpReq.getParameter("K-date");

			Member loginMember = (Member) session.getAttribute("loginMember");
			int memberNo = loginMember.getMemberNo();

			Event event = new Event();

			event.setEventTitle(title);
			event.setEventContent(content);
			event.setEventDt(date);

			KAdminService service = new KAdminService();

			String mode = mpReq.getParameter("mode");
			

			if (mode.equals("insert")) {
				
				int eventNo = service.insertEvent(event, imageList);

				String path = null;

				if (eventNo > 0) {
					session.setAttribute("message", "게시글이 등록되었습니다.");
					path = req.getContextPath() + "/event/detail?no=" + eventNo;
					
				} else {
					session.setAttribute("message", "게시글 등록 실패");
					path = "eventWrite?mode=insert";
				}

				resp.sendRedirect(path);

			}

			if (mode.equals("update")) {
				
				int eventNo = Integer.parseInt(mpReq.getParameter("no")); // 어떤 게시글 수정할 건지
				
				String deleteList = mpReq.getParameter("deleteList"); // 이미지 변경사항(삭제) 목록
							
				event.setEventNo(eventNo);
				
				int result = service.updateEvent(event, deleteList, imageList);
				
				String path = null;
				String message = null;
				
				if(result>0) {
					message = "수정 성공";
					path = req.getContextPath() + "/event/detail?no=" + eventNo;
				} else {
					message = "수정 실패";
					path = req.getHeader("referer");
				}
				
				session.setAttribute("message", message);
				resp.sendRedirect(path);
				
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}
profile
개발 일지

0개의 댓글