Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 인터페이스
- GRANT VIEW
- 참조형변수
- 정수형타입
- abstract
- exception
- 다형성
- 예외처리
- 객체 비교
- EnhancedFor
- NestedFor
- 오라클
- 환경설정
- 집합_SET
- 추상메서드
- 생성자오버로드
- 어윈 사용법
- 한국건설관리시스템
- Java
- 컬렉션 타입
- 자바
- 예외미루기
- 제네릭
- 자동차수리시스템
- 대덕인재개발원
- 컬렉션프레임워크
- oracle
- cursor문
- 메소드오버로딩
- 사용자예외클래스생성
Archives
- Today
- Total
거니의 velog
(5) 로그인 페이지 > 코드 리뷰 본문
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set value="${pageContext.request.contextPath }" var="contextPath" />
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="author" content="부루마불" />
<meta name="description" content="대덕인재개발원 7월반 4조 부루마불의 여기갈래 프로젝트입니다." />
<meta name="keywords" content="부루마불, 여기갈래, 여행, 통합, 플랫폼" />
<meta name="copyright" content="대덕인재개발원" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>여기갈래 > 로그인</title>
<link href="${contextPath }/resources/images/favicon.ico" rel="shoutcut icon" />
<!-- 공통 css -->
<link href="${contextPath }/resources/css/login.css" rel="stylesheet" />
<!-- 제이쿼리 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<!-- 공통 js -->
<script defer src="${contextPath }/resources/js/util.js"></script>
<script defer src="${contextPath }/resources/js/login.js"></script>
<!-- 부트스트랩 모듈 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<!-- 스위트 얼럿 모듈 -->
<link href="${contextPath }/resources/css/sweetalert2.min.css" rel="stylesheet" />
<script defer src="${contextPath }/resources/js/sweetalert2.all.min.js"></script>
<!-- sockjs -->
<script src="${contextPath }/resources/js/sockjs.min.js"></script>
<c:if test="${not empty message }">
<script>
//alert("${message}");
$(function(){
// 성공시
<c:if test="${msgflag eq 'su'}">
Swal.fire({
title: "성공",
text: "${message}",
icon: "success"
});
</c:if>
// 실패시
<c:if test="${msgflag eq 'fa'}">
Swal.fire({
title: "실패",
text: "${message}",
icon: "error"
});
</c:if>
// 정보성 메시지
<c:if test="${msgflag eq 'in'}">
Swal.fire({
title: "안내",
text: "${message}",
icon: "info"
});
</c:if>
});
<c:remove var="message" scope="request" />
<c:remove var="message" scope="session" />
</script>
</c:if>
<c:if test="${not empty errors && msgflag eq 'in'}">
<script>
// alert("${errors}");
$(function(){
Swal.fire({
title: "서버오류",
text: "${errors}",
icon: "error"
});
});
<c:remove var="errors" scope="request" />
<c:remove var="errors" scope="session" />
</script>
</c:if>
</head>
<body class="scroll">
<section id="loginContainer">
<article>
<h1>
<a href="/index.do">
<img src="${contextPath }/resources/images/logo.png" alt="메인 로고" />
</a>
</h1>
<div class="loginBox">
<h2>여기갈래</h2>
<p>Travel Integration Platform System</p>
<form action="/login/loginCheck.do" id="loginForm" name="loginForm" method="post">
<input class="form-control" type="text" id="memId" name="memId" placeholder="아이디" autocomplete="off" value="${member.memId }" />
<input class="form-control" type="password" id="memPw" name="memPw" placeholder="비밀번호" autocomplete="off" value="${member.memPw }" />
<div>
<a href="/login/signup.do">회원가입</a>
<a href="/login/findIdPw.do">ID/비밀번호 찾기</a>
</div>
<button class="btn btn-success" type="button" id="loginBtn">로그인</button>
</form>
<p class="testBtnShow">
Copyright © 2023. Burumabool. All right reserved.
<br />
YOgIGaLE v.2.1
</p>
</div>
<div class="testBtnGroup">
<div>
<button class="btn btn-primary" type="button" id="adminAccount">관리자 계정</button>
<button class="btn btn-secondary" type="button" id="lgjAccount">테스트 계정</button>
</div>
<div>
<button class="btn btn-success" type="button" id="iuAccount">아이유 계정</button>
<button class="btn btn-info" type="button" id="wonAccount">장원영 계정</button>
</div>
<div>
<button class="btn btn-warning" type="button" id="haAccount">하루토 계정</button>
<button class="btn btn-danger" type="button" id="kiAccount">키이오 계정</button>
</div>
</div>
</article>
<div class="stylecomp_firstbar"></div>
<div class="stylecomp_secondbar"></div>
<div class="bg_video">
<div class="donttouch"></div>
<iframe src="https://www.youtube.com/embed/jX2t-FPDQ2g?autoplay=1&mute=1&controls=0&loop=1&playlist=jX2t-FPDQ2g" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
</section>
<script>
$(function(){
var memId = $("#memId");
var memPw = $("#memPw");
var loginBtn = $("#loginBtn");
var loginForm = $("#loginForm");
$.loginMouseOverEvent();
$.loginMouseOutEvent();
$.enterKeyUpEvent();
// 테스트 계정 함수
$.testAccountFn();
loginBtn.on("click", function(){
var idFlag = $.falsyCheckFn(memId, "아이디");
if(!idFlag) return;
var pwFlag = $.falsyCheckFn(memPw, "비밀번호");
if(!pwFlag) return;
// 실시간 알림 - 로그인 내용 저장 시작
var realrecIdArr; // 모든 유저를 대상으로 알림
$.ajaxMembersIdListGetFn(function(result){
var loginMemVO = {
memId : memId.val(),
memPw : memPw.val()
};
console.log("loginMemVO : ", loginMemVO);
$.ajax({
type : "get",
url : "/loginMemInfoRtAlertSaveInfo.do",
data : loginMemVO,
dataType : "json",
success : function(res){
console.log("res : ", res);
realrecIdArr = result;
console.log("realrecIdArr : ", realrecIdArr);
var realsenId = res.memId; // 발신자 아이디
var realsenName = res.memName; // 발신자 이름
var realsenTitle = "로그인"; // 실시간 알림 제목
var realsenContent = realsenName+"("+realsenId+")님이 로그인하였습니다."; // 실시간 알림 내용
var realsenType = "logininfo"; // 정보
var realsenReadyn = "N"; // 안 읽음
var realsenUrl = "empty"; // 갈데 없음
// db에 저장하고 1번만 읽고 바로 realsenReadyn = N을 realsenReadyn = Y로 처리한다.
// 로그아웃 시 해당 정보를 삭제해야 한다.
var dbSaveFlag = true; // db에 저장
var userImgSrc = res.memProfileimg; // 유저 프로파일 이미지 정보
var realrecNo = "empty";
var rtAlert = {
"realrecIdArr": realrecIdArr,
"realsenId": realsenId,
"realsenName": realsenName,
"realsenTitle": realsenTitle,
"realsenContent": realsenContent,
"realsenType": realsenType,
"realsenReadyn": realsenReadyn,
"realsenUrl": realsenUrl,
"realsenPfimg": userImgSrc
};
console.log("login > rtAlert : ", rtAlert);
$.realTimeAlertWebSocketFn(rtAlert, dbSaveFlag, userImgSrc, realrecNo);
}
});
});
// 실시간 알림 - 로그인 내용 저장 끝
// 로그인 처리
setTimeout(()=>{
loginForm.submit();
}, 2000);
});
});
</script>
</body>
</html>
@charset "utf-8";
@import url('https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&family=Noto+Sans+KR:wght@100;300;500;700;900&display=swap');
/* css reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 공통 스타일 */
body {
color: #333!important;
font-family: "Noto Sans KR", sans-serif!important;
}
a {
color: #333!important;
text-decoration: none!important;
}
nav ol,
nav ul {
list-style: none;
}
/* 스크롤바 없애기 */
/* ( 크롬, 사파리, 오페라, 엣지 ) 동작 */
.scroll::-webkit-scrollbar {
display: none;
}
.scroll {
-ms-overflow-style: none; /* 인터넷 익스플로러 */
scrollbar-width: none; /* 파이어폭스 */
}
.cen {
max-width: 1200px;
width: 100%;
margin: auto;
}
/* 로그인 스타일 */
#loginContainer,
#idPwFindContainer,
#signContainer {
width: 100vw;
height: 100vh;
background-color: #333;
position: relative;
overflow: hidden;
}
#loginContainer article {
width: 400px;
background-color: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 20px;
z-index: 100;
}
#loginContainer>article>h1 {
position: absolute;
top: -130px;
left: 50%;
transform: translateX(-50%);
margin-bottom: 0px!important;
}
#loginContainer>article>h1>a {
display: block;
width: 250px;
height: 250px;
border-radius: 50%;
transition: all 0.4s;
}
#loginContainer>article>h1>a:hover {
box-shadow: 0px 0px 100px white;
}
#loginContainer>article>h1>a>img {
display: block;
width: 100%;
height: 100%;
}
#loginContainer>article>div {
padding: 20px;
padding-top: 120px;
padding-bottom: 30px;
}
#loginContainer h2 {
text-align: center;
font-weight: 900;
font-size: 2.5rem;
margin-bottom: 10px;
letter-spacing: 1px;
}
#loginContainer>article>div>p:first-of-type {
text-align: center;
}
#loginContainer>article>div>p:last-of-type {
text-align: center;
font-size: 0.8rem;
}
#loginForm input {
margin-bottom: 15px;
outline: none;
}
#loginForm>div {
overflow: auto;
margin-bottom: 15px;
}
#loginForm a {
color: #0D6EFD!important;
text-decoration: underline!important;
}
#loginForm a:first-of-type {
display: block;
float: left;
}
#loginForm a:last-of-type {
display: block;
float: right;
}
#loginBtn {
width: 100%;
margin-bottom: 15px;
}
.stylecomp_firstbar {
width: 500px;
height: 5000px;
background-color: red;
position: absolute;
top: 50%;
left: 50%;
transition: all 0.4s;
transform: translate(-50%, -50%) rotate(70deg);
z-index: 90;
}
.stylecomp_secondbar {
width: 500px;
height: 5000px;
background-color: #dc1c2c;
position: absolute;
top: 50%;
left: 50%;
transition: all 0.4s;
transform: translate(-50%, -50%) rotate(70deg);
top: 65%;
z-index: 80;
}
.bg_video {
width: 100vw;
height: 100vh;
position: relative;
}
.donttouch {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: #333;
z-index: 20;
}
.bg_video iframe {
display: block;
position: absolute;
width: 100vw;
height: 100vh;
transform: scale(1.3);
}
/* 아이디/비밀번호 스타일 */
#idPwFindContainer article {
width: 500px;
background-color: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 20px;
z-index: 100;
padding: 25px;
padding-top: 120px;
}
#idPwFindContainer>article>h1 {
position: absolute;
top: -75px;
left: 50%;
transform: translateX(-50%);
margin-bottom: 0px!important;
}
#idPwFindContainer>article>h1>a {
display: block;
width: 200px;
height: 200px;
border-radius: 50%;
transition: all 0.4s;
}
#idPwFindContainer>article>h1>a:hover {
box-shadow: 0px 0px 100px white;
}
#idPwFindContainer>article>h1>a>img {
display: block;
width: 100%;
height: 100%;
}
.findContents {
margin-bottom: 10px;
}
.findContents h2 {
text-align: center;
font-weight: 700;
font-size: 1.9rem;
margin-bottom: 10px;
letter-spacing: -1px;
}
.findContents input {
margin-bottom: 15px
}
.loginPageGoBtn {
position: absolute;
right: 25px;
}
.searchTxt {
color: red;
font-size: 1.3rem;
}
/* 회원가입 스타일 */
#signContainer article {
width: 500px;
background-color: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 20px;
padding: 20px;
z-index: 100;
}
.profileContents {
position: relative;
}
.profileContents div {
width: 200px;
height: 200px;
overflow: hidden;
border-radius: 50%;
position: absolute;
top: 50%;
transform: translateY(-50%);
top: -5px;
right: -95px;
background-color: white;
}
.profileContents img {
width: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.profileIcon {
position: absolute;
top: 60px;
right: -75px;
background-color: #eee;
width: 50px;
height: 50px;
border-radius: 50%;
text-align: center;
cursor: pointer;
}
.genderTxt {
margin-right: 10px;
}
#memPw {
margin-bottom: 15px;
}
.profileIcon i {
font-size: 2em;
line-height: 50px;
}
.inputCont {
margin-bottom: 5px;
overflow: auto;
height: 48px;
}
.inputCont:nth-of-type(3),
.inputCont:nth-of-type(12),
.inputCont:last-of-type {
height: auto;
}
.inputCont label {
display: block;
width: 100px;
float: left;
}
.inputCont input {
display: block;
width: calc(100% - 100px);
float: left;
}
.inputNone label {
display: inline;
width: auto;
float: none;
}
.inputNone input {
display: inline;
width: auto;
float: none;
}
.inputCont:first-of-type {
display: none;
}
/* 테스트 계정 스타일링 */
.testBtnGroup {
padding: 0px 20px 20px!important;
text-align: center;
display: none;
}
.testBtnGroup button {
margin-right: 10px;
}
.testBtnGroup button:last-of-type {
margin-right: 0px;
}
.testBtnGroup>div {
margin-bottom: 10px;
}
.testBtnShow {
cursor: pointer;
transition: all 0.4s;
border-radius: 4px;
}
.testBtnShow:hover {
background-color: #333;
color: white;
padding: 10px 0px;
}
/* 미디어 쿼리 (PC용) */
@media all and (max-width: 1410px) {
.bg_video iframe {
width: 1410px;
}
}
/* 미디어 쿼리 (태블릿용) */
@media all and (max-width: 768px) {
.stylecomp_firstbar {
width: 300px;
transform: translate(-50%, -50%) rotate(20deg);
}
.stylecomp_secondbar{
width: 300px;
transform: translate(-50%, -50%) rotate(20deg);
left: 60%;
}
}
@media all and (max-width: 670px) {
#signContainer article {
width: 300px;
}
.profileContents div {
width: 100px;
height: 100px;
top: 15px;
right: -45px;
}
.profileIcon {
top: 50px;
right: -30px;
}
}
@media all and (max-width: 630px) {
#idPwFindContainer h1 {
display: none;
}
#idPwFindContainer article {
padding-top: 25px;
width: 300px;
}
.findContents {
margin-bottom: 20px;
}
.findContents h2 {
font-size: 1.5rem;
}
.findContents p {
font-size: 0.9rem;
}
}
@media all and (max-width: 510px) {
#loginContainer article {
width: 280px;
}
#loginContainer h2 {
font-size: 2rem;
}
#loginContainer>article>div>p:first-of-type {
font-size: 0.8rem;
}
#loginContainer>article>div>p:last-of-type {
font-size: 0.6rem;
}
.stylecomp_firstbar {
display: none;
}
.stylecomp_secondbar{
display: none;
}
#loginForm a:first-of-type {
font-size: 0.9rem;
}
#loginForm a:last-of-type {
font-size: 0.9rem;
}
}
// 공통 함수
// 마우스 오버/아웃 이벤트
$.findMouseOverEvent = function(cont){
cont.mouseover(function(){
donttouch.stop().fadeOut();
});
};
$.findMouseOutEvent = function(cont){
cont.mouseout(function(){
donttouch.stop().fadeIn();
});
};
// 로그인 화면 페이지 함수
var logCont = $("#loginContainer>article");
var comp_fir = $(".stylecomp_firstbar");
var comp_sec = $(".stylecomp_secondbar");
var donttouch = $(".donttouch");
$.loginMouseOverEvent = function(){
logCont.mouseover(function(){
comp_fir.css({
transform : "translate(-50%, -80%) rotate(70deg)"
});
comp_sec.css({
transform : "translate(-50%, -20%) rotate(70deg)"
});
donttouch.stop().fadeOut();
});
};
$.loginMouseOutEvent = function(){
logCont.mouseout(function(){
comp_fir.css({
transform : "translate(-50%, -50%) rotate(70deg)"
});
comp_sec.css({
transform : "translate(-50%, -50%) rotate(70deg)"
});
donttouch.stop().fadeIn();
});
};
$.enterKeyUpEvent = function(){
$(window).keyup(function(e){
//console.log(e.keyCode);
// enter키 : 13
if(e.keyCode == 13) {
$("#loginBtn").trigger("click");
}
});
};
// 아이디/비밀번호 찾기 페이지 함수
var loginPageGoBtn = $(".loginPageGoBtn");
var profileIcon = $(".profileIcon");
var imgFile = $("#imgFile");
$.loginPageGoFn = function(){
loginPageGoBtn.click(function(){
location.href = "/login/signin.do";
});
};
// 회원가입 페이지 함수
$.fileChangeEvent = function(){
profileIcon.click(function(){
imgFile.trigger("click");
imgFile.change(function() {
console.log("Selected file: " + this.files[0].name); // 이슈 확인
});
});
};
// 아이디, 비밀번호 찾기 함수
// 객체 비구조화 할당 사용
$.findChkFn = function(findOutObj, {url, msgEl, msg}){
console.log(findOutObj);
$.ajax({
type: "post",
url: url,
data: JSON.stringify(findOutObj),
contentType: "application/json;charset=utf-8",
success: function(res){
console.log("결과 : " + res);
if(!res) {
$(msgEl).html("회원님의 "+msg+" 정보를 찾을 수 없습니다.");
}else {
if(msg == "아이디"){
var id = res.memId;
$(msgEl).html("회원님의 "+msg+"는 [<span class='searchTxt'>"+id+"</span>] 입니다.");
}else if(msg == "비밀번호"){
//var pw = res.memPw;
//$(msgEl).html("회원님의 "+msg+"는 [<span class='searchTxt'>"+pw+"</span>] 입니다.");
$(msgEl).html("회원님의 "+msg+"를 재설정합니다.");
// 비밀번호 재설정 팝업창
var modalHtmlTxt = `
<div class="modal fade" id="chgPwModal">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">비밀번호 재설정</h4>
</div>
<div class="modal-body">
<div>
<p>새로 등록할 비밀번호를 입력해 주세요.</p>
<div class="chgPwChkBadge">
<span class="badge bg-danger">비밀번호 불일치</span>
</div>
</div>
<form action="/login/changePw.do" method="post" id="chgPwForm" name="chgPwForm">
<input type="hidden" id="memId2" name="memId" />
<div>
<label for="memPw">비밀번호 입력</label>
<input style="margin-bottom: 0px;" class="form-control" type="password" id="memPw" name="memPw" placeholder="새로 변경할 비밀번호 입력" />
</div>
<div>
<label for="memPwChk">비밀번호 확인</label>
<input class="form-control" type="password" id="memPwChk" name="memPwChk" placeholder="새로 변경할 비밀번호 입력" />
</div>
<button class="btn btn-primary" type="button" id="chgPwBtn">비밀번호 재설정</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">취소</button>
</div>
</div>
</div>
</div>
`;
$("#chgPwModal").remove();
$("body").append(modalHtmlTxt);
var chgPwModal = new bootstrap.Modal(document.getElementById('chgPwModal'));
chgPwModal.show();
// 회원 아이디 보내기
var memIdVal = $("#memId");
var chgMemid = $("#memId2");
chgMemid.val(memIdVal.val());
// 비밀번호 재설정 > 비밀번호 확인 메서드
var memPw = $("#memPw");
var memPwChk = $("#memPwChk");
var pwChkFlag = false;
var pwObj = {
el1: memPw,
el2: memPwChk,
msgEl: ".chgPwChkBadge",
msg: "비밀번호"
};
$.inputValMismatchChkFn(pwObj, function(result){
pwChkFlag = result;
});
var chgPwForm = $("#chgPwForm");
var chgPwBtn = $("#chgPwBtn");
chgPwBtn.click(function(){
if(pwChkFlag) {
chgPwForm.submit();
}else {
//alert("비밀번호가 일치하는지 확인해주세요.");
Swal.fire({
title: "안내",
text: "비밀번호가 일치하는지 확인해주세요.",
icon: "info"
});
}
});
}
}
}
});
};
// 쓸데없이 하는 거에 비해서 복잡, 매개변수는 많으면 {} 처리 -> 넹 센세...
// 객체 비구조화 할당 사용
$.matchKeyupEvent = function({el, msgEl, msg, col, url}, callback){
el.keyup(function(){
var valTxt = $(this).val();
//console.log("valTxt : ",valTxt);
if(!valTxt) {
$(msgEl).html("<span class='badge bg-danger'>"+msg+" 사용불가</span>");
callback(false);
}else {
var data = {
[col] : valTxt
};
//console.log("data : ", data);
$.ajax({
type: "post",
url: url,
data: JSON.stringify(data),
contentType: "application/json;charset=utf-8",
success: function(res){
if(res === "NOTEXIST") {
$(msgEl).html("<span class='badge bg-success'>"+msg+" 사용가능</span>");
callback(true);
}else {
$(msgEl).html("<span class='badge bg-danger'>"+msg+" 사용불가</span>");
callback(false);
}
}
});
}
});
};
// 두 input 사이 간의 값 비교
$.inputValMismatchChkFn = function({el1, el2, msgEl, msg}, callback){
el1.keyup(function(){
var el1Val = el1.val();
var el2Val = el2.val();
if(!el1Val){
$(msgEl).html("<span class='badge bg-danger'>"+msg+" 불일치</span>");
callback(false);
}else {
if(el1Val === el2Val){
$(msgEl).html("<span class='badge bg-success'>"+msg+" 일치</span>");
callback(true);
}else {
$(msgEl).html("<span class='badge bg-danger'>"+msg+" 불일치</span>");
callback(false);
}
}
});
el2.keyup(function(){
var el1Val = el1.val();
var el2Val = el2.val();
if(!el2Val){
$(msgEl).html("<span class='badge bg-danger'>"+msg+" 불일치</span>");
callback(false);
}else {
if(el1Val === el2Val){
$(msgEl).html("<span class='badge bg-success'>"+msg+" 일치</span>");
callback(true);
}else {
$(msgEl).html("<span class='badge bg-danger'>"+msg+" 불일치</span>");
callback(false);
}
}
});
};
// 관리자, 테스트 계정 버튼 기능
$.testAccountFn = function(){
var testBtnShow = $(".testBtnShow");
var testBtnGroup = $(".testBtnGroup");
var loginBox = $(".loginBox");
var token = false; // 현재 테스트 박스가 눈에 보이지 않는 상태
testBtnShow.click(function(){
if(!token) { // 눈에 보이게 한다!
loginBox.css({
paddingBottom: "0px"
});
testBtnGroup.show();
token = true; // 눈에 보이는 상태임을 표시
}else {
loginBox.css({
paddingBottom: "30px"
});
testBtnGroup.hide();
token = false; // 눈에 보이지 않는 상태임을 표시
}
});
var loginIdEl = $("#loginForm #memId");
var loginPwEl = $("#loginForm #memPw");
var loginBtn = $("#loginBtn")
var adminAccount = $("#adminAccount");
var lgjAccount = $("#lgjAccount");
var iuAccount = $("#iuAccount");
var wonAccount = $("#wonAccount");
var haAccount = $("#haAccount");
var kiAccount = $("#kiAccount");
// 관리자 계정 로그인 처리 함수
adminAccount.click(function(){
var adminId = "admin";
var adminPw = "admin1234";
loginIdEl.val(adminId);
loginPwEl.val(adminPw);
loginBtn.trigger("click");
});
// 테스트 계정 로그인 처리 함수
lgjAccount.click(function(){
var testId = "chantest1";
var testPw = "1234";
loginIdEl.val(testId);
loginPwEl.val(testPw);
loginBtn.trigger("click");
});
// 아이유 계정 로그인 처리 함수
iuAccount.click(function(){
var testId = "iuforever9802";
var testPw = "dkdldb9802";
loginIdEl.val(testId);
loginPwEl.val(testPw);
loginBtn.trigger("click");
});
// 장원영 계정 로그인 처리 함수
wonAccount.click(function(){
var testId = "wonyoung0408";
var testPw = "dnjsdud0408";
loginIdEl.val(testId);
loginPwEl.val(testPw);
loginBtn.trigger("click");
});
// 하루토 계정 로그인 처리 함수
haAccount.click(function(){
var testId = "haru0404";
var testPw = "gkfnxh0404";
loginIdEl.val(testId);
loginPwEl.val(testPw);
loginBtn.trigger("click");
});
// 키이오 계정 로그인 처리 함수
kiAccount.click(function(){
var testId = "kio0411";
var testPw = "zldh0411";
loginIdEl.val(testId);
loginPwEl.val(testPw);
loginBtn.trigger("click");
});
};
// daum 주소 API(주소 찾기)
function DaumPostcode() {
new daum.Postcode({
oncomplete: function(data) {
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
// 각 주소의 노출 규칙에 따라 주소를 조합한다.
// 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
var addr = ''; // 주소 변수
var extraAddr = ''; // 참고항목 변수
//사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
addr = data.roadAddress;
} else { // 사용자가 지번 주소를 선택했을 경우(J)
addr = data.jibunAddress;
}
// 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
if (data.userSelectedType === 'R') {
// 법정동명이 있을 경우 추가한다. (법정리는 제외)
// 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
if (data.bname !== '' && /[동|로|가]$/g.test(data.bname)) {
extraAddr += data.bname;
}
// 건물명이 있고, 공동주택일 경우 추가한다.
if (data.buildingName !== '' && data.apartment === 'Y') {
extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
}
}
// 우편번호와 주소 정보를 해당 필드에 넣는다.
document.getElementById('memPostcode').value = data.zonecode;
document.getElementById("memAddress1").value = addr;
// 커서를 상세주소 필드로 이동한다.
document.getElementById("memAddress2").focus();
}
}).open();
};
// 윈도우 가로 길이 변경 이벤트
$(window).resize(function(){
//console.log("화면길이 조정중이유");
var winW = $(this).outerWidth();
// 로그인 페이지 컴포넌트 스타일 초기화
comp_fir.removeAttr("style");
comp_sec.removeAttr("style");
// 아이디/비밀번호 찾기 버튼 크기 조정
var findContentsBtns = $(".findContents button");
if(winW > 630) {
findContentsBtns.removeClass("btn-sm");
}else {
findContentsBtns.addClass("btn-sm");
}
// 종횡비 함수
var profileBox = $(".profileContents>div");
var profileImg = $(".profileContents img");
$.ratioBoxH(profileBox, profileImg);
});
package kr.or.ddit.users.login.vo;
import org.springframework.web.multipart.MultipartFile;
import lombok.Data;
@Data
public class MemberVO {
private int memNo;
private String memId;
private String memPw;
private String memName;
private String memGender;
private String memEmail;
private String memPhone;
private String memPostcode;
private String memAddress1;
private String memAddress2;
private String gradeCode;
private String enabled;
private int memCategory;
private String memRegdate;
private String memAgedate;
private MultipartFile imgFile;
private String memProfileimg;
private int memPoint;
}
package kr.or.ddit.users.login.controller;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import kr.or.ddit.users.login.service.LoginService;
import kr.or.ddit.users.login.vo.MemberVO;
import kr.or.ddit.utils.ServiceResult;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
@RequestMapping("/login")
public class LoginController {
@Resource(name = "uploadPath")
private String resourcePath;
@Inject
private LoginService loginService;
// 로그인 페이지 이동
@CrossOrigin(origins = "http://localhost")
@RequestMapping(value = "/signin.do", method = RequestMethod.GET)
public String signin(String message, Model model) {
if(StringUtils.isNotBlank(message)) {
// 성공, 실패, 정보
// 성공 : su
// 실패 : fa
// 정보 : in
model.addAttribute("message", message);
model.addAttribute("msgflag", "in");
}
return "login/signin";
}
// 회원 가입 페이지 이동
@CrossOrigin(origins = "http://localhost")
@RequestMapping(value = "/signup.do", method = RequestMethod.GET)
public String signup() {
return "login/signup";
}
// Ajax > 아이디 중복체크 메서드
@RequestMapping(value = "/idCheck.do", method = RequestMethod.POST)
public ResponseEntity<String> idCheck(@RequestBody Map<String, String> map){
ServiceResult result = loginService.idCheck(map.get("memId"));
return new ResponseEntity<String>(result.toString(), HttpStatus.OK);
}
// Ajax > 이메일 중복체크 메서드
@RequestMapping(value = "/emailCheck.do", method = RequestMethod.POST)
public ResponseEntity<String> emailCheck(@RequestBody Map<String, String> map){
ServiceResult result = loginService.emailCheck(map.get("memEmail"));
return new ResponseEntity<String>(result.toString(), HttpStatus.OK);
}
// 회원 가입 메서드
@RequestMapping(value = "/signup.do", method = RequestMethod.POST)
public String signup(
HttpServletRequest req,
MemberVO memberVO,
Model model,
RedirectAttributes ra,
@RequestParam("imgFile") MultipartFile imgFile
) {
log.info("imgFile : " + imgFile.getOriginalFilename());
log.info("memberVO : " + memberVO.toString());
// 이미지 파일이 없는 경우 예외 처리
if(imgFile.isEmpty()) {
model.addAttribute("message", "이미지 파일을 업로드해 주세요.");
model.addAttribute("msgflag", "in");
return "login/signup";
}
String goPage = "";
Map<String, String> errors = new HashMap<String, String>();
if(StringUtils.isBlank(memberVO.getMemId())) {
errors.put("memId", "아이디를 입력해 주세요.");
}
if(StringUtils.isBlank(memberVO.getMemPw())) {
errors.put("memPw", "비밀번호를 입력해 주세요.");
}
if(StringUtils.isBlank(memberVO.getMemName())) {
errors.put("memName", "이름을 입력해 주세요.");
}
if(errors.size() > 0) { // 에러 정보가 존재
model.addAttribute("errors", errors);
model.addAttribute("msgflag", "in");
model.addAttribute("member", memberVO);
goPage = "login/signup"; // 회원 가입 페이지로 이동
}else { // 정상적인 데이터
ServiceResult result = loginService.signup(req, memberVO);
if(result.equals(ServiceResult.OK)) { // 가입 성공
ra.addFlashAttribute("message", "회원가입을 완료하였습니다!");
ra.addFlashAttribute("msgflag", "su");
goPage = "redirect:/login/signin.do"; // 로그인 페이지로 이동
}else { // 가입 실패
model.addAttribute("message", "서버에러, 다시 시도해 주세요!");
model.addAttribute("msgflag", "fa");
model.addAttribute("member", memberVO);
goPage = "login/signup"; // 회원 가입 페이지로 이동
}
}
return goPage;
}
// 아이디/비밀번호 페이지 이동
@CrossOrigin(origins = "http://localhost")
@RequestMapping(value = "/findIdPw.do", method = RequestMethod.GET)
public String findIdPw() {
return "login/findIdPw";
}
// Ajax > 아이디 찾기 메서드
@RequestMapping(value = "/findId.do", method = RequestMethod.POST)
public ResponseEntity<MemberVO> findId(
@RequestBody Map<String, String> map
){
MemberVO result = loginService.findId(map);
return new ResponseEntity<MemberVO>(result, HttpStatus.OK);
}
// Ajax > 비밀번호 찾기 메서드
@RequestMapping(value = "/findPw.do", method = RequestMethod.POST)
public ResponseEntity<MemberVO> findPw(
@RequestBody Map<String, String> map
){
MemberVO result = loginService.findPw(map);
return new ResponseEntity<MemberVO>(result, HttpStatus.OK);
}
// 비밀번호 변경 처리 메서드
@PostMapping("/changePw.do")
public String changePw(
MemberVO memberVO,
Model model,
RedirectAttributes ra
) {
/** 자료 수집 및 정의 */
Map<String, Object> param = new HashMap<String, Object>();
param.put("memId", memberVO.getMemId());
param.put("memPw", memberVO.getMemPw());
/** 서비스 호출 */
loginService.changePw(param);
/** 반환 자료 */
ServiceResult result = (ServiceResult) param.get("result");
String message = (String) param.get("message");
String goPage = (String) param.get("goPage");
/** 자료 검증 */
log.info("result : " + result);
log.info("message : " + message);
log.info("goPage : " + goPage);
if(result.equals(ServiceResult.OK)) { // 업데이트 성공
ra.addFlashAttribute("message", message);
ra.addFlashAttribute("msgflag", "su");
}else { // 업데이트 실패
model.addAttribute("message", message);
model.addAttribute("msgflag", "fa");
}
/** 자료 반환 */
return goPage;
}
// 로그인 처리 메서드
@RequestMapping(value = "/loginCheck.do", method = RequestMethod.POST)
public String loginCheck(
HttpSession session,
MemberVO memberVO,
Model model,
RedirectAttributes ra
) {
String goPage = "";
Map<String, String> errors = new HashMap<String, String>();
if(StringUtils.isBlank(memberVO.getMemId())) {
errors.put("memId", "아이디를 입력해 주세요");
}
if(StringUtils.isBlank(memberVO.getMemPw())) {
errors.put("memPw", "비밀번호를 입력해 주세요");
}
if(errors.size() > 0) { // 에러가 있음
model.addAttribute("errors", errors);
model.addAttribute("msgflag", "fa");
model.addAttribute("member", memberVO);
goPage = "login/signin";
}else {
MemberVO member = loginService.loginCheck(memberVO);
if(member != null) {
if(member.getEnabled().equals("0")) { // 탈퇴한 회원
ra.addFlashAttribute("message", "탈퇴한 회원 계정입니다.");
ra.addFlashAttribute("msgflag", "in");
goPage = "redirect:/login/signin.do";
}else {
session.setAttribute("sessionInfo", member);
int intervalInSeconds = 60 * 60; // 1시간을 초로 계산합니다
session.setMaxInactiveInterval(intervalInSeconds);
ra.addFlashAttribute("message", member.getMemName() + "님, 환영합니다!");
ra.addFlashAttribute("msgflag", "su");
goPage = "redirect:/index.do";
}
}else {
model.addAttribute("message", "존재하지 않는 회원입니다.");
model.addAttribute("msgflag", "in");
model.addAttribute("member", memberVO);
goPage = "login/signin";
}
}
return goPage;
}
// 로그아웃 메서드
@RequestMapping(value = "/logout.do", method = RequestMethod.GET)
public String logout(
HttpSession session,
RedirectAttributes ra
) {
session.invalidate();
ra.addFlashAttribute("message", "로그아웃 되었습니다.");
ra.addFlashAttribute("msgflag", "in");
return "redirect:/login/signin.do";
}
}
package kr.or.ddit.users.login.service;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import kr.or.ddit.users.login.vo.MemberVO;
import kr.or.ddit.utils.ServiceResult;
public interface LoginService {
public ServiceResult idCheck(String memId);
public ServiceResult emailCheck(String memEmail);
public ServiceResult signup(HttpServletRequest req, MemberVO memberVO);
public MemberVO findId(Map<String, String> map);
public MemberVO findPw(Map<String, String> map);
public MemberVO loginCheck(MemberVO memberVO);
public void changePw(Map<String, Object> param);
}
package kr.or.ddit.users.login.service.impl;
import java.io.File;
import java.util.Map;
import java.util.UUID;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import kr.or.ddit.mapper.LoginMapper;
import kr.or.ddit.users.login.service.LoginService;
import kr.or.ddit.users.login.vo.MemberVO;
import kr.or.ddit.utils.ServiceResult;
@Service
@Transactional(rollbackFor = Exception.class)
public class LoginServiceImpl implements LoginService {
@Inject
private LoginMapper loginMapper;
@Override
public ServiceResult idCheck(String memId) {
ServiceResult result = null;
MemberVO memberVO = loginMapper.idCheck(memId);
if(memberVO != null) {
result = ServiceResult.EXIST;
}else {
result = ServiceResult.NOTEXIST;
}
return result;
}
@Override
public ServiceResult emailCheck(String memEmail) {
ServiceResult result = null;
MemberVO memberVO = loginMapper.emailCheck(memEmail);
if(memberVO != null) {
result = ServiceResult.EXIST;
}else {
result = ServiceResult.NOTEXIST;
}
return result;
}
@Override
public ServiceResult signup(HttpServletRequest req, MemberVO memberVO) {
ServiceResult result = null;
// 회원가입 시, 프로필 이미지로 파일 업로드 할 서버 경로 지정
String uploadPath = req.getServletContext().getRealPath("/resources/profile");
File file = new File(uploadPath);
if (!file.exists()) {
file.mkdirs();
}
String profileImg = ""; // 회원정보에 추가될 프로필 이미지 경로
try {
// 넘겨받은 회원정보에서 파일 데이터 가져오기
MultipartFile profileImgFile = memberVO.getImgFile();
// 넘겨받은 파일 데이터가 존재할 때
if(profileImgFile.getOriginalFilename() != null && !profileImgFile.getOriginalFilename().equals("")) {
String fileName = UUID.randomUUID().toString(); // UUID 파일명 생성
fileName += "_" + profileImgFile.getOriginalFilename(); // UUID_원본파일명으로 생성
uploadPath += "/" + fileName; // /resources/profile/UUID_원본파일명
profileImgFile.transferTo(new File(uploadPath)); // 해당 위치에 파일 복사
profileImg = "/resources/profile/" + fileName; // 파일 복사가 일어난 파일의 위치로 접근하기 위한 URI 설정
}
memberVO.setMemProfileimg(profileImg);
} catch (Exception e) {
e.printStackTrace();
}
int status = loginMapper.signup(memberVO);
if(status > 0) { // 등록 성공
result = ServiceResult.OK;
}else { // 등록 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public MemberVO findId(Map<String, String> map) {
MemberVO member = loginMapper.findId(map);
return member;
}
@Override
public MemberVO findPw(Map<String, String> map) {
MemberVO member = loginMapper.findPw(map);
return member;
}
@Override
public MemberVO loginCheck(MemberVO memberVO) {
return loginMapper.loginCheck(memberVO);
}
@Override
public void changePw(Map<String, Object> param) {
/** 파라미터 조회 */
String memId = (String) param.get("memId");
String memPw = (String) param.get("memPw");
/** 파라미터 정의 */
MemberVO memberVO = new MemberVO();
int status = 0;
ServiceResult result = null;
String message = "";
String goPage = "";
/** 메인로직 처리 */
// 해당 회원의 비밀번호를 변경
memberVO.setMemId(memId);
memberVO.setMemPw(memPw);
status = loginMapper.changePw(memberVO);
if(status > 0) { // 비밀번호 변경 성공
result = ServiceResult.OK;
message = memId + " 회원의 비밀번호 변경에 성공했습니다. 로그인 페이지로 이동합니다.";
goPage = "redirect:/login/signin.do"; // 로그인 페이지로 이동
}else { // 비밀번호 변경 실패
result = ServiceResult.FAILED;
message = "서버 오류, 다시 시도해 주세요.";
goPage = "login/findIdPw"; // 아이디/비밀번호 페이지로 이동
}
/** 반환자료 저장 */
param.put("result", result);
param.put("message", message);
param.put("goPage", goPage);
}
}
package kr.or.ddit.mapper;
import java.util.Map;
import kr.or.ddit.users.login.vo.MemberVO;
public interface LoginMapper {
public MemberVO idCheck(String memId);
public MemberVO emailCheck(String memEmail);
public int signup(MemberVO memberVO);
public MemberVO findId(Map<String, String> map);
public MemberVO findPw(Map<String, String> map);
public MemberVO loginCheck(MemberVO memberVO);
public int changePw(MemberVO memberVO);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.mapper.LoginMapper">
<select id="idCheck" parameterType="string" resultType="memberVO">
SELECT
mem_no,
mem_id,
mem_pw,
mem_name,
mem_gender,
mem_email,
mem_phone,
mem_postcode,
mem_address1,
mem_address2,
mem_profileimg,
grade_code,
enabled,
mem_category,
mem_regdate,
mem_agedate
FROM
members
WHERE 1=1
AND mem_id = #{memId}
</select>
<select id="emailCheck" parameterType="string" resultType="memberVO">
SELECT
mem_no,
mem_id,
mem_pw,
mem_name,
mem_gender,
mem_email,
mem_phone,
mem_postcode,
mem_address1,
mem_address2,
mem_profileimg,
grade_code,
enabled,
mem_category,
mem_regdate,
mem_agedate
FROM
members
WHERE 1=1
AND mem_email = #{memEmail}
</select>
<insert id="signup" parameterType="memberVO">
<selectKey keyProperty="memNo" order="BEFORE" resultType="int">
select seq_members.nextval from dual
</selectKey>
INSERT INTO members (
mem_no,
mem_id,
mem_pw,
mem_name,
mem_gender,
mem_email,
mem_phone,
mem_postcode,
mem_address1,
mem_address2,
mem_profileimg,
grade_code,
enabled,
mem_category,
mem_regdate,
mem_agedate
) VALUES (
#{memNo},
#{memId},
#{memPw},
#{memName},
#{memGender},
#{memEmail},
#{memPhone},
#{memPostcode},
#{memAddress1},
#{memAddress2},
#{memProfileimg},
'NOR01',
'1',
'01',
sysdate,
#{memAgedate}
)
</insert>
<select id="findId" parameterType="java.util.HashMap" resultType="memberVO">
SELECT
mem_no,
mem_id,
mem_pw,
mem_name,
mem_gender,
mem_email,
mem_phone,
mem_postcode,
mem_address1,
mem_address2,
mem_profileimg,
grade_code,
enabled,
mem_category,
mem_regdate,
mem_agedate
FROM
members
WHERE 1=1
AND mem_email = #{memEmail}
AND mem_name = #{memName}
</select>
<select id="findPw" parameterType="java.util.HashMap" resultType="memberVO">
SELECT
mem_no,
mem_id,
mem_pw,
mem_name,
mem_gender,
mem_email,
mem_phone,
mem_postcode,
mem_address1,
mem_address2,
mem_profileimg,
grade_code,
enabled,
mem_category,
mem_regdate,
mem_agedate
FROM
members
WHERE 1=1
AND mem_id = #{memId}
AND mem_email = #{memEmail}
AND mem_name = #{memName}
</select>
<select id="loginCheck" parameterType="string" resultType="memberVO">
SELECT
mem_no,
mem_id,
mem_pw,
mem_name,
mem_gender,
mem_email,
mem_phone,
mem_postcode,
mem_address1,
mem_address2,
mem_profileimg,
grade_code,
enabled,
mem_category,
mem_regdate,
mem_agedate
FROM
members
WHERE 1=1
AND mem_id = #{memId}
AND mem_pw = #{memPw}
</select>
<update id="changePw" parameterType="memberVO">
UPDATE members
SET
mem_pw = #{memPw}
WHERE
mem_id = #{memId}
</update>
</mapper>
'대덕인재개발원 > 대덕인재개발원_최종 포트폴리오' 카테고리의 다른 글
(7) 회원가입 페이지 > 코드 리뷰 (0) | 2024.02.15 |
---|---|
(6) 로그인 페이지 > 화면 설명 (0) | 2024.02.15 |
(4) 랜딩 페이지 > 화면 설명 (0) | 2024.02.15 |
(3) 랜딩 페이지 > 코드 리뷰 (0) | 2024.02.15 |
(2) 프로젝트 구조 및 설정 2 (0) | 2024.02.15 |