
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-box flex justify-between">
<div class="flex20 content-box">
<div class="left-content flex100 content-box">
<div class="content-box">
<div class="content-titleZone">
<p class="box-title">부서 목록</p>
</div>
<div class="content-zone overflow-y">
<ul class="tree-wrap" v-if="deptTreeList.length > 0">
<TreeMenu v-for="(item, idx) in deptTreeList" :key="idx" :node="item" :currentDeptCode="selectedDept" @changeCurrent="fnSelectDept" />
</ul>
</div>
</div>
</div>
</div>
<div class="right-content flex80">
<!-- 부서 정보 -->
<div class="content-titleZone">
<p class="box-title">부서 정보</p>
</div>
<div class="table-zone">
<div class="form-box">
<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="currentDept.dept_code" :disabled="editMode == 'update'" />
<button style="flex-grow: 1" class="small-btn blue-border-btn" v-if="editMode == 'create'" @click="fnDeptCodeDupChk">중복확인</button>
</td>
<th>부서명</th>
<td>
<input type="text" class="full-input" v-model="currentDept.dept_nm" />
</td>
</tr>
<tr>
<th>부서설명</th>
<td>
<input type="text" class="full-input" v-model="currentDept.dept_dc" />
</td>
<th>상위부서</th>
<td style="display: flex">
<input type="text" class="full-input" v-model="currentDept.upper_dept_nm" readonly />
<button style="flex-grow: 1" class="small-btn blue-border-btn" @click="fnOpenModalByDeptList">부서찾기</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="flex justify-end">
<button class="blue-btn small-btn" v-if="editMode == 'create'" @click="fnInsertDept">등록</button>
<button class="blue-btn small-btn" v-else @click="fnUpdateDept">수정</button>
<button class="red-border-btn small-btn" v-if="editMode == 'update'" @click="fnDeleteDept">삭제</button>
<button class="blue-border-btn small-btn" @click="fnCancelDept"><span v-if="editMode == 'create'">초기화</span><span v-else>취소</span></button>
</div>
<!-- 부서 내 사용자 목록 -->
<DeptUserList :deptCode="selectedDept.id" />
<!-- 부서 내 호스트 목록 -->
<DeptHostList :deptCode="selectedDept.id" />
</div>
</div>
</div>
</div>
<!-- 부서찾기 모달 -->
<div v-show="isDeptModalOpen" class="modal-wrapper">
<div class="modal-container">
<div class="modal-title flex justify-between align-center">
<h2>부서 찾기</h2>
<button class="close-btn" @click="fnCloseModalByDeptList">
<svg-icon type="mdi" :width="20" :height="20" :path="closePath"></svg-icon>
</button>
</div>
<div class="modal-content-monthly">
<div class="flex justify-center w100 mb10">
<div class="search-bar w100">
<div class="flex justify-between align-center">
<div class="flex25 pl0">
<select class="square-select full-select" v-model="searchDataByDept.key">
<option :value="null">전체</option>
<option value="dept_code">부서코드</option>
<option value="dept_nm">부서명</option>
</select>
</div>
<div class="flex75 flex align-center no-gutter pr0">
<input type="text" class="square-input flex90" placeholder="부서를 검색해주세요" v-model="searchDataByDept.value" @keyup.enter="fnSelectUpperDeptList" />
<button class="square-button blue-btn flex10" @click="fnSelectUpperDeptList">
<svg-icon type="mdi" :path="searchPath" class="square-icon"></svg-icon>
</button>
</div>
</div>
</div>
</div>
<div class="overflow-y" style="height: 500px">
<table class="sticky-table list-table2">
<colgroup>
<col style="width: 35%" />
<col style="width: 35%" />
<col style="width: 30%" />
</colgroup>
<thead>
<tr>
<th>부서코드</th>
<th>부서명</th>
<th>비고</th>
</tr>
</thead>
<tbody>
<template v-if="selectDeptList.length > 0">
<tr v-for="(item, idx) in selectDeptList" :key="idx" :class="{ red: item.isUsed == false }">
<td>{{ item.dept_code }}</td>
<td>{{ item.dept_nm }}</td>
<td><button type="button" class="small-btn blue-border-btn" @click="fnSelectedUpperDept(item)">선택</button></td>
</tr>
</template>
<tr v-else>
<td colspan="3">데이터가 존재하지 않습니다.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from '../../common/defaultAxios.js';
// icon용 svg import
import SvgIcon from "@jamescoyle/vue-icon";
import { mdiMagnify, mdiClose } from "@mdi/js";
// 컴포넌트 import
import PageNavigation from "../../component/PageNavigation.vue";
import TreeMenu from "../../component/treeMenu/TreeMenu.vue";
import DeptUserList from "./department/DeptUserList.vue";
import DeptHostList from "./department/DeptHostList.vue";
export default {
components: { SvgIcon, PageNavigation, TreeMenu, DeptUserList, DeptHostList },
data() {
return {
// icon용 svg path
searchPath: mdiMagnify,
closePath: mdiClose,
// 부서
searchByDept: Object.assign({}, this.$getDefaultSerchVO()),
searchDataByDept: this.$getDefaultSerchItem(null, "string"),
// 호스트
searchByHost: Object.assign({}, this.$getDefaultSerchVO()),
searchByDirectory: Object.assign({}, this.$getDefaultSerchVO()),
// default
editMode: 'create',
deptTreeList: [],
deptVO: {},
originDept: {},
currentDept: {},
selectedDept: {
"upId": null,
"id": null,
"nm": null,
"dp": null,
"ordr": null,
"childList": [],
}, // 부서 목록에서 선택한 부서
// 부서 정보
isDeptCodeDupChk: false, // 부서코드 중복확인 여부
// 부서 찾기 모달 관련
isDeptModalOpen: false,
selectDeptList: [],
};
},
mounted() {
this.fnSelectDeptListForTree();
},
watch: {
// 부서코드 변경 시 중복확인 여부 false로 변경
"currentDept.dept_code"() {
this.isDeptCodeDupChk = false;
},
},
methods: {
// 부서 목록 조회 (트리형 목록 용도)
fnSelectDeptListForTree() {
const vm = this;
axios({
url: "/department",
method: "get",
headers: { "Content-Type": "application/json; charset=UTF-8" },
})
.then(response => {
vm.deptVO = response.data.resultData.departmentVO;
vm.deptTreeList = response.data.resultData.hierachyList;
})
.catch(error => {
this.$showAlert("에러 발생", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
});
},
// 부서코드 중복확인
fnDeptCodeDupChk() {
const vm = this;
// 유효성 검사
if (!vm.validationDeptCode()) {
return;
};
axios({
url: "/department/" + vm.currentDept.dept_code,
method: "get",
headers: { "Content-Type": "application/json; charset=UTF-8" },
})
.then(response => {
if (response.data.resultData.checkDuplicateOrgCode) {
vm.$showAlert("부서코드 중복확인", "사용중인 부서코드입니다.");
vm.currentDept.dept_code = null;
} else {
vm.$showAlert("부서코드 중복확인", "사용할 수 있는 부서코드입니다.");
vm.isDeptCodeDupChk = true;
}
})
.catch(error => {
this.$showAlert("에러 발생", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
});
},
// #부서찾기모달
// 부서찾기 모달 열기
fnOpenModalByDeptList() {
this.fnSelectUpperDeptList(); // 부서 목록 조회(자신 제외)
this.isDeptModalOpen = true;
},
// 부서찾기 모달 닫기
fnCloseModalByDeptList() {
this.isDeptModalOpen = false;
},
// 부서 목록 조회(자신 제외)
fnSelectUpperDeptList() {
const vm = this;
// 데이터 세팅
vm.searchByDept.searchObjectList = [];
vm.searchByDept.searchObjectList.push(vm.searchDataByDept);
// 실행
axios({
url: "/department/departments/" + vm.currentDept.dept_code,
method: "post",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: vm.searchByDept,
})
.then(response => {
if (response.data != null) {
vm.selectDeptList = response.data.resultData.selectDeptList;
vm.searchByDept = response.data.resultData.searchVO;
// 하위 부서 선택을 제외하기 위한 옵션 추가
if (!vm.$isEmpty(vm.selectDeptList)) {
for (let dept of vm.selectDeptList) {
dept.isUsed = true;
let selectChildDeptList = response.data.resultData.selectChildDeptList;
if (!vm.$isEmpty(selectChildDeptList)) {
for (let deptCode of selectChildDeptList) {
if (dept.dept_code == deptCode) {
dept.isUsed = false;
break;
}
}
}
}
}
} else {
this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
}
})
.catch(error => {
vm.$showAlert("사용자 관리", "목록 불러오기 오류, 관리자에게 문의바랍니다.");
});
},
// 부서찾기 모달 내 부서 선택
fnSelectedUpperDept(dept) {
if (!dept.isUsed) {
this.$showAlert("부서 찾기", "자신의 하위 부서는 선택할 수 없습니다.");
return;
}
this.currentDept.upper_dept = dept.dept_code;
this.currentDept.upper_dept_nm = dept.dept_nm;
this.fnCloseModalByDeptList(); // 부서찾기 모달 닫기
},
// 부서 등록
fnInsertDept() {
const vm = this;
// 유효성 검사
if (!vm.insertDeptValidation()) {
return
};
// 실행
axios({
url: "/department",
method: "post",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: vm.currentDept,
})
.then(response => {
vm.$showAlert("부서 등록", "부서 등록이 완료되었습니다.");
// 초기화
vm.fnCancelDept();
vm.fnSelectDeptListForTree() // 부서 목록 조회 (트리형 목록 용도)
})
.catch(error => {
this.$showAlert("에러 발생", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
});
},
// 부서 수정
fnUpdateDept() {
const vm = this;
// 실행
axios({
url: "/department",
method: "put",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: vm.currentDept,
})
.then(response => {
vm.$showAlert("부서 수정", "부서 정보가 수정되었습니다.");
// 초기화
vm.fnCancelDept();
vm.fnSelectDeptListForTree(); // 부서 목록 조회 (트리형 목록 용도)
})
.catch(error => {
this.$showAlert("에러 발생", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
});
},
// 부서 삭제
async fnDeleteDept() {
const vm = this;
let isConfirmChk = await this.$showConfirm("경고", "선택한 부서를 삭제하시겠습니까?");
if (!isConfirmChk) {
return;
}
// 실행
axios({
url: `/department`,
method: "delete",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: vm.currentDept,
})
.then(response => {
vm.$showAlert("부서 삭제", "부서 삭제에 성공했습니다.");
// 초기화
vm.fnCancelDept();
vm.fnSelectDeptListForTree(); // 부서 목록 조회 (트리형 목록 용도)
})
.catch(error => {
vm.$showAlert("부서 삭제", "삭제오류, 관리자에게 문의바랍니다.");
});
},
// 부서 취소
fnCancelDept() {
if (this.$isEmpty(this.currentDept.dept_code)
&& this.$isEmpty(this.currentDept.dept_nm)
&& this.$isEmpty(this.currentDept.dept_dc)
&& this.$isEmpty(this.currentDept.upper_dept_nm)) {
this.$showAlert("부서 정보", "입력한 정보가 없습니다.");
} else {
this.editMode = 'create';
this.currentDept = this.deptVO;
this.selectedDept = {};
this.isDeptCodeDupChk = false; // 부서코드 중복확인 여부
// 사용자 목록
this.userList = [];
this.userSelectList = [];
this.searchByUser = Object.assign({}, this.$getDefaultSerchVO());
this.searchDataByUser = this.$getDefaultSerchItem(null, "string");
};
},
// 부서 상세 조회
fnSelectDept(currentDept) {
const vm = this;
// 데이터 세팅
vm.selectedDept = currentDept;
// 실행
axios({
url: "/department/selectDept/" + currentDept.id,
method: "get",
headers: { "Content-Type": "application/json; charset=UTF-8" },
})
.then(response => {
vm.editMode = 'update';
vm.originDept = response.data.resultData.departmentVO;
vm.currentDept = Object.assign({}, response.data.resultData.departmentVO);
})
.catch(error => {
vm.$showAlert("오류", "불러오기 오류, 관리자에게 문의바랍니다.");
});
},
// #유효성 검사
// 부서 등록용 유효성 검사
insertDeptValidation() {
// 부서코드 중복 검사 여부 확인
if (!this.isDeptCodeDupChk) {
this.$showAlert("부서 등록", "부서코드 중복확인 후 등록해주세요.");
return false;
}
// 부서코드 유효성 검사
if (!this.validationDeptCode()) {
return false;
}
return true;
},
// 부서코드 유효성 검사
validationDeptCode() {
// 부서코드 null 검사
if (this.$isEmpty(this.currentDept.dept_code)) {
this.$showAlert("부서 등록", "부서코드를 입력해주세요.");
return false;
}
// 부서코드 숫자만 검사
if (!/^\d+$/.test(this.currentDept.dept_code)) {
this.$showAlert("부서 등록", "부서코드는 숫자만 입력할 수 있습니다.");
return false;
}
return true;
},
},
};
</script>