
File name
Commit message
Commit date
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-zone sch-full">
<div class="content">
<div class="scroll">
<div class="form-box">
<div class="form-box-title">
<p>기본정보</p>
<p><span>*</span>필수입력</p>
</div>
<div class="form-content">
<div class="layout">
<label class="form-title"><span>*</span> 아이디</label>
<input
type="text"
class="form-control sm"
v-model="mbrVO.lgnId"
ref="mbrId"
minlength="5"
maxlength="50"
placeholder="아이디를 입력하세요."
:disabled="mbrVO.mbrId != null"
/>
</div>
<div class="layout">
<label class="form-title"><span>*</span> 이름</label>
<input
type="text"
class="form-control sm"
ref="mbrNm"
v-model="mbrVO.mbrNm"
minlength="2"
maxlength="50"
placeholder="이름을 입력하세요."
/>
</div>
<div class="layout">
<label class="form-title">
<p v-if="pageId == null"><span>*</span> 비밀번호</p>
<p v-else>비밀번호변경</p>
</label>
<div class="form-group">
<input
type="password"
class="form-control sm"
ref="newPswd"
v-model="pswd.newPswd"
minlength="9"
placeholder="영문, 숫자, 특수문자 조합 9자 이상"
/>
<span
:class="{
'red-text': pswd.errorPwd,
}"
>
영문, 숫자, 특수문자를 조합하여 입력해주세요. (9자 이상)
</span>
</div>
</div>
<div class="layout">
<label class="form-title">
<p v-if="pageId == null"><span>*</span> 비밀번호확인</p>
<p v-else>비밀번호변경 확인</p>
</label>
<input
type="password"
:class="{ 'form-control sm': true, 'error': pswd.pswdChk }"
ref="newPswdChk"
v-model="pswd.newPswdChk"
minlength="9"
:placeholder="
pageId == null
? '비밀번호 확인을 입력하세요.'
: '변경할 비밀번호 확인을 입력하세요'
"
/>
</div>
<template v-if="showOpt.isMblNo || showOpt.isTelNo">
<div v-if="showOpt.isMblNo" class="layout">
<label class="form-title"><span>*</span> 휴대폰번호</label>
<input
type="text"
class="form-control sm"
ref="mblTelno"
v-model="mbrVO.mblTelno"
minlength="10"
maxlength="11"
oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\.*)/g, '');"
placeholder="휴대폰번호를 입력하세요."
/>
</div>
</template>
<div v-if="showOpt.isTelNo" class="layout">
<label class="form-title">전화번호</label>
<input
type="text"
class="form-control sm"
ref="telno"
v-model="mbrVO.telno"
oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\.*)/g, '');"
placeholder="전화번호를 입력하세요."
/>
</div>
<template v-if="showOpt.isEml || showOpt.isSmsAgree || showOpt.isEmlAgree">
<div v-if="showOpt.isEml" class="layout">
<label class="form-title"><span>*</span> 이메일</label>
<div class="check-area">
<input
type="text"
class="form-control sm"
ref="emailId"
v-model="email.id"
oninput="this.value =
this.value.replace(/[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g, '');"
placeholder="이메일을 입력하세요."
/>
<div>@</div>
<template v-if="email.select == 'self'">
<input
type="text"
class="form-control sm"
ref="emailAddress"
v-model="email.address"
/>
</template>
<select
class="form-select sm"
ref="emailSelect"
v-model="email.select"
>
<option value="">선택하세요</option>
<option value="self">직접입력</option>
<option value="naver.com">naver.com</option>
<option value="google.com">google.com</option>
<option value="hanmail.net">hanmail.net</option>
<option value="nate.com">nate.com</option>
<option value="kakao.com">kakao.com</option>
</select>
</div>
</div>
<div v-if="showOpt.isSmsAgree" class="layout">
<label class="form-title"><span>*</span>
문자수신
</label>
<div class="check-area">
<div class="form-check">
<input
type="radio"
name="smsRcptnAgreYn"
id="smsY"
class="mr5"
v-model="mbrVO.smsRcptnAgreYn"
value="Y"
/>
<label for="smsY">수신</label>
</div>
<div class="form-check">
<input
type="radio"
name="smsRcptnAgreYn"
id="smsN"
class="mr5"
v-model="mbrVO.smsRcptnAgreYn"
value="N"
/>
<label for="smsN">미수신</label>
</div>
</div>
</div>
<div v-if="showOpt.isEmlAgree" class="layout">
<label class="form-title"><span>*</span>
이메일수신
</label>
<div class="check-area">
<div class="form-check">
<input
type="radio"
name="emlRcptnAgreYn"
id="y"
class="mr5"
v-model="mbrVO.emlRcptnAgreYn"
value="Y"
/>
<label for="y">수신</label>
</div>
<div class="form-check">
<input
type="radio"
name="emlRcptnAgreYn"
id="n"
class="mr5"
v-model="mbrVO.emlRcptnAgreYn"
value="N"
/>
<label for="n">미수신</label>
</div>
</div>
</div>
</template>
<template v-if="showOpt.isAddr">
<div class="layout">
<label class="form-title"><span>*</span> 우편번호</label>
<input
type="text"
class="form-control sm"
v-model="mbrVO.zip"
readonly
/>
<button
:class="{
'large-btn': true,
'blue-border-btn': pageRole == 'adm',
'green-border-btn': pageRole == 'portal',
}"
@click="fnZipSearch"
>
찾기
</button>
</div>
<div class="layout">
<label class="form-title"><span>*</span> 주소</label>
<input
type="text"
class="form-control sm"
v-model="mbrVO.addr"
readonly
/>
</div>
<div class="layout">
<label class="form-title">
상세주소
</label>
<input
type="text"
class="form-control sm"
ref="daddr"
v-model="mbrVO.daddr"
placeholder="상세주소를 입력하세요."
/>
</div>
</template>
<template v-if="showOpt.isStts && pageRole == 'adm'">
<div class="layout">
<label class="form-title"><span>*</span> 회원상태</label>
<select class="form-select sm" v-model="mbrVO.mbrStts">
<option value="1">승인</option>
<option value="2">승인대기</option>
<option value="0">탈퇴</option>
<option value="3">차단</option>
</select>
</div>
<div class="layout" v-if="showOpt.isCntrlDt">
<label class="form-title">차단일</label>
<input
type="date"
class="form-control sm"
ref="cntrlDt"
v-model="mbrVO.cntrlDt"
/>
</div>
</template>
<div class="layout" v-if="showOpt.isCntrlRsn">
<label class="form-title">차단 사유</label>
<input
type="text"
class="form-control sm"
ref="cntrlRsn"
v-model="mbrVO.cntrlRsn"
placeholder="차단 사유를 입력하세요."
/>
</div>
<div v-if="showOpt.isAuthor && pageRole == 'adm'" class="layout">
<UserAuthorList :mbrVO="mbrVO" />
</div>
</div>
</div>
</div>
</div>
</div>
<div class="btn-wrap">
<button
:class="{
'btn sm main': true,
// 'blue-btn': pageRole == 'adm',
// 'green-btn': pageRole == 'portal',
}"
@click="fnUpsert"
>
{{ pageId == null ? "등록" : "수정" }}
</button>
<button class="btn sm tertiary" @click="fnCancel">취소</button>
</div>
</template>
<script>
// RESOURCES
import {
defaultAdminInfoParams,
defaultUserInfoParams,
} from "../../../resources/js/defaultUserInfoParams";
import validateParams from "../../../resources/js/validateParams";
// COMPONENT
import UserAuthorList from "./UserAuthorList.vue";
// API
import {
mbrDetailProc,
mbrInsertProc,
mbrUpdateProc,
} from "../../../resources/api/mbrInfo";
export default {
mixins: [validateParams],
components: { UserAuthorList },
props: {
pageId: {
type: String,
},
pageNm: {
type: String,
default: "user",
},
pageTit: {
type: String,
required: true,
},
},
data() {
return {
pageRole: this.$store.state.userType, // 유저 권한
mbrVO: {},
showOpt: { ...defaultUserInfoParams }, // 유저정보 표시 여부 객체
pswd: {
newPswd: null,
newPswdChk: null,
errorPwd: null,
pswdChk: null,
},
email: {
id: null,
select: "",
address: null,
},
};
},
created() {
this.fnMbrViewDetail();
if (this.pageNm == "adm" && this.pageRole == "adm") {
this.showOpt = defaultAdminInfoParams;
}
},
computed: {
routerPaths() {
return {
list: this.$store.state.path + "/list.page",
view: this.$store.state.path + "/view.page",
insert: this.$store.state.path + "/insert.page",
};
},
},
methods: {
// axios: 사용자 정보 상세 조회
async fnMbrViewDetail() {
// 데이터 세팅
const data = { mbrId: this.pageId };
// 실행
try {
const response = await mbrDetailProc(data);
if (this.pageRole == "portal") {
for (let author of response.data.data.authorList) {
if (author.authrtCd == "ROLE_ADMIN") {
this.showOpt = defaultAdminInfoParams;
}
}
}
this.mbrVO = response.data.data;
let authorCount = response.data.data.authorList.length;
if (authorCount < 1) {
if (!this.showOpt.isAuthor) {
this.mbrVO.authorList = [
{
authrtNm: "관리자",
authrtCd: "ROLE_ADMIN",
},
];
} else {
this.mbrVO.authorList = [
{
authrtNm: "사용자",
authrtCd: "ROLE_USER",
},
];
}
}
this.changeFormat(); // 휴대폰번호, 전화번호, 이메일 표기변경
} catch (error) {
alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
}
},
// 표기변경
changeFormat() {
// 휴대폰 번호
let mblNo = this.mbrVO.mblTelno;
if (mblNo != null) {
this.mbrVO.mblTelno = mblNo.replace(/[^0-9]/g, "");
}
// 전화번호
let telNo = this.mbrVO.telno;
if (telNo != null) {
this.mbrVO.telno = telNo.replace(/[^0-9]/g, "");
}
// 이메일
if (this.mbrVO.eml != null) {
const email = this.mbrVO.eml.split("@");
this.email.id = email[0];
switch (email[1]) {
case "naver.com":
case "google.com":
case "hanmail.net":
case "nate.com":
case "kakao.com":
this.email.select = email[1];
break;
default:
this.email.select = "self";
this.email.address = email[1];
break;
}
}
},
// 비밀번호변경 검증
pswdCheck() {
console.log("비밀번호: ", this.pswd.newPswd);
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;
}
},
// 우편번호 찾기 버튼
fnZipSearch() {
let width = 500; //팝업의 너비
let height = 600; //팝업의 높이
new window.daum.Postcode({
oncomplete: (data) => {
width: width;
height: height;
this.mbrVO.zip = data.zonecode;
this.mbrVO.addr = data.roadAddress;
},
}).open({
left: window.screen.width / 2 - width / 2,
top: window.screen.height / 2 - height / 2,
});
},
// axios: 등록 및 수정
async fnUpsert() {
// 유효성검사
if (!this.validation()) {
return;
}
// 데이터 세팅
let data = this.mbrVO;
this.fnDataSetting(data);
const proc = this.pageId == null ? mbrInsertProc : mbrUpdateProc;
// 실행
try {
const response = await proc(data);
alert(response.data.message);
this.$router.push({
path: this.routerPaths.view,
query: {
pageId:
this.pageId == null ? response.data.data.mbrId : this.pageId,
},
});
} catch (error) {
const errorData = error.response.data;
if (errorData.message != null && errorData.message != "") {
alert(error.response.data.message);
} else {
alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
}
}
},
// 데이터 세팅
fnDataSetting(data) {
// 비밀번호
if (this.pswd.newPswd != null && this.pswd.newPswd != "") {
data.pswd = this.pswd.newPswd.replace(/(\s*)/g, "");
} else {
data.pswd = null;
}
// 이메일
data.eml = this.emailSum();
// 회원 상태가 차단이 아니면 차단일, 차단 사유 삭제
if (data.mbrStts != 3) {
data.cntrlDt = null;
data.cntrlRsn = null;
}
},
// 유효성검사
validation() {
// 아이디
if (!this.validateId(this.mbrVO.lgnId)) {
return false;
}
// 이름
if (!this.validateNm(this.mbrVO.mbrNm)) {
return false;
}
// 비밀번호
if (!this.validatePswd(this.pageId, this.pswd)) {
return false;
}
// 휴대폰번호
if (this.showOpt.isMblNo) {
if (!this.validateMblNo(this.mbrVO.mblTelno)) {
return false;
}
}
// 이메일
if (this.showOpt.isEml) {
if (!this.validateEml(this.email)) {
return false;
}
}
// 문자수신
if (this.showOpt.isSmsAgree) {
if (!this.validateSmsAgre(this.mbrVO.smsRcptnAgreYn)) {
return false;
}
}
// 이메일수신
if (this.showOpt.isEmlAgree) {
if (!this.validateEmlAgre(this.mbrVO.emlRcptnAgreYn)) {
return false;
}
}
// 주소
if (this.showOpt.isAddr) {
if (!this.validateAddr(this.mbrVO)) {
return false;
}
}
if (this.pageRole == "adm") {
if (this.showOpt.isAuthor) {
// 회원상태: 차단
if (this.showOpt.isStts) {
if (!this.validateBlock(this.mbrVO)) {
return false;
}
}
// 사용자 권한
if (this.mbrVO.authorList.length < 1) {
alert("사용자의 권한을 최소 1개 이상 추가하세요.");
return false;
}
}
}
return true;
},
// 이메일 합체
emailSum() {
if (this.email.select != "self") {
return this.email.id + "@" + this.email.select;
} else {
return this.email.id + "@" + this.email.address;
}
},
// 취소
fnCancel() {
const isCheck = confirm("작성을 취소하시겠습니까?");
if (isCheck) {
if (this.pageRole != "adm") {
this.$router.push({
path: this.routerPaths.view,
});
} else {
this.$router.push({
path: this.routerPaths.list,
});
}
}
},
},
watch: {
// 비밀번호변경 감시
"pswd.newPswd"() {
this.pswdCheck();
this.pswdChkCheck();
},
// 비밀번호변경확인 감시
"pswd.newPswdChk"() {
this.pswdChkCheck();
},
// 회원상태 감시
"mbrVO.mbrStts"() {
if (this.mbrVO.mbrStts == 3) {
this.mbrVO.cntrlDt = new Date().toISOString().substring(0, 10);
this.$refs.cntrlRsn.focus();
} else {
this.mbrVO.cntrlDt = null;
this.mbrVO.cntrlRsn = null;
}
},
},
};
</script>