
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="popup-overlay" @click.self="handleClose">
<div class="popup-content">
<div class="card">
<div class="card-body">
<h2 class="card-title">직원 목록</h2>
<div class="sch-form-wrap">
<div class="input-group">
<div class="sch-input">
<input type="text" class="form-control" placeholder="직원명" v-model="searchParams.searchText" @keyup.enter="handleSearch">
<button type="button" class="ico-sch" @click="handleSearch">
<SearchOutlined />
</button>
</div>
</div>
</div>
<div class="tbl-wrap">
<table id="myTable" class="tbl data">
<thead>
<tr>
<th>직급</th>
<th>직책</th>
<th>부서</th>
<th>이름</th>
<th>선택</th>
</tr>
</thead>
<tbody>
<tr v-for="(employee, index) in employeeList" :key="index">
<td>{{ employee.clsfNm }}</td>
<td>{{ employee.rspofcNm }}</td>
<td>{{ employee.deptNm }}</td>
<td>{{ employee.userNm }}</td>
<td>
<button type="button" class="btn sm secondary" @click="handleSelectEmployee(employee)" :disabled="isEmployeeDisabled(employee.userId)"> 선택 </button>
</td>
</tr>
</tbody>
</table>
</div>
<Pagination :search="searchParams" @onChange="handlePageChange" />
</div>
</div>
<button @click="handleClose" class="close-btn">
<CloseCircleFilled />
</button>
</div>
</div>
</template>
<script>
import { SearchOutlined, CloseCircleFilled } from '@ant-design/icons-vue';
import Pagination from '../Pagination.vue';
// API
import { findUsersForModalProc } from '../../../resources/api/user';
export default {
name: 'EmployeeSelectionModal',
components: {
SearchOutlined,
CloseCircleFilled,
Pagination
},
props: {
// 이미 선택된 사용자 목록
selectedEmployees: {
type: Array,
default: () => [],
},
// 사용자 목록 내 유저아이디 key(혹은 column) 값
idField: {
type: String,
default: 'userId',
},
// 필터링용 날짜 정보
dateInfo: {
type: Object,
default: () => ({}),
}
},
emits: ['close', 'select'],
data() {
return {
employeeList: [],
searchParams: {
searchType: 'nm', // 검색조건 (사용자 이름으로 고정)
searchText: null, // 검색어
bgnde: null, // 시작 일 (YYYY-MM-DD)
beginHour: null, // 시작 시
endde: null, // 종료 일 (YYYY-MM-DD)
endHour: null, // 종료 시
},
}
},
computed: {
selectedEmployeeIds() {
return new Set(this.selectedEmployees.map(member => member[this.idField]));
}
},
watch: {
dateInfo: {
handler(newDateInfo) {
this.applyDateInfo(); // dateInfo 검색 조건에 적용
},
deep: true,
immediate: true
}
},
mounted() {
this.fetchEmployeeList();
},
methods: {
// dateInfo 검색 조건에 적용
applyDateInfo() {
if (this.dateInfo && Object.keys(this.dateInfo).length > 0) {
this.searchParams.bgnde = this.dateInfo.bgnde || null;
this.searchParams.beginHour = this.dateInfo.beginHour || null;
this.searchParams.endde = this.dateInfo.endde || null;
this.searchParams.endHour = this.dateInfo.endHour || null;
}
},
// 직원 목록 조회
async fetchEmployeeList() {
try {
const response = await findUsersForModalProc(this.searchParams);
const result = response.data.data;
this.employeeList = result.users;
this.searchParams = result.search;
} catch (error) {
const message = error.response?.data?.message || '데이터 조회에 실패했습니다.';
alert(message);
console.error(error);
}
},
// 검색 처리
async handleSearch() {
await this.fetchEmployeeList();
},
// 직원 선택 불가 여부 확인
isEmployeeDisabled(userId) {
return this.selectedEmployeeIds.has(userId) || this.$store.state.userInfo.userId === userId;
},
// 직원 선택
handleSelectEmployee(employee) {
this.$emit('select', employee);
this.handleClose();
},
// 모달 닫기
handleClose() {
this.$emit('close');
},
// 페이지 변경
handlePageChange(currentPage) {
this.searchParams.currentPage = Number(currentPage);
this.$nextTick(() => {
this.fetchEmployeeList();
});
},
}
}
</script>
<style scoped>
.popup-content {
width: 50%;
}
</style>