
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="col-lg-12">
<div class="card">
<div class="card-body">
<h2 class="card-title">휴가 현황</h2>
<div class="form-group">
<div class="form-conts">
<div class="form-conts datepicker-conts">
<div class="datepicker-input">
<input type="date" class="form-control datepicker cal" v-model="request.bgnde" style="max-width: 200px;" @change="changeDate" />
<mark>~</mark>
<input type="date" class="form-control datepicker cal" v-model="request.endde" style="max-width: 200px;" @change="changeDate" />
</div>
</div>
</div>
</div>
<div class="boxs">
<div class="color-boxs">
<div v-for="(item, idx) of useSummary" :key="idx" :class="getBoxClass(idx)" @click="fnFindUseList(item)">
<h3>{{ item.name }}</h3> {{ item.value }}
</div>
<div v-for="(item, idx) of notUseSummary" :key="idx" :class="getBoxClass(useSummary.length + idx)" @click="fnFindNotUseList(item.code)">
<h3>{{ item.codeNm }}</h3> {{ item.value }}
</div>
</div>
</div>
<div class="tbl-wrap">
<table id="myTable" class="tbl data">
<colgroup>
<col style="width: 15%;">
<col style="width: 40%;">
<col style="width: 30%;">
<col style="width: 15%;">
</colgroup>
<thead>
<tr>
<th>구분</th>
<th>기간</th>
<th>신청일</th>
<th>상태</th>
</tr>
</thead>
<tbody>
<template v-if="formattedListData.length > 0">
<tr v-for="(item, idx) in formattedListData" :key="idx" @click="fnMoveTo('view', item.vcatnId)">
<td :class="getTypeColorClass(item.formattedVcatnKnd)">{{ item.formattedVcatnKnd }}</td>
<td>{{ item.formattedBgnde }} {{ item.formattedBeginHour }}:{{ item.formattedBeginMnt }} ~ {{ item.formattedEndde }} {{ item.formattedEndHour }}:{{ item.formattedEndMnt }}</td>
<td>{{ item.rgsde }}</td>
<td :class="getStatusClass(item.formattedStatus)">{{ item.formattedStatus }}</td>
</tr>
</template>
<tr v-else>
<td colspan="4">해당 기간 내 등록된 휴가가 없습니다.</td>
</tr>
</tbody>
</table>
</div>
<Pagenation :search="request" @onChange="fnChangeCurrentPage" />
</div>
</div>
</div>
</template>
<script>
import { SearchOutlined } from '@ant-design/icons-vue';
import Pagenation from '../../../component/Pagenation.vue';
// API
import { findVcatnsSummary, findMyVcatnsProc } from '../../../../resources/api/vcatn';
export default {
components: {
SearchOutlined,
Pagenation
},
data() {
return {
photoicon: "/client/resources/img/photo_icon.png",
color: ['blue', 'red', 'green', 'purple', 'orange'],
colorMap: [],
useSummary: [], // 연차 소모성 휴가
notUseSummary: [], // 연차 비 소모성 휴가
// 휴가 현황 목록 조회용
listData: [],
request: {
vcatnKnds: null, // 휴가 종류
bgnde: null, // 시작일
endde: null, // 종료일
},
// 공통코드(구분, 상태) 목록 조회용
vcatnKnds: [],
confmTypes: [],
serachRequest: {
searchType: "upperCd",
searchText: null,
},
};
},
computed: {
formattedListData() {
if (!this.listData || !Array.isArray(this.listData)) {
return [];
}
return this.listData.map(item => {
const vcatnKnd = this.vcatnKnds.find(v => v.code === item.vcatnKnd);
const confmAt = this.confmTypes.find(v => v.codeValue === item.confmAt);
return {
...item,
formattedVcatnKnd: vcatnKnd ? vcatnKnd.codeNm : item.vcatnKnd,
formattedBgnde: item.bgnde ? item.bgnde.split(' ')[0] : '',
formattedEndde: item.endde ? item.endde.split(' ')[0] : '',
formattedBeginHour: item.beginHour ? item.beginHour.toString().padStart(2, '0') : '00',
formattedEndHour: item.endHour ? item.endHour.toString().padStart(2, '0') : '00',
formattedBeginMnt: item.beginMnt ? item.beginMnt.toString().padStart(2, '0') : '00',
formattedEndMnt: item.endMnt ? item.endMnt.toString().padStart(2, '0') : '00',
formattedStatus: confmAt ? confmAt.codeNm : item.confmAt,
};
});
}
},
created() {
this.vcatnCodes(); // 휴가 종류 코드 조회
this.confmTypeCodes(); // 상태 코드 조회
},
mounted() {
this.findSummary(); // 현황 조회
this.findList(); // 목록 조회
},
methods: {
// 휴가 종류 코드 조회
async confmTypeCodes() {
this.vcatnKnds = []; // 초기화
this.serachRequest.searchText = "sanctn_mby_vcatn";
const codes = await this.$findCodeList(this.serachRequest);
if (codes && Array.isArray(codes)) {
for (const code of codes) {
this.serachRequest.searchText = code.code;
const result = await this.$findCodeList(this.serachRequest);
if (result && Array.isArray(result)) {
this.vcatnKnds.push(...result);
}
}
}
},
// 상태 코드 조회
async vcatnCodes() {
this.confmTypes = []; // 초기화
this.serachRequest.searchText = "confm_code";
const codes = await this.$findCodeList(this.serachRequest);
if (codes && Array.isArray(codes)) {
this.confmTypes = codes;
}
},
// 현황 조회
async findSummary() {
const vm = this;
try {
const response = await findVcatnsSummary(vm.request);
const result = response.data.data;
this.request.bgnde = new Date(result.data.bgnde).toISOString().split('T')[0];
this.request.endde = new Date(result.data.endde).toISOString().split('T')[0];
if (result.data.yryc < 1) {
this.request.endde = new Date().toISOString().split('T')[0];
}
let yrycCyfdCo = result.data.yrycCyfdCo;
let totalCo = result.data.yrycCo + yrycCyfdCo;
let useCo = result.useSummary.useCo;
let notUseCo = totalCo - useCo;
this.useSummary = []; // 초기화
this.useSummary.push({ key: 'totalCo', name: '전체', value: totalCo + '(' + yrycCyfdCo + ')' });
this.useSummary.push({ key: 'useCo', name: '사용', value: useCo, codeList: result.useSummary.codeList });
this.useSummary.push({ key: 'notUseCo', name: '미사용', value: notUseCo });
this.notUseSummary = []; // 초기화
this.notUseSummary = result.notUseSummary;
this.colorMap = []; // 초기화
const keys = Object.keys(this.notUseSummary);
for (let i = 0; i < Object.keys(this.notUseSummary).length; i++) {
this.colorMap.push({
code: keys[i].code,
class: this.color[this.useSummary.length + i],
})
}
} catch (error) {
if (error.response) {
alert(error.response.data.message);
} else {
alert("에러가 발생했습니다.");
}
console.error(error.message);
};
},
// 현황에 클래스 부여
getBoxClass(idx) {
if (idx === 0) return 'box';
return `box ${this.color[(idx - 1) % this.color.length]}`;
},
// 날짜 선택
changeDate() {
if (!this.request.bgnde || !this.request.endde) {
return;
}
const startDate = new Date(this.request.bgnde);
const endDate = new Date(this.request.endde);
if (endDate < startDate) {
alert('종료일은 시작일보다 이전일 수 없습니다.');
this.request.endde = this.request.bgnde;
return;
}
this.findList(); // 목록 조회
},
// 목록 조회
async findList() {
const vm = this;
try {
delete vm.request.vcatnKndList;
const response = await findMyVcatnsProc(vm.request);
const result = response.data.data;
vm.listData = result.lists;
vm.request = result.search;
} catch (error) {
if (error.response) {
alert(error.response.data.message);
} else {
alert("에러가 발생했습니다.");
}
console.error(error.message);
};
},
// 목록 필터 조회
fnFindUseList(item) {
if (item.key === 'totalCo') {
this.request.vcatnKnds = null;
} else if (item.key === 'useCo') {
this.request.vcatnKnds = item.codeList.map(code => code.code).join(", ");
} else {
return;
}
this.findList(); // 목록 조회
},
fnFindNotUseList(vcatnKnd) {
this.request.vcatnKnds = vcatnKnd;
this.findList(); // 목록 조회
},
// 구분에 클래스 부여
getTypeColorClass(code) {
for (let color of this.colorMap) {
if (color.code === code) {
return 'vcatnKnd ' + color.class;
}
}
return 'vcatnKnd blue';
},
// 상태에 따른 클래스 반환 메소드
getStatusClass(status) {
if (status === '승인') return 'status-approved';
if (status === '대기') return 'status-pending';
return '';
},
// 페이지 이동
fnChangeCurrentPage(currentPage) {
this.request.currentPage = Number(currentPage);
this.$nextTick(() => {
this.findList();
});
},
// 페이지 이동
fnMoveTo(type, id) {
const routes = {
'list': { name: 'hyugaStatue' },
'view': { name: 'HyugaDetail', query: { id } },
'edit': { name: 'hyugaInsert', query: this.$isEmpty(id) ? {} : { id } },
};
if (routes[type]) {
if (!this.$isEmpty(this.pageId) && type === 'list') {
this.$router.push({ name: 'HyugaDetail', query: { id: this.pageId } });
}
this.$router.push(routes[type]);
} else {
alert("올바르지 않은 경로를 요청하여 목록으로 이동합니다.");
this.$router.push(routes['list']);
}
},
},
};
</script>
<style scoped>
tr {
cursor: pointer;
}
.box {
cursor: pointer;
}
.vcatnKnd.red {
color: #E92727 !important;
}
.vcatnKnd.green {
color: #3C97AB !important;
}
.vcatnKnd.blue {
color: #1D75E1 !important;
}
.vcatnKnd.purple {
color: #A36CD4 !important;
}
.vcatnKnd.orange {
color: #F7941C !important;
}
</style>