
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
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="sch-form-wrap title-wrap">
<h3><img :src="h3icon" alt="">승인 대기</h3>
<div class="input-group">
<select name="" id="" class="form-select">
<option :value="currentYear">{{ currentYear }}년</option>
<option value="all">전체</option>
<template v-for="year in remainingYears" :key="year">
<option :value="year" v-if="year !== currentYear"> {{ year }}년</option>
</template>
</select>
<select name="" id="" class="form-select">
<option :value="currentMonth">{{ currentMonth }}월</option>
<option value="all">전체</option>
<template v-for="month in remainingMonths" :key="month">
<option :value="month" v-if="month !== currentMonth"> {{ month }}월</option>
</template>
</select>
<div class="sch-input">
<input type="text" class="form-control" placeholder="신청자명">
<button class="ico-sch">
<SearchOutlined />
</button>
</div>
</div>
</div>
<div class="tbl-wrap">
<table id="myTable" class="tbl data">
<colgroup>
<col style="width: 13%;">
<col style="width: 13%;">
<col style="width: 13%;">
<col style="width: 48%;">
<col style="width: 13%;">
</colgroup>
<thead>
<tr>
<th>구분</th>
<th>결재구분</th>
<th>신청자</th>
<th>기간</th>
<th>신청일</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, idx) in waitListData" :key="idx" :class="{ 'expired': true }">
<td>{{ getCodeName('type', item.iemInfo.vcatnKnd) }}</td>
<td>{{ getCodeName('cate', item.sanctnSe) }}</td>
<td>{{ item.registerInfo.userNm }}</td>
<td>{{ $formattedDate(item.iemInfo.bgnde, item.iemInfo.beginHour, item.iemInfo.beginMnt) }} ~ {{ $formattedDate(item.iemInfo.bgnde, item.iemInfo.beginHour, item.iemInfo.beginMnt) }}</td>
<td>{{ item.registerInfo.userNm }}</td>
</tr>
</tbody>
</table>
</div>
<Pagenation :search="waitRequest" @onChange="(currentPage) => fnChangeCurrentPage(currentPage, 'wait')" />
<div class="sch-form-wrap title-wrap">
<h3><img :src="h3icon" alt="">승인 이력</h3>
<div class="input-group">
<select name="" id="" class="form-select">
<option :value="currentYear">{{ currentYear }}년</option>
<option value="all">전체</option>
<template v-for="year in remainingYears" :key="year">
<option :value="year" v-if="year !== currentYear"> {{ year }}년 </option>
</template>
</select>
<select name="" id="" class="form-select">
<option :value="currentMonth">{{ currentMonth }}월</option>
<option value="all">전체</option>
<template v-for="month in remainingMonths" :key="month">
<option :value="month" v-if="month !== currentMonth"> {{ month }}월 </option>
</template>
</select>
<select name="" id="" class="form-select">
<option value="all">상태</option>
<option value="">승인</option>
<option value="">반려</option>
</select>
<div class="sch-input">
<input type="text" class="form-control" placeholder="신청자명">
<button class="ico-sch">
<SearchOutlined />
</button>
</div>
</div>
</div>
<div class="tbl-wrap">
<table id="myTable" class="tbl data">
<colgroup>
<col style="width: 13%;">
<col style="width: 13%;">
<col style="width: 13%;">
<col style="width: 35%;">
<col style="width: 13%;">
<col style="width: 13%;">
</colgroup>
<thead>
<tr>
<th>구분</th>
<th>결재구분</th>
<th>신청자</th>
<th>기간</th>
<th>신청일</th>
<th>상태</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in confmListData" :key="index" :class="{ 'expired': true }">
<td>{{ getCodeName('type', item.iemInfo.vcatnKnd) }}</td>
<td>{{ getCodeName('cate', item.sanctnSe) }}</td>
<td>{{ item.registerInfo.userNm }}</td>
<td>{{ $formattedDate(item.iemInfo.bgnde, item.iemInfo.beginHour, item.iemInfo.beginMnt) }} ~ {{ $formattedDate(item.iemInfo.bgnde, item.iemInfo.beginHour, item.iemInfo.beginMnt) }}</td>
<td>{{ item.registerInfo.userNm }}</td>
<td :class="getStatusClass(item.status)">{{ getCodeName('confm', item.confmAt) }}</td>
</tr>
</tbody>
</table>
</div>
<Pagenation :search="confmRequest" @onChange="(currentPage) => fnChangeCurrentPage(currentPage, 'wait')" />
</div>
</div>
</div>
</template>
<script>
import { SearchOutlined } from '@ant-design/icons-vue';
import Pagenation from '../../../component/Pagenation.vue';
// API
import { findSanctnsProc } from '../../../../resources/api/sanctns';
const currentYear = new Date().getFullYear();
const currentMonth = new Date().getMonth() + 1;
export default {
components: {
SearchOutlined,
Pagenation,
},
data() {
return {
photoicon: "/client/resources/img/photo_icon.png",
h3icon: "/client/resources/img/h3icon.png",
// 목록 조회용
waitListData: [],
waitRequest: {
sanctnDe: null, // 결재일
sanctnIem: null, // 결재항목 : 출장 구분 or 휴가 종류 (휴가/출장 구분 코드)
sanctnMbyId: null, // 결재 주체 아이디 : 휴가/출장 아이디
},
confmListData: [],
confmRequest: {
sanctnDe: null, // 결재일
sanctnIem: null, // 결재항목 : 출장 구분 or 휴가 종류 (휴가/출장 구분 코드)
sanctnMbyId: null, // 결재 주체 아이디 : 휴가/출장 아이디
},
currentMonth,
selectedMonth: currentMonth,
remainingMonths: Array.from({ length: 12 }, (_, i) => i + 1),
currentYear,
selectedYear: currentYear,
remainingYears: Array.from({ length: 10 }, (_, i) => currentYear - i),
currentPage: 1,
totalPages: 3,
// 데이터 초기화
years: [2023, 2024, 2025], // 연도 목록
months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 월 목록
selectedYear: '',
selectedMonth: '',
// 공통코드 목록
sanctnCodes: [], // 결재 종류 코드 목록
sanctnMbyCodes: [], // 결재 항목 코드 목록
sanctnConfmCodes: [], // 결재 상태 코드 목록
};
},
computed: {},
created() {
this.initializeSanctnCodes();
console.log("sanctnCodes: ", this.sanctnCodes);
console.log("sanctnMbyCodes: ", this.sanctnMbyCodes);
},
mounted() {
this.findList('wait'); // 목록 조회
this.findList('confm'); // 목록 조회
},
methods: {
// 결재 관련 코드 초기화
async initializeSanctnCodes() {
try {
this.sanctnCodes = [];
this.sanctnMbyCodes = [];
// 순차적으로 코드 조회 및 추가
const vcatnCodes = await this.findCodeByDepth2('sanctn_mby_vcatn'); // 휴가 종류
this.sanctnCodes.push(...vcatnCodes);
const bsrpCodes = await this.findCodeByDepth1('sanctn_mby_bsrp'); // 출장 종류
this.sanctnCodes.push(...bsrpCodes);
const sanctnCodes = await this.findCodeByDepth1('sanctn_code'); // 결재 구분
this.sanctnMbyCodes.push(...sanctnCodes);
const confmCodes = await this.findCodeByDepth1('confm_code'); // 상태 코드
this.sanctnConfmCodes.push(...confmCodes);
} catch (error) {
console.error('코드 조회 중 오류 발생:', error);
}
},
// 코드 목록 조회 (depth 1)
async findCodeByDepth1(upperCode) {
try {
const searchRequest = {
searchType: 'upperCd',
searchText: upperCode,
};
const codes = await this.$findCodeList(searchRequest);
return Array.isArray(codes) ? codes : [];
} catch (error) {
console.error(`코드 조회 실패 (${upperCode}):`, error);
return [];
}
},
// 코드 목록 조회 (depth 2)
async findCodeByDepth2(upperCode) {
try {
const parentCodes = await this.findCodeByDepth1(upperCode);
const childCodes = [];
for (const code of parentCodes) {
const result = await this.findCodeByDepth1(code.code);
childCodes.push(...result);
}
return childCodes;
} catch (error) {
console.error(`하위 코드 조회 실패 (${upperCode}):`, error);
return [];
}
},
// 코드 매핑
getCodeName(type, code) {
let codeList;
if (type === 'type') {
codeList = this.sanctnCodes;
} else if (type === 'cate') {
codeList = this.sanctnMbyCodes;
} else if (type === 'confm') {
const foundCode = this.sanctnConfmCodes?.find(item => item.codeValue === code);
return foundCode ? foundCode.codeNm : code;
} else {
return code; // 알 수 없는 타입이면 원본 반환
}
const foundCode = codeList?.find(item => item.code === code);
return foundCode ? foundCode.codeNm : code;
},
// 목록 조회
async findList(type) {
const vm = this;
try {
let request = {};
if (type === 'wait') {
request = vm.waitRequest;
} else if (type == 'confm') {
request = vm.confmRequest;
}
const response = await findSanctnsProc(request);
const result = response.data.data;
if (type === 'wait') {
vm.waitListData = result.lists;
vm.waitRequest = result.search;
} else if (type == 'confm') {
vm.confmListData = result.lists;
vm.confmRequest = result.search;
}
} catch (error) {
if (error.response) {
alert(error.response.data.message);
} else {
alert("에러가 발생했습니다.");
}
console.error(error.message);
};
},
// 페이지 이동
fnChangeCurrentPage(currentPage, type) {
if (type === 'wait') {
this.waitRequest.currentPage = Number(currentPage);
} else if (type === 'confm') {
this.confmRequest.currentPage = Number(currentPage);
}
this.$nextTick(() => {
this.findList(type);
});
},
async onClickSubmit() {
// `useMutation` 훅을 사용하여 mutation 함수 가져오기
const { mutate, onDone, onError } = useMutation(mygql);
try {
const result = await mutate();
console.log(result);
} catch (error) {
console.error('Mutation error:', error);
}
},
registerLeave() {
console.log("등록 버튼 클릭됨");
// Vue의 반응성 문제를 피하기 위해, 새로운 객체를 추가합니다.
this.DeptData = [
...this.DeptData,
{ member: '', deptNM: '', acceptTerms: false }
];
console.log(this.DeptData); // 배열 상태 출력
},
getStatusClass(status) {
if (status === '승인') return 'status-approved';
if (status === '대기') return 'status-pending';
return '';
},
},
};
</script>
<style scoped>
tr {
cursor: pointer;
}
</style>