File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<div class="login-container">
<div class="login-bg">
<div>
</div>
</div>
<div class="login ">
<div class="logo flex justify-end"><img src="../resources/img/logo.png" alt=""></div>
<div class="join-box">
<div class="flex align-center justify-start mb40">
<img src="../resources/img/icon1.png" alt="" class="mr20">
<h2>회원가입</h2>
</div>
<label class="mr20 title1">
<input type="radio" v-model="selectedTab" value="tab1" />
학생
</label>
<label class="mr20 title1">
<input type="radio" v-model="selectedTab" value="tab2" />
학부모
</label>
<label class="mr20 title1">
<input type="radio" v-model="selectedTab" value="tab3" />
선생님
</label>
<!-- 학생 -->
<div class="login-form mt20" v-if="selectedTab === 'tab1'">
<div class="mb10 flex justify-between align-center">
<p class="title" for="username">아이디</p>
<input type="text" id="username" v-model="userId" placeholder="아이디를 입력하세요.">
</div>
<p class="title2 flex align-center mb20 help" for="username" v-if="!isUserIdValid">
<img src="../resources/img/img194_78p.png" alt="">
<em class="gray ml10">영문, 숫자를 조합하여 주세요 (6자리 이상)</em>
</p>
<p class="title2 flex align-center mb20 help" for="username" v-else>
<img src="../resources/img/img193_78p.png" alt="">
<em class="green ml10">사용 가능한 아이디입니다.</em>
</p>
<div class="flex justify-between align-center mb10">
<p class="title" for="password">비밀번호</p>
<input type="password" id="password" v-model="password" placeholder="비밀번호를 입력하세요.">
</div>
<p class="title2 mb20 flex align-center help" for="password" v-if="!isPasswordValid">
<img src="../resources/img/img194_78p.png" alt="">
<em class="gray ml10">영문, 숫자, 특수문자 3가지를 조합하여 주세요.(6자리 이상)</em>
</p>
<p class="title2 mb20 flex align-center help" for="password" v-else>
<img src="../resources/img/img193_78p.png" alt="">
<em class="green ml10">비밀번호가 유효합니다.</em>
</p>
<div class="flex justify-between align-center mb10">
<p class="title" for="passwordCheck">비밀번호 확인</p>
<input type="password" id="passwordCheck" v-model="passwordCheck" placeholder="비밀번호를 입력하세요.">
</div>
<p class="title2 mb20 flex align-center help" for="passwordCheck"
v-if="!isPasswordMatched || !isPasswordValid">
<img src="../resources/img/img194_78p.png" alt="">
<em class="gray ml10">비밀번호가 일치하지 않습니다.</em>
</p>
<p class="title2 mb20 flex align-center help" for="passwordCheck" v-else>
<img src="../resources/img/img193_78p.png" alt="">
<em class="green ml10">비밀번호가 일치합니다.</em>
</p>
<div class="mb30 flex justify-between align-center">
<p class="title" for="username">이름</p>
<input type="text" id="username" v-model="username" placeholder="이름을 입력하세요.">
</div>
<div class="mb30 flex justify-between align-center">
<p class="title" for="username">전화번호</p>
<div class="flex justify-between align-center" style="width: 100%;"><input style="width: 12rem;"
type="text" id="username" v-model="tel1">
<p class="title2">-</p><input style="width: 14rem;" type="text" id="username" v-model="tel2">
<p class="title2">-</p><input style="width: 14rem;" type="text" id="username" v-model="tel3">
</div>
</div>
<div class="mb30 flex justify-between align-center">
<p class="title" for="username">학교</p>
<div class="search-wrap" style="width: 100%;">
<input type="text" placeholder="검색하세요." disabled v-model="userIns">
<button @click="buttonSearch" type="button" title="위원회 검색">
<img src="../resources/img/look_t.png" alt="">
</button>
</div>
</div>
<div class="mb30 flex justify-between align-center">
<div class="flex justify-between align-center" style="width: 100%;">
<p class="title" for="username"></p>
<input style="width: 12rem;" type="text" id="username" v-model="userGrade" placeholder="학년">
<p class="title2">-</p><input style="width: 14rem;" type="text" id="username" v-model="userClass"
placeholder="반">
<p class="title2">-</p><input style="width: 14rem;" type="text" id="username" v-model="userNumber"
placeholder="번호">
</div>
</div>
<div class="flex justify-end align-center mb10">
<input type="checkbox" class="ui-checkbox mr10">
<p class="title2" for="password">개인정보 수집 동의</p>
</div>
<button style="width: 100%;" class="login-btn mt50" type="submit" @click="submitForm"><img
src="../resources/img/btn_.png" alt="">
<p>회원가입</p>
</button>
</div>
<!-- 학부모 -->
<div class="login-form mt20" v-else-if="selectedTab === 'tab2'">
<div class="mb10 flex justify-between align-center">
<p class="title" for="username">아이디</p>
<input type="text" id="username" v-model="userId" placeholder="아이디를 입력하세요.">
</div>
<p class="title2 flex align-center mb20 help" for="username" v-if="!isUserIdValid">
<img src="../resources/img/img194_78p.png" alt="">
<em class="gray ml10">영문, 숫자를 조합하여 주세요 (6자리 이상)</em>
</p>
<p class="title2 flex align-center mb20 help" for="username" v-else>
<img src="../resources/img/img193_78p.png" alt="">
<em class="green ml10">사용 가능한 아이디입니다.</em>
</p>
<div class="flex justify-between align-center mb10">
<p class="title" for="password">비밀번호</p>
<input type="password" id="password" v-model="password" placeholder="비밀번호를 입력하세요.">
</div>
<p class="title2 mb20 flex align-center help" for="password" v-if="!isPasswordValid">
<img src="../resources/img/img194_78p.png" alt="">
<em class="gray ml10">영문, 숫자, 특수문자 3가지를 조합하여 주세요.(6자리 이상)</em>
</p>
<p class="title2 mb20 flex align-center help" for="password" v-else>
<img src="../resources/img/img193_78p.png" alt="">
<em class="green ml10">비밀번호가 유효합니다.</em>
</p>
<div class="flex justify-between align-center mb10">
<p class="title" for="passwordCheck">비밀번호 확인</p>
<input type="password" id="passwordCheck" v-model="passwordCheck" placeholder="비밀번호를 입력하세요.">
</div>
<p class="title2 mb20 flex align-center help" for="passwordCheck"
v-if="!isPasswordMatched || !isPasswordValid">
<img src="../resources/img/img194_78p.png" alt="">
<em class="gray ml10">비밀번호가 일치하지 않습니다.</em>
</p>
<p class="title2 mb20 flex align-center help" for="passwordCheck" v-else>
<img src="../resources/img/img193_78p.png" alt="">
<em class="green ml10">비밀번호가 일치합니다.</em>
</p>
<div class="mb30 flex justify-between align-center">
<p class="title" for="username">이름</p>
<input type="text" id="username" v-model="username" placeholder="이름을 입력하세요.">
</div>
<div class="mb30 flex justify-between align-center">
<p class="title" for="username">전화번호</p>
<div class="flex justify-between align-center" style="width: 100%;"><input style="width: 12rem;"
type="text" id="username" v-model="tel1">
<p class="title2">-</p><input style="width: 14rem;" type="text" id="username" v-model="tel2">
<p class="title2">-</p><input style="width: 14rem;" type="text" id="username" v-model="tel3">
</div>
</div>
<div class="flex justify-between mb20">
<p class="title " for="username"><em class="yellow">학생 정보</em></p>
<div class="flex justify-end align-center mb10">
<img src="../resources/img/img192_78p.png" alt="" @click="openModal">
<p class="title2 ml10" for="password">자녀 추가하기</p>
</div>
</div>
<div v-if="students.length > 0" class="flex justify-between mb20">
<table class="table-wrap">
<thead style="text-align: center; ">
<tr>
<th>자녀 이름</th>
<th>자녀 아이디</th>
</tr>
</thead>
<tbody>
<tr v-for="(student, index) in students">
<td>{{ student.userNm }}</td>
<td>{{ student.loginId }}</td>
</tr>
</tbody>
</table>
</div>
<div class="mb30 flex justify-between align-center">
<p class="title" for="username">학교</p>
<div class="search-wrap" style="width: 100%;">
<input type="text" placeholder="검색하세요." disabled v-model="userIns">
<button @click="buttonSearch" type="button" title="위원회 검색">
<img src="../resources/img/look_t.png" alt="">
</button>
</div>
</div>
<div class="flex justify-end align-center mb10">
<input type="checkbox" class="ui-checkbox mr10">
<p class="title2" for="password">개인정보 수집 동의</p>
</div>
<button style="width: 100%;" class="login-btn mt50" type="submit" @click="submitForm"><img
src="../resources/img/btn_.png" alt="">
<p>회원가입</p>
</button>
</div>
<!-- 선생님 -->
<div class="login-form mt20" v-else-if="selectedTab === 'tab3'">
<div class="mb10 flex justify-between align-center">
<p class="title" for="username">아이디</p>
<input type="text" id="username" v-model="userId" placeholder="아이디를 입력하세요.">
</div>
<p class="title2 flex align-center mb20 help" for="username" v-if="!isUserIdValid">
<img src="../resources/img/img194_78p.png" alt="">
<em class="gray ml10">영문, 숫자를 조합하여 주세요 (6자리 이상)</em>
</p>
<p class="title2 flex align-center mb20 help" for="username" v-else>
<img src="../resources/img/img193_78p.png" alt="">
<em class="green ml10">사용 가능한 아이디입니다.</em>
</p>
<div class="flex justify-between align-center mb10">
<p class="title" for="password">비밀번호</p>
<input type="password" id="password" v-model="password" placeholder="비밀번호를 입력하세요.">
</div>
<p class="title2 mb20 flex align-center help" for="password" v-if="!isPasswordValid">
<img src="../resources/img/img194_78p.png" alt="">
<em class="gray ml10">영문, 숫자, 특수문자 3가지를 조합하여 주세요.(6자리 이상)</em>
</p>
<p class="title2 mb20 flex align-center help" for="password" v-else>
<img src="../resources/img/img193_78p.png" alt="">
<em class="green ml10">비밀번호가 유효합니다.</em>
</p>
<div class="flex justify-between align-center mb10">
<p class="title" for="passwordCheck">비밀번호 확인</p>
<input type="password" id="passwordCheck" v-model="passwordCheck" placeholder="비밀번호를 입력하세요.">
</div>
<p class="title2 mb20 flex align-center help" for="passwordCheck"
v-if="!isPasswordMatched || !isPasswordValid">
<img src="../resources/img/img194_78p.png" alt="">
<em class="gray ml10">비밀번호가 일치하지 않습니다.</em>
</p>
<p class="title2 mb20 flex align-center help" for="passwordCheck" v-else>
<img src="../resources/img/img193_78p.png" alt="">
<em class="green ml10">비밀번호가 일치합니다.</em>
</p>
<div class="mb30 flex justify-between align-center">
<p class="title" for="username">이름</p>
<input type="text" id="username" v-model="username" placeholder="이름을 입력하세요.">
</div>
<div class="mb30 flex justify-between align-center">
<p class="title" for="username">전화번호</p>
<div class="flex justify-between align-center" style="width: 100%;"><input style="width: 12rem;"
type="text" id="username" v-model="tel1">
<p class="title2">-</p><input style="width: 14rem;" type="text" id="username" v-model="tel2">
<p class="title2">-</p><input style="width: 14rem;" type="text" id="username" v-model="tel3">
</div>
</div>
<div class="mb30 flex justify-between align-center">
<p class="title" for="username">학교</p>
<div class="search-wrap" style="width: 100%;">
<input type="text" placeholder="검색하세요." disabled v-model="userIns">
<button @click="buttonSearch" type="button" title="위원회 검색">
<img src="../resources/img/look_t.png" alt="">
</button>
</div>
</div>
<div class="mb30 flex justify-between align-center">
<p class="title" for="username">이메일</p>
<input type="text" id="username" v-model="email" placeholder="이메일을 입력하세요.">
</div>
<div class="flex justify-end align-center mb10">
<input type="checkbox" class="ui-checkbox mr10">
<p class="title2" for="password">개인정보 수집 동의</p>
</div>
<button style="width: 100%;" class="login-btn mt50" type="submit" @click="submitForm"><img
src="../resources/img/btn_.png" alt="">
<p>회원가입</p>
</button>
</div>
</div>
</div>
</div>
<div v-show="searchOpen" class="popup-wrap">
<div class="popup-box" style="width: 70rem; margin: 0 auto;">
<div class="flex justify-between mb30">
<p class="popup-title">학교 검색</p>
<button type="button" class="popup-close-btn" @click="closeBtn">
<svg-icon type="mdi" :path="mdiWindowClose" class="close-btn"></svg-icon>
</button>
</div>
<div class="mb30 flex justify-between align-center">
<p class="title1" for="username" style="width: 12rem;">시/도</p>
<div class="search-wrap flex justify-end" style="width: 100%;">
<input type="text" placeholder="시도명을 정확하게 입력하세요. (EX : 서울특별시, 경기도)" v-model="searchCity">
</div>
</div>
<div class="mb10 flex justify-between align-center">
<p class="title1" for="username" style="width: 12rem;">학교급</p>
<div class="search-wrap" style="width: 100%;">
<select name="" id="" class="mr10 data-wrap" v-model="searchLevel">
<option value="초등학교">초등학교</option>
<option value="중학교">중학교</option>
<option value="고등학교">고등학교</option>
</select>
</div>
</div>
<div class="mb10 flex justify-between align-center">
<p class="title1" for="username" style="width: 12rem;">학교명</p>
<div class="search-wrap" style="width: 100%;">
<input type="text" placeholder="학교명을 입력하세요." v-model="searchSchoolName">
<button @click="searchSchool" type="button" title="위원회 검색">
<img src="../resources/img/look_t.png" alt="">
</button>
</div>
</div>
<div v-if="schools.length > 0" style="max-height: 400px; overflow-y: auto;">
<table class="table-wrap">
<thead style="text-align: center; ">
<tr>
<th>선택</th>
<th>학교명</th>
<th>학교종류</th>
<th>시도명</th>
</tr>
</thead>
<tbody>
<tr v-for="(school, index) in schools" :key="school.SD_SCHUL_CODE">
<td>
<input type="radio" name="selectedSchool" :value="school" v-model="selectedSchool">
</td>
<td>{{ school.SCHUL_NM }}</td>
<td>{{ school.SCHUL_KND_SC_NM }}</td>
<td>{{ school.LCTN_SC_NM }}</td>
</tr>
</tbody>
</table>
</div>
<p class="title2 mb20 flex align-center help" for="username" style="margin-left: 10rem;"
v-if="schools.length === 0">
<img src="../resources/img/img194_78p.png" alt="">
<em class="gray ml10">학교명을 입력 후 찾기 버튼을 클릭하십시오.</em>
</p>
<div class="flex justify-center ">
<button type="button" title="글쓰기" class="new-btn mr10" @click="closeBtn">
취소
</button>
<button type="button" title="글쓰기" class="new-btn" @click="selectSchool">
학교선택 / Select School
</button>
</div>
</div>
</div>
<div v-show="showModal" class="popup-wrap">
<div class="popup-box" style="width: 70rem; margin: 0 auto;">
<div class="find-form mt30">
<div v-if="!searchResult">
<div class="mb20 flex justify-between align-center">
<p class="title2" for="username" style="width: 12rem;">자녀 이름</p>
<input class="data-wrap" type="text" id="username" v-model="findUserNm" placeholder="이름을 입력하세요."
style="width: 45rem;">
</div>
<div class="mb30 flex justify-between align-center">
<p class="title2" for="username" style="width: 12rem;">자녀 전화번호</p>
<div class="flex justify-between align-center"><input class="data-wrap" style="width: 14rem;"
type="text" id="username" v-model="findTel1">
<p class="title2">-</p><input class="data-wrap" style="width: 14rem;" type="text" id="username"
v-model="findTel2">
<p class="title2">-</p><input class="data-wrap" style="width: 14rem;" type="text" id="username"
v-model="findTel3">
</div>
</div>
<div class="flex justify-center ">
<button type="button" title="글쓰기" class="new-btn mr10" @click="closeModal">
취소
</button>
<button @click="findId" type="button" title="글쓰기" class="new-btn">
찾기
</button>
</div>
</div>
<div v-else>
<div class="flex justify-center mt30">
<p class="title2">자녀 찾기가 완료 되었습니다.</p>
</div>
<table class="table-wrap mt30 mb30">
<tr>
<td class="thead">이름</td>
<td>{{ findUserInfo.userNm }}</td>
</tr>
<tr>
<td class="thead">아이디</td>
<td>{{ findUserInfo.loginId }}</td>
</tr>
</table>
<div class="flex justify-center ">
<button @click="closeModal" type="button" title="글쓰기" class="new-btn">
추가하기
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import SvgIcon from '@jamescoyle/vue-icon';
import { mdiMagnify, mdiWindowClose } from '@mdi/js';
import axios from "axios";
export default {
data() {
return {
mdiWindowClose: mdiWindowClose,
userId: '',
username: '',
password: '',
passwordCheck: '',
tel1: '',
tel2: '',
tel3: '',
findUserNm: '',
findTel1: '',
findTel2: '',
findTel3: '',
userGrade: '',
userClass: '',
userNumber: '',
userIns: '',
email: null,
selectedTab: 'tab1', // 초기 선택 탭
showModal: false,
searchOpen: false,
searchCity: '',
searchLevel: '초등학교', // 기본값 설정
searchSchoolName: '',
schools: [],
students: [],
selectedSchool: null, // 선택된 학교
searchResult: false,
findUserInfo: {},
}
},
methods: {
submitForm() {
const vm = this;
const passwordPattern = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{6,}$/;
if (!vm.userId) {
alert("로그인 아이디가 비어 있습니다!");
return;
}
if (!vm.password) {
alert("비밀번호가 비어 있습니다!");
return;
}
if (vm.password !== vm.passwordCheck) {
alert("비밀번호가 일치하지 않습니다.");
return;
}
if (!passwordPattern.test(vm.password)) {
alert("비밀번호는 영문, 숫자, 특수문자를 조합하여 6자리 이상이어야 합니다.");
return;
}
if (!vm.username) {
alert("유저 이름이 비어 있습니다!");
return;
}
if (!vm.tel1 && !vm.tel2 && !vm.tel3) {
alert("전화번호가 비어 있습니다!");
return;
}
const telno = vm.tel1 + '-' + vm.tel2 + '-' + vm.tel3;
let auth = null;
if (vm.selectedTab === 'tab1') {
auth = 'STUDENT'
} else if (vm.selectedTab === 'tab2') {
auth = 'PARENT'
} else if (vm.selectedTab === 'tab3') {
auth = 'TEACHER'
}
axios({
url: "/auth/insertUser.json",
method: "post",
data: {
loginId: vm.userId,
password: vm.password,
userNm: vm.username,
email: vm.email,
telno: telno,
authcd: auth
},
}).then(function (response) {
if (response.data.status === 'success') {
alert("회원가입에 성공했습니다!")
vm.goToApp();
} else {
alter("입력창을 다시 확인해주세요!")
}
}).catch(function (error) {
});
},
// 학교 찾기
searchSchool() {
if (!this.searchSchoolName) {
alert("학교명을 입력해주세요!");
return;
}
axios({
url: "https://open.neis.go.kr/hub/schoolInfo",
method: "get",
params: {
KEY: "51f16da8aa344339a49812c23bcedb24", // 인증키를 넣어주세요
Type: "json",
pIndex: 1,
pSize: 100,
SCHUL_NM: this.searchSchoolName,
LCTN_SC_NM: this.searchCity,
SCHUL_KND_SC_NM: this.searchLevel
},
}).then(response => {
const data = response.data.schoolInfo;
if (data && data[1] && data[1].row) {
this.schools = data[1].row; // 학교 정보를 schools에 저장
} else {
alert("검색된 학교가 없습니다");
this.schools = []; // 결과가 없을 경우 빈 배열로 초기화
}
}).catch(error => {
console.error(error);
});
},
selectSchool() {
if (this.selectedSchool) {
this.userIns = this.selectedSchool.SCHUL_NM; // 선택된 학교 이름 정보를 userIns에 저장
this.closeBtn(); // 팝업 닫기
} else {
alert("학교를 선택해 주세요.");
}
},
// 자녀 찾기
findId() {
const vm = this;
const telno = vm.findTel1 + '-' + vm.findTel2 + '-' + vm.findTel3;
axios({
url: "/auth/findId.json",
method: "post",
data: {
telno: telno,
userNm: vm.findUserNm,
},
}).then(function (response) {
vm.findUserInfo = response.data;
vm.searchResult = true;
}).catch(function (error) {
alert("등록되지 않은 자녀입니다!");
console.log(error);
});
},
goToApp() {
this.$router.push('/Login.page');
},
openModal() {
this.showModal = true;
},
closeModal() {
if (Object.keys(this.findUserInfo).length > 0) {
const isDuplicate = this.students.some(student => student.loginId === this.findUserInfo.loginId);
if (!isDuplicate) {
this.students.push(this.findUserInfo);
} else {
alert("이미 추가된 학생입니다.");
}
}
this.searchResult = false;
this.findUserInfo = null;
this.showModal = false;
},
buttonSearch() {
this.searchOpen = true;
},
closeBtn() {
this.searchOpen = false;
},
},
computed: {
isUserIdValid() {
// 사용자 아이디 유효성 검사 (예: 6자 이상, 영어와 숫자)
const regex = /^[a-zA-Z0-9]{6,}$/;
return regex.test(this.userId);
},
isPasswordValid() {
// 비밀번호 유효성 검사 (예: 6자 이상, 영문, 숫자, 특수문자 포함)
const regex = /^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{6,}$/;
return regex.test(this.password);
},
isPasswordMatched() {
// 비밀번호 확인 일치 여부
return this.password === this.passwordCheck;
}
},
components: {
SvgIcon
},
}
</script>
<style scoped></style>