류윤주 류윤주 04-07
Merge branch 'master' of http://210.180.118.83/jhpark/cms_frontend
@2278643d0efd79455bdb69695250281e90a0fd6f
client/views/common/filters.js
--- client/views/common/filters.js
+++ client/views/common/filters.js
@@ -12,7 +12,7 @@
     // Context Path를 제외한 URL 생성
     logicalPath(path) {
         const contextPath = store.state.contextPath || '';
-        return (contextPath !== '/' && path.startsWith(contextPath)) ? path.slice(contextPath.length) : path;
+        return (contextPath !== '' && path.startsWith(contextPath)) ? path.slice(contextPath.length) : path;
     },
 
     // 아이디 정규식(5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용)
client/views/layout/AdminMenu.vue
--- client/views/layout/AdminMenu.vue
+++ client/views/layout/AdminMenu.vue
@@ -114,6 +114,11 @@
                 // 부모 메뉴 클릭 시 펼치기만 함
                 menu.isOpen = !menu.isOpen;
             } else {
+                if(menu.routerUrl === "") {
+                    // 하위메뉴가 없는 상위메뉴일 시 알림 출력
+                    alert("하위 메뉴가 존재하지 않습니다.");
+                    return;
+                }
                 // 2뎁스 또는 3뎁스 선택 시 menuClick 실행
                 this.menuClick(menu);
             }
client/views/pages/adm/departmentManagement/DepartmentManagement.vue
--- client/views/pages/adm/departmentManagement/DepartmentManagement.vue
+++ client/views/pages/adm/departmentManagement/DepartmentManagement.vue
@@ -130,7 +130,7 @@
                         :checked="selectedMbr.includes(row.loginId)"
                         @change="() => checkboxChange(row, idx)"
                       />
-                      <label for="'check_' + idx"></label>
+                      <label :for="'check_' + idx"></label>
                       </div>
                     </template>
                   </ListTable>
@@ -167,7 +167,7 @@
       <div class="modal-title">
         <p>사용자 목록</p>
       </div>
-      <button class="close-btn" @click="modalClose">X</button>
+      <button class="btn-close" @click="modalClose">X</button>
     </template>
     <ListTable
       :className="'admin-list'"
client/views/pages/adm/preferences/commonCodeManagement/CommonCodeManagement.vue
--- client/views/pages/adm/preferences/commonCodeManagement/CommonCodeManagement.vue
+++ client/views/pages/adm/preferences/commonCodeManagement/CommonCodeManagement.vue
@@ -233,9 +233,9 @@
         alert("코드를 입력해주세요.");
         return false;
       }
-      const alpha = /^[A-Z_]*$/;
+      const alpha = /^[a-zA-Z_]*$/;
       if (!alpha.test(this.viewCode.cd)) {
-        alert("코드는 영문(대문자)과 언더바(_)만 사용하여 작성해주세요.");
+        alert("코드는 영문과 언더바(_)만 사용하여 작성해주세요.");
         return false;
       }
       if (
client/views/pages/adm/system/LoginPolicy/LoginPolicy.vue
--- client/views/pages/adm/system/LoginPolicy/LoginPolicy.vue
+++ client/views/pages/adm/system/LoginPolicy/LoginPolicy.vue
@@ -121,9 +121,9 @@
         const loginPolicy = {};
         loginPolicy.allowMultipleLogin = this.allowMultipleLogin;
         await saveByLoginPolicy(loginPolicy);
-        alert('중복 로그인 설정이 저장되었습니다.');
+        alert(res.data.message);
       } catch (err) {
-        alert('중복 로그인 설정 저장 실패');
+        alert(res.data.message);
         this.allowMultipleLogin = this.previousAllowMultipleLogin;
       }
     },
@@ -139,7 +139,7 @@
       try {
         const loginMode = {};
         loginMode.lgnMode = this.lgnMode;
-        //         await saveByLoginMode(loginMode);
+        await saveByLoginMode(loginMode);
         alert('로그인 방식이 변경되었습니다.\n다시 로그인해주세요.');
         store.commit("setStoreReset");
         window.location = this.$filters.ctxPath('/login.page');
@@ -167,8 +167,8 @@
       if (!this.validation()) {
         return;
       }
-      // const isCheck = confirm("Context Path를 변경하면 로그아웃됩니다.\n계속하시겠습니까?");
-      const isCheck = confirm("Context Path를 변경하시겠습니까?");
+      const isCheck = confirm("Context Path를 변경하면 로그아웃됩니다.\n계속하시겠습니까?");
+      // const isCheck = confirm("Context Path를 변경하시겠습니까?");
       if (isCheck) {
         try {
           let ctx = { path: this.cntxtPth };
@@ -180,11 +180,11 @@
               storeCtx = '';
             }
             store.commit("setContextPath", storeCtx); // 캐시 초기화 요청을 보내기 위한 Context Path 정보 저장
-            // const cacheRes = await cacheReSet(); // 캐시 초기화
-            // alert(cacheRes.data.message);
-            // store.commit("setStoreReset"); // 캐시 초기화 후 Store 초기화
-            // window.location.reload(); // AppRouter 재실행을 위한 페이지 새로고침
-            window.location.href = `${storeCtx}/adm/main.page`;
+            const cacheRes = await cacheReSet(); // 캐시 초기화
+            store.commit("setStoreReset"); // 캐시 초기화 후 Store 초기화
+            store.commit("setContextPath", storeCtx); // 라우터 Context Path 정보 저장
+            window.location.href = `${storeCtx}/login.page`;
+            // window.location.href = `${storeCtx}/adm/main.page`;
           } else {
             alert(res.data.message);
           }
 
client/views/pages/adm/system/contextPath/ContextPathSelectList.vue (deleted)
--- client/views/pages/adm/system/contextPath/ContextPathSelectList.vue
@@ -1,165 +0,0 @@
-<template>
-  <div class="search-bar">
-    <input
-      type="text"
-      class="form-control sm"
-      placeholder="경로를 입력하세요."
-      v-model="search.searchText"
-      @keyup.enter="findAll"
-    />
-
-    <button class="btn-ico xsm  main ico-sch" @click="findAll">
-      <span class="sr-only">검색</span>
-    </button>
-  </div>
-  <div class="content-zone">
-    <div class="content">
-      <div class="scroll">
-        <div class="tbl-wrap">
-          <ListTable
-            :className="'data cursor'"
-            :colgroup="colgroup"
-            :thead="thead"
-            :tbody="tbody"
-            @listClick="fnView"
-          >
-            <template v-slot:button="{ row, idx }">
-              <button
-                class="btn-ico md ico-del"
-                @click.stop="fnDel(row, idx)"
-                v-if="pageAuth.delAuthrt == 'Y'"
-              >
-              </button>
-            </template>
-          </ListTable>
-        </div>
-      </div>
-    </div>
-  </div>
-  <div class="btn-wrap list">
-      <div></div>
-      <PaginationButton :className="'pagination'"
-              v-model:currentPage="search.currentPage"
-              :pagination="search"
-              :click="findAll"
-            />
-      <button
-        class="btn sm main"
-        @click="fnAdd"
-        v-if="pageAuth.regAuthrt == 'Y'"
-      >
-        등록
-      </button>
-    </div>
-</template>
-
-<script>
-import ListTable from "../../../../component/table/ListTable.vue";
-import PaginationButton from "../../../../component/pagination/PaginationButton.vue";
-import { findAll, del } from "../../../../../resources/api/cntxtPth";
-import queryParams from "../../../../../resources/js/queryParams";
-import { toRaw } from "vue";
-import { defaultSearchParams } from "../../../../../resources/js/defaultSearchParams";
-
-export default {
-  mixins: [queryParams],
-  components: {
-    ListTable: ListTable,
-    PaginationButton: PaginationButton,
-  },
-  data() {
-    return {
-      // 페이지 컨텍스트 패스 객체
-      pageAuth: JSON.parse(localStorage.getItem("vuex")).pageAuth,
-
-      colgroup: ["4%", "20", "25%", "13%", "13%", "5%"],
-      thead: ["NO", "경로", "사용여부", "등록자", "등록일", "삭제"],
-      tbody: [],
-      search: { ...defaultSearchParams },
-      list: [], // 컨텍스트 패스 목록
-      listCnt: 0,
-    };
-  },
-  created() {
-    this.resotreQueryParams("queryParams");
-    this.findAll();
-  },
-  methods: {
-    // 목록 조회
-    async findAll() {
-      this.saveQueryParams("queryParams", this.search); // 검색조건 저장
-      try {
-        const res = await findAll(toRaw(this.search));
-        this.list = res.data.data.list;
-        this.listCnt = res.data.data.pagination.totalRecordCount;
-        this.search = res.data.data.pagination;
-        this.makeTbody();
-        console.log("this.list : ", this.list);
-      } catch (error) {
-        // console.log("error : ", error);
-      }
-    },
-    // 상세 조회
-    fnView(idx) {
-      this.saveQueryParams("queryParams", this.search); // 검색조건 저장
-      this.$router.push({
-        name: "admContextPathSelectListOne",
-        query: {
-          pageId: this.list[idx]["cntxtPthId"],
-        },
-      });
-    },
-    // 등록 페이지 이동
-    fnAdd() {
-      this.$router.push({
-        name: "admContextPathInsert",
-      });
-    },
-    // 삭제
-    async fnDel(row, idx) {
-      if (this.list[idx].sysPvsnYn == 0) {
-        alert("시스템에서 제공하는 정보는 삭제할수 없습니다.");
-        return;
-      }
-      if (!confirm("삭제하시겠습니까?")) {
-        return;
-      }
-      try {
-        const res = await del(this.list[idx]);
-        alert(res.data.message);
-        if (res.status == 200) {
-          this.findAll();
-        }
-      } catch (error) {
-        alert("에러가 발생했습니다.\n시스템관리자에게 문의하세요.");
-      }
-    },
-    // tbody 생성
-    makeTbody() {
-      this.tbody = []; // 초기화
-      this.tbody = this.list.map((cntxtPth, index) => {
-        let id =
-          this.listCnt -
-          index -
-          (this.search.currentPage - 1) * this.search.recordSize; // 번호
-        let path = cntxtPth.path; // 경로
-        let useYn = cntxtPth.useYn; // 사용여부
-        let writer; // 작성자
-        let writeDt; // 작성일
-        // 수정 이력 확인 후 수정된 경우가 없다면 최초 작성자로 등록
-        if (cntxtPth.mdfr == null || cntxtPth.mdfr === "") {
-          writer = cntxtPth.rgtrNm;
-          writeDt = cntxtPth.regDt;
-        } else {
-          writer = cntxtPth.mdfrNm;
-          writeDt = cntxtPth.mdfcnDt;
-        }
-        return { id, path, useYn, writer, writeDt };
-      });
-    },
-  },
-  watch: {},
-  computed: {},
-  mounted() {},
-};
-</script>
client/views/pages/login/Login.vue
--- client/views/pages/login/Login.vue
+++ client/views/pages/login/Login.vue
@@ -131,7 +131,17 @@
               alert("알 수 없는 로그인 방식입니다.");
               return;
           }
-          const url = this.restoreRedirect("redirect");
+
+          let url = this.restoreRedirect("redirect");
+          const ctx = store.state.contextPath;
+          if (ctx !== "") {
+            // redirect 값에서 Context Path 추가
+            url = this.$filters.ctxPath(url);
+          } else {
+            // redirect 값에서 기존 Context Path 제거
+            url = url.replace(/^\/[^\/]+/, ""); // 첫 번째 '/' 이후의 경로만 남김
+          }
+
           if (url != null && url != "") {
             if (url == this.$filters.ctxPath("/searchId.page") || url == this.$filters.ctxPath("/resetPswd.page")) {
               this.$router.push({ path: this.$filters.ctxPath("/main.page") });
server/modules/web/server.js
--- server/modules/web/server.js
+++ server/modules/web/server.js
@@ -57,9 +57,9 @@
 /**
  * @author : 하석형
  * @since : 2023.08.24
- * @dscription : ROOT URL -> index.html
+ * @dscription : /, /{ContextPath}/ -> index.html
  */
-webServer.get("/", function (request, response) {
+webServer.get(/^\/([^\/]+\/)?$/, function (request, response) {
   //response.sendFile을 통한 HTTP html reponse (html내용 Streaming)
   response.sendFile(`${BASE_DIR}/client/views/index.html`);
 });
Add a comment
List