
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="card" style="height: 100%;">
<div class="card-body">
<div>
<h2 class="card-title">승인 대기 목록</h2>
<div style="height: 50%;">
<div class="d-flex justify-between align-center">
<h3 class="sub-title">승인 대기</h3>
<div class="search-wrap mb10">
<select class="form-select sm" v-model="pendingSearchParams.year" @change="handlePageChange(1, 'pending')">
<option value="">연도 전체</option>
<option v-for="year in yearOptions" :key="year" :value="year">{{ year }}년</option>
</select>
<select class="form-select sm" v-model="pendingSearchParams.month" @change="handlePageChange(1, 'pending')">
<option value="">월 전체</option>
<option v-for="month in monthOptions" :key="month" :value="month">{{ month }}월</option>
</select>
<input type="text" class="form-control sm" v-model="pendingSearchParams.searchText" placeholder="검색어를 입력하세요." @keyup.enter="handleSearch('pending')">
<button button="button" class="ico-sch" @click="handleSearch('pending')">
<SearchOutlined />
</button>
</div>
</div>
<div class="tbl-wrap mb20">
<table id="myTable" class="tbl data common-radius">
<colgroup>
<col style="width: 13.33%;">
<col style="width: 13.33%;">
<col style="width: 13.33%;">
<col style="width: 30%;">
<col style="width: 30%;">
</colgroup>
<thead>
<tr>
<th style="border-radius: 1rem 0 0 0;">구분</th>
<th>결재구분</th>
<th>신청자</th>
<th>기간</th>
<th style="border-radius: 0 1rem 0 0;">신청일</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, idx) in pendingApprovalList" :key="idx" @click="handleDetailNavigation(item.sanctnMbyId)">
<td>{{ item.sanctnIemNm }}</td>
<td>{{ item.sanctnSeNm }}</td>
<td>{{ item.registerNm }}</td>
<td>{{ $formattedDates(item) }}</td>
<td>{{ item.rgsde }}</td>
</tr>
</tbody>
</table>
</div>
<Pagenation :search="pendingSearchParams" @onChange="(currentPage) => handlePageChange(currentPage, 'pending')" />
</div>
<div style="height: 50%;">
<div class="d-flex justify-between align-center">
<h3 class="sub-title">승인 이력</h3>
<div class="search-wrap mb10">
<select class="form-select sm" v-model="historySearchParams.year" @change="handlePageChange(1, 'history')">
<option value="">연도 전체</option>
<option v-for="year in yearOptions" :key="year" :value="year">{{ year }}년</option>
</select>
<select class="form-select sm" v-model="historySearchParams.month" @change="handlePageChange(1, 'history')">
<option value="">월 전체</option>
<option v-for="month in monthOptions" :key="month" :value="month">{{ month }}월</option>
</select>
<select name="" id="" class="form-select sm">
<option value="all">상태</option>
<option value="">승인</option>
<option value="">반려</option>
</select>
<input type="text" class="form-control sm" v-model="historySearchParams.searchText" placeholder="검색어를 입력하세요." @keyup.enter="handleSearch('history')">
<button button="button" class="ico-sch" @click="handleSearch('history')">
<SearchOutlined />
</button>
</div>
</div>
<div class="tbl-wrap mb20">
<table id="myTable" class="tbl data">
<colgroup>
<col style="width: 13.33%;">
<col style="width: 13.33%;">
<col style="width: 13.33%;">
<col style="width: 30%;">
<col style="width: 16.66%;">
<col style="width: 13.33%;">
</colgroup>
<thead>
<tr>
<th style="border-radius: 1rem 0 0 0;">구분</th>
<th>결재구분</th>
<th>신청자</th>
<th>기간</th>
<th>신청일</th>
<th style="border-radius: 0 1rem 0 0;">상태</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in approvalHistoryList" :key="index" class="expired" @click="handleDetailNavigation(item.sanctnMbyId)">
<td>{{ item.sanctnIemNm }}</td>
<td>{{ item.sanctnSeNm }}</td>
<td>{{ item.registerNm }}</td>
<td>{{ $formattedDates(item) }}</td>
<td>{{ item.rgsde }}</td>
<td>{{ item.confmAtNm }}</td>
</tr>
</tbody>
</table>
</div>
<Pagenation :search="historySearchParams" @onChange="(currentPage) => handlePageChange(currentPage, 'history')" />
</div>
</div>
</div>
</div>
</template>
<script>
import { SearchOutlined } from '@ant-design/icons-vue';
import Pagenation from '../../../component/Pagination.vue';
// API
import { findPendingApprovalsProc } from '../../../../resources/api/sanctns';
export default {
components: {
SearchOutlined,
Pagenation,
},
data() {
return {
sectionIcon: "/client/resources/img/h3icon.png",
yearOptions: [2023, 2024, 2025], // 연도 목록
monthOptions: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 월 목록
// 승인 대기 목록
pendingApprovalList: [],
pendingSearchParams: {
year: '',
month: '',
isConfmAt: true, // 변경불가 (고정값)
searchText: '',
currentUserId: this.$store.state.userInfo.userId, // 변경불가 (고정값)
},
// 승인 이력 목록
approvalHistoryList: [],
historySearchParams: {
year: '',
month: '',
isConfmAt: false, // 변경불가 (고정값)
searchText: '',
currentUserId: this.$store.state.userInfo.userId, // 변경불가 (고정값)
},
};
},
created() {
this.generateYearOptions();
},
mounted() {
this.fetchApprovalList('pending'); // 승인 대기 목록
this.fetchApprovalList('history'); // 승인 이력 목록
},
methods: {
generateYearOptions() {
const startYear = 2020;
const currentYear = new Date().getFullYear();
for (let year = currentYear; year >= startYear; year--) {
this.yearOptions.push(year);
}
},
// 목록 조회
async fetchApprovalList(listType) {
const vm = this;
try {
let searchParams = {};
if (listType === 'pending') {
searchParams = vm.pendingSearchParams;
} else if (listType === 'history') {
searchParams = vm.historySearchParams;
}
const response = await findPendingApprovalsProc(searchParams);
const result = response.data.data;
if (listType === 'pending') {
vm.pendingApprovalList = result.lists;
vm.pendingSearchParams = result.search;
} else if (listType === 'history') {
vm.approvalHistoryList = result.lists;
vm.historySearchParams = result.search;
}
} catch (error) {
this.handleError(error);
};
},
// 검색 실행
handleSearch(listType) {
if (listType === 'pending') {
this.pendingSearchParams.currentPage = 1;
} else if (listType === 'history') {
this.historySearchParams.currentPage = 1;
}
this.fetchApprovalList(listType);
},
// 페이지 변경
handlePageChange(currentPage, listType) {
if (listType === 'pending') {
this.pendingSearchParams.currentPage = Number(currentPage);
} else if (listType === 'history') {
this.historySearchParams.currentPage = Number(currentPage);
}
this.$nextTick(() => {
this.fetchApprovalList(listType);
});
},
// 상세 페이지 이동
handleDetailNavigation(id) {
const approvalType = id.split('_')[0];
if (approvalType === "VCATN") {
this.$router.push({ name: 'HyugaDetail', query: { id, type: 'sanctns' } });
} if (approvalType === "BSRP") {
this.$router.push({ name: 'ChuljangDetailAll', query: { id, type: 'sanctns' } });
}
},
// 에러 처리
handleError(error) {
const message = error.response?.data?.message || "에러가 발생했습니다.";
alert(message);
console.error(error.message);
},
},
};
</script>
<style scoped>
tr {
cursor: pointer;
}
</style>