박민혁 박민혁 07-15
250715 박민혁 아이디 / 비밀번호 찾기 (이메일 & 휴대폰 인증 제외)
@3185d41d5544f770cf0bb36a1f91492a4672e9ae
client/resources/api/auth.js
--- client/resources/api/auth.js
+++ client/resources/api/auth.js
@@ -24,3 +24,24 @@
 export const checkEmailProc = (data) => {
     return apiClient.post(`/auth/checkEmail.json`, data);
 };
+
+// 아이디 찾기
+export const findIdProc = (data) => {
+    return apiClient.post(`/auth/findId.json`, data);
+}
+
+// 아이디 가져오기
+export const findLoginIdProc = (data) => {
+    return apiClient.post(`/auth/findLoginId.json`, data);
+}
+
+
+// 비밀번호 찾기
+export const findPasswordProc = (data) => {
+    return apiClient.post(`/auth/findPassword.json`, data);
+}
+
+// 비밀번호 변경
+export const updatePasswordProc = (data) => {
+    return apiClient.post(`/auth/updatePassword.json`, data);
+}
client/views/pages/common/Find.vue
--- client/views/pages/common/Find.vue
+++ client/views/pages/common/Find.vue
@@ -1,77 +1,88 @@
 <template>
-  <div class="find-wrap">
-    <div class="login-logo mb50">
-        <img src="../../../resources/img/content/login_logo.svg" alt="로고">
-    </div>
-    <div class="login-box">
-        <p v-if="type === 'id'" class="find-title mb30">아이디 찾기</p>
-        <p v-else-if="type === 'pw'" class="find-title mb30">비밀번호 찾기</p>
-        <div class="error-message mb30">
-            <p>
-                <img src="../../../resources/img/component/common/ico_invalid_error_20.svg" alt=""> 
-                <span v-if="type === 'id' && step === 1">아이디 찾을 방법을 선택해주세요.</span>
-                <span v-if="type === 'pw' && step === 1">비밀번호 찾을 방법을 선택해주세요.</span> 
-                <span v-if="type === 'id' && step === 2">아이디를 찾았습니다.</span>
-                <span v-if="type === 'pw' && step === 2">변경할 비밀번호를 입력해주세요.</span> 
-            </p>
+    <div class="find-wrap">
+        <div class="login-logo mb50">
+            <img src="../../../resources/img/content/login_logo.svg" alt="로고">
         </div>
-        <div class="find-methods" v-if="step === 1">
-            <div class="form-check">
-                <input type="radio" id="find-phone" name="find-method" value="phone"  v-model="selectedMethod"/>
-                <label for="find-phone">회원 정보에 등록한 휴대전화로 인증</label>
-                <!-- 휴대폰 인증 영역 -->
-                <div v-if="selectedMethod === 'phone'" class="auth-form phone-auth">
-                    <p class="warning">회원정보에 등록한 휴대전화 번호와 입력된 휴대전화번호가 같아야, 인증번호를 받을 수 있습니다.</p>
-                    <input type="text" placeholder="이름"  class="form-control sm mb10"/>
-                    <div class="input-group mb10">
-                            <input type="tel" placeholder="휴대전화 번호"  class="form-control sm "/>
-                            <button class="btn sm black" @click="certification">인증번호 받기</button>
+        <div class="login-box">
+            <p v-if="type === 'id'" class="find-title mb30">아이디 찾기</p>
+            <p v-else-if="type === 'pw'" class="find-title mb30">비밀번호 찾기</p>
+            <div class="error-message mb30">
+                <p>
+                    <img src="../../../resources/img/component/common/ico_invalid_error_20.svg" alt="">
+                    <span v-if="type === 'id' && step === 1">아이디 찾을 방법을 선택해주세요.</span>
+                    <span v-if="type === 'pw' && step === 1">비밀번호 찾을 방법을 선택해주세요.</span>
+                    <span v-if="type === 'id' && step === 2">아이디를 찾았습니다.</span>
+                    <span v-if="type === 'pw' && step === 2">변경할 비밀번호를 입력해주세요.</span>
+                </p>
+            </div>
+            <div class="find-methods" v-if="step === 1">
+                <div class="form-check">
+                    <input type="radio" id="find-phone" name="find-method" value="phone" v-model="selectedMethod" />
+                    <label for="find-phone">회원 정보에 등록한 휴대전화로 인증</label>
+                    <!-- 휴대폰 인증 영역 -->
+                    <div v-if="selectedMethod === 'phone'" class="auth-form phone-auth">
+                        <p class="warning">회원정보에 등록한 휴대전화 번호와 입력된 휴대전화번호가 같아야, 인증번호를 받을 수 있습니다.</p>
+                        <input type="text" placeholder="아이디" class="form-control sm mb10" v-model="form.loginId"
+                            v-if="type === 'pw'" />
+                        <input type="text" placeholder="이름" class="form-control sm mb10" v-model="form.memberName" />
+                        <div class="input-group mb10">
+                            <input type="tel" placeholder="휴대전화 번호" class="form-control sm "
+                                v-model="form.phoneNumber" />
+                            <button class="btn sm black" @click="findProc">인증번호 받기</button>
+                        </div>
+                        <input type="text" placeholder="인증번호 입력" class="form-control sm"
+                            style="background-color: #ebebeb;" v-model="isValidCode" />
                     </div>
-                    <input type="text" placeholder="인증번호 입력"  class="form-control sm" style="background-color: #ebebeb;"/>
                 </div>
-            </div>
-            <div class="form-check">
-                <input type="radio" id="find-email" name="find-method" value="email"  v-model="selectedMethod"/>
-                <label for="find-email">본인 확인 이메일로 인증</label>
-                <!-- 이메일 인증 영역 -->
-                <div v-if="selectedMethod === 'email'" class="auth-form email-auth">
-                    <!-- <p class="warning">회원정보에 등록한 휴대전화 번호와 입력된 휴대전화번호가 같아야, 인증번호를 받을 수 있습니다.</p> -->
-                    <input type="text" placeholder="이름"  class="form-control sm mb10"/>
-                    <div class="input-group mb10">
-                            <input type="tel" placeholder="이메일 주소"  class="form-control sm "/>
-                            <button class="btn sm black">인증번호 받기</button>
+                <div class="form-check">
+                    <input type="radio" id="find-email" name="find-method" value="email" v-model="selectedMethod" />
+                    <label for="find-email">본인 확인 이메일로 인증</label>
+                    <!-- 이메일 인증 영역 -->
+                    <div v-if="selectedMethod === 'email'" class="auth-form email-auth">
+                        <!-- <p class="warning">회원정보에 등록한 휴대전화 번호와 입력된 휴대전화번호가 같아야, 인증번호를 받을 수 있습니다.</p> -->
+                        <input type="text" placeholder="아이디" class="form-control sm mb10" v-model="form.loginId"
+                            v-if="type === 'pw'" />
+                        <input type="text" placeholder="이름" class="form-control sm mb10" v-model="form.memberName" />
+                        <div class="input-group mb10">
+                            <input type="tel" placeholder="이메일 주소" class="form-control sm " v-model="form.email" />
+                            <button class="btn sm black" @click="findProc">인증번호 받기</button>
+                        </div>
+                        <input type="text" placeholder="인증번호 입력" class="form-control sm"
+                            style="background-color: #ebebeb;" v-model="isValidCode" />
                     </div>
-                    <input type="text" placeholder="인증번호 입력"  class="form-control sm" style="background-color: #ebebeb;"/>
                 </div>
             </div>
-        </div>
-        <div class="find-methods" v-else-if="step === 2">
-            <div v-if="type === 'id'">
-                <div class="input-group">
-                    <label for="id">아이디</label>
-                    <input type="text" id="id" class="form-control sm" disabled/>
+            <div class="find-methods" v-else-if="step === 2">
+                <div v-if="type === 'id'">
+                    <div class="input-group">
+                        <label for="id">아이디</label>
+                        <input type="text" id="id" class="form-control sm" disabled v-model="loginId" />
+                    </div>
+                </div>
+                <div v-else-if="type === 'pw'">
+                    <div class="input-group">
+                        <label for="pw" class="newpw">새 비밀번호</label>
+                        <input type="password" id="pw" placeholder="8-16자의 영문/ 숫자 조합으로 입력해주세요."
+                            class="form-control sm mb10" v-model="password" />
+                    </div>
+                    <div class="input-group">
+                        <label for="pwCk" class="newpw">새 비밀번호 확인</label>
+                        <input type="password" id="pwCk" placeholder="다시 입력해주세요." class="form-control sm mb10"
+                            v-model="passwordCheck" />
+                    </div>
                 </div>
             </div>
-            <div v-else-if="type === 'pw'">
-                <div class="input-group">
-                    <label for="pw" class="newpw">새 비밀번호</label>
-                    <input type="password" id="pw" placeholder="8-16자의 영문/ 숫자 조합으로 입력해주세요." class="form-control sm mb10"/>
-                </div>
-                <div class="input-group">
-                    <label for="pwCk" class="newpw">새 비밀번호 확인</label>
-                    <input type="password" id="pwCk" placeholder="다시 입력해주세요." class="form-control sm mb10"/>
-                </div>
+            <div class="btn-zone">
+                <button class="btn lg netx-btn" @click="checkCode" v-if="isChecking">다음</button>
+                <button class="btn lg netx-btn" @click="checkResult" v-if="!isChecking">확인</button>
             </div>
-        </div>
-        <div class="btn-zone">
-            <button class="btn lg netx-btn" @click="stepGo(2)">다음</button>
-        </div>
 
+        </div>
     </div>
-  </div>
 </template>
 
 <script>
+import { findIdProc, findLoginIdProc, findPasswordProc, updatePasswordProc } from '../../../resources/api/auth';
 
 export default {
     props: ['type'],
@@ -80,35 +91,223 @@
         return {
             step: 1, // 단계 관리 (1: 방법 선택, 2: 인증 입력 등)
             selectedMethod: '', // 선택된 인증 방법
+            form: {
+                memberName: '', // 이름
+                email: '', // 이메일
+                phoneNumber: '', // 폰 번호
+                loginId: '', // 비번 찾기용
+                type: '', // 'email' 또는 'phone'
+            },
+            isValid: false,
+            isValidCode: '',
+            loginId: '',
+            password: null,
+            passwordCheck: null,
+            isChecking: true,
         };
     },
     methods: {
         stepGo() {
             if (this.step === 1 && !this.selectedMethod) {
-                this.$alert({ message: '인증 방법을 선택해주세요.',icon:require('../../../resources/img/component/common/ico_invalid_error_20.svg') });
+                this.$alert({ message: '인증 방법을 선택해주세요.', icon: require('../../../resources/img/component/common/ico_invalid_error_20.svg') });
                 return;
-            }else{
+            } else {
                 this.step = 2; // 다음 단계로 이동
-            }   
+                if (this.type === 'id') {
+                    this.findLoginIdProc();
+                }
+            }
         },
-        certification() {
-            // 인증번호 받기 로직 구현
-            this.$alert(
-                { message: '인증번호가 발송되었습니다.',
-                    icon:require('../../../resources/img/content/ico_certification.svg') ,
-                    subMessage: '인증번호가 오지 않으면 입력하신 정보가 회원정보와 일치하는지 확인해주세요.'
-                 }
-            );
-        }
+
+        // 아이디, 비밀번호 찾기 구분
+        findProc() {
+            if(this.type === 'id') {
+                this.findIdProc();
+            } else if (this.type === 'pw') {
+                this.findPasswordProc();
+            }
+        },
+
+        // 아이디 찾기
+        async findIdProc() {
+            const vm = this;
+            vm.isValid = false;
+
+            // 이메일을 선택했을 때
+            if (vm.selectedMethod === 'email') {
+                if (!vm.form.memberName || !vm.form.email) {
+                    vm.$alert({ message: '이름과 이메일을 입력해주세요.' });
+                    return;
+                }
+
+                vm.form.type = 'email';
+            } else if (vm.selectedMethod === 'phone') {
+                if (!vm.form.memberName || !vm.form.phoneNumber) {
+                    vm.$alert({ message: '이름과 전화번호를 입력해주세요.' });
+                    return;
+                }
+
+                vm.form.type = 'phone';
+            }
+            try {
+                const res = await findIdProc(vm.form);
+                if (res.data.result === 1) {
+                    vm.$alert(
+                        {
+                            message: '인증번호가 발송되었습니다.',
+                            icon: require('../../../resources/img/content/ico_certification.svg'),
+                            subMessage: '인증번호가 오지 않으면 입력하신 정보가 회원정보와 일치하는지 확인해주세요.'
+                        }
+                    );
+                    vm.isValid = true;
+                } else {
+                    vm.$alert(
+                        {
+                            message: '해당 이름과 회원 정보가 없습니다.',
+                            icon: require('../../../resources/img/content/ico_certification.svg'),
+                            subMessage: '입력하신 정보가 회원정보와 일치하는지 다시 확인해주세요.'
+                        }
+                    );
+                }
+            } catch (e) {
+                vm.$alert({ message: '오류가 발생했습니다.' });
+            }
+
+        },
+        // 아이디 가져오기
+        async findLoginIdProc() {
+            const vm = this;
+            try {
+                const res = await findLoginIdProc(vm.form);
+                if (res.data.result) {
+                    vm.loginId = res.data.result;
+                }
+            } catch (e) {
+                vm.$alert({ message: '오류가 발생했습니다.' });
+            }
+
+        },
+
+        // 비밀번호 찾기
+        async findPasswordProc() {
+            const vm = this;
+            vm.isValid = false;
+
+            // 이메일을 선택했을 때
+            if (vm.selectedMethod === 'email') {
+                if (!vm.form.loginId || !vm.form.memberName || !vm.form.email) {
+                    vm.$alert({ message: '아이디와 이름과 이메일을 입력해주세요.' });
+                    return;
+                }
+
+                vm.form.type = 'email';
+            } else if (vm.selectedMethod === 'phone') {
+                if (!vm.form.loginId || !vm.form.memberName || !vm.form.phoneNumber) {
+                    vm.$alert({ message: '아이디와 이름과 전화번호를 입력해주세요.' });
+                    return;
+                }
+
+                vm.form.type = 'phone';
+            }
+            try {
+                const res = await findPasswordProc(vm.form);
+                if (res.data.result === 1) {
+                    vm.$alert(
+                        {
+                            message: '인증번호가 발송되었습니다.',
+                            icon: require('../../../resources/img/content/ico_certification.svg'),
+                            subMessage: '인증번호가 오지 않으면 입력하신 정보가 회원정보와 일치하는지 확인해주세요.'
+                        }
+                    );
+                    vm.isValid = true;
+                } else {
+                    vm.$alert(
+                        {
+                            message: '해당 이름과 회원 정보가 없습니다.',
+                            icon: require('../../../resources/img/content/ico_certification.svg'),
+                            subMessage: '입력하신 정보가 회원정보와 일치하는지 다시 확인해주세요.'
+                        }
+                    );
+                }
+            } catch (e) {
+                vm.$alert({ message: '오류가 발생했습니다.' });
+            }
+
+        },
+
+        // 비밀번호 변경
+        async updatePasswordProc() {
+            const vm = this;
+
+            // 비밀번호 검증
+            const pwRegex = /^[a-zA-Z0-9]{8,16}$/;
+            if (!vm.password || !pwRegex.test(vm.password)) {
+                vm.$alert({ message: '비밀번호는 영문+숫자 조합의 8~16자여야 합니다.' });
+                return;
+            }
+
+            // 비밀번호 확인
+            if (vm.password !== vm.passwordCheck) {
+                vm.$alert({ message: '비밀번호를 다시 입력해주세요.' });
+                return;
+            }
+
+            const passwordData = {
+                loginId: vm.form.loginId,
+                password: vm.password,
+            }
+
+            try {
+                const res = await updatePasswordProc(passwordData);
+                if (res.data.result === 1) {
+                    vm.$alert(
+                        {
+                            message: '비밀번호가 변경되었습니다.',
+                        }
+                    );
+                    vm.$router.push({ path: "/login.page" });
+                }
+            } catch (e) {
+                vm.$alert({ message: '오류가 발생했습니다.' });
+            }
+
+        },
+
+
+        // 인증번호 확인 - 폰 문자 메세지는 비용이 드는 것이기에 임의의 인증번호 6자리만 입력하면 되도록
+        async checkCode() {
+            const vm = this;
+
+            if (vm.isValid) {
+                if (!vm.isValidCode || vm.isValidCode.length != 6) {
+                    vm.$alert({ message: '인증번호를 입력해주세요.' });
+                    return;
+                }
+                vm.isChecking = false;
+                vm.stepGo(2);
+            } else {
+                vm.$alert({ message: '인증번호 받기를 진행해주세요.' });
+            }
+        },
+
+        // 아이디 비밀번호 인증 후의 로직
+        checkResult() {
+            if (this.type === 'id') {
+                this.$router.push({ path: "/login.page" });
+
+            } else if (this.type === 'pw') {
+                this.updatePasswordProc();
+            }
+        },
 
     },
     watch: {},
     computed: {},
     components: {},
-    created() {},
+    created() { },
     mounted() {
     },
-    beforeUnmount() {},
+    beforeUnmount() { },
 };
 
 </script>
(파일 끝에 줄바꿈 문자 없음)
client/views/pages/common/Join.vue
--- client/views/pages/common/Join.vue
+++ client/views/pages/common/Join.vue
@@ -139,9 +139,9 @@
             }
 
             // 비밀번호 검증
-            const pwRegex = /^[a-zA-Z0-9]{3,16}$/;
+            const pwRegex = /^[a-zA-Z0-9]{8,16}$/;
             if (!vm.password || !pwRegex.test(vm.password)) {
-                vm.$alert({ message: '비밀번호는 영문+숫자 조합의 3~16자여야 합니다.' });
+                vm.$alert({ message: '비밀번호는 영문+숫자 조합의 8~16자여야 합니다.' });
                 return;
             }
 
Add a comment
List