
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="container">
<div class="page-titleZone flex justify-between align-center">
<p class="main-title flex80">사용자 관리</p>
<PageNavigation />
</div>
<div class="content-wrap">
<div class="content content-box flex100">
<div class="column-list">
<div class="content-titleZone flex justify-between align-center">
<p class="box-title">사용자 목록</p>
<div class="search-bar">
<div class="flex justify-end align-center">
<select class="square-select" v-model="search_data.key">
<option :value="null">선택</option>
<option value="ui.user_id">아이디</option>
<option value="ui.user_nm">이름</option>
<option value="orgnzt_info.dept_nm">부서</option>
</select>
<div class="search-square">
<div class="flex justify-end align-center no-gutter">
<input type="text" class="square-input flex90" placeholder="검색어를 입력해 주세요." v-model="search_data.value" @keyup.enter="fnSelectUserList" />
<button class="square-button blue-btn flex10" @click="fnSelectUserList">
<svg-icon type="mdi" :path="searchPath" class="square-icon"></svg-icon>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="flex justify-between align-center">
<div class="count-zone">
<p>총 <span>{{ userList.length }}</span>건 중 <span>{{ userSelectList.length }}</span>건 선택</p>
</div>
<div class="cunt-selectZone">
<select v-model="search.perPage" @change="fnSelectUserList">
<option value="10">10개 보기</option>
<option value="20">20개 보기</option>
</select>
</div>
</div>
<div class="table-zone">
<table class="list-table">
<colgroup>
<col style="width: 5%" />
<col style="width: 5%" />
<col style="width: 17%" />
<col style="width: 17%" />
<col style="width: 17%" />
<col style="width: 17%" />
<col style="width: 17%" />
<col style="width: 5%" />
</colgroup>
<thead>
<tr>
<th>
<input type="checkbox" v-model="isChkAll" @change="fnChkAll()" />
</th>
<th>번호</th>
<th>아이디</th>
<th>이름</th>
<th>이메일</th>
<th>부서</th>
<th>등록날짜</th>
<th>잠김여부</th>
</tr>
</thead>
<tbody>
<template v-if="userList.length > 0">
<tr v-for="(item, idx) in userList" :key="idx" @click="fnSelectUser(item.userId)">
<td>
<input type="checkbox" :value="item" v-model="userSelectList" @click.stop="" @change="fnChangeChk" />
</td>
<td>{{ search.totalRows - idx - (search.currentPage - 1) * search.perPage }}</td>
<td>{{ item.userId }}</td>
<td>{{ item.userNm }}</td>
<td>{{ item.userEmail }}</td>
<td>{{ item.deptNm }}</td>
<td>{{ $filters.dateTime(item.creatDt) }}</td>
<td>{{ item.lockAt ? "잠금" : "-" }}</td>
</tr>
</template>
<tr v-else>
<td colspan="8">등록된 데이터가 없습니다.</td>
</tr>
</tbody>
</table>
</div>
<div class="flex justify-end">
<button class="red-border-btn small-btn" @click="fnDeleteUser">선택 삭제</button>
</div>
<PaginationButton v-model:currentPage="search.currentPage" :perPage="search.perPage" :totalCount="search.totalRows" :maxRange="5" :click="fetchMemberList" />
</div>
<div class="data-set">
<div class="form-box">
<div class="content-titleZone">
<p class="box-title" v-if="editMode == 'create'">사용자 등록</p>
<p class="box-title" v-else>사용자 수정</p>
</div>
<div class="table-zone">
<table class="form-table2">
<colgroup>
<col style="width: 10%" />
<col style="width: 40%" />
<col style="width: 10%" />
<col style="width: 40%" />
</colgroup>
<tbody>
<tr>
<th>아이디</th>
<td style="display: flex">
<input type="text" class="full-input" v-model="currentUser.userId" :disabled="editMode == 'update'" />
<button class="small-btn blue-border-btn" style="flex-grow: 1" v-if="editMode == 'create'" @click="fnDuplicateChk('id')">중복확인</button>
</td>
<th>이름</th>
<td>
<input type="text" class="full-input" v-model="currentUser.userNm" />
</td>
</tr>
<tr v-if="editMode == 'create'">
<th>비밀번호</th>
<td>
<input type="password" class="full-input" style="width: 100%" v-model="currentUser.userPassword" />
</td>
<th>비밀번호 확인</th>
<td>
<input type="password" class="full-input" style="width: 100%" v-model="userPasswordConfirm" />
</td>
</tr>
<tr>
<th>이메일</th>
<td style="display: flex">
<input type="text" class="full-input" v-model="currentUser.userEmail" />
<button class="small-btn blue-border-btn" style="flex-grow: 1" @click="fnDuplicateChk('email')">중복확인</button>
</td>
<th>부서</th>
<td>
<select class="full-select" v-model="currentUser.dept_code">
<option :value="null" disabled>부서를 선택해주세요.</option>
<option v-for="(item, idx) in deptList" :key="idx" :value="item.dept_code"> {{ item.dept_nm }} </option>
</select>
</td>
</tr>
<tr v-if="editMode == 'update'">
<th>잠김여부</th>
<td style="display: flex">
<input type="text" class="full-input" :value="currentUser.lockAt ? '잠금 (사용불가)' : '미잠금 (사용가능)'" readonly>
<button class="blue-border-btn small-btn" style="flex-grow: 1" v-if="currentUser.lockAt" @click="fnUpdateUserLockAt">잠금해제</button>
</td>
<th></th>
<td></td>
</tr>
</tbody>
</table>
</div>
<div class="flex justify-end">
<button class="blue-border-btn small-btn" v-if="editMode == 'update'" @click="fnOpenModal">비밀번호 변경</button>
<button class="blue-btn small-btn" v-if="editMode == 'create'" @click="fnInsertUser">등록</button>
<button class="blue-btn small-btn" v-else @click="fnUpdateUser">수정</button>
<button class="blue-border-btn small-btn" @click="fnCancel">취소</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 비밀번호 변경 모달 -->
<div v-show="modalOpen" class="modal-wrapper">
<div class="modal-container small-modal">
<div class="modal-title">
<div class="flex justify-between align-center">
<h2>비밀번호 변경</h2>
<button class="close-btn" @click="fnCloseModal">X</button>
</div>
</div>
<div class="modal-content-monthly">
<div class="table-zone">
<table class="form-table">
<colgroup>
<col style="width: 40%" />
<col style="width: 60%" />
</colgroup>
<tbody>
<tr>
<th>새 비밀번호</th>
<td>
<input type="password" class="full-input" v-model="userPassword" />
</td>
</tr>
<tr>
<th>새 비밀번호 확인</th>
<td>
<input type="password" class="full-input" v-model="userPasswordConfirm" />
</td>
</tr>
</tbody>
</table>
<div class="modal-end flex justify-between" style="flex-wrap: nowrap;">
<button class="blue-btn large-btn" @click="fnUpdateUserPassword">수정</button>
<button class="blue-border-btn small-btn" @click="fnCancel"><span v-if="editMode == 'create'">초기화</span><span v-else>취소</span></button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
// icon용 svg import
import SvgIcon from "@jamescoyle/vue-icon";
import { mdiMagnify, mdiClose } from "@mdi/js";
// 컴포넌트 import
import PageNavigation from "../../component/PageNavigation.vue";
import PaginationButton from "../../component/PaginationButton.vue";
export default {
components: { SvgIcon, PageNavigation, PaginationButton },
data() {
return {
// icon용 svg path
closePath: mdiClose,
searchPath: mdiMagnify,
// 검색
search: this.$getDefaultSerchVO(),
search_data: this.$getDefaultSerchItem(null, "string"),
// default
editMode: 'create',
memberVO: {},
originUser: {},
currentUser: {},
userPassword: null,
userPasswordConfirm: null,
isChkAll: false,
userList: [],
userSelectList: [],
deptList: [],
// 비밀번호 변경
modalOpen: false,
// 중복검사
isIdChk: false,
isEmailChk: false,
};
},
mounted() {
this.fnSelectUser(); // 사용자 상세 조회
this.fnSelectUserList(); // 사용자 목록 조회
this.fnSelectDeptList(); // 부서 목록 조회
},
watch: {
//아이디 값 변경 시 중복 검사 false로 변경
"currentUser.userId"() {
this.isIdChk = false;
},
//이메일 값 변경 시 중복 검사 false로 변경
"currentUser.userEmail"() {
this.isEmailChk = false;
},
},
methods: {
// 사용자 목록 조회
fnSelectUserList() {
const vm = this;
// 데이터 세팅
let data = vm.search;
data.searchObjectList = []; // 초기화
data.searchObjectList.push(vm.search_data);
// 실행
axios({
url: "/member/list",
method: "post",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: data,
})
.then(response => {
if (response.data != null) {
vm.userList = response.data.resultData.members;
vm.search = response.data.resultData.searchVO;
} else {
this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
}
})
.catch(error => {
vm.$showAlert("사용자 관리", "목록 불러오기 오류, 관리자에게 문의바랍니다.");
});
},
// 사용자 목록 전체 선택
fnChkAll() {
if (this.isChkAll) {
this.userSelectList = this.userList;
} else {
this.userSelectList = [];
}
},
// 사용자 목록 상세 선택
fnChangeChk() {
if (this.userSelectList.length == this.userList.length) {
this.isChkAll = true;
} else {
this.isChkAll = false;
}
},
// 사용자 선택 삭제
async fnDeleteUser() {
const vm = this;
// 선택 목록 확인
if (vm.userSelectList.length === 0) {
vm.$showAlert("사용자 관리", "선택한 사용자가 없습니다.");
return;
}
// 삭제 확인
if (!(await vm.$showConfirm("사용자 관리", "선택한 사용자를 삭제하시겠습니까?"))) {
return;
}
// 실행
axios({
url: "/member",
method: "delete",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: vm.userSelectList,
})
.then(response => {
if (response.data.checkMessage.status === 200) {
vm.$showAlert("사용자 관리", "선택한 사용자가 삭제되었습니다.");
// 삭제 후 작업
vm.isChkAll = false; // 체크 박스 리셋
vm.userSelectList = []; // 사용자 선택 목록 초기화
vm.fnSelectUserList(); // 전체 재조회
} else {
vm.$showAlert("사용자 관리", response.data.checkMessage.message);
}
})
.catch(error => {
vm.$showAlert("사용자 관리", "처리 중 오류가 발생했습니다. 관리자에게 문의바랍니다.");
});
},
// 부서 목록 조회
fnSelectDeptList() {
const vm = this;
// 데이터 세팅
let search = Object.assign({}, this.$getDefaultSerchVO());
search.currentPage = 0;
search.perPage = 0;
// 실행
axios({
url: "/department/departments",
method: "post",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: search,
})
.then(response => {
if (response.data != null) {
vm.deptList = response.data.resultData.selectDeptList;
} else {
this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
}
})
.catch(error => {
vm.$showAlert("사용자 관리", "목록 불러오기 오류, 관리자에게 문의바랍니다.");
});
},
// 사용자 등록
fnInsertUser() {
const vm = this;
// 유효성 검사
if (!vm.insertValidation()) {
return;
}
// 실행
axios({
url: "/member",
method: "post",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: vm.currentUser,
})
.then(response => {
if (response.data.checkMessage.status === 200) {
vm.$showAlert("사용자 관리", "사용자 등록이 완료되었습니다.");
vm.currentUser = Object.assign({}, vm.memberVO); // 초기화
vm.fnSelectUserList();
} else {
vm.$showAlert("사용자 관리", response.data.checkMessage.message);
}
})
.catch(error => {
vm.$showAlert("사용자 관리", "사용자 등록에 실패했습니다. 다시 시도해주세요.");
});
},
// 사용자 상세 조회
fnSelectUser(userId) {
const vm = this;
// 데이터 세팅
let url = null;
if (vm.$isEmpty(userId)) {
url = "/member/selectUser";
} else {
url = "/member/selectUser/" + userId;
}
// 실행
axios({
url: url,
method: "post",
headers: { "Content-Type": "application/json; charset=UTF-8" },
})
.then(response => {
if (vm.$isEmpty(userId)) {
vm.memberVO = response.data;
} else {
vm.editMode = 'update';
vm.originUser = response.data;
vm.currentUser = Object.assign({}, response.data);
}
})
.catch(error => {
vm.$showAlert("사용자 관리", "불러오기 오류, 관리자에게 문의바랍니다.");
});
},
// 사용자 수정
fnUpdateUser() {
const vm = this;
// 유효성 검사
if (!vm.updateValidation()) {
return;
}
// 실행
axios({
url: "/member",
method: "put",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: vm.currentUser
})
.then(response => {
if (response.data.checkMessage.status === 200) {
vm.$showAlert("사용자 관리", "사용자 정보가 수정되었습니다.");
vm.originUser = Object.assign({}, vm.memberVO); // 초기화
vm.currentUser = Object.assign({}, vm.memberVO); // 초기화
vm.editMode = 'create';
vm.fnSelectUserList();
} else {
vm.$showAlert("사용자 관리", response.data.checkMessage.message);
}
})
.catch(error => {
vm.$showAlert("사용자 관리", "수정 오류, 관리자에게 문의해주세요.");
});
},
// 중복확인 버튼 동작
fnDuplicateChk(type) {
if (type == 'id') {
this.idDuplicateChk();
} else if (type == 'email') {
this.emailDuplicateChk();
}
},
// 아이디 중복 검사
idDuplicateChk() {
const vm = this;
// 유효성 검사
if (!vm.$idCheck(vm.currentUser.userId)) {
vm.$showAlert("사용자 관리", "아이디 형식이 올바르지 않습니다. (5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용가능)");
return false;
}
// 실행
axios({
url: "/member/" + vm.currentUser.userId,
method: "get",
headers: { "Content-Type": "application/json; charset=UTF-8" },
})
.then(response => {
if (response.data.resultData.checkDuplicateUserId) {
vm.isIdChk = false;
vm.$showAlert("사용자 관리", "사용중인 아이디입니다.");
} else {
vm.isIdChk = true;
vm.$showAlert("사용자 관리", "사용할 수 있는 아이디입니다.");
}
})
.catch(error => {
this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
});
},
// 이메일 중복 검사
emailDuplicateChk() {
const vm = this;
// 유효성 검사
if (!vm.validationEmail()) {
return;
}
// 실행
axios({
url: "/member/email",
method: "get",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: vm.currentUser.userEmail,
})
.then(response => {
if (response.data.resultData.result) {
vm.$showAlert("사용자 관리", "사용중인 이메일입니다.");
vm.isEmailChk = false;
} else {
vm.$showAlert("사용자 관리", "사용할 수 있는 이메일입니다.");
vm.isEmailChk = true;
}
})
.catch(error => {
this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
});
},
// 사용자 잠금 해제
fnUpdateUserLockAt() {
const vm = this;
// 실행
axios({
url: "/member/updateUser/LockAt/" + vm.currentUser.userId,
method: "post",
headers: { "Content-Type": "application/json; charset=UTF-8" },
})
.then(response => {
if (response.data.checkMessage.status === 200) {
vm.$showAlert("사용자 관리", "사용자 잠금이 해제되었습니다.");
vm.fnSelectUser(vm.currentUser.userId); // 사용자 상세 재조회
} else {
vm.$showAlert("사용자 관리", response.data.checkMessage.message);
}
})
.catch(error => {
vm.$showAlert("사용자 관리", "수정 오류, 관리자에게 문의해주세요.");
});
},
// 사용자 비밀번호 변경 모달 열기
fnOpenModal() {
this.userPassword = null;
this.userPasswordConfirm = null;
this.modalOpen = true;
},
// 사용자 비밀번호 변경 모달 열기
fnCloseModal() {
this.modalOpen = false;
},
// 사용자 비밀번호 변경
fnUpdateUserPassword() {
const vm = this;
// 유효성 검사
vm.currentUser.userPassword = vm.userPassword;
if (!vm.validationPassword()) {
return;
}
// 실행
axios({
url: "/member",
method: "patch",
headers: {
"Content-Type": "application/json",
},
data: {
userId: vm.currentUser.userId,
userPassword: vm.userPassword,
},
})
.then(response => {
if (response.data.resultData.result) {
vm.$showAlert("비밀번호 변경", "비밀번호 변경에 성공했습니다.");
vm.modalOpen = false;
} else {
vm.$showAlert("비밀번호 변경", "비밀번호 변경에 실패했습니다. 다시 시도해주세요.");
}
})
.catch(error => {
vm.$showAlert("비밀번호 변경", "비밀번호 변경에 실패했습니다. 다시 시도해주세요.");
});
},
// 사용자 등록 취소
fnCancel() {
if (this.editMode == 'update') {
this.editMode = 'create';
}
// 초기화
this.userPassword = null;
this.userPasswordConfirm = null;
this.currentUser = Object.assign({}, this.memberVO);
},
// #유효성 검사
// 등록용 유효성 검사
insertValidation() {
// 아이디 유효성 검사
if (!this.validationId()) {
return false;
}
// 아이디 중복 검사 여부
if (!this.isIdChk) {
this.$showAlert("사용자 관리", "아이디 중복 확인 후 시도해주세요.");
return false;
}
// 이름 유효성 검사
if (!this.validationName()) {
return false;
}
// 비밀번호 유효성 검사
if (!this.validationPassword()) {
return false;
}
// 이메일 유효성 검사
if (!this.validationEmail()) {
return false;
}
// 이메일 중복 검사 여부
if (!this.isEmailChk) {
this.$showAlert("사용자 관리", "이메일 중복확인 후 등록해주세요.");
return false;
}
return true;
},
// 수정용 유효성 검사
updateValidation() {
if (JSON.stringify(this.currentUser) === JSON.stringify(this.originUser)) {
this.$showAlert("사용자 관리", "수정된 정보가 없습니다.");
return;
}
// 이름 유효성 검사
if (!this.validationName()) {
return false;
}
// 이메일 유효성 검사
if (!this.validationEmail()) {
return false;
}
// 이메일 중복 검사 여부
if (!this.isEmailChk) {
this.$showAlert("사용자 관리", "이메일 중복확인 후 수정해주세요.");
return false;
}
return true;
},
// 아이디 유효성 검사
validationId() {
let id = this.currentUser.userId;
if (this.$isEmpty(id)) {
this.$showAlert("사용자 관리", "아이디를 입력해주세요.");
return false;
}
if (!this.$idCheck(id)) {
this.$showAlert("사용자 관리", "아이디 형식이 올바르지 않습니다. (5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용가능)");
return false;
}
return true;
},
// 이름 유효성 검사
validationName() {
let name = this.currentUser.userNm;
if (this.$isEmpty(name)) {
this.$showAlert("사용자 관리", "이름을 입력해주세요.");
return false;
}
let validateName = /^[가-힣A-Za-z\s]+$/;
if (!validateName.test(name)) {
this.$showAlert("사용자 관리", "이름에 숫자와 특수문자를 입력할 수 없습니다.");
return false;
}
return true;
},
// 비밀번호 유효성 검사
validationPassword() {
if (this.$isEmpty(this.currentUser.userPassword)) {
this.$showAlert("사용자 관리", "비밀번호를 입력해주세요.");
return false;
}
if (!this.$pwCheck(this.currentUser.userPassword)) {
this.$showAlert("사용자 관리", "비밀번호 형식이 올바르지 않습니다. (8~16자의 영문 대문자, 소문자, 숫자, 특수문자 사용가능)");
return false;
}
if (this.currentUser.userPassword !== this.userPasswordConfirm) {
this.$showAlert("사용자 관리", "비밀번호가 일치하지 않습니다. 다시 입력해주세요.");
return false;
}
return true;
},
// 이메일 유효성 검사
validationEmail() {
let email = this.currentUser.userEmail;
// 1. null검사
if (this.$isEmpty(email)) {
this.$showAlert("사용자 관리", "이메일을 입력해주세요.");
return false;
}
// 2. 정규식 검사
if (!this.$email(email)) {
this.$showAlert("사용자 관리", "이메일 형식이 올바르지 않습니다.");
return false;
}
return true;
},
},
};
</script>