
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">
<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">
<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>