
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>