jichoi / calendar star
박정하 박정하 07-28
250725 박정하 공통코드 관리 추가
@44550f5fdcb38313279150fd2cc442a8b8578491
 
client/resources/api/cmmnCode.js (deleted)
--- client/resources/api/cmmnCode.js
@@ -1,6 +0,0 @@
-import apiClient from "./index";
-
-// 조회 - 목록
-export const findCodeListProc = data => {
-  return apiClient.post('/system/cmmnCode/findCodeList.json', data);
-}(파일 끝에 줄바꿈 문자 없음)
 
client/resources/api/code.js (added)
+++ client/resources/api/code.js
@@ -0,0 +1,21 @@
+import apiClient from "./index";
+
+// 등록
+export const saveCodeProc = data => {
+  return apiClient.post('/code/saveCode.json', data);
+}
+
+// 목록 조회
+export const findCodesProc = data => {
+  return apiClient.get('/code/findCodes.json', { params: data });
+}
+
+// 상세 조회
+export const findCodeProc = data => {
+  return apiClient.get(`/code/${data}/findCode.json`);
+}
+
+// 수정
+export const updateCodeProc = (id, data) => {
+  return apiClient.put(`/code/${id}/updateCode.json`, data);
+}(파일 끝에 줄바꿈 문자 없음)
 
client/resources/api/menu.js (added)
+++ client/resources/api/menu.js
@@ -0,0 +1,6 @@
+import apiClient from "./index";
+
+// 목록 조회
+export const findMenusProc = () => {
+  return apiClient.get('/menu/findMenus.json');
+}(파일 끝에 줄바꿈 문자 없음)
client/resources/api/sanctns.js
--- client/resources/api/sanctns.js
+++ client/resources/api/sanctns.js
@@ -1,5 +1,10 @@
 import apiClient from "./index";
 
+// 결재 요청 목록 조회
+export const findMyRequestsProc = data => {
+  return apiClient.get('/sanctn/findMyRequests.json', { params: data });
+}
+
 // 조회 - 목록
 export const findSanctnsProc = data => {
   return apiClient.get('/sanctn/findSanctns.json', { params: data });
client/resources/js/cmmnPlugin.js
--- client/resources/js/cmmnPlugin.js
+++ client/resources/js/cmmnPlugin.js
@@ -1,5 +1,5 @@
 import store from '../../views/pages/AppStore'
-import { findCodeListProc } from '../api/cmmnCode'
+import { findCodeListProc } from '../api/code'
 
 export default {
   install(Vue) {
client/views/component/Pagination.vue (Renamed from client/views/component/Pagenation.vue)
--- client/views/component/Pagenation.vue
+++ client/views/component/Pagination.vue
No changes
 
client/views/component/Popup/CodePopup.vue (deleted)
--- client/views/component/Popup/CodePopup.vue
@@ -1,118 +0,0 @@
-<template>
-    <div  class="popup-overlay" @click.self="$emit('close')">
-                <div class="popup-content">
-                  <div class="card">
-                    <div class="card-body">
-                      <h2 class="card-title">코드 목록</h2>
-                      <div class="sch-form-wrap">
-                        <div class="input-group">
-                          <select name="" id="" class="form-select">
-          <option value="">전체</option>
-          <option value="">상위코드</option>
-          <option value="">상위코드명</option>
-          <option value="">코드</option>
-          <option value="">코드명</option>
-        </select>
-                          <div class="sch-input">
-              <input type="text" class="form-control">
-              <button class="ico-sch"><SearchOutlined /></button>
-            </div>
-                        </div>
-                      </div>
-
-                      <!-- Table  -->
-                      <div class="tbl-wrap">
-                        <table id="myTable" class="tbl data">
-                          <!-- 동적으로 <th> 생성 -->
-                          <thead>
-                            <tr>
-                              <th>상위코드 </th>
-                              <th>상위코드명</th>
-                              <th>코드</th>
-                              <th>코드명</th>
-                              <th>선택</th>
-                            </tr>
-                          </thead>
-                          <!-- 동적으로 <td> 생성 -->
-                          <tbody>
-                            <tr v-for="(item, index) in popuplistData" :key="index">
-      <td>{{ item.parentCode }}</td>
-      <td>{{ item.parentCodeName }}</td>
-      <td>{{ item.code }}</td>
-      <td>{{ item.codeName }}</td>
-      <td>
-        <button
-          type="button"
-          class="btn sm sm secondary"
-          @click="selectPerson(item)"
-        >
-          선택
-        </button>
-      </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 -->
-                    </div>
-                  </div>
-                  <button @click="$emit('close')" class="close-btn">
-                    <CloseCircleFilled />
-                  </button>
-                </div>
-              </div>
-</template>
-<script>
-import { SearchOutlined, CloseCircleFilled } from '@ant-design/icons-vue';
-
-export default {
-    data() {
-        return {
-            popuplistData: [
-            {
-        parentCode: '상위코드1',
-        parentCodeName: '상위코드명1',
-        code: '코드1',
-        codeName: '코드명1'
-      },
-      ],
-        }
-    },
-    components: {
-    SearchOutlined, CloseCircleFilled
-  },
-  methods: {
-    selectPerson(item) {
-    this.$emit('select', item); // 부모에게 데이터 전달
-  },
-    
-  }
-}
-</script>
-<style scoped>
-.popup-content {
-    width: 50%;
-}
-</style>(파일 끝에 줄바꿈 문자 없음)
 
client/views/component/Popup/CodeSelectorModal.vue (added)
+++ client/views/component/Popup/CodeSelectorModal.vue
@@ -0,0 +1,167 @@
+<template>
+  <div class="popup-overlay">
+    <div class="popup-content">
+      <div class="card">
+        <div class="card-body">
+          <h2 class="card-title">공통코드 목록</h2>
+          <div class="sch-form-wrap">
+            <div class="input-group">
+              <select name="searchType" id="searchType" class="form-select" v-model="searchParams.searchType">
+                <option value="">전체</option>
+                <option v-for="(item, index) of searchOptions" :key="index" :value="item.key"> {{ item.label }} </option>
+              </select>
+              <div class="sch-input">
+                <input type="text" class="form-control" v-model="searchParams.searchText" @keyup.enter="handleSearch" placeholder="검색어를 입력하세요">
+                <button class="ico-sch" @click="handleSearch" type="button">
+                  <SearchOutlined />
+                </button>
+              </div>
+            </div>
+          </div>
+          <div class="tbl-wrap">
+            <table class="tbl data">
+              <colgroup>
+                <col style="width: 23%;">
+                <col style="width: 23%;">
+                <col style="width: 23%;">
+                <col style="width: 23%;">
+                <col style="width: 8%;">
+              </colgroup>
+              <thead>
+                <tr>
+                  <th>상위코드</th>
+                  <th>상위코드명</th>
+                  <th>코드</th>
+                  <th>코드명</th>
+                  <th>선택</th>
+                </tr>
+              </thead>
+              <tbody>
+                <template v-if="codeList.length > 0">
+                  <tr v-for="(item, index) in codeList" :key="index">
+                    <td>{{ item.upperCode || '-' }}</td>
+                    <td>{{ item.upperCodeNm || '-' }}</td>
+                    <td>{{ item.code }}</td>
+                    <td>{{ item.codeNm }}</td>
+                    <td>
+                      <button type="button" class="btn sm secondary" @click="handleCodeSelect(item)"> 선택 </button>
+                    </td>
+                  </tr>
+                </template>
+                <tr v-else>
+                  <td colspan="5" class="text-center">검색 결과가 없습니다.</td>
+                </tr>
+              </tbody>
+            </table>
+          </div>
+          <Pagination :search="searchParams" @onChange="handlePageChange" />
+        </div>
+      </div>
+      <button @click="handleModalClose" class="close-btn" type="button">
+        <CloseCircleFilled />
+      </button>
+    </div>
+  </div>
+</template>
+<script>
+import { SearchOutlined, CloseCircleFilled } from '@ant-design/icons-vue';
+import Pagination from "../Pagination.vue";
+// API
+import { findCodesProc } from "../../../resources/api/code";
+
+export default {
+  name: 'CodeSelectorModal',
+
+  components: {
+    SearchOutlined,
+    CloseCircleFilled,
+    Pagination,
+  },
+
+  props: {
+    currentCodeId: {
+      type: String,
+      default: null
+    },
+  },
+
+  emits: ['select', 'close'],
+
+  data() {
+    return {
+      codeList: [],
+
+      searchOptions: [
+        { key: "UPPER_CODE", label: "상위코드" },
+        { key: "UPPERCODE_NAME", label: "상위코드 이름" },
+        { key: "CODE", label: "코드" },
+        { key: "CODE_NAME", label: "코드 이름" },
+      ],
+
+      searchParams: {
+        searchType: '',
+        searchText: '',
+        recordSize: 5,
+        pageSize: 5,
+        currentPage: 1,
+        currentCodeId: this.currentCodeId, // 백엔드에서 제외할 코드ID
+      }
+    }
+  },
+
+  mounted() {
+    this.fetchCodeList();
+  },
+
+  methods: {
+    // 코드 목록 조회
+    async fetchCodeList() {
+      try {
+        const response = await findCodesProc(this.searchParams);
+        const result = response.data.data;
+
+        this.codeList = result.codes;
+        this.searchParams = result.search;
+      } catch (error) {
+        this.handleError(error);
+      }
+    },
+
+    // 검색 실행
+    handleSearch() {
+      this.searchParams.currentPage = 1;
+      this.fetchCodeList();
+    },
+
+    // 페이지 변경
+    handlePageChange(currentPage) {
+      this.searchParams.currentPage = Number(currentPage);
+      this.$nextTick(() => {
+        this.fetchCodeList();
+      });
+    },
+
+    // 코드 선택
+    handleCodeSelect(selectedCode) {
+      this.$emit('select', selectedCode);
+    },
+
+    // 모달 닫기
+    handleModalClose() {
+      this.$emit('close');
+    },
+
+    // 에러 처리
+    handleError(error) {
+      const message = error.response?.data?.message || "에러가 발생했습니다.";
+      alert(message);
+      console.error(error.message);
+    },
+  },
+}
+</script>
+<style scoped>
+.popup-content {
+  width: 50%;
+}
+</style>(파일 끝에 줄바꿈 문자 없음)
client/views/component/Popup/CorpCarPopup.vue
--- client/views/component/Popup/CorpCarPopup.vue
+++ client/views/component/Popup/CorpCarPopup.vue
@@ -34,7 +34,7 @@
               </tbody>
             </table>
           </div>
-          <Pagenation :search="request" @onChange="fnChangeCurrentPage" />
+          <Pagination :search="request" @onChange="fnChangeCurrentPage" />
         </div>
       </div>
       <button @click="$emit('close')" class="close-btn">
@@ -45,14 +45,14 @@
 </template>
 <script>
 import { SearchOutlined, CloseCircleFilled } from '@ant-design/icons-vue';
-import Pagenation from '../Pagenation.vue';
+import Pagination from '../Pagination.vue';
 // API
 import { findAllAsSetVhcle } from '../../../resources/api/asset'
 
 export default {
   components: {
     SearchOutlined, CloseCircleFilled,
-    Pagenation
+    Pagination
   },
 
   props: {
client/views/component/Popup/CorpCardPopup.vue
--- client/views/component/Popup/CorpCardPopup.vue
+++ client/views/component/Popup/CorpCardPopup.vue
@@ -32,7 +32,7 @@
               </tbody>
             </table>
           </div>
-          <Pagenation :search="request" @onChange="fnChangeCurrentPage" />
+          <Pagination :search="request" @onChange="fnChangeCurrentPage" />
         </div>
       </div>
       <button @click="$emit('close')" class="close-btn">
@@ -43,14 +43,14 @@
 </template>
 <script>
 import { SearchOutlined, CloseCircleFilled } from '@ant-design/icons-vue';
-import Pagenation from '../Pagenation.vue';
+import Pagination from '../Pagination.vue';
 // API
 import { findAllAsSetCard } from '../../../resources/api/asset'
 
 export default {
   components: {
     SearchOutlined, CloseCircleFilled,
-    Pagenation,
+    Pagination,
   },
 
   props: {
client/views/component/Popup/HrPopup.vue
--- client/views/component/Popup/HrPopup.vue
+++ client/views/component/Popup/HrPopup.vue
@@ -38,7 +38,7 @@
               </tbody>
             </table>
           </div>
-          <Pagenation :search="request" @onChange="fnChangeCurrentPage" />
+          <Pagination :search="request" @onChange="fnChangeCurrentPage" />
         </div>
       </div>
       <button @click="$emit('close')" class="close-btn">
@@ -49,14 +49,14 @@
 </template>
 <script>
 import { SearchOutlined, CloseCircleFilled } from '@ant-design/icons-vue';
-import Pagenation from '../Pagenation.vue';
+import Pagination from '../Pagination.vue';
 // API
 import { findUsersProc } from '../../../resources/api/user';
 
 export default {
   components: {
     SearchOutlined, CloseCircleFilled,
-    Pagenation
+    Pagination
   },
 
   props: {
client/views/layout/LeftNavBar.vue
--- client/views/layout/LeftNavBar.vue
+++ client/views/layout/LeftNavBar.vue
@@ -174,7 +174,7 @@
     items: [
       { name: 'AuthorManagementPage', title: '사용자권한관리' },
       { name: 'MenuAuthorManagementPage', title: '접근제어관리' },
-      { name: 'commonCodeManagement', title: '공통코드관리' }
+      { name: 'CodeManagementListPage', title: '공통코드관리' }
     ]
   }
 }
client/views/pages/AppRouter.js
--- client/views/pages/AppRouter.js
+++ client/views/pages/AppRouter.js
@@ -63,9 +63,9 @@
 //시스템관리
 import AuthorManagementComp from '../pages/Manager/system/AuthorManagement.vue';
 import MenuAuthorManagementComp from './Manager/system/MenuAuthorManagement.vue';
-import commonCodeManagement from '../pages/Manager/system/commonCodeManagement.vue';
-import commonCodeInsert from '../pages/Manager/system/commonCodeInsert.vue';
-import commonCodeDetail from '../pages/Manager/system/commonCodeDetail.vue';
+import CodeManagementListComp from '../pages/Manager/system/CodeManagementList.vue';
+import CodeManagementInsertComp from '../pages/Manager/system/CodeManagementInsert.vue';
+import CodeManagementViewComp from '../pages/Manager/system/CodeManagementView.vue';
 
 const routes = [
   { path: '/', name: '/', component: Main },
@@ -153,9 +153,9 @@
     children: [
       { path: 'AuthorManagement.page', name: 'AuthorManagementPage', component: AuthorManagementComp},
       { path: 'MenuAuthorManagement.page', name: 'MenuAuthorManagementPage', component: MenuAuthorManagementComp },
-      { path: 'commonCodeManagement.page', name: 'commonCodeManagement', component: commonCodeManagement },
-      { path: 'commonCodeInsert.page', name: 'commonCodeInsert', component: commonCodeInsert },
-      { path: 'commonCodeDetail.page', name: 'commonCodeDetail', component: commonCodeDetail },
+      { path: 'CodeManagementList.page', name: 'CodeManagementListPage', component: CodeManagementListComp },
+      { path: 'CodeManagementInsert.page', name: 'CodeManagementInsertPage', component: CodeManagementInsertComp },
+      { path: 'CodeManagementView.page', name: 'CodeManagementViewPage', component: CodeManagementViewComp },
     ]
   },
 ];
 
client/views/pages/Manager/approval/approval.vue (deleted)
--- client/views/pages/Manager/approval/approval.vue
@@ -1,141 +0,0 @@
-<template>
-  <div class="sidemenu">
-    <div class="myinfo simple">
-      <div class="name-box">
-        <div class="img-area">
-          <div><img :src="photoicon" alt="">
-            <p class="name">OOO과장</p>
-          </div>
-          <div class="info">
-            <p>솔루션 개발팀</p>
-            <i class="fa-bars"></i>
-            <p>팀장</p>
-          </div>
-        </div>
-      </div>
-      <details class="menu-box" open>
-        <summary>
-          <p>결재</p>
-          <div class="icon"><img :src="topmenuicon" alt=""></div>
-        </summary>
-        <ul>
-          <li> <router-link :to="{ name: 'approvalRequest' }" exact-active-class="active-link" v-slot="{ isExactActive }">
-              <p>결재 요청</p>
-              <div class="icon" v-if="isExactActive">
-                <img :src="menuicon" alt="">
-              </div>
-            </router-link></li>
-          <li>
-            <router-link :to="{ name: 'approvalList' }" exact-active-class="active-link" v-slot="{ isExactActive }">
-              <p>승인 대기 목록</p>
-              <div class="icon" v-if="isExactActive">
-                <img :src="menuicon" alt="">
-              </div>
-            </router-link>
-          </li>
-        </ul>
-      </details>
-    </div>
-  </div>
-  <!-- End Page Title -->
-  <div class="content">
-    <router-view></router-view>
-  </div>
-</template>
-<script>
-import { ref } from 'vue';
-
-export default {
-  data() {
-    return {
-      photoicon: "/client/resources/img/photo_icon.png",
-      menuicon: "/client/resources/img/menuicon.png",
-      topmenuicon: "/client/resources/img/topmenuicon.png",
-      // 데이터 초기화
-      years: [2023, 2024, 2025], // 연도 목록
-      months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 월 목록
-      selectedYear: '',
-      selectedMonth: '',
-      DeptData: [
-        { member: '', deptNM: '', acceptTerms: false },
-        // 더 많은 데이터 추가...
-      ],
-      filteredData: [],
-    };
-  },
-  computed: {
-  },
-  methods: {
-    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); // 배열 상태 출력
-    },
-    saveChanges() {
-      // 로컬스토리지에 DeptData 저장
-      localStorage.setItem('DeptData', JSON.stringify(this.DeptData));
-      console.log('데이터가 로컬스토리지에 저장되었습니다.');
-    },
-    deletePending() {
-      // 선택된 항목만 필터링하여 삭제
-      const selectedItems = this.DeptData.filter(item => item.acceptTerms);
-
-      // 승인된 항목이 없으면 삭제 진행
-      if (selectedItems.length > 0) {
-        this.DeptData = this.DeptData.filter(item => !item.acceptTerms);
-        alert(`${selectedItems.length}개의 항목이 삭제되었습니다.`);
-      } else {
-        alert("선택된 항목이 없습니다.");
-      }
-    },
-    // 날짜 필터 적용
-    filterData() {
-      this.filteredData = this.DeptData.filter(item => {
-        const itemYear = new Date(item.startDate).getFullYear();
-        const itemMonth = new Date(item.startDate).getMonth() + 1; // 월은 0부터 시작하므로 1을 더해줍니다.
-
-        return (
-          (!this.selectedYear || itemYear === parseInt(this.selectedYear)) &&
-          (!this.selectedMonth || itemMonth === parseInt(this.selectedMonth))
-        );
-      });
-    },
-
-    // 페이지 변경
-    changePage(page) {
-      this.currentPage = page;
-    },
-  },
-  created() {
-    // 로컬스토리지에서 기존 데이터가 있으면 불러오기
-    const storedData = localStorage.getItem('DeptData');
-    if (storedData) {
-      this.DeptData = JSON.parse(storedData);
-    }
-  },
-  mounted() {
-
-    // 처음에는 모든 데이터를 표시
-    this.filteredData = this.DeptData;
-
-  },
-};
-</script>
-<style scoped></style>
client/views/pages/Manager/asset/CardInfoManagement.vue
--- client/views/pages/Manager/asset/CardInfoManagement.vue
+++ client/views/pages/Manager/asset/CardInfoManagement.vue
@@ -119,7 +119,7 @@
             </table>
 
           </div>
-          <Pagenation :search="searchReqHisDTO" @onChange="fnChangeCurrentPage" />
+          <Pagination :search="searchReqHisDTO" @onChange="fnChangeCurrentPage" />
         </div>
       </div>
     </div>
@@ -133,7 +133,7 @@
 import HrPopup from "../../../component/Popup/HrPopup.vue";
 import { SearchOutlined, CloseCircleFilled } from '@ant-design/icons-vue';
 import { saveAsSetCard, findAllAsSetCard, updateAsSetCard, findAllAsSetCardHis } from "../../../../resources/api/asset"; //카드 정보 API
-import Pagenation from "../../../component/Pagenation.vue";
+import Pagination from "../../../component/Pagination.vue";
 
 export default {
   data() {
@@ -149,7 +149,7 @@
       startbtn: "/client/resources/img/start.png",
       stopbtn: "/client/resources/img/stop.png",
       moreicon: "/client/resources/img/more.png",
-      
+
       checkCard: false,
       cardId: null,
       selectedCards: [],
@@ -188,7 +188,7 @@
     }
   },
   components: {
-    SearchOutlined, CloseCircleFilled, HrPopup, Pagenation
+    SearchOutlined, CloseCircleFilled, HrPopup, Pagination
   },
   methods: {
     // 페이지 이동
client/views/pages/Manager/asset/CardList.vue
--- client/views/pages/Manager/asset/CardList.vue
+++ client/views/pages/Manager/asset/CardList.vue
@@ -51,7 +51,7 @@
           </table>
 
         </div>
-        <Pagenation :search="searchReqHisResDTO" @onChange="fnChangeCurrentPageRes" />
+        <Pagination :search="searchReqHisResDTO" @onChange="fnChangeCurrentPageRes" />
         <div class="sch-form-wrap title-wrap">
           <h3><img :src="h3icon" alt="">사용이력</h3>
           <div class="input-group">
@@ -100,7 +100,7 @@
           </table>
 
         </div>
-        <Pagenation :search="searchReqHisRtnDTO" @onChange="fnChangeCurrentPageRtn" />
+        <Pagination :search="searchReqHisRtnDTO" @onChange="fnChangeCurrentPageRtn" />
       </div>
     </div>
   </div>
@@ -109,7 +109,7 @@
 <script>
 import { ref } from 'vue';
 import { SearchOutlined } from '@ant-design/icons-vue';
-import Pagenation from "../../../component/Pagenation.vue";
+import Pagination from "../../../component/Pagination.vue";
 import { findAllAsSetCardHis } from "../../../../resources/api/asset"; //카드 정보 API
 export default {
   data() {
@@ -160,7 +160,7 @@
   computed: {
   },
   components: {
-    SearchOutlined, Pagenation
+    SearchOutlined, Pagination
   },
   methods: {
     // 페이지 이동 예약현황황
@@ -182,7 +182,7 @@
         console.error("검색 중 오류 발생:", error);
       }
     },
-    // 페이지 이동 사용현황 
+    // 페이지 이동 사용현황
     fnChangeCurrentPageRtn(currentPage) {
       this.searchReqHisRtnDTO.currentPage = Number(currentPage);
       this.$nextTick(() => {
client/views/pages/Manager/asset/VhcleInfoManagement.vue
--- client/views/pages/Manager/asset/VhcleInfoManagement.vue
+++ client/views/pages/Manager/asset/VhcleInfoManagement.vue
@@ -152,7 +152,7 @@
             </table>
 
           </div>
-          <Pagenation :search="searchReqHisDTO" @onChange="fnChangeCurrentPage" />
+          <Pagination :search="searchReqHisDTO" @onChange="fnChangeCurrentPage" />
         </div>
       </div>
     </div>
@@ -166,7 +166,7 @@
 import { SearchOutlined } from '@ant-design/icons-vue';
 import HrPopup from "../../../component/Popup/HrPopup.vue";
 import { saveAsSetVhcle, findAllAsSetVhcle, updateAsSetVhcle, findAllAsSetVhcleHis } from "../../../../resources/api/asset"; //카드 정보 API
-import Pagenation from "../../../component/Pagenation.vue";
+import Pagination from "../../../component/Pagination.vue";
 
 export default {
   data() {
@@ -183,7 +183,7 @@
       startbtn: "/client/resources/img/start.png",
       stopbtn: "/client/resources/img/stop.png",
       moreicon: "/client/resources/img/more.png",
-      
+
       checkVhcle: false,
       vhcleId: null,
       selectedVhcles: [],
@@ -226,7 +226,7 @@
     }
   },
   components: {
-    SearchOutlined, HrPopup, Pagenation
+    SearchOutlined, HrPopup, Pagination
   },
   methods: {
     // 페이지 이동
client/views/pages/Manager/asset/VhcleList.vue
--- client/views/pages/Manager/asset/VhcleList.vue
+++ client/views/pages/Manager/asset/VhcleList.vue
@@ -56,7 +56,7 @@
           </table>
 
         </div>
-        <Pagenation :search="searchReqHisResDTO" @onChange="fnChangeCurrentPageRes" />
+        <Pagination :search="searchReqHisResDTO" @onChange="fnChangeCurrentPageRes" />
         <div class="sch-form-wrap title-wrap">
           <h3><img :src="h3icon" alt="">사용이력</h3>
           <div class="input-group">
@@ -110,7 +110,7 @@
           </table>
 
         </div>
-        <Pagenation :search="searchReqHisRtnDTO" @onChange="fnChangeCurrentPageRtn" />
+        <Pagination :search="searchReqHisRtnDTO" @onChange="fnChangeCurrentPageRtn" />
       </div>
     </div>
   </div>
@@ -119,14 +119,14 @@
 <script>
 import { ref } from 'vue';
 import { SearchOutlined } from '@ant-design/icons-vue';
-import Pagenation from "../../../component/Pagenation.vue";
+import Pagination from "../../../component/Pagination.vue";
 import { findAllAsSetVhcleHis } from "../../../../resources/api/asset"; //차량 정보 API
 export default {
   data() {
     return {
       photoicon: "/client/resources/img/photo_icon.png",
       h3icon: "/client/resources/img/h3icon.png",
-      
+
       searchReqHisResDTO: {
         searchType: "all",
         searchText: null,
@@ -170,7 +170,7 @@
   computed: {
   },
   components: {
-    SearchOutlined, Pagenation
+    SearchOutlined, Pagination
   },
   methods: {
     // 페이지 이동 예약현황황
@@ -192,7 +192,7 @@
         console.error("검색 중 오류 발생:", error);
       }
     },
-    // 페이지 이동 사용현황 
+    // 페이지 이동 사용현황
     fnChangeCurrentPageRtn(currentPage) {
       this.searchReqHisRtnDTO.currentPage = Number(currentPage);
       this.$nextTick(() => {
client/views/pages/Manager/attendance/ChuljangStatue.vue
--- client/views/pages/Manager/attendance/ChuljangStatue.vue
+++ client/views/pages/Manager/attendance/ChuljangStatue.vue
@@ -41,7 +41,7 @@
             </tbody>
           </table>
         </div>
-        <Pagenation :search="request" @onChange="fnChangeCurrentPage" />
+        <Pagination :search="request" @onChange="fnChangeCurrentPage" />
       </div>
     </div>
   </div>
client/views/pages/Manager/attendance/hyugaStatue.vue
--- client/views/pages/Manager/attendance/hyugaStatue.vue
+++ client/views/pages/Manager/attendance/hyugaStatue.vue
@@ -55,21 +55,21 @@
             </tbody>
           </table>
         </div>
-        <Pagenation :search="request" @onChange="fnChangeCurrentPage" />
+        <Pagination :search="request" @onChange="fnChangeCurrentPage" />
       </div>
     </div>
   </div>
 </template>
 <script>
 import { SearchOutlined } from '@ant-design/icons-vue';
-import Pagenation from '../../../component/Pagenation.vue';
+import Pagination from '../../../component/Pagination.vue';
 // API
 import { findVcatnsSummary, findVcatnsProc } from '../../../../resources/api/vcatn';
 
 export default {
   components: {
     SearchOutlined,
-    Pagenation
+    Pagination
   },
 
   data() {
 
client/views/pages/Manager/system/CodeManagementInsert.vue (added)
+++ client/views/pages/Manager/system/CodeManagementInsert.vue
@@ -0,0 +1,242 @@
+<template>
+  <div class="card">
+    <div class="card-body">
+      <h2 class="card-title">공통코드 {{ isEditMode ? '수정' : '등록' }}</h2>
+      <p class="require">* 필수입력</p>
+      <div class="tbl-wrap needs-validation detail">
+        <table class="tbl data radius-table">
+          <colgroup>
+            <col style="width: 25%;">
+            <col style="width: 75%;">
+          </colgroup>
+          <tbody>
+            <tr>
+              <th>상위코드</th>
+              <td>
+                <input type="text" id="parentCode" v-model="formData.upperCode" readonly />
+                <button type="button" class="btn sm primary" @click="handleModalOpen"> 검색 </button>
+              </td>
+            </tr>
+            <tr>
+              <th>상위코드 명</th>
+              <td>
+                <input type="text" id="parentCodeName" v-model="formData.upperCodeNm" readonly />
+              </td>
+            </tr>
+            <tr>
+              <th>코드 *</th>
+              <td>
+                <input type="text" id="code" v-model="formData.code" :disabled="isEditMode" />
+              </td>
+            </tr>
+            <tr>
+              <th>코드명 *</th>
+              <td>
+                <input type="text" id="codeName" v-model="formData.codeNm" />
+              </td>
+            </tr>
+            <tr>
+              <th>코드 설정값</th>
+              <td>
+                <input type="text" id="codeValue" v-model="formData.codeValue" />
+              </td>
+            </tr>
+            <tr>
+              <th>설명</th>
+              <td>
+                <textarea name="description" id="description" v-model="formData.dc"></textarea>
+              </td>
+            </tr>
+            <tr>
+              <th>사용여부 *</th>
+              <td>
+                <div class="chk-area">
+                  <div class="form-check">
+                    <input type="radio" name="isActive" id="activeTrue" value="Y" v-model="formData.useAt" disabled>
+                    <label for="activeTrue">사용</label>
+                  </div>
+                  <div class="form-check">
+                    <input type="radio" name="isActive" id="activeFalse" value="N" v-model="formData.useAt" disabled>
+                    <label for="activeFalse">미사용</label>
+                  </div>
+                </div>
+              </td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
+      <div class="buttons">
+        <template v-if="!isEditMode">
+          <button type="button" class="btn sm primary" @click="handleCreate">등록</button>
+          <button type="button" class="btn sm tertiary" @click="handleNavigation('list')">취소</button>
+        </template>
+        <template v-else>
+          <button type="button" class="btn sm primary" @click="handleUpdate">수정</button>
+          <button type="button" class="btn sm tertiary" @click="handleNavigation('view', codeId)">취소</button>
+        </template>
+      </div>
+    </div>
+  </div>
+  <CodeSelectorModal v-if="isModalVisible" :current-code-id="codeId" @select="handleCodeSelect" @close="handleModalClose" />
+</template>
+<script>
+import CodeSelectorModal from "../../../component/Popup/CodeSelectorModal.vue";
+import { saveCodeProc, findCodeProc, updateCodeProc } from "../../../../resources/api/code";
+
+export default {
+  name: 'CodeFormPage',
+
+  components: {
+    CodeSelectorModal
+  },
+
+  data() {
+    return {
+      codeId: null,
+      isModalVisible: false,
+
+      formData: {
+        code: null,
+        codeNm: null,
+        upperCode: null,
+        upperCodeNm: null,
+        dc: null,
+        useAt: 'Y',
+        codeValue: null,
+      }
+    }
+  },
+
+  computed: {
+    isEditMode() {
+      return !this.$isEmpty(this.codeId);
+    }
+  },
+
+  created() {
+    this.codeId = this.$route.query.id;
+  },
+
+  mounted() {
+    if (this.isEditMode) {
+      this.fetchCodeDetail();
+    }
+  },
+
+  methods: {
+    // 상세 정보 조회
+    async fetchCodeDetail() {
+      try {
+        const response = await findCodeProc(this.codeId);
+        const result = response.data.data;
+
+        this.formData = result.code;
+      } catch (error) {
+        this.handleError(error);
+      }
+    },
+
+    // 신규 등록
+    async handleCreate() {
+      try {
+        if (!this.validateForm()) return;
+
+        const requestData = {
+          code: this.formData.code,
+          codeNm: this.formData.codeNm,
+          upperCode: this.formData.upperCode,
+          dc: this.formData.dc,
+          codeValue: this.formData.codeValue,
+        };
+
+        await saveCodeProc(requestData);
+        alert('등록되었습니다.');
+        this.handleNavigation('list');
+      } catch (error) {
+        this.handleError(error);
+      }
+    },
+
+    // 수정
+    async handleUpdate() {
+      try {
+        if (!this.validateForm()) return;
+
+        const requestData = {
+          codeNm: this.formData.codeNm,
+          upperCode: this.formData.upperCode,
+          dc: this.formData.dc,
+          useAt: this.formData.useAt,
+          codeValue: this.formData.codeValue,
+        };
+
+        await updateCodeProc(this.codeId, requestData);
+        alert('수정되었습니다.');
+        this.handleNavigation('view', this.codeId);
+      } catch (error) {
+        this.handleError(error);
+      }
+    },
+
+    // 폼 유효성 검사
+    validateForm() {
+      if (!this.formData.code?.trim()) {
+        alert('코드를 입력해주세요.');
+        return false;
+      }
+      if (!this.formData.codeNm?.trim()) {
+        alert('코드명을 입력해주세요.');
+        return false;
+      }
+      return true;
+    },
+
+    // 모달 열기
+    handleModalOpen() {
+      this.isModalVisible = true;
+    },
+
+    // 모달 닫기
+    handleModalClose() {
+      this.isModalVisible = false;
+    },
+
+    // 상위 코드 선택
+    handleCodeSelect(selectedCode) {
+      this.formData.upperCode = selectedCode.code;
+      this.formData.upperCodeNm = selectedCode.codeNm;
+      this.handleModalClose();
+    },
+
+    // 페이지 이동
+    handleNavigation(type, id) {
+      const routeMap = {
+        'list': { name: 'CodeManagementListPage' },
+        'view': { name: 'CodeManagementViewPage', query: { id } },
+        'edit': { name: 'CodeManagementInsertPage', query: this.$isEmpty(id) ? {} : { id } },
+      };
+
+      const route = routeMap[type];
+      if (route) {
+        this.$router.push(route);
+      } else {
+        this.handleNavigationError(type);
+      }
+    },
+
+    // 네비게이션 에러 처리
+    handleNavigationError(type) {
+      console.warn(`유효하지 않은 라우트 타입: ${type}`);
+      alert("올바르지 않은 경로를 요청하여 목록으로 이동합니다.");
+      this.$router.push({ name: 'CodeManagementListPage' });
+    },
+
+    // 에러 처리
+    handleError(error) {
+      const message = error.response?.data?.message || "에러가 발생했습니다.";
+      alert(message);
+      console.error(error.message);
+    }
+  }
+}
+</script>(파일 끝에 줄바꿈 문자 없음)
 
client/views/pages/Manager/system/CodeManagementList.vue (added)
+++ client/views/pages/Manager/system/CodeManagementList.vue
@@ -0,0 +1,176 @@
+<template>
+  <div class="col-lg-12">
+    <div class="card">
+      <div class="card-body">
+        <h2 class="card-title">공통코드 관리</h2>
+        <div class="sch-form-wrap">
+          <div class="input-group">
+            <select name="searchType" id="searchType" class="form-select" v-model="searchParams.searchType">
+              <option value="">전체</option>
+              <option v-for="(item, index) of searchOptions" :key="index" :value="item.key"> {{ item.label }} </option>
+            </select>
+            <div class="sch-input">
+              <input type="text" class="form-control" v-model="searchParams.searchText" @keyup.enter="handleSearch" placeholder="검색어를 입력하세요">
+              <button class="ico-sch" @click="handleSearch" type="button">
+                <SearchOutlined />
+              </button>
+            </div>
+          </div>
+        </div>
+        <div class="tbl-wrap">
+          <table id="codeTable" class="tbl data">
+            <colgroup>
+              <col style="width: 18%;">
+              <col style="width: 18%;">
+              <col style="width: 18%;">
+              <col style="width: 18%;">
+              <col style="width: 18%;">
+              <col style="width: 10%;">
+            </colgroup>
+            <thead>
+              <tr>
+                <th>상위코드</th>
+                <th>상위코드명</th>
+                <th>코드</th>
+                <th>코드명</th>
+                <th>등록일</th>
+                <th>사용여부</th>
+              </tr>
+            </thead>
+            <tbody>
+              <template v-if="codeList.length > 0">
+                <tr v-for="(code, index) in codeList" :key="index" :class="{ expired: code.useAt === 'N' }" @click="handleNavigation('view', code.code)">
+                  <td>{{ code.upperCode }}</td>
+                  <td>{{ code.upperCodeNm }}</td>
+                  <td>{{ code.code }}</td>
+                  <td>{{ code.codeNm }}</td>
+                  <td>{{ formatDate(code.rgsde) }}</td>
+                  <td>{{ getActiveStatusText(code.useAt) }}</td>
+                </tr>
+              </template>
+              <tr v-else>
+                <td colspan="6" class="text-center">등록된 코드가 없습니다.</td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+        <Pagination :search="searchParams" @onChange="handlePageChange" />
+        <div class="buttons">
+          <button type="button" class="btn sm primary" @click="handleNavigation('edit')">등록</button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import { SearchOutlined } from '@ant-design/icons-vue';
+import Pagination from "../../../component/Pagination.vue";
+// API
+import { findCodesProc } from "../../../../resources/api/code";
+
+export default {
+  name: 'CodeListPage',
+
+  components: {
+    SearchOutlined,
+    Pagination,
+  },
+
+  data() {
+    return {
+      codeList: [], // 코드 목록
+
+      searchOptions: [
+        { key: "UPPER_CODE", label: "상위코드" },
+        { key: "UPPERCODE_NAME", label: "상위코드 이름" },
+        { key: "CODE", label: "코드" },
+        { key: "CODE_NAME", label: "코드 이름" },
+      ],
+
+      searchParams: {
+        searchType: '',
+        searchText: '',
+        currentPage: 1,
+      }
+    }
+  },
+
+  mounted() {
+    this.fetchCodeList();
+  },
+
+  methods: {
+    // 코드 목록 조회
+    async fetchCodeList() {
+      try {
+        const response = await findCodesProc(this.searchParams);
+        const result = response.data.data;
+
+        this.codeList = result.codes;
+        this.searchParams = result.search;
+      } catch (error) {
+        this.handleError(error);
+      }
+    },
+
+    // 날짜 포맷팅
+    formatDate(dateString) {
+      return dateString ? dateString.split(' ')[0] : '-';
+    },
+
+    // 사용여부 텍스트 반환
+    getActiveStatusText(useAt) {
+      return useAt === 'Y' ? '사용중' : useAt === 'N' ? '미사용' : '';
+    },
+
+    // 검색 실행
+    handleSearch() {
+      this.searchParams.currentPage = 1;
+      this.fetchCodeList();
+    },
+
+    // 페이지 변경
+    handlePageChange(currentPage) {
+      this.searchParams.currentPage = Number(currentPage);
+      this.$nextTick(() => {
+        this.fetchCodeList();
+      });
+    },
+
+    // 페이지 이동
+    handleNavigation(type, id) {
+      const routeMap = {
+        'list': { name: 'CodeManagementListPage' },
+        'view': { name: 'CodeManagementViewPage', query: { id } },
+        'edit': { name: 'CodeManagementInsertPage', query: this.$isEmpty(id) ? {} : { id } },
+      };
+
+      const route = routeMap[type];
+      if (route) {
+        this.$router.push(route);
+      } else {
+        this.handleNavigationError(type);
+      }
+    },
+
+    // 네비게이션 에러 처리
+    handleNavigationError(type) {
+      console.warn(`유효하지 않은 라우트 타입: ${type}`);
+      alert("올바르지 않은 경로를 요청하여 목록으로 이동합니다.");
+      this.$router.push({ name: 'CodeManagementListPage' });
+    },
+
+    // 에러 처리
+    handleError(error) {
+      const message = error.response?.data?.message || "에러가 발생했습니다.";
+      alert(message);
+      console.error(error.message);
+    },
+  },
+};
+</script>
+<style scoped>
+tr {
+  cursor: pointer;
+}
+</style>(파일 끝에 줄바꿈 문자 없음)
 
client/views/pages/Manager/system/CodeManagementView.vue (added)
+++ client/views/pages/Manager/system/CodeManagementView.vue
@@ -0,0 +1,163 @@
+<template>
+  <div class="card">
+    <div class="card-body">
+      <h2 class="card-title">공통코드 상세</h2>
+      <p class="require">* 필수입력</p>
+      <div class="tbl-wrap">
+        <table class="tbl data radius-table">
+          <colgroup>
+            <col style="width: 25%;">
+            <col style="width: 25%;">
+            <col style="width: 25%;">
+            <col style="width: 25%;">
+          </colgroup>
+          <tbody>
+            <tr>
+              <th>상위코드</th>
+              <td>{{ codeDetail.upperCode }}</td>
+              <th>상위코드 명</th>
+              <td>{{ codeDetail.upperCodeNm }}</td>
+            </tr>
+            <tr>
+              <th>코드</th>
+              <td>{{ codeDetail.code }}</td>
+              <th>코드명</th>
+              <td>{{ codeDetail.codeNm }}</td>
+            </tr>
+            <tr>
+              <th>코드 설정값</th>
+              <td colspan="3">{{ codeDetail.codeValue }}</td>
+            </tr>
+            <tr>
+              <th>설명</th>
+              <td colspan="3">
+                <p>{{ codeDetail.dc }}</p>
+              </td>
+            </tr>
+            <tr>
+              <th>사용여부</th>
+              <td colspan="3">{{ getActiveStatusText(codeDetail.useAt) }}</td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
+      <div class="buttons">
+        <button type="button" class="btn sm secondary" v-if="codeDetail.useAt === 'Y'" @click="handleStatusUpdate('N')"> 삭제 </button>
+        <button type="button" class="btn sm secondary" v-if="codeDetail.useAt === 'N'" @click="handleStatusUpdate('Y')"> 복구 </button>
+        <button type="button" class="btn sm primary" @click="handleNavigation('edit', pageId)"> 수정 </button>
+        <button type="button" class="btn sm tertiary" @click="handleNavigation('list')"> 목록 </button>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+// API
+import { findCodeProc, updateCodeProc } from "../../../../resources/api/code";
+
+export default {
+  name: 'CodeDetailPage',
+
+  data() {
+    return {
+      pageId: null,
+
+      codeDetail: {
+        code: null,
+        codeNm: null,
+        upperCode: null,
+        upperCodeNm: null,
+        dc: null,
+        useAt: 'Y',
+        codeValue: null,
+      }
+    }
+  },
+
+  created() {
+    this.pageId = this.$route.query.id;
+    if (this.$isEmpty(this.pageId)) {
+      alert("게시물이 존재하지 않습니다.");
+      this.handleNavigation('list');
+    }
+  },
+
+  mounted() {
+    this.fetchCodeDetail();
+  },
+
+  methods: {
+    // 상세 정보 조회
+    async fetchCodeDetail() {
+      try {
+        const response = await findCodeProc(this.pageId);
+        const result = response.data.data;
+
+        this.codeDetail = result.code;
+      } catch (error) {
+        this.handleError(error);
+      }
+    },
+
+    // 사용상태 업데이트 (삭제/복구)
+    async handleStatusUpdate(status) {
+      try {
+        if (status === "N") {
+          const isConfirmed = confirm("삭제하시겠습니까?");
+          if (!isConfirmed) return;
+        }
+
+        const updateData = {
+          codeNm: this.codeDetail.codeNm,
+          useAt: status,
+        };
+
+        const response = await updateCodeProc(this.pageId, updateData);
+        const result = response.data.data;
+
+        this.codeDetail = result.code;
+        const message = status === "Y" ? "복구에 성공했습니다." : "삭제에 성공했습니다.";
+        alert(message);
+
+        this.fetchCodeDetail();
+      } catch (error) {
+        this.handleError(error);
+      }
+    },
+
+    // 사용여부 텍스트 반환
+    getActiveStatusText(useAt) {
+      return useAt === 'Y' ? "사용중" : "미사용";
+    },
+
+    // 페이지 이동
+    handleNavigation(type, id) {
+      const routeMap = {
+        'list': { name: 'CodeManagementListPage' },
+        'view': { name: 'CodeManagementViewPage', query: { id } },
+        'edit': { name: 'CodeManagementInsertPage', query: this.$isEmpty(id) ? {} : { id } },
+      };
+
+      const route = routeMap[type];
+      if (route) {
+        this.$router.push(route);
+      } else {
+        this.handleNavigationError(type);
+      }
+    },
+
+    // 네비게이션 에러 처리
+    handleNavigationError(type) {
+      console.warn(`유효하지 않은 라우트 타입: ${type}`);
+      alert("올바르지 않은 경로를 요청하여 목록으로 이동합니다.");
+      this.$router.push({ name: 'CodeManagementListPage' });
+    },
+
+    // 에러 처리
+    handleError(error) {
+      const message = error.response?.data?.message || "에러가 발생했습니다.";
+      alert(message);
+      console.error(error.message);
+    }
+  }
+}
+</script>(파일 끝에 줄바꿈 문자 없음)
 
client/views/pages/Manager/system/commonCodeDetail.vue (deleted)
--- client/views/pages/Manager/system/commonCodeDetail.vue
@@ -1,144 +0,0 @@
-<template>
-  <div class="card ">
-    <div class="card-body ">
-      <h2 class="card-title">사용자권한관리</h2>
-      <p class="require"><img :src="require" alt=""> 필수입력</p>
-          <form class="row g-3 pt-3  needs-validation detail" @submit.prevent="handleSubmit"
-            style="margin-bottom: 3rem;">
-            <div class="col-12">
-          <div class="col-12 border-x">
-            <label for="where" class="form-label">상위코드</label>
-            <input type="text" class="form-control" id="where" v-model="where"  readonly />
-          </div>
-          <div class="col-12 border-x">
-            <label for="where" class="form-label">상위코드 명</label>
-            <input type="text" class="form-control" id="where" v-model="where" readonly/>
-          </div>
-  
-       </div>
-       <div class="col-12">
-          <div class="col-12 border-x">
-            <label for="where" class="form-label">코드</label>
-            <input type="text" class="form-control" id="where" v-model="where"readonly />
-          </div>
-          <div class="col-12 border-x">
-            <label for="where" class="form-label">코드명</label>
-            <input type="text" class="form-control" id="where" v-model="where" readonly/>
-          </div>
-  
-       </div>
-
-            <div class="col-12 chuljang ">
-              <label for="prvonsh" class="form-label">설명</label>
-              <input type="text" class="form-control textarea" id="reason" v-model="reason" readonly/>
-            </div>
-            <div class="col-12 border-x input-radio">
-              <label for="prvonsh" class="form-label">사용여부</label>
-                <input type="text" class="form-control" id="where" v-model="where" readonly/>
-            </div>
-
-
-          </form>
-          <div class="buttons">
-        <button type="submit" class="btn sm btn-red">삭제</button>
-        <button type="submit" class="btn sm secondary">수정</button>
-        <button type="reset" class="btn sm tertiary">목록</button>
-      </div>
-    </div>
-
-  </div>
-
-</template>
-
-<script>
-import GoogleCalendar from "../../../component/GoogleCalendar.vue"
-import { SearchOutlined } from '@ant-design/icons-vue';
-export default {
-  data() {
-    return {
-      require: "/client/resources/img/require.png",
-      h3icon: "/client/resources/img/h3icon.png",
-      photoicon: "/client/resources/img/photo_icon.png",
-      img1: "/client/resources/img/img.png",
-      icon1: "/client/resources/img/icon.png",
-      dateicon: "/client/resources/img/date.png",
-      startbtn: "/client/resources/img/start.png",
-      stopbtn: "/client/resources/img/stop.png",
-      moreicon: "/client/resources/img/more.png",
-      today: new Date().toLocaleDateString('ko-KR', {
-        year: 'numeric',
-        month: '2-digit',
-        day: '2-digit',
-        weekday: 'short',
-      }),
-      time: this.getCurrentTime(),
-      listData: Array.from({ length: 20 }, (_, i) => ({
-        department: `부서 ${i + 1}`,
-        name: `이름 ${i + 1}`,
-        position: `직급 ${i + 1}`
-      }))
-    }
-  },
-  components: {
-    SearchOutlined
-  },
-  methods: {
-    formatBudget(amount) {
-      return new Intl.NumberFormat().format(amount) + ' 원';
-    },
-    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;
-    },
-    getStatusClass(status) {
-      return status === 'active' ? 'status-active' : 'status-inactive';
-    },
-    getStatusClass(status) {
-      if (status === '미진행') return 'status-pending';
-      if (status === '진행중') return 'status-approved';
-
-      // Default empty string
-      return '';
-    },
-    getCurrentTime() {
-      const now = new Date();
-      const hours = String(now.getHours()).padStart(2, '0');
-      const minutes = String(now.getMinutes()).padStart(2, '0');
-      const seconds = String(now.getSeconds()).padStart(2, '0');
-      return `${hours}:${minutes}:${seconds}`;
-    },
-    getCategoryClass(category) {
-      switch (category) {
-        case '용역': return 'category-service';
-        case '내부': return 'category-internal';
-        case '국가과제': return 'category-government';
-        default: return '';
-      }
-    },
-  },
-  watch: {
-
-  },
-  computed: {
-
-  },
-  mounted() {
-    console.log('main mounted');
-    setInterval(() => {
-      this.time = this.getCurrentTime();
-    }, 1000);
-  }
-}
-</script>
-<style scoped>
-tr {
-  cursor: pointer;
-}
-</style>(파일 끝에 줄바꿈 문자 없음)
 
client/views/pages/Manager/system/commonCodeInsert.vue (deleted)
--- client/views/pages/Manager/system/commonCodeInsert.vue
@@ -1,168 +0,0 @@
-<template>
-  <div class="card ">
-    <div class="card-body ">
-      <h2 class="card-title">사용자권한관리</h2>
-      <p class="require"><img :src="require" alt=""> 필수입력</p>
-          <form class=" needs-validation detail" @submit.prevent="handleSubmit"
-            style="margin-bottom: 3rem;">
-            <div class="col-12">
-          <div class="col-12 border-x">
-            <label for="where" class="form-label">상위코드</label>
-            <input type="text" class="form-control" id="where" v-model="selectedparentCode"  />
-            <input type="button" class="form-control " value="검색" @click="showPopup = true" />
-            <CodePopup v-if="showPopup" @close="showPopup = false" @select="addCode" />
-          </div>
-          <div class="col-12 border-x">
-            <label for="where" class="form-label">상위코드 명</label>
-            <input type="text" class="form-control" id="where" v-model="where" />
-          </div>
-  
-       </div>
-       <div class="col-12">
-          <div class="col-12 border-x">
-            <label for="where" class="form-label"><p>코드<p class="require"><img :src="require" alt=""></p></p></label>
-            <input type="text" class="form-control" id="where" v-model="where" />
-          </div>
-          <div class="col-12 border-x">
-            <label for="where" class="form-label"><p>코드명<p class="require"><img :src="require" alt=""></p></p></label>
-            <input type="text" class="form-control" id="where" v-model="where" />
-          </div>
-  
-       </div>
-
-            <div class="col-12 chuljang ">
-              <label for="prvonsh" class="form-label">설명</label>
-              <input type="text" class="form-control textarea" id="reason" v-model="reason" />
-            </div>
-            <div class="col-12 border-x input-radio">
-              <label for="prvonsh" class="form-label"> <p>사용여부
-                <p class="require"><img :src="require" alt=""></p>
-                </p></label>
-              <div class="chk-area">
-                <div class="form-check">
-                  <input type="radio" name="rdo_1" id="rdo_1">
-                  <label for="rdo_1">사용</label>
-                </div>
-                <div class="form-check">
-                  <input type="radio" name="rdo_1" id="rdo_2" checked>
-                  <label for="rdo_2">미사용</label>
-                </div>
-              </div>
-            </div>
-
-
-          </form>
-          <div class="buttons">
-        <button type="submit" class="btn sm primary">등록</button>
-        <button type="reset" class="btn sm tertiary">취소</button>
-      </div>
-    </div>
-
-  </div>
-
-</template>
-
-<script>
-import GoogleCalendar from "../../../component/GoogleCalendar.vue"
-import { SearchOutlined } from '@ant-design/icons-vue';
-import CodePopup from "../../../component/Popup/CodePopup.vue";
-export default {
-  data() {
-    return {
-      showPopup: true,
-      codes: [],
-      selectedparentCode: '',
-      require: "/client/resources/img/require.png",
-      h3icon: "/client/resources/img/h3icon.png",
-      photoicon: "/client/resources/img/photo_icon.png",
-      img1: "/client/resources/img/img.png",
-      icon1: "/client/resources/img/icon.png",
-      dateicon: "/client/resources/img/date.png",
-      startbtn: "/client/resources/img/start.png",
-      stopbtn: "/client/resources/img/stop.png",
-      moreicon: "/client/resources/img/more.png",
-      today: new Date().toLocaleDateString('ko-KR', {
-        year: 'numeric',
-        month: '2-digit',
-        day: '2-digit',
-        weekday: 'short',
-      }),
-      time: this.getCurrentTime(),
-      listData: Array.from({ length: 20 }, (_, i) => ({
-        department: `부서 ${i + 1}`,
-        name: `이름 ${i + 1}`,
-        position: `직급 ${i + 1}`
-      }))
-    }
-  },
-  components: {
-    SearchOutlined, CodePopup
-  },
-  methods: {
-    addCode(selectedUser) {
-      this.codes.push({
-        parentCode: selectedUser.parentCode,
-      });
-
-      this.selectedparentCode = selectedUser.parentCode; // 입력창에 표시
-      this.showPopup = false;
-    },
-    formatBudget(amount) {
-      return new Intl.NumberFormat().format(amount) + ' 원';
-    },
-    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;
-    },
-    getStatusClass(status) {
-      return status === 'active' ? 'status-active' : 'status-inactive';
-    },
-    getStatusClass(status) {
-      if (status === '미진행') return 'status-pending';
-      if (status === '진행중') return 'status-approved';
-
-      // Default empty string
-      return '';
-    },
-    getCurrentTime() {
-      const now = new Date();
-      const hours = String(now.getHours()).padStart(2, '0');
-      const minutes = String(now.getMinutes()).padStart(2, '0');
-      const seconds = String(now.getSeconds()).padStart(2, '0');
-      return `${hours}:${minutes}:${seconds}`;
-    },
-    getCategoryClass(category) {
-      switch (category) {
-        case '용역': return 'category-service';
-        case '내부': return 'category-internal';
-        case '국가과제': return 'category-government';
-        default: return '';
-      }
-    },
-  },
-  watch: {
-
-  },
-  computed: {
-
-  },
-  mounted() {
-    console.log('main mounted');
-    setInterval(() => {
-      this.time = this.getCurrentTime();
-    }, 1000);
-  }
-}
-</script>
-<style scoped>
-tr {
-  cursor: pointer;
-}
-</style>(파일 끝에 줄바꿈 문자 없음)
 
client/views/pages/Manager/system/commonCodeManagement.vue (deleted)
--- client/views/pages/Manager/system/commonCodeManagement.vue
@@ -1,189 +0,0 @@
-<template>
-<div class="col-lg-12">
-  <div class="card">
-    <div class="card-body">
-      <h2 class="card-title">공통코드관리</h2>
-      <div class="sch-form-wrap">
-        <div class="input-group">
-          <select name="" id="" class="form-select">
-          <option value="">전체</option>
-          <option value="">상위코드</option>
-          <option value="">상위코드명</option>
-          <option value="">코드</option>
-          <option value="">코드명</option>
-        </select>
-        <div class="sch-input">
-              <input type="text" class="form-control">
-              <button class="ico-sch">
-                <SearchOutlined />
-              </button>
-            </div>
-        </div>
-      </div>
-     
-      <!-- Table  -->
-      <div class="tbl-wrap">
-        <table id="myTable" class="tbl data">
-          <!-- 동적으로 <th> 생성 -->
-          <thead>
-            <tr>
-              <th>상위코드 </th>
-              <th>상위코드명</th>
-              <th>코드</th>
-              <th>코드명</th>
-              <th>등록일</th>
-              <th>사용여부</th>
-            </tr>
-          </thead>
-          <!-- 동적으로 <td> 생성 -->
-          <tbody>
-            <tr v-for="(item, index) in listData" :key="index" :class="{ expired: !isUsed(item.used) }" @click="goToDetailPage(item)">
-      <td>{{ item.parentCode }}</td>
-      <td>{{ item.parentName }}</td>
-      <td>{{ item.code }}</td>
-      <td>{{ item.name }}</td>
-      <td>{{ item.createdAt }}</td>
-      <td :class="getStatusClass(item.used)">{{ item.used }}</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 -->
-      <div class="buttons">
-    <button type="button" class="btn sm sm primary" @click="goToPage('등록') ">
-      등록
-    </button>
-
-    <!-- 신청 종류 선택 모달 -->
-    <div v-if="showOptions" class="modal-overlay">
-      <div class="modal-box">
-        <p>신청 종류를 선택하세요</p>
-        <button @click="goToPage('휴가')">휴가신청</button>
-        <button @click="goToPage('출장')">출장신청</button>
-        <button class="cancel" @click="showOptions = false">취소</button>
-      </div>
-    </div>
-  </div>
-    </div>
-  </div>
-</div>
-</template>
-
-<script>
-import { ref } from 'vue';
-import { SearchOutlined } from '@ant-design/icons-vue';
-export default {
-  data() {
-    return {
-      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: [
-      {
-          parentCode: 'A01',
-          parentName: '부서코드',
-          code: 'A0101',
-          name: '총무부',
-          createdAt: '2024-01-10',
-          used: 'Y',
-        },
-        {
-          parentCode: 'A01',
-          parentName: '부서코드',
-          code: 'A0102',
-          name: '인사부',
-          createdAt: '2024-03-21',
-          used: 'N',
-        },],
-      filteredData: [],
-    };
-  },
-  computed: {
-  },
-  components: {
-    SearchOutlined
-  },
-  methods: {
-    goToDetailPage(item) {
-    // item.id 또는 다른 식별자를 사용하여 URL을 구성할 수 있습니다.
-    this.$router.push({ name: 'commonCodeDetail', query: { id: item.id } });
-  },
-    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: 'commonCodeInsert' });
-  } 
-},
-getStatusClass(used) {
-      return used === 'Y' ? 'status-approved' : 'status-pending';
-    },
-   
-    isUsed(used) {
-      return used === 'Y';
-    },
-  },
-  created() {
-  },
-  mounted() {
-
-
-  },
-};
-</script>
-
-<style scoped>
-tr{cursor: pointer;}
-</style>
Add a comment
List