Files
sake/build/resources/main/templates/login.html

441 lines
21 KiB
HTML

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.w3.org/1999/html">
<head>
<!-- 메타정보-->
<meta charset="UTF-8">
<meta name="description" th:content="${shopInfo.metaDc}">
<meta name="keywords" th:content="${shopInfo.metaKwrd}">
<!-- CSS -->
<!-- 공통 CSS-->
<link rel="stylesheet" href="/sopmall/pc/css/default.css">
<!-- 테마 CSS-->
<link rel = 'stylesheet' th:href="|/sopmall/pc${shopInfo.cssCours}|" th:if="${#strings.startsWith(shopInfo.cssCours, '/')}">
<link rel = 'stylesheet' th:href="|/sopmall/pc/${shopInfo.cssCours}|" th:if="${!#strings.startsWith(shopInfo.cssCours, '/')}">
<!-- 파비콘-->
<link rel = 'icon' th:href="|/sopmall${shopInfo.fviconCours}|" th:if="${#strings.startsWith(shopInfo.fviconCours, '/')}">
<link rel = 'icon' th:href="|/sopmall/${shopInfo.fviconCours}|" th:if="${!#strings.startsWith(shopInfo.fviconCours, '/')}">
<!-- 타이틀-->
<title th:text="${shopInfo.metaSj}"></title>
<!--js-->
<script src="/sopmall/pc/js/common.js"></script>
</head>
<script>
/**************************************************************
* input
* 특정 input(select)에 특정 event 발생시 처리할 함수 지정
* 파라미터 설명{
* selector : 대상 input Object selector
* eventType : 대상 event종류(예시>keyup)
* callback : 대상 event발생 시 호출될 callback함수
* }
****************************************************************/
const fn_set_event = function (selector, eventType, callback) {
document.querySelector(selector).addEventListener(eventType, function () {
let target = this;
callback(target);
});
}
/**************************************************************
* 데이터 NULL 여부
* 파라미터 설명 {
* data : 데이터
* }
****************************************************************/
const fn_is_empty = (data) => {
if (typeof data === 'undefined' ||
data === 'undefined' ||
data === null ||
data === '' ||
data === 'null' ||
data.length === 0 ||
(typeof data === 'object' && !Object.keys(data).length)) {
return true;
} else {
return false;
}
}
/**************************************************************
* 포매팅 (input 값 포매팅)
* 전화번호(일반전화번호, 휴대전화번호, 대표번호) 자동 포매팅(-) 설정
* 파라미터 설명{
* target : 대상 Object
* }
****************************************************************/
const fn_fmt_telno = function (target) {
// 숫자만 허용
target.value = target.value.replace(/[^0-9]/g, '');
if (target.value.length <= 11) {
if (target.value.length == 11) {
// 휴대전화번호 혹은 02를 제외한 전화번호
target.value = target.value.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3');
} else if (target.value.length == 9) {
// 02를 포함한 9자리 전화번호(02-000-0000)
target.value = target.value.replace(/(\d{2})(\d{3})(\d{4})/, '$1-$2-$3');
} else if (target.value.length == 8) {
// 대표전화번호 일 경우(0000-0000)
target.value = target.value.replace(/(\d{4})(\d{4})/, '$1-$2');
} else {
if (target.value.indexOf('02') == 0) {
// 02를 포함한 10자리 전화번호(02-0000-0000)
target.value = target.value.replace(/(\d{2})(\d{4})(\d{4})/, '$1-$2-$3');
} else {
// 02를 제외한 10자리 전화번호(032-000-0000)
target.value = target.value.replace(/(\d{3})(\d{3})(\d{4})/, '$1-$2-$3');
}
}
}
}
/* ********************************************************
* 주문 상세 이동
******************************************************** */
const fn_go_ordr_dtl = function () {
var accessUrl = document.getElementById('accessUrl').value;
if(accessUrl.startsWith("http://") && !(accessUrl.includes("dev.") || accessUrl.includes("loc."))){
accessUrl = accessUrl.replace("http://", "https://");
}
var form = document.getElementById('condForm');
form.setAttribute('method', 'post');
form.setAttribute('action', accessUrl+'/sopmal/main/selectNMbrOrdrDtlInqire');
form.submit();
}
/* ********************************************************
* 주문 번호 조회
******************************************************** */
const fn_select_oderNumbber = function() {
let sopMalCd = document.getElementById('sopMalCd').value;
let ordrInnb = document.getElementById('ordrInnb').value;
let mbtlnb = document.getElementById('mbtlnb').value;
let accessUrl = document.getElementById('accessUrl').value;
if (fn_is_empty(ordrInnb)) {
alert("주문번호를 입력해주세요.");
return false;
}
if (fn_is_empty(mbtlnb)) {
alert("주문 시 입력한 휴대폰번호를 입력해주세요.");
return false;
}
const form = document.getElementById('condForm');
const formData = new FormData(form); // 폼 데이터
fetch('/login/selectNMbrMbtlnbInqire', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
sopMalCd: sopMalCd,
ordrInnb: ordrInnb,
mbtlnb: mbtlnb,
accessUrl: accessUrl
})
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// let result = data.resBody;
// let parsedResult = JSON.parse(result.result);
// let confirmAt = parsedResult.confirmAt;
let confirmAt = data.confirmAt;
if (confirmAt === 'Y') {
fn_go_ordr_dtl();
} else {
alert("휴대폰번호가 일치하지않습니다.");
}
})
.catch(error => {
alert("비회원 주문조회 실패");
console.error('Error:', error);
});
}
/* ********************************************************
* 체크박스 값변경
******************************************************** */
const fn_set_checkbox = function(_target) {
if ($(_target).is(':checked')) {
$(_target).val('Y');
} else {
$(_target).val('N');
}
}
/* ********************************************************
* 아이디 저장 기능 구현
******************************************************** */
document.addEventListener('DOMContentLoaded', function () {
const usernameInput = document.getElementById('username');
const rememberCheckbox = document.querySelector('input[type="checkbox"]');
const savedUsername = localStorage.getItem('savedUsername');
// 페이지 로드 시, 저장된 아이디가 있으면 입력 필드에 채워넣기
if (savedUsername) {
usernameInput.value = savedUsername;
rememberCheckbox.checked = true; // 체크박스도 체크 상태로 유지
}
// 체크박스 상태 변경 시 아이디 저장 또는 삭제
rememberCheckbox.addEventListener('change', function () {
if (this.checked) {
// 체크된 경우, 아이디를 localStorage에 저장
const username = usernameInput.value;
if (username) {
localStorage.setItem('savedUsername', username);
}
} else {
// 체크 해제된 경우, 저장된 아이디 삭제
localStorage.removeItem('savedUsername');
}
});
// 로그인 버튼 클릭 시 아이디 저장 처리
document.querySelector('.login__loginBtn').addEventListener('click', function () {
if (rememberCheckbox.checked) {
const username = usernameInput.value;
if (username) {
localStorage.setItem('savedUsername', username); // 아이디 저장
}
} else {
localStorage.removeItem('savedUsername'); // 체크 해제 시 아이디 삭제
}
});
//아이디 저장시 alert메시지 삭제
fn_hide_alertTxt('username', 'mbrIdAlertText');
});
</script>
<body>
<main>
<div class="sub-wrapper">
<div class="sub-content">
<div class="page-title center">
<h2 class="page-title__title">
<a th:href="${accessUrl}">
<img class="page-title__logo" th:src="@{${cdnurl}+${shopInfo.topFilCours}+'/'+${shopInfo.topSysFilNm}}" th:alt="${shopInfo.sopmalNm}">
</a>
<span class="visually-hidden">로그인</span>
</h2>
<th:block th:if="${purchasingAt == 'Y'}">
<p class="page-title__subTitle">회원으로 주문하시면 마일리지, 쿠폰, 할인 등 다양한 혜택을 받으실 수 있습니다.</p>
</th:block>
<th:block th:unless="${purchasingAt == 'Y'}">
<p class="page-title__subTitle">회원 로그인을 하시면 각종 혜택 및 정보를 제공 받으실 수 있습니다.</p>
</th:block>
</div>
<div class="login">
<div class="boxTab">
<button type="button" class="boxTab__tabBtn current">회원</button>
<button type="button" class="boxTab__tabBtn">비회원(주문조회)</button>
</div>
<div class="boxTab__content login-content current">
<form id="loginForm">
<input type="hidden" id="realm" th:value="${realm}">
<input type="hidden" id="redirectUri" th:value="${redirectUri}">
<input type="hidden" id="accessUrl" th:value="${accessUrl}">
<input type="hidden" id="sopMalCd" th:value="${sopMalCd}">
<div class="login__inputBox">
<input class="input-text full inputTarget" type="text" name="username" id="username" title="아이디"
placeholder="아이디" oninput="fn_hide_alertTxt('username','mbrIdAlertText');">
<p class="login__inputBox__alertText"><span id="mbrIdAlertText">아이디를 입력해 주세요.</span></p>
<input class="input-text full inputTarget" type="password" name="password" id="password" title="비밀번호"
placeholder="비밀번호" onkeyup="fn_hide_alertTxt('password','mbrPwAlertText',event);">
<p class="login__inputBox__alertText"><span id="mbrPwAlertText">비밀번호를 입력해 주세요.</span></p>
</div>
<button type="submit" class="btn xl full dark login__loginBtn">로그인</button>
</form>
<div class="login__misc">
<div class="b-checkbox-container">
<label class="b-checkbox is-medium checkbox">
<input type="checkbox" value="N" name="" onchange="fn_set_checkbox(this);">
<span class="check"></span>
<span class="control-label">아이디 저장</span>
</label>
</div>
<a class="login__misc__link" th:href="${accessUrl + '/sopmal/mbr/selectIdPasswordSearch'}">아이디/비밀번호 찾기</a>
</div>
<div class="login__signIn">
<p class="login__signIn__text">아직 <span th:text="${shopInfo.sopmalNm}"></span> 회원이 아니세요?</p>
<a class="login__signIn__link" th:href="${accessUrl + '/sopmal/mbr/selectJoinGuidance'}">회원가입</a>
</div>
<div class="login__sns">
<th:block th:if="${shopInfo.kakaoIntrlckAt == 'Y'}">
<button type="button" class="login__sns__btn kakao" onclick="openSocialLoginPopup('KAKAO')"><i class="icon icon_kakaoLogin"></i>카카오 로그인</button>
</th:block>
<th:block th:if="${shopInfo.naverIntrlckAt == 'Y'}">
<button type="button" class="login__sns__btn naver" onclick="openSocialLoginPopup('NAVER')"><i class="icon icon_naverLogin"></i>네이버 로그인</button>
</th:block>
</div>
<br>
<th:block th:if="${purchasingAt == 'Y'}">
<button class="btn xl full gray login__loginBtn" onclick="nmbrPurchsForm()">비회원으로 구매하기</button>
</th:block>
</div>
<div class="boxTab__content login-content">
<form id="condForm">
<div class="login__inputBox">
<input class="input-text full inputTarget" type="text" id="ordrInnb" name="ordrInnb" title="주문번호"
placeholder="주문번호" oninput="fn_hide_alertTxt('ordrInnb','nmbrOrdrAlertText');">
<p class="login__inputBox__alertText"><span id="nmbrOrdrAlertText">주문번호를 입력해 주세요.</span></p>
<input class="input-text number full inputTarget" type="tel" id="mbtlnb" name="mbtlnb" title="휴대폰번호"
placeholder="주문 시 입력한 휴대폰번호('-'없이)" oninput="fn_hide_alertTxt('mbtlnb','nmbrPwAlertText');">
<p class="login__inputBox__alertText"><span id="nmbrPwAlertText">휴대폰번호를 입력해 주세요.</span></p>
</div>
<button type="button" class="btn xl full dark" onclick="fn_select_oderNumbber();">조회</button>
</form>
</div>
</div>
</div>
</div>
</main>
<script>
/* ********************************************************
* 로그인
******************************************************** */
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
const realm = document.getElementById('realm').value;
const username = document.getElementById('username').value.replace(/\s+/g, '');
const password = document.getElementById('password').value.replace(/\s+/g, '');
const redirectUri = document.getElementById('redirectUri').value;
const accessUrl = document.getElementById('accessUrl').value;
const sopMalCd = document.getElementById('sopMalCd').value;
fetch(`/login/${realm}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: username,
password: password,
redirectUri: redirectUri,
accessUrl: accessUrl,
sopMalCd: sopMalCd
})
})
.then(response => {
console.log(response)
if (response.ok) {
return response;
}else{
switch(response.status){
case 401:
throw new Error('회원아이디나 비밀번호를 다시 확인해주세요.');
case 404:
break;
default:
throw new Error('회원 로그인에 실패하였습니다. 관리자에게 문의해주세요.');
}
}
})
.then(data => {
console.log('Login successful', data);
let moveTo = redirectUri;
if(redirectUri === '') moveTo = '/'
console.log('move', moveTo);
console.log('data.url', data.url);
window.location.href = data.url;
})
.catch(error => {
console.error('Error:', error);
alert(error.message);
});
});
/* ********************************************************
* 로그아웃
******************************************************** */
const logout = () => {
fetch('/logout', {
method: 'GET',
credentials: 'include'
}).then(response => {
if (response.ok) {
window.location.href = '/login';
} else {
console.error('Logout failed');
}
}).catch(error => {
console.error('Error:', error);
});
}
/* ********************************************************
* SNS 소셜 로그인
******************************************************** */
const openSocialLoginPopup = (provider) => {
var redirectUri = document.getElementById('redirectUri').value;
var sopMalCd = document.getElementById('sopMalCd').value;
var accessUrl = document.getElementById('accessUrl').value;
var tmpProvider = sopMalCd +'-'+ provider;
var width = 600;
var height = 600;
var left = (screen.width / 2) - (width / 2);
var top = (screen.height / 2) - (height / 2);
var url = '/oauth2/authorization/' + tmpProvider + '?access_url=' + encodeURIComponent(accessUrl) + '&redirect_uri=' + encodeURIComponent(redirectUri) + "&oauth2_type=login";
window.open(url, 'SocialLoginPopup', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=' + width + ', height=' + height + ', top=' + top + ', left=' + left);
}
const receiveMessage = (event) => {
if(event.origin !== window.location.origin) {
return;
}
if(event.data.type === 'LOGIN_SUCCESS') {
window.location.href = event.data.redirectUrl;
}
}
window.addEventListener('message', receiveMessage, false);
//비회원 주문 폼 이동
function nmbrPurchsForm(){
var accessUrl = document.getElementById('accessUrl').value;
window.location.href = accessUrl+'/sopmal/ordr/selectNmbrPurchsForm';
}
//로그인,주문조회 input 이벤트
function fn_hide_alertTxt(targetId, targetAlertId,event) {
const inputLen = document.querySelector("#" + targetId).value.length;
const target = document.querySelector("#" + targetAlertId);
if (inputLen > 0) {
if (targetId === 'password') {
if (event.getModifierState("CapsLock")) {
target.textContent = "Caps Lock이 켜져 있습니다.";
target.style.display = 'block';
} else {
target.style.display = 'none';
}
} else {
target.style.display = 'none';
}
} else {
if (targetId === 'password') {
target.textContent = "비밀번호를 입력해주세요.";
}
target.style.display = 'block'
}
}
</script>
</body>
</html>