
File name
Commit message
Commit date
05-22
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<div class="content pt50 pb50">
<router-link :to="{ path: $filters.ctxPath('/login.page') }">←</router-link>
<div class="content w1200">
<div class="page-title point-font mb30">
<p v-show="tabView === 'id'">아이디 찾기</p>
<p v-show="tabView === 'pw'">비밀번호 찾기</p>
</div>
<ul class="flex align-center find-tab mb30 pd10">
<li v-for="(tab, idx) in tabList" :key="idx" @click="showTab(tab.id)" :class="{
'gd-6 pd5 text-ct radius': true,
'tab-active': tabView === tab.id,
}" :style="{ fontWeight: tabView === tab.id ? 'bold' : 'normal' }">
{{ tab.name }}
</li>
</ul>
<div class="tab-content">
<div class="flex-column justify-center content" v-if="tabView === 'id' && !certYn"
style="min-height: 275px">
<ul class="flex align-center find-tab mb30 pd10">
<li v-for="(tab, idx) in idTabList" :key="idx" @click="showSubTab('id', tab.id)" :class="{
'gd-6 pd5 text-ct radius': true,
'tab-active': idTabView === tab.id,
}" :style="{ fontWeight: idTabView === tab.id ? 'bold' : 'normal' }">
{{ tab.name }}
</li>
</ul>
<div class="flex-column justify-center content">
<div>
<div>
<div v-show="idTabView === 'eml'" class="input-group mb20">
<label for="eml" class="login-label">이메일</label>
<input type="text" name="" id="eml" class="full-input login-input"
v-model="mbrVO.eml" placeholder="이메일을 입력하세요" ref="eml" />
</div>
<div v-show="idTabView === 'tel'" class="input-group mb20">
<label for="name" class="login-label">이름</label>
<input type="text" name="" id="name" class="full-input login-input"
v-model="mbrVO.mbrNm" placeholder="이름을 입력하세요" ref="mbrNm" />
</div>
<div v-show="idTabView === 'tel'" class="input-group mb20">
<label for="mblTelno" class="login-label">휴대폰 번호</label>
<input type="text" name="" id="mblTelno" class="full-input login-input"
v-model="mbrVO.mblTelno" @input="inputFormatPhone" maxlength="13"
placeholder="휴대폰 번호를 입력하세요" ref="mblTelno" />
</div>
</div>
<div>
<button class="btn sm main" @click="fnSend">
{{ !sendYn ? "인증코드 발송" : "인증코드 재발송" }}
</button>
<span v-show="sendYn">인증코드가 발송되었습니다.</span>
</div>
</div>
<div v-show="sendYn">
<div>
<input type="text" class="form-control md" ref="code" @input="inputCode" v-model="code"
maxlength="6" placeholder="인증코드를 입력하세요." />
<!-- <span v-show="certYn">인증코드가 확인되었습니다.</span> -->
</div>
<div class="btn-wrap">
<button class="btn sm main" @click="fnCheck">인증코드 확인</button>
</div>
</div>
<!-- <button v-show="certYn" class="btn sm main" @click="fnSearchPswd">
다음
</button> -->
</div>
</div>
<div class="flex-column justify-center content" v-if="tabView === 'pw' && !certYn"
style="min-height: 275px">
<ul class="flex align-center find-tab mb30 pd10">
<li v-for="(tab, idx) in pwTabList" :key="idx" @click="showSubTab('pw', tab.id)" :class="{
'gd-6 pd5 text-ct radius': true,
'tab-active': pwTabView === tab.id,
}" :style="{ fontWeight: pwTabView === tab.id ? 'bold' : 'normal' }">
{{ tab.name }}
</li>
</ul>
<div class="flex-column justify-center content">
<div>
<div>
<div class="input-group mb20">
<label for="lgnId" class="login-label">아이디</label>
<input type="text" name="" id="lgnId" class="full-input login-input"
v-model="mbrVO.lgnId" placeholder="아이디를 입력하세요" ref="lgnId" />
</div>
<div v-show="pwTabView === 'eml'" class="input-group mb20">
<label for="eml" class="login-label">이메일</label>
<input type="text" name="" id="eml" class="full-input login-input"
v-model="mbrVO.eml" placeholder="이메일을 입력하세요" ref="eml" />
</div>
<div v-show="pwTabView === 'tel'" class="input-group mb20">
<label for="mbrNm" class="login-label">이름</label>
<input type="text" name="" id="mbrNm" class="full-input login-input"
v-model="mbrVO.mbrNm" placeholder="이름을 입력하세요" ref="mbrNm" />
</div>
<div v-show="pwTabView === 'tel'" class="input-group mb20">
<label for="mblTelno" class="login-label">휴대폰 번호</label>
<input type="text" name="" id="mblTelno" class="full-input login-input"
v-model="mbrVO.mblTelno" @input="inputFormatPhone" maxlength="13"
placeholder="휴대폰 번호를 입력하세요" ref="mblTelno" />
</div>
</div>
<div>
<button class="btn sm main" @click="fnSend">
{{ !sendYn ? "인증코드 발송" : "인증코드 재발송" }}
</button>
<span v-show="sendYn">인증번호가 발송되었습니다.</span>
</div>
</div>
<div v-show="sendYn">
<div>
<input type="text" class="form-control md" ref="code" @input="inputCode" v-model="code"
maxlength="6" placeholder="인증코드를 입력하세요." />
<!-- <span v-show="certYn">인증코드가 확인되었습니다.</span> -->
</div>
<div class="btn-wrap">
<button class="btn sm main" @click="fnCheck">인증코드 확인</button>
</div>
</div>
<!-- <button v-show="certYn" class="btn sm main" @click="fnSearchPswd">
다음
</button> -->
</div>
</div>
<div class="flex-column justify-center content" v-if="certYn" style="min-height: 275px">
<div class="text-ct">
<p v-show="tabView === 'id'">회원님의 아이디는 <strong>{{ mbrVO.lgnId }}</strong> 입니다.</p>
<p v-show="tabView === 'pw'">새 비밀번호를 설정해주세요.</p>
<div v-show="tabView === 'pw'">
<div class="input-group mb20">
<label for="newPswd" class="form-control sm">새 비밀번호</label>
<input type="password" name="" id="newPswd" class="full-input login-input"
v-model="pswd.newPswd" minlength="9" placeholder="영문, 숫자, 특수문자 조합 9자 이상"
ref="newPswd" />
<span :class="{ 'red-text': pswd.errorPwd }">영문, 숫자, 특수문자를 조합하여 입력해주세요. (9자 이상)</span>
</div>
<div class="input-group mb20">
<label for="newPswdChk" :class="{ 'form-control sm': true, 'error': pswd.pswdChk }">새
비밀번호확인</label>
<input type="password" name="" id="newPswdChk" class="full-input login-input"
v-model="pswd.newPswdChk" minlength="9" placeholder="비밀번호 확인을 입력하세요."
ref="newPswdChk" />
</div>
<button class="btn sm main" @click="fnSetPswd">
완료
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import validateParams from "../../../resources/js/validateParams";
// API
import { searchIdProc, existMbrProc, setNewPswdProc } from "../../../resources/api/mbrInfo";
import { sendAuthEmailProc, checkAuthEmailProc } from "../../../resources/api/email";
import { sendAuthSMSProc, checkAuthSMSProc } from "../../../resources/api/sms";
export default {
mixins: [validateParams],
data: () => {
return {
isLoading: false, // 로딩 여부
tabList: [
{ id: "id", name: "아이디 찾기" },
{ id: "pw", name: "비밀번호 찾기" },
],
tabView: "id",
idTabList: [
{ id: "eml", name: "이메일로 찾기" },
{ id: "tel", name: "휴대폰번호로 찾기" },
],
idTabView: "eml",
pwTabList: [
{ id: "eml", name: "이메일로 찾기" },
{ id: "tel", name: "휴대폰번호로 찾기" },
],
pwTabView: "eml",
// 회원 정보
mbrVO: {
lgnId: null,
mbrNm: null,
pswd: null,
eml: null,
mblTelno: null,
},
sendYn: false, // 인증코드 발송 여부
code: null, // 인증코드
certYn: false, // 인증여부
// 비밀번호 정보
pswd: {
newPswd: null,
newPswdChk: null,
errorPwd: false, // 비밀번호 유효성 검사 실패 여부
pswdChk: false, // 비밀번호 확인 실패 여부
},
};
},
created() {
const tab = this.$route.query.tab;
if (tab) {
this.tabView = tab;
}
},
methods: {
// 초기화
init() {
// 회원 정보 초기화
this.mbrVO = {
lgnId: null,
mbrNm: null,
pswd: null,
eml: null,
mblTelno: null,
};
this.sendYn = false; // 인증코드 발송 여부 초기화
this.code = null; // 인증코드 초기화
this.certYn = false; // 인증여부 초기화
// 비밀번호 정보 초기화
this.pswd = {
newPswd: null,
newPswdChk: null,
errorPwd: false, // 비밀번호 유효성 검사 실패 여부
pswdChk: false, // 비밀번호 확인 실패 여부
};
},
// 메인 탭 전환
showTab(content) {
this.init(); // 초기화
this.idTabView = "eml";
this.pwTabView = "eml";
this.tabView = content;
},
// 서브 탭 전환
showSubTab(type, content) {
this.init(); // 초기화
if (type === 'id') {
this.idTabView = content;
} else if (type === 'pw') {
this.pwTabView = content;
}
},
// 아이디찾기 유효성검사
validationId() {
if (this.idTabView === "eml") {
// 이메일
if (!this.validateEmlFull(this.mbrVO.eml)) {
return false;
}
} else if (this.idTabView === "tel") {
// 이름
if (!this.validateNm(this.mbrVO.mbrNm)) {
return false;
}
// 휴대폰번호
if (!this.validateMblNo(this.mbrVO.mblTelno)) {
return false;
}
}
return true;
},
// 비밀번호초기화 유효성검사
validationPswd() {
// 아이디
if (!this.validateId(this.mbrVO.lgnId)) {
return false;
}
if (this.pwTabView === "eml") {
// 이메일
if (!this.validateEmlFull(this.mbrVO.eml)) {
return false;
}
} else if (this.pwTabView === "tel") {
// 이름
if (!this.validateNm(this.mbrVO.mbrNm)) {
return false;
}
// 휴대폰번호
if (!this.validateMblNo(this.mbrVO.mblTelno)) {
return false;
}
}
return true;
},
// 휴대폰 번호 입력 포맷
inputFormatPhone(event) {
let input = event.target.value.replace(/[^0-9]/g, '');
if (input.length <= 3) {
this.mbrVO.mblTelno = input;
} else if (input.length <= 6) {
this.mbrVO.mblTelno = input.slice(0, 3) + '-' + input.slice(3);
} else if (input.length <= 10) {
// 10자리는 3-3-4
this.mbrVO.mblTelno = input.slice(0, 3) + '-' + input.slice(3, 6) + '-' + input.slice(6);
} else {
// 기본은 3-4-4
this.mbrVO.mblTelno = input.slice(0, 3) + '-' + input.slice(3, 7) + '-' + input.slice(7, 11);
}
},
// 인증코드 발송
async fnSend() {
// 유효성검사
if (this.tabView === "id") {
if (!this.validationId()) {
return;
}
} else if (this.tabView === "pw") {
if (!this.validationPswd()) {
return;
}
if (!await this.fnExistMbr()) {
return;
}
}
// 데이터 세팅
let data = this.mbrVO;
this.fnDataSetting(data);
let subTab = this.tabView === "id" ? this.idTabView : this.pwTabView; // 서브 탭 확인
const certType = subTab === "eml" ? sendAuthEmailProc({ email: data.eml }) : sendAuthSMSProc({ mblTelno: data.mblTelno }); // 인증코드 발송 API 선택
try {
this.sendYn = true; // 인증코드 발송
const res = await certType;
if (res.status == 200) {
// alert(res.data.message);
}
} catch (error) {
const errorData = error.response.data;
if (errorData.message != null && errorData.message != "") {
alert(error.response.data.message);
} else {
alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
}
this.sendYn = false; // 발송 실패시 인증코드 발송 여부 초기화
}
},
// 인증코드 입력
inputCode(event) {
const input = event.target.value.replace(/[^0-9]/g, '');
this.code = input;
},
// 인증코드 확인
async fnCheck() {
let subTab = this.tabView === "id" ? this.idTabView : this.pwTabView; // 서브 탭 확인
const certType = subTab === "eml" ? checkAuthEmailProc({ email: this.mbrVO.eml, code: this.code }) : checkAuthSMSProc({ mblTelno: this.mbrVO.mblTelno, code: this.code }); // 인증코드 발송 API 선택
try {
const res = await certType;
if (res.status == 200) {
this.fnSearchId();
}
} catch (error) {
const errorData = error.response.data;
if (errorData.message != null && errorData.message != "") {
alert(error.response.data.message);
this.$refs.code.focus();
} else {
alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
}
}
},
// axios: 아이디 찾기
async fnSearchId() {
// 유효성검사
// if (!this.validationId()) {
// return;
// }
// 데이터 세팅
let data = this.mbrVO;
this.fnDataSetting(data);
// 실행
try {
const res = await searchIdProc(data);
if (res.status == 200) {
this.mbrVO.lgnId = res.data.data;
this.certYn = true;
// let isCheck = confirm("회원님의 아이디는 " + lgnId + "입니다.\n로그인 페이지로 이동하시겠습니까?");
// if (isCheck) {
// this.$router.push({
// path: this.$filters.ctxPath("/login.page"),
// });
// }
}
} catch (error) {
const errorData = error.response?.data;
if (errorData?.message != null && errorData?.message != "") {
// alert("입력하신 정보와 일치하는 아이디가 존재하지 않습니다.");
alert(error.response.data.message);
} else {
alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
}
}
},
// axios: 회원정보 존재 확인
async fnExistMbr() {
// 데이터 세팅
let data = this.mbrVO;
// 실행
let result = false;
try {
const res = await existMbrProc(data);
result = res.data.data; // true or false
} catch (error) {
const errorData = error.response?.data;
if (errorData?.message != null && errorData?.message != "") {
alert("입력하신 정보와 일치하는 회원이 존재하지 않습니다.");
} else {
alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
}
} finally {
return result;
}
},
// axios: 새 비밀번호 설정
async fnSetPswd() {
// 유효성검사
if (!this.validatePswd(null, this.pswd)) {
return false;
}
// 데이터 세팅
// this.mbrVO.pswd = this.pswd.newPswd; // 새 비밀번호 설정
let data = this.mbrVO;
this.fnDataSetting(data);
// 실행
try {
const res = await setNewPswdProc(data);
if (res.status == 200) {
alert("비밀번호가 변경되었습니다.\n변경된 비밀번호로 로그인해주세요.");
this.$router.push({
path: this.$filters.ctxPath("/login.page"),
});
}
} catch (error) {
const errorData = error.response?.data;
if (errorData?.message != null && errorData?.message != "") {
// alert("입력하신 정보와 일치하는 회원이 존재하지 않습니다.");
alert(error.response.data.message);
} else {
alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
}
}
},
// 비밀번호변경 검증
pswdCheck() {
if (this.pswd.newPswd != null && this.pswd.newPswd != "") {
const validate =
/^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[$`~!@$!%*#^?&()\-_=+])/;
if (
!validate.test(this.pswd.newPswd)
) {
this.pswd.errorPwd = true;
} else if (this.pswd.newPswd != null && this.pswd.newPswd != "") {
this.pswd.errorPwd = false;
}
} else {
this.pswd.errorPwd = null;
}
},
// 비밀번호변경확인 검증
pswdChkCheck() {
if (this.pswd.newPswdChk != null && this.pswd.newPswdChk != "") {
if (this.pswd.newPswd == this.pswd.newPswdChk) {
this.pswd.pswdChk = false;
} else {
this.pswd.pswdChk = true;
}
} else {
this.pswd.pswdChk = null;
}
},
// 데이터 세팅
fnDataSetting(data) {
// 비밀번호
if (this.pswd.newPswd != null && this.pswd.newPswd != "") {
data.pswd = this.pswd.newPswd.replace(/(\s*)/g, "");
} else {
data.pswd = null;
}
// 휴대폰 번호
data.mblTelno = this.mbrVO.mblTelno?.replace(/-/g, ''); // 하이픈 제거
},
},
watch: {
// 비밀번호변경 감시
"pswd.newPswd"() {
this.pswdCheck();
this.pswdChkCheck();
},
// 비밀번호변경확인 감시
"pswd.newPswdChk"() {
this.pswdChkCheck();
},
}
};
</script>