jichoi / calendar star
박정하 박정하 07-22
250722 박정하 휴가, 출장, 결재 수정
@828a3c408d9d19e5e578a5f9565d96327b1cae6f
client/resources/api/sanctns.js
--- client/resources/api/sanctns.js
+++ client/resources/api/sanctns.js
@@ -2,5 +2,5 @@
 
 // 조회 - 목록
 export const findSanctnsProc = data => {
-  return apiClient.get('/sanctn/findSanctns.json', data);
+  return apiClient.get('/sanctn/findSanctns.json', { params: data });
 }
(파일 끝에 줄바꿈 문자 없음)
client/resources/api/vcatn.js
--- client/resources/api/vcatn.js
+++ client/resources/api/vcatn.js
@@ -11,8 +11,8 @@
 }
 
 // 조회 - 목록
-export const findMyVcatnsProc = data => {
-  return apiClient.get('/vcatn/findMyVcatns.json', { params: data });
+export const findVcatnsProc = data => {
+  return apiClient.get('/vcatn/findVcatns.json', { params: data });
 }
 
 // 조회 - 상세
client/resources/js/cmmnPlugin.js
--- client/resources/js/cmmnPlugin.js
+++ client/resources/js/cmmnPlugin.js
@@ -55,11 +55,23 @@
     }
 
     // 날짜 형식 변경
-    Vue.config.globalProperties.$formattedDate = (day, hour, min) => {
-      let beginHour = hour ? hour.toString().padStart(2, '0') : '00';
-      let beginMnt = min ? min.toString().padStart(2, '0') : '00';
+    Vue.config.globalProperties.$formattedDate = (d, h, m) => {
+      if (Vue.config.globalProperties.$isEmpty(d) || Vue.config.globalProperties.$isEmpty(h) || Vue.config.globalProperties.$isEmpty(m)) {
+        return;
+      }
+      let day = d.split(' ')[0];
+      let hour = h.toString().padStart(2, '0');
+      let minute = m.toString().padStart(2, '0');
 
-      return day.split(' ')[0] + " " + beginHour + ":" + beginMnt
+      return day + " " + hour + ":" + minute
+    }
+
+    // 기간 형식 변경
+    Vue.config.globalProperties.$formattedDates = (item) => {
+      const startDate = Vue.config.globalProperties.$formattedDate(item.bgnde, item.beginHour, item.beginMnt);
+      const endDate = Vue.config.globalProperties.$formattedDate(item.endde, item.endHour, item.endMnt);
+
+      return startDate + " ~ " + endDate;
     }
 
     // 공통코드 조회 (부모 코드로 자식 코드 조회)
client/views/pages/Employee/ChuljangList.vue
--- client/views/pages/Employee/ChuljangList.vue
+++ client/views/pages/Employee/ChuljangList.vue
@@ -70,7 +70,7 @@
   <td>{{ item.where }}</td>
   <td>{{ item.purpose }}</td>
   <td >{{ item.selectedMember }}
-    
+
   </td>
 </tr>
               </tbody>
@@ -101,7 +101,7 @@
 
   },
   methods: {
-    
+
     registerLeave() {
       console.log("등록 버튼 클릭됨");
 
@@ -150,7 +150,6 @@
   created() {
   // 로컬스토리지에서 기존 데이터가 있으면 불러오기
   const storedData = localStorage.getItem('ChuljangFormData');
-  console.log(storedData);
   if (storedData) {
     // Parse the data and wrap it in an array
     const parsedData = JSON.parse(storedData);
@@ -159,10 +158,10 @@
   }
 },
   mounted() {
-    
+
     // 처음에는 모든 데이터를 표시
     this.filteredData = this.ChuljangData;
-  
+
   },
 };
 </script>
client/views/pages/Employee/HyugaList.vue
--- client/views/pages/Employee/HyugaList.vue
+++ client/views/pages/Employee/HyugaList.vue
@@ -145,13 +145,12 @@
         });
       }
     },
-    
+
 
   },
   created() {
       // 로컬스토리지에서 기존 데이터가 있으면 불러오기
       const storedData = localStorage.getItem('HyugaFormData');
-      console.log(storedData);
       if (storedData) {
         // Parse the data and wrap it in an array
         const parsedData = JSON.parse(storedData);
client/views/pages/Employee/HyugaOk.vue
--- client/views/pages/Employee/HyugaOk.vue
+++ client/views/pages/Employee/HyugaOk.vue
@@ -145,13 +145,12 @@
         });
       }
     },
-    
+
 
   },
   created() {
       // 로컬스토리지에서 기존 데이터가 있으면 불러오기
       const storedData = localStorage.getItem('HyugaFormData');
-      console.log(storedData);
       if (storedData) {
         // Parse the data and wrap it in an array
         const parsedData = JSON.parse(storedData);
client/views/pages/Manager/approval/approval.vue
--- client/views/pages/Manager/approval/approval.vue
+++ client/views/pages/Manager/approval/approval.vue
@@ -127,7 +127,6 @@
   created() {
     // 로컬스토리지에서 기존 데이터가 있으면 불러오기
     const storedData = localStorage.getItem('DeptData');
-    console.log(storedData);
     if (storedData) {
       this.DeptData = JSON.parse(storedData);
     }
client/views/pages/Manager/approval/approvalList.vue
--- client/views/pages/Manager/approval/approvalList.vue
+++ client/views/pages/Manager/approval/approvalList.vue
@@ -6,19 +6,13 @@
         <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 class="form-select" v-model="waitRequest.year" @change="fnChangeCurrentPage(1, 'wait')">
+              <option value="">연도 전체</option>
+              <option v-for="year in years" :key="year" :value="year">{{ year }}년</option>
             </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 class="form-select" v-model="waitRequest.month" @change="fnChangeCurrentPage(1, 'wait')">
+              <option value="">월 전체</option>
+              <option v-for="month in months" :key="month" :value="month">{{ month }}월</option>
             </select>
             <div class="sch-input">
               <input type="text" class="form-control" placeholder="신청자명">
@@ -31,11 +25,11 @@
         <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%;">
+              <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>
@@ -47,12 +41,12 @@
               </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 v-for="(item, idx) in waitList" :key="idx">
+                <td>{{ item.sanctnIemNm }}</td>
+                <td>{{ item.sanctnSeNm }}</td>
+                <td>{{ item.applcntNm }}</td>
+                <td>{{ $formattedDates(item) }}</td>
+                <td>{{ item.rgsde }}</td>
               </tr>
             </tbody>
           </table>
@@ -61,19 +55,13 @@
         <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 class="form-select" v-model="confmRequest.year" @change="fnChangeCurrentPage(1, 'wait')">
+              <option value="">연도 전체</option>
+              <option v-for="year in years" :key="year" :value="year">{{ year }}년</option>
             </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 class="form-select" v-model="confmRequest.month" @change="fnChangeCurrentPage(1, 'wait')">
+              <option value="">월 전체</option>
+              <option v-for="month in months" :key="month" :value="month">{{ month }}월</option>
             </select>
             <select name="" id="" class="form-select">
               <option value="all">상태</option>
@@ -91,12 +79,12 @@
         <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%;">
+              <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>
@@ -109,13 +97,13 @@
               </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 v-for="(item, index) in confmList" :key="index" :class="{ 'expired': true }">
+                <td>{{ item.sanctnIemNm }}</td>
+                <td>{{ item.sanctnSeNm }}</td>
+                <td>{{ item.applcntNm }}</td>
+                <td>{{ $formattedDates(item) }}</td>
+                <td>{{ item.rgsde }}</td>
+                <td>{{ item.confmAtNm }}</td>
               </tr>
             </tbody>
           </table>
@@ -131,9 +119,6 @@
 // API
 import { findSanctnsProc } from '../../../../resources/api/sanctns';
 
-const currentYear = new Date().getFullYear();
-const currentMonth = new Date().getMonth() + 1;
-
 export default {
   components: {
     SearchOutlined,
@@ -145,33 +130,30 @@
       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: '',
+
+      // 목록 조회용
+      waitList: [],
+      waitRequest: {
+        year: '',
+        month: '',
+        sanctnDe: null, // 결재일
+        sanctnIem: null, // 결재항목 : 출장 구분 or 휴가 종류 (휴가/출장 구분 코드)
+        sanctnMbyId: null, // 결재 주체 아이디 : 휴가/출장 아이디
+        confmAts: "W", // 승인여부
+        confmerId: this.$store.state.userInfo.userId,
+      },
+      confmList: [],
+      confmRequest: {
+        year: '',
+        month: '',
+        sanctnDe: null, // 결재일
+        sanctnIem: null, // 결재항목 : 출장 구분 or 휴가 종류 (휴가/출장 구분 코드)
+        sanctnMbyId: null, // 결재 주체 아이디 : 휴가/출장 아이디
+        confmAts: "A,R", // 승인여부
+        confmerId: this.$store.state.userInfo.userId,
+      },
 
       // 공통코드 목록
       sanctnCodes: [], // 결재 종류 코드 목록
@@ -182,12 +164,7 @@
 
   computed: {},
 
-  created() {
-    this.initializeSanctnCodes();
-
-    console.log("sanctnCodes: ", this.sanctnCodes);
-    console.log("sanctnMbyCodes: ", this.sanctnMbyCodes);
-  },
+  created() { },
 
   mounted() {
     this.findList('wait'); // 목록 조회
@@ -195,84 +172,6 @@
   },
 
   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;
@@ -289,10 +188,10 @@
         const result = response.data.data;
 
         if (type === 'wait') {
-          vm.waitListData = result.lists;
+          vm.waitList = result.lists;
           vm.waitRequest = result.search;
         } else if (type == 'confm') {
-          vm.confmListData = result.lists;
+          vm.confmList = result.lists;
           vm.confmRequest = result.search;
         }
       } catch (error) {
@@ -316,34 +215,6 @@
       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 '';
     },
   },
 };
client/views/pages/Manager/approval/approvalRequest.vue
--- client/views/pages/Manager/approval/approvalRequest.vue
+++ client/views/pages/Manager/approval/approvalRequest.vue
@@ -5,29 +5,13 @@
         <h2 class="card-title">결재 요청</h2>
         <div class="sch-form-wrap">
           <div class="input-group">
-            <select name="" id="" class="form-select">
-              <option :value="currentYear">{{ currentYear }}년</option>
-  <option value="all">전체</option>
-  <option
-    v-for="year in remainingYears"
-    :key="year"
-    :value="year"
-    v-if="year !== currentYear"
-  >
-    {{ year }}년
-  </option>
+            <select class="form-select" v-model="request.year" @change="fnChangeCurrentPage(1)">
+              <option value="">연도 전체</option>
+              <option v-for="year in years" :key="year" :value="year">{{ year }}년</option>
             </select>
-            <select name="" id="" class="form-select">
-              <option :value="currentMonth">{{ currentMonth }}월</option>
-  <option value="all">전체</option>
-  <option
-    v-for="month in remainingMonths"
-    :key="month"
-    :value="month"
-    v-if="month !== currentMonth"
-  >
-    {{ month }}월
-  </option>
+            <select class="form-select" v-model="request.month" @change="fnChangeCurrentPage(1)">
+              <option value="">월 전체</option>
+              <option v-for="month in months" :key="month" :value="month">{{ month }}월</option>
             </select>
             <select name="" id="" class="form-select">
               <option value="" selected>전체</option>
@@ -42,14 +26,19 @@
             </select>
           </div>
         </div>
-
-        <!-- Table  -->
         <div class="tbl-wrap">
           <table id="myTable" class="tbl data">
-            <!-- 동적으로 <th> 생성 -->
+            <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>구분 </th>
+                <th>구분</th>
                 <th>결재구분</th>
                 <th>신청자</th>
                 <th>기간</th>
@@ -57,162 +46,115 @@
                 <th>상태</th>
               </tr>
             </thead>
-            <!-- 동적으로 <td> 생성 -->
             <tbody>
-              <tr v-for="(item, index) in listData" :key="index" :class="{ 'expired': isPastPeriod(item.period) }">
-                <td>{{ item.type }}</td>
-                <td>{{ item.approvalType }}</td>
-                <td>{{ item.applicant }}</td>
-                <td>{{ item.period }}</td>
-                <td>{{ item.requestDate }}</td>
-                <td :class="getStatusClass(item.status)">{{ item.status }}</td>
+              <tr v-for="(item, idx) of lists" :key="idx">
+                <td>{{ item.sanctnIemNm }}</td>
+                <td>{{ item.sanctnSeNm }}</td>
+                <td>{{ item.applcntNm }}</td>
+                <td>{{ $formattedDates(item) }}</td>
+                <td>{{ item.rgsde }}</td>
+                <td>{{ item.confmAtNm }}</td>
               </tr>
             </tbody>
           </table>
-
         </div>
-        <div class="pagination">
-          <ul>
-            <!-- 왼쪽 화살표 (이전 페이지) -->
-            <li class="arrow" :class="{ disabled: currentPage === 1 }" @click="changePage(currentPage - 1)">
-              &lt;
-            </li>
-
-            <!-- 페이지 번호 -->
-            <li v-for="page in totalPages" :key="page" :class="{ active: currentPage === page }"
-              @click="changePage(page)">
-              {{ page }}
-            </li>
-
-            <!-- 오른쪽 화살표 (다음 페이지) -->
-            <li class="arrow" :class="{ disabled: currentPage === totalPages }" @click="changePage(currentPage + 1)">
-              &gt;
-            </li>
-          </ul>
-        </div>
-        <!-- End Table -->
+        <Pagenation :search="request" @onChange="fnChangeCurrentPage" />
         <div class="buttons">
-          <button type="button" class="btn sm primary" @click="showOptions = true">
-            등록
-          </button>
-
-          <!-- 신청 종류 선택 모달 -->
-          <div v-if="showOptions" class="popup-overlay">
-            <div class="popup-content">
-              <div class="card">
-                <div class="card-body">
-                  <h2 class="card-title">신청종류선택</h2>
-                  <div class="buttons">
-                    <button class="btn hyuga" @click="goToPage('휴가')">휴가신청</button>
-                    <button class="btn chuljang" @click="goToPage('출장')">출장신청</button>
-                  </div>
-                </div>
-              </div>
-              <button class="close-btn" @click="showOptions = false"> <CloseCircleFilled /></button>
-            </div>
-
-          </div>
+          <button type="button" class="btn sm primary" @click="showOptions = true"> 등록 </button>
         </div>
       </div>
     </div>
   </div>
+  <div v-if="showOptions" class="popup-overlay">
+    <div class="popup-content">
+      <div class="card">
+        <div class="card-body">
+          <h2 class="card-title">신청종류선택</h2>
+          <div class="buttons">
+            <button class="btn hyuga" @click="goToPage('휴가')">휴가신청</button>
+            <button class="btn chuljang" @click="goToPage('출장')">출장신청</button>
+          </div>
+        </div>
+      </div>
+      <button class="close-btn" @click="showOptions = false">
+        <CloseCircleFilled />
+      </button>
+    </div>
+  </div>
 </template>
-
 <script>
-import { ref } from 'vue';
 import { SearchOutlined, CloseCircleFilled } from '@ant-design/icons-vue';
-const currentYear = new Date().getFullYear();
-const currentMonth = new Date().getMonth() + 1;
+import Pagenation from '../../../component/Pagenation.vue';
+// API
+import { findSanctnsProc } from '../../../../resources/api/sanctns';
+
 export default {
+  components: {
+    SearchOutlined, CloseCircleFilled,
+    Pagenation,
+  },
+
   data() {
     return {
-      currentMonth,
-      selectedMonth: currentMonth,
-      remainingMonths: Array.from({ length: 12 }, (_, i) => i + 1),
-      currentYear,
-      selectedYear: currentYear,
-      remainingYears: Array.from({ length: 10 }, (_, i) => currentYear - i),
-      showOptions: false,
-      currentPage: 1,
-      totalPages: 3,
       photoicon: "/client/resources/img/photo_icon.png",
-      // 데이터 초기화
-      years: [2023, 2024, 2025], // 연도 목록
-      months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 월 목록
-      selectedYear: '',
-      selectedMonth: '',
-      listData: [
-        {
-          type: '연차',
-          approvalType: '결재',
-          applicant: '홍길동',
-          period: '2025-05-10 ~ 2025-15-03',
-          requestDate: '2025-04-25',
-          status: '대기'
-        }, {
-          type: '반차',
-          approvalType: '전결',
-          applicant: '홍길동',
-          period: '2025-05-01 ~ 2025-05-03',
-          requestDate: '2025-04-25',
-          status: '승인'
-        }],
-      filteredData: [],
+      showOptions: false,
+
+      years: [],
+      months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
+
+      lists: [],
+      request: {
+        year: '',
+        month: '',
+        register: this.$store.state.userInfo.userId,
+      },
     };
   },
-  components: {
-    SearchOutlined, CloseCircleFilled
-  },
-  computed: {
-  },
-  methods: {
-    changePage(page) {
-      if (page < 1 || page > this.totalPages) return;
-      this.currentPage = page;
-      this.$emit('page-changed', page); // 필요 시 부모에 알림
-    },
-    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);
-      }
-    },
-    goToPage(type) {
-      if (type === '휴가') {
-        this.$router.push({ name: 'HyugaInsert' });
-      } else if (type === '출장') {
-        this.$router.push({ name: 'HyugaChuljangDetailDetail' });
-      }
-    },
-    getStatusClass(status) {
-      if (status === '승인') return 'status-approved';
-      if (status === '대기') return 'status-pending';
-      return '';
-    },
-    isPastPeriod(period) {
-      // 예: '2025-05-01 ~ 2025-05-03' → 종료일 추출
-      const endDateStr = period.split('~')[1]?.trim();
-      if (!endDateStr) return false;
-
-      const endDate = new Date(endDateStr);
-      const today = new Date();
-
-      // 현재 날짜보다 과거면 true
-      return endDate < today;
-    }
-  },
   created() {
+    this.generateYears();
   },
+
   mounted() {
+    this.findList(); // 목록 조회
+  },
 
+  methods: {
+    generateYears() {
+      const startYear = 2020;
+      const currentYear = new Date().getFullYear();
 
+      for (let year = currentYear; year >= startYear; year--) {
+        this.years.push(year);
+      }
+    },
+
+    // 목록 조회
+    async findList() {
+      const vm = this;
+      try {
+        const response = await findSanctnsProc(vm.request);
+        const result = response.data.data;
+
+        this.lists = result.lists;
+        this.request = result.search;
+      } catch (error) {
+        if (error.response) {
+          alert(error.response.data.message);
+        } else {
+          alert("에러가 발생했습니다.");
+        }
+        console.error(error.message);
+      };
+    },
+
+    // 페이지 이동
+    fnChangeCurrentPage(currentPage) {
+      this.request.currentPage = Number(currentPage);
+      this.$nextTick(() => {
+        this.findList();
+      });
+    },
   },
 };
-</script>
-
-<style scoped></style>
+</script>
(파일 끝에 줄바꿈 문자 없음)
client/views/pages/Manager/asset/asset.vue
--- client/views/pages/Manager/asset/asset.vue
+++ client/views/pages/Manager/asset/asset.vue
@@ -155,7 +155,6 @@
   created() {
     // 로컬스토리지에서 기존 데이터가 있으면 불러오기
     const storedData = localStorage.getItem('DeptData');
-    console.log(storedData);
     if (storedData) {
       this.DeptData = JSON.parse(storedData);
     }
client/views/pages/Manager/attendance/HyugaDetail.vue
--- client/views/pages/Manager/attendance/HyugaDetail.vue
+++ client/views/pages/Manager/attendance/HyugaDetail.vue
@@ -4,71 +4,48 @@
       <h2 class="card-title">휴가 현황</h2>
       <div class="form-card">
         <h1>휴가신청서</h1>
-        <div v-if="detailData.sanctnList && detailData.sanctnList.length > 0" class="approval-box tbl-wrap tbl2">
-          <table class="tbl data">
-            <tbody>
-              <tr class="thead">
-                <td rowspan="2" class="th">승인자</td>
-                <template v-for="(item, idx) of detailData.sanctnList" :key="idx">
-                  <td>{{ fnFindNm(item.clsf) }}</td>
-                </template>
-              </tr>
-              <tr>
-                <td v-for="(item, idx) of detailData.sanctnList" :key="idx">
-                  <template v-if="item.confmAt === 'A'">
-                    <p v-if="item.sanctnSe === 'sanctn_agncy'">(대결)</p>
-                    <p class="name">{{ item.confmerInfo?.userNm || '' }}</p>
-                    <small class="date">{{ new Date(item.sanctnDe).toISOString().split('T')[0] }}</small>
-                  </template>
-                  <template v-else-if="item.confmAt === 'R'">
-                    <p class="name">반려</p>
-                  </template>
-                </td>
-              </tr>
-            </tbody>
-          </table>
-        </div>
+        <SanctnViewList v-if="detailData.sanctnList.length > 0" :sanctns="detailData.sanctnList" />
         <form class="row g-3 needs-validation detail" novalidate>
           <div class="col-12">
             <div class="col-12 border-x">
               <label for="vcatnType" class="form-label">유형</label>
-              <p>{{ formattedVcatnKnd }}</p>
+              <p>{{ detailData.vcatnKndNm }}</p>
             </div>
             <div class="col-12 border-x">
               <label for="applicant" class="form-label">신청자</label>
-              <p>{{ detailData.registerInfo?.userNm || '' }}</p>
+              <p>{{ detailData.userNm }}</p>
             </div>
           </div>
           <div class="col-12">
             <div class="col-12 border-x">
               <label for="department" class="form-label">부서</label>
-              <p>{{ detailData.registerInfo?.userDeptInfo?.deptVO?.deptNm || '' }}</p>
+              <p>{{ detailData.deptNm }}</p>
             </div>
             <div class="col-12 border-x">
               <label for="position" class="form-label">직급</label>
-              <p>{{ formattedClsf }}</p>
+              <p>{{ detailData.clsfNm }}</p>
             </div>
           </div>
           <div class="col-12">
             <label for="period" class="form-label">기간</label>
-            <p>{{ formattedPeriod }}</p>
+            <p>{{ $formattedDates(detailData) }}</p>
           </div>
           <div class="col-12 hyuga">
             <label for="details" class="form-label">세부사항</label>
-            <ViewerComponent :content="detailData.detailCn || ''" />
+            <ViewerComponent :content="detailData.detailCn" />
           </div>
           <div class="col-12">
             <label for="requestDate" class="form-label">신청일</label>
-            <p>{{ detailData.rgsde || '' }}</p>
+            <p>{{ detailData.rgsde }}</p>
           </div>
           <div class="col-12">
             <label for="status" class="form-label">상태</label>
-            <p>{{ formattedStatus }}</p>
+            <p>{{ detailData.confmAtNm }}</p>
           </div>
           <div v-if="detailData.confmAt === 'R'" class="col-12 border-x return">
             <label for="rejectReason" class="form-label">반려사유</label>
             <template v-for="(item, idx) of detailData.sanctnList" :key="idx">
-              <p v-if="item.confmAt === 'R'">{{ item.returnResn || '' }}</p>
+              <p v-if="item.confmAt === 'R'">{{ item.returnResn }}</p>
             </template>
           </div>
         </form>
@@ -86,77 +63,53 @@
 <script>
 import ReturnPopup from '../../../component/Popup/ReturnPopup.vue';
 import ViewerComponent from '../../../component/editor/ViewerComponent.vue';
+import SanctnViewList from '../../../component/Sanctn/SanctnViewList.vue';
 // API
 import { findVcatnProc, deleteVcatnProc } from '../../../../resources/api/vcatn';
 
 export default {
-  components: { ReturnPopup, ViewerComponent },
+  components: {
+    ReturnPopup, ViewerComponent,
+    SanctnViewList,
+  },
 
   data() {
     return {
       require: "/client/resources/img/require.png",
 
       pageId: null,
-      isRegister: false,
       showPopup: false,
+      isRegister: false,
 
-      // 휴가 신청서 정보
       detailData: {
-        registerInfo: {},
-        sanctnList: [],
-        confmAt: '',
-        vcatnKnd: '',
-        clsf: '',
-        bgnde: '',
-        endde: '',
-        detailCn: '',
-        rgsde: ''
+        vcatnId: null,
+        userId: null,
+        userNm: null,
+        vcatnKnd: null,
+        vcatnKndNm: null,
+        deptId: null,
+        deptNm: null,
+        clsf: null,
+        clsfNm: null,
+        bgnde: null,
+        beginHour: null,
+        beginMnt: null,
+        endde: null,
+        endHour: null,
+        endMnt: null,
+        detailCn: null,
+        confmAt: null,
+        confmAtNm: null,
+        rgsde: null,
+        register: null,
+        updde: null,
+        updusr: null,
+        sanctnList: []
       },
-
-      cmmnCodes: {
-        vcatnKndCodeList: [],
-        clsfCodeList: [],
-        confmCodeList: []
-      }
     };
   },
 
-  computed: {
-    formattedVcatnKnd() {
-      if (!this.cmmnCodes.vcatnKndCodeList || this.cmmnCodes.vcatnKndCodeList.length === 0) return this.detailData.vcatnKnd;
-      const vcatnKnd = this.cmmnCodes.vcatnKndCodeList.find(v => v.code === this.detailData.vcatnKnd);
-      return vcatnKnd ? vcatnKnd.codeNm : this.detailData.vcatnKnd;
-    },
-
-    formattedClsf() {
-      if (!this.cmmnCodes.clsfCodeList || this.cmmnCodes.clsfCodeList.length === 0) return this.detailData.clsf;
-      const clsf = this.cmmnCodes.clsfCodeList.find(v => v.code === this.detailData.clsf);
-      return clsf ? clsf.codeNm : this.detailData.clsf;
-    },
-
-    formattedStatus() {
-      if (!this.cmmnCodes.confmCodeList || this.cmmnCodes.confmCodeList.length === 0) return this.detailData.confmAt;
-      const confmAt = this.cmmnCodes.confmCodeList.find(v => v.codeValue === this.detailData.confmAt);
-      return confmAt ? confmAt.codeNm : this.detailData.confmAt;
-    },
-
-    formattedPeriod() {
-      if (!this.detailData.bgnde || !this.detailData.endde) return '';
-
-      const formattedBgnde = this.detailData.bgnde.split(' ')[0];
-      const formattedBeginHour = this.detailData.beginHour?.toString().padStart(2, '0') || '00';
-      const formattedBeginMnt = this.detailData.beginMnt?.toString().padStart(2, '0') || '00';
-      const startDay = `${formattedBgnde} ${formattedBeginHour}:${formattedBeginMnt}`;
-
-      const formattedEndde = this.detailData.endde.split(' ')[0];
-      const formattedEndHour = this.detailData.endHour?.toString().padStart(2, '0') || '00';
-      const formattedEndMnt = this.detailData.endMnt?.toString().padStart(2, '0') || '00';
-      const endDay = `${formattedEndde} ${formattedEndHour}:${formattedEndMnt}`;
-
-      const dayCount = this.calculateDayCount();
-      return `${startDay} ~ ${endDay} (${dayCount}일)`;
-    },
-  },
+  computed: {},
 
   async created() {
     this.pageId = this.$route.query.id;
@@ -164,9 +117,6 @@
       alert("게시물이 존재하지 않습니다.");
       this.fnMoveTo('list');
     }
-
-    // 코드 목록 초기화
-    this.cmmnCodes = await this.$defaultCodes();
   },
 
   mounted() {
@@ -191,15 +141,6 @@
         console.error(error.message);
         this.fnMoveTo('list');
       }
-    },
-
-    fnFindNm(code) {
-      if (this.$isEmpty(code)) {
-        return code;
-      }
-
-      const clsf = this.cmmnCodes.clsfCodeList.find(v => v.code === code);
-      return clsf ? clsf.codeNm : code;
     },
 
     // 일수 계산
client/views/pages/Manager/attendance/HyugaInsert.vue
--- client/views/pages/Manager/attendance/HyugaInsert.vue
+++ client/views/pages/Manager/attendance/HyugaInsert.vue
@@ -10,14 +10,8 @@
           </label>
           <select class="form-select" style="max-width: 200px;" v-model="editData.vcatnKnd" @change="fnOnchangeVcatnKnd">
             <option value="" disabled hidden>유형 선택</option>
-            <option v-for="(item, idx) of cmmnCodes.vcatnKndCodeList" :key="idx" :value="item.code">{{ item.codeNm }}</option>
+            <option v-for="(item, idx) of vcatnKnds" :key="idx" :value="item.code">{{ item.codeNm }}</option>
           </select>
-          <template v-if="showSubTypeSelect">
-            <select class="form-select mt-2" style="max-width: 200px;" v-model="editData.vcatnSubKnd" @change="fnOnchangeVcatnSubKnd">
-              <option value="" disabled hidden>세부 유형 선택</option>
-              <option v-for="(item, idx) of subTypes" :key="idx" :value="item.code">{{ item.codeNm }}</option>
-            </select>
-          </template>
         </div>
         <div class="col-12">
           <label for="bgnde" class="form-label">
@@ -50,9 +44,9 @@
               <PlusCircleFilled />
             </button>
           </label>
-          <HrPopup v-if="isOpenModal && isCodesLoaded" :sanctns="editData.sanctnList" :cmmnCodes="cmmnCodes" @onSelected="fnAddSanctn" @close="isOpenModal = false" />
+          <HrPopup v-if="isOpenModal" :lists="editData.sanctnList" @onSelected="fnAddSanctn" @close="isOpenModal = false" />
           <div class="approval-container">
-            <SanctnList v-model:sanctns="editData.sanctnList" @delSanctn="fnDelSanctn" />
+            <SanctnList v-model:lists="editData.sanctnList" @delSanctn="fnDelSanctn" />
           </div>
         </div>
         <div class="col-12 border-x hyuga">
@@ -90,13 +84,14 @@
   data() {
     return {
       require: "/client/resources/img/require.png",
+
       pageId: null,
       isOpenModal: false,
+
       editData: {
         vcatnId: null,
         userId: null,
-        vcatnKnd: '',
-        vcatnSubKnd: '', // 세부 유형 추가
+        vcatnKnd: null,
         deptId: null,
         clsf: null,
         bgnde: null,
@@ -107,49 +102,77 @@
         endMnt: null,
         detailCn: null,
         confmAt: null,
-        sanctnList: [],
+        rgsde: null,
+        register: null,
+        updde: null,
+        updusr: null,
+        sanctnList: []
       },
       dayCnt: 0,
       totalDays: 0,
-      cmmnCodes: {},
       workConfig: {
         startHour: 9,    // 근무 시작 시간
         endHour: 18,     // 근무 종료 시간
         lunchStart: 12,  // 점심 시작 시간
         lunchEnd: 13,    // 점심 종료 시간
       },
-      subTypes: [],
+
+      vcatnKnds: [],
+      halfDaySubTypes: [],
+      vcatnSubKnd: null,
+
+      sanctnCodes: [],
     };
   },
 
   computed: {
-    // 세부 유형 선택박스를 보여줄지 여부
     showSubTypeSelect() {
-      return this.dayCnt === 0.5 && this.subTypes.length > 0;
+      return this.dayCnt === 0.5;
     },
 
-    // cmmnCodes가 로드되었는지 확인
-    isCodesLoaded() {
-      return this.cmmnCodes && Object.keys(this.cmmnCodes).length > 0;
+    // 현재 선택된 유형이 반차 하위 유형인지 확인
+    isHalfDaySubType() {
+      return this.halfDaySubTypes.some(item => item.code === this.editData.vcatnKnd);
     }
   },
 
   async created() {
     this.pageId = this.$route.query.id;
-    this.cmmnCodes = await this.$defaultCodes();
-    for (const vcatnType of this.cmmnCodes.vcatnKndCodeList) {
-      if (parseFloat(vcatnType.codeValue) === 0.5) {
-        this.subTypes = await this.$findChildCodes(vcatnType.code);
-        break;
+
+    // 휴가 유형 조회
+    this.vcatnKnds = []; // 초기화
+    let halfDaySubTypes = [];
+    const vcatnKndCodes = await this.$findChildCodes('sanctn_mby_vcatn');
+    for (const code of vcatnKndCodes) {
+      const childCodes = await this.$findChildCodes(code.code);
+      for (const childCode of childCodes) {
+        if (parseFloat(childCode.codeValue) === 0.5) {
+          // 반차(0.5)인 경우 해당 유형은 제외하고 하위 코드만 추가
+          const subTypes = await this.$findChildCodes(childCode.code);
+          this.vcatnKnds.push(...subTypes);
+          halfDaySubTypes.push(...subTypes);
+        } else {
+          // 반차가 아닌 경우 그대로 추가
+          this.vcatnKnds.push(childCode);
+        }
       }
+    }
+    this.halfDaySubTypes = halfDaySubTypes;
+
+    if (this.vcatnKnds.length > 0) {
+      this.editData.vcatnKnd = this.vcatnKnds[0].code;
+    }
+
+    // 결재 구분
+    this.sanctnCodes = await this.$findChildCodes('sanctn_code');
+
+    // 상세 조회 (pageId가 있는 경우)
+    if (!this.$isEmpty(this.pageId)) {
+      await this.findData();
     }
   },
 
-  mounted() {
-    if (!this.$isEmpty(this.pageId)) {
-      this.findData();
-    }
-  },
+  mounted() { },
 
   watch: {
     'editData.bgnde'(newVal, oldVal) {
@@ -165,6 +188,7 @@
   },
 
   methods: {
+    // 상세 조회
     async findData() {
       try {
         const response = await findVcatnProc(this.pageId);
@@ -174,21 +198,9 @@
         this.editData.bgnde = this.editData.bgnde.split(' ')[0];
         this.editData.endde = this.editData.endde.split(' ')[0];
 
-        let sanctns = [];
-        for (let sanctn of this.editData.sanctnList) {
-          let data = {
-            confmerId: sanctn.confmerId,
-            clsf: sanctn.clsf,
-            sanctnOrdr: sanctn.sanctnOrdr,
-            sanctnSe: sanctn.sanctnSe,
-            clsfNm: sanctn.confmerInfo?.clsf,
-            userNm: sanctn.confmerInfo?.userNm
-          }
-          sanctns.push(data);
-        }
-        this.editData.sanctnList = sanctns;
-
+        await this.$nextTick();
         await this.fnOnchangeVcatnKnd();
+
       } catch (error) {
         console.error('데이터 조회 실패:', error);
         const message = error.response?.data?.message || "데이터를 불러오는데 실패했습니다.";
@@ -199,23 +211,19 @@
 
     // 유형 변경
     async fnOnchangeVcatnKnd() {
-      if (!this.isCodesLoaded || !Array.isArray(this.cmmnCodes.vcatnKndCodeList)) {
-        console.warn('cmmnCodes가 초기화되지 않았습니다.');
-        return;
-      }
-
-      const selectedVcatn = this.cmmnCodes.vcatnKndCodeList.find(item => item.code === this.editData.vcatnKnd);
+      const selectedVcatn = this.vcatnKnds.find(item => item.code === this.editData.vcatnKnd);
       if (!selectedVcatn) {
         console.warn('선택된 휴가 유형을 찾을 수 없습니다.');
         return;
       }
 
-      this.dayCnt = parseFloat(selectedVcatn.codeValue);
-
-      if (this.dayCnt === 0.5) {
+      // 반차 하위 유형인지 확인
+      if (this.isHalfDaySubType) {
+        this.dayCnt = 0.5;
+        this.setHalfDayTime(selectedVcatn);
         this.changeBgnde(); // 반차일 경우 종료일을 시작일과 동일하게 설정
       } else {
-        this.editData.vcatnSubKnd = ''; // 세부 유형 선택 초기화
+        this.dayCnt = parseFloat(selectedVcatn.codeValue);
 
         // 전체 근무시간으로 설정
         this.editData.beginHour = this.workConfig.startHour.toString().padStart(2, '0');
@@ -224,17 +232,6 @@
         this.editData.endMnt = '00';
         this.calculateTotalDays();
       }
-    },
-
-    // 세부 유형 변경
-    fnOnchangeVcatnSubKnd() {
-      if (this.dayCnt === 0.5) {
-        const selectedSubType = this.subTypes.find(item => item.code === this.editData.vcatnSubKnd);
-        if (selectedSubType) {
-          this.setHalfDayTime(selectedSubType);
-        }
-      }
-      this.calculateTotalDays();
     },
 
     // 반차 시간 설정 메서드
@@ -359,13 +356,16 @@
     // 승인자
     fnAddSanctn(user) {
       const data = {
-        confmerId: user.userId,
-        clsf: user.clsf,
-        sanctnOrdr: this.editData.nmprList.length + 1,
-        sanctnSe: this.cmmnCodes.sanctnCodeList[0].code,
+        sanctnId: null,                                   // 결재 아이디
+        confmerId: user.userId,                           // 승인자 아이디
+        clsf: user.clsf,                                  // 직급
+        sanctnOrdr: this.editData.sanctnList.length + 1,  // 결재 순서
+        sanctnIem: this.editData.vcatnKnd,                // 결재 항목
+        sanctnMbyId: null,                                // 결재 주체 아이디
+        sanctnSe: this.sanctnCodes[0].code,               // 결재구분
 
-        clsfNm: this.formatClsf(user.clsf),
-        userNm: user.userNm,
+        confmerNm: user.userNm,                           // 승인자 이름
+        clsfNm: user.clsfNm,                              // 직급 이름
       };
 
       this.editData.sanctnList.push(data);
@@ -379,12 +379,7 @@
       });
     },
 
-    // 직급 매칭
-    formatClsf(code) {
-      const clsfCode = this.cmmnCodes?.clsfCodeList?.find(item => item.code === code);
-      return clsfCode?.codeNm || code;
-    },
-
+    // 이전 승인자 조회
     async fnRecord() {
       try {
         const response = await findLastVcatnProc();
@@ -403,6 +398,7 @@
       }
     },
 
+    // 유효성 검사
     validateForm() {
       if (this.$isEmpty(this.editData.vcatnKnd)) {
         alert("유형을 선택해 주세요.");
@@ -424,38 +420,35 @@
         return false;
       }
 
-      if (this.dayCnt === 0.5) {
-        if (this.$isEmpty(this.editData.vcatnSubKnd)) {
-          alert("세부 유형을 선택해 주세요.");
-          return false;
-        }
-      }
-
       return true;
     },
 
+    // 신청
     async fnSave() {
       try {
         if (!this.validateForm()) {
           return;
         }
 
+        // 데이터 세팅
+        let data = this.editData;
         if (!this.$isEmpty(this.pageId)) {
-          this.editData.confm_at = 'W';
+          data.confmAt = 'W';
         }
 
-        const response = this.$isEmpty(this.pageId) ? await saveVcatnProc(this.editData) : await updateVcatnProc(this.editData);
+        const response = this.$isEmpty(this.pageId) ? await saveVcatnProc(data) : await updateVcatnProc(data);
         const message = this.$isEmpty(this.pageId) ? "등록되었습니다." : "수정되었습니다.";
         alert(message);
 
         this.fnMoveTo('view', response.data.data.pageId);
       } catch (error) {
         console.error('저장 실패:', error);
-        const message = error.response?.data?.message || "저장에 실패했습니다.";
+        const message = error.response.data.message || "저장에 실패했습니다.";
         alert(message);
       }
     },
 
+    // 페이지 이동
     fnMoveTo(type, id) {
       const routes = {
         'list': { name: 'hyugaStatue' },
client/views/pages/Manager/attendance/attendance.vue
--- client/views/pages/Manager/attendance/attendance.vue
+++ client/views/pages/Manager/attendance/attendance.vue
@@ -176,7 +176,6 @@
   created() {
     // 로컬스토리지에서 기존 데이터가 있으면 불러오기
     const storedData = localStorage.getItem('DeptData');
-    console.log(storedData);
     if (storedData) {
       this.DeptData = JSON.parse(storedData);
     }
client/views/pages/Manager/attendance/hyugaStatue.vue
--- client/views/pages/Manager/attendance/hyugaStatue.vue
+++ client/views/pages/Manager/attendance/hyugaStatue.vue
@@ -41,12 +41,12 @@
               </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>
+              <template v-if="lists.length > 0">
+                <tr v-for="(item, idx) in lists" :key="idx" @click="fnMoveTo('view', item.vcatnId)">
+                  <td>{{ item.vcatnKndNm }}</td>
+                  <td>{{ $formattedDates(item) }}</td>
                   <td>{{ item.rgsde }}</td>
-                  <td :class="getStatusClass(item.formattedStatus)">{{ item.formattedStatus }}</td>
+                  <td>{{ item.confmAtNm }}</td>
                 </tr>
               </template>
               <tr v-else>
@@ -64,7 +64,7 @@
 import { SearchOutlined } from '@ant-design/icons-vue';
 import Pagenation from '../../../component/Pagenation.vue';
 // API
-import { findVcatnsSummary, findMyVcatnsProc } from '../../../../resources/api/vcatn';
+import { findVcatnsSummary, findVcatnsProc } from '../../../../resources/api/vcatn';
 
 export default {
   components: {
@@ -82,52 +82,18 @@
       useSummary: [], // 연차 소모성 휴가
       notUseSummary: [], // 연차 비 소모성 휴가
 
-      // 휴가 현황 목록 조회용
-      listData: [],
       request: {
         vcatnKnds: null, // 휴가 종류
         bgnde: null, // 시작일
         endde: null, // 종료일
       },
-
-      // 공통코드(구분, 상태) 목록 조회용
-      vcatnKnds: [],
-      confmTypes: [],
-      serachRequest: {
-        searchType: "upperCd",
-        searchText: null,
-      },
+      lists: [],
     };
   },
 
-  computed: {
-    formattedListData() {
-      if (!this.listData || !Array.isArray(this.listData)) {
-        return [];
-      }
+  computed: {},
 
-      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(); // 상태 코드 조회
-  },
+  created() { },
 
   mounted() {
     this.findSummary(); // 현황 조회
@@ -135,35 +101,6 @@
   },
 
   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;
@@ -208,6 +145,27 @@
       };
     },
 
+    // 목록 조회
+    async findList() {
+      const vm = this;
+      try {
+        delete vm.request.vcatnKndList;
+
+        const response = await findVcatnsProc(vm.request);
+        const result = response.data.data;
+
+        vm.lists = result.lists;
+        vm.request = result.search;
+      } catch (error) {
+        if (error.response) {
+          alert(error.response.data.message);
+        } else {
+          alert("에러가 발생했습니다.");
+        }
+        console.error(error.message);
+      };
+    },
+
     // 현황에 클래스 부여
     getBoxClass(idx) {
       if (idx === 0) return 'box';
@@ -231,27 +189,6 @@
       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') {
@@ -264,27 +201,12 @@
 
       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 '';
     },
 
     // 페이지 이동
Add a comment
List