하석형 하석형 06-30
250630 하석형 이메일, 핸드폰 인증
@3d26ccf2ef0048100fc4d6cd81081dc98a7117ea
client/resources/api/email.js
--- client/resources/api/email.js
+++ client/resources/api/email.js
@@ -2,15 +2,15 @@
 
 // 이메일 인증코드 발송
 export const sendAuthEmailProc = email => {
-    return apiClient.post(`/sys/email/sendEmailVerifyCode.json`, email);
+    return apiClient.post(`/sys/email/sendEmailCertifyCode.json`, email);
 }
 
 // 이메일 인증코드 확인
 export const checkAuthEmailProc = email => {
-    return apiClient.post(`/sys/email/checkEmailVerifyCode.json`, email);
+    return apiClient.post(`/sys/email/checkEmailCertifyCode.json`, email);
 }
 
 // 2차 인증 이메일 인증코드 확인
 export const check2ndAuthProc = email => {
-    return apiClient.post(`/sys/email/check2ndAuthEmailVerifyCode.json`, email);
+    return apiClient.post(`/sys/email/check2ndAuthEmailCertifyCode.json`, email);
 }
client/resources/api/mbrInfo.js
--- client/resources/api/mbrInfo.js
+++ client/resources/api/mbrInfo.js
@@ -48,4 +48,9 @@
 // 이메일 중복 검사
 export const emailCheckProc = (data) => {
   return apiClient.post(`/mbr/findByCheckEmail.json`, data);
+};
+
+// 휴대폰번호 중복 검사
+export const mblTelnoCheckProc = (data) => {
+  return apiClient.post(`/mbr/findByCheckMblTelno.json`, data);
 };
(파일 끝에 줄바꿈 문자 없음)
 
client/resources/api/sms.js (added)
+++ client/resources/api/sms.js
@@ -0,0 +1,16 @@
+import apiClient from "./index";
+
+// SMS 인증코드 발송
+export const sendAuthSMSProc = sms => {
+    return apiClient.post(`/sys/sms/sendSMSCertifyCode.json`, sms);
+}
+
+// SMS 인증코드 확인
+export const checkAuthSMSProc = sms => {
+    return apiClient.post(`/sys/sms/checkSMSCertifyCode.json`, sms);
+}
+
+// 2차 인증 SMS 인증코드 확인
+export const check2ndAuthSMSProc = sms => {
+    return apiClient.post(`/sys/sms/check2ndAuthSMSCertifyCode.json`, sms);
+}
client/views/pages/login/ResetPswd.vue
--- client/views/pages/login/ResetPswd.vue
+++ client/views/pages/login/ResetPswd.vue
@@ -15,7 +15,8 @@
                 </li>
             </ul>
             <div class="tab-content">
-                <div class="flex-column justify-center content" v-if="tabView === 'id' && !certYn" style="min-height: 275px">
+                <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,
@@ -29,18 +30,19 @@
                             <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" />
+                                    <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" />
+                                    <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" />
+                                    <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>
@@ -65,7 +67,8 @@
                         </button> -->
                     </div>
                 </div>
-                <div class="flex-column justify-center content" v-if="tabView === 'pw' && !certYn" style="min-height: 275px">
+                <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,
@@ -79,23 +82,24 @@
                             <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" />
+                                    <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" />
+                                    <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" />
+                                    <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" />
+                                    <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>
@@ -127,14 +131,17 @@
                         <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>
+                                <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" />
+                                <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">
                                 완료
@@ -152,6 +159,7 @@
 // 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],
@@ -248,7 +256,7 @@
                 this.pwTabView = content;
             }
         },
-        
+
         // 아이디찾기 유효성검사
         validationId() {
             if (this.idTabView === "eml") {
@@ -314,7 +322,7 @@
         // 인증코드 발송
         async fnSend() {
             // 유효성검사
-            if(this.tabView === "id") {
+            if (this.tabView === "id") {
                 if (!this.validationId()) {
                     return;
                 }
@@ -326,9 +334,16 @@
                     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 sendAuthEmailProc({email: this.mbrVO.eml});
+                const res = await certType;
                 if (res.status == 200) {
                     // alert(res.data.message);
                 }
@@ -351,8 +366,11 @@
 
         // 인증코드 확인
         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 checkAuthEmailProc({email: this.mbrVO.eml, code: this.code});
+                const res = await certType;
                 if (res.status == 200) {
                     this.fnSearchId();
                 }
@@ -375,10 +393,11 @@
             // }
             // 데이터 세팅
             let data = this.mbrVO;
+            this.fnDataSetting(data);
             // 실행
             try {
                 const res = await searchIdProc(data);
-                if(res.status == 200) {
+                if (res.status == 200) {
                     this.mbrVO.lgnId = res.data.data;
                     this.certYn = true;
                     // let isCheck = confirm("회원님의 아이디는 " + lgnId + "입니다.\n로그인 페이지로 이동하시겠습니까?");
@@ -423,12 +442,13 @@
         // axios: 새 비밀번호 설정
         async fnSetPswd() {
             // 유효성검사
-			if (!this.validatePswd(null, this.pswd)) {
-				return false;
-			}
+            if (!this.validatePswd(null, this.pswd)) {
+                return false;
+            }
             // 데이터 세팅
-            this.mbrVO.pswd = this.pswd.newPswd; // 새 비밀번호 설정
+            // this.mbrVO.pswd = this.pswd.newPswd; // 새 비밀번호 설정
             let data = this.mbrVO;
+            this.fnDataSetting(data);
             // 실행
             try {
                 const res = await setNewPswdProc(data);
@@ -450,33 +470,46 @@
         },
 
         // 비밀번호변경 검증
-		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;
-			}
-		},
+        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: {
@@ -486,7 +519,7 @@
             this.pswdChkCheck();
         },
         // 비밀번호변경확인 감시
-            "pswd.newPswdChk"() {
+        "pswd.newPswdChk"() {
             this.pswdChkCheck();
         },
     }
client/views/pages/login/SignUp.vue
--- client/views/pages/login/SignUp.vue
+++ client/views/pages/login/SignUp.vue
@@ -182,7 +182,7 @@
 // COMPONENETS
 import UserInfoInsert from "../../component/userInfo/UserInfoInsert.vue";
 
-import { mbrDetailProc, mbrInsertProc, emailCheckProc } from "../../../resources/api/mbrInfo";
+import { mbrDetailProc, mbrInsertProc, emailCheckProc, mblTelnoCheckProc } from "../../../resources/api/mbrInfo";
 import { sendAuthEmailProc, checkAuthEmailProc } from "../../../resources/api/email";
 
 export default {
@@ -362,12 +362,6 @@
 
 			// 이메일
 			data.eml = this.emailSum();
-
-			// 회원 상태가 차단이 아니면 차단일, 차단 사유 삭제
-			if (data.mbrStts != 3) {
-				data.cntrlDt = null;
-				data.cntrlRsn = null;
-			}
 		},
 
 		// 유효성검사
@@ -438,16 +432,17 @@
 				return;
 			}
 			// 데이터 세팅
-			let eml = this.emailSum();
+			let data = this.mbrVO;
+			this.fnDataSetting(data);
 
 			// 이메일 중복 검사
-			if(await this.fnEmailCheck(eml)) {
+			if(await this.fnEmailCheck(data.eml)) {
 				return;
 			}
 
             try {
 				this.sendYn = true; // 인증코드 발송
-				const res = await sendAuthEmailProc({email: eml});
+				const res = await sendAuthEmailProc({email: data.eml});
                 if (res.status == 200) {
 					// alert(res.data.message);
                 }
@@ -509,6 +504,27 @@
 			}
         },
 
+		// 휴대폰번호 중복 검사
+        async fnMblTelnoCheck(eml) {
+			let result = true;
+            try {
+                const res = await mblTelnoCheckProc({eml: eml});
+                if (res.status == 200) {
+                    result = false; // 중복된 이메일이 없으면 false
+                }
+            } 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관리자에게 문의해주세요.");
+                }
+            } finally {
+				return result; // 중복 검사 결과 반환
+			}
+        },
+
 		// 취소
 		fnCancel() {
 			const isCheck = confirm("회원가입을 취소하시겠습니까?");
Add a comment
List