하석형 하석형 05-23
250523 하석형 관리자/사용자 로그인 페이지 구분
@2cc414ac6df6652f73c1f98b6f173a3b74bdc540
 
client/resources/img/page/admin_background.jpg (Binary) (added)
+++ client/resources/img/page/admin_background.jpg
Binary file is not shown
client/resources/img/page/background.jpg (Binary)
--- client/resources/img/page/background.jpg
+++ client/resources/img/page/background.jpg
Binary file is not shown
client/resources/scss/admin/login.scss
--- client/resources/scss/admin/login.scss
+++ client/resources/scss/admin/login.scss
@@ -17,9 +17,28 @@
             height: 100%;
             @include flex-layout(flex, stretch,);
 
-            .background-img{
+            .admin-background-img{
                 width: 50%;
                 height: 100%;
+                background-image: url(#{$url}/page/admin_background.jpg);
+                background-position: bottom right 10%;
+                background-size: auto 100%;
+                position: relative;
+
+                p{
+                    font-size: var(--tk-fz-heading-md);
+                    color: #0b4dd1;
+                    font-weight: 700;
+                    position: absolute;
+                    top: 5rem;
+                    left: 5rem;
+                    // animation: bounce 1.5s infinite ease-in-out;
+                }
+            }
+
+            .background-img{
+                width: 100%;
+                height: 100%;
                 background-image: url(#{$url}/page/background.jpg);
                 background-position: bottom right 10%;
                 background-size: auto 100%;
client/views/layout/AdminMenu copy.vue
--- client/views/layout/AdminMenu copy.vue
+++ client/views/layout/AdminMenu copy.vue
@@ -101,7 +101,7 @@
     async fnlogOut() {
       await this.logout();
       this.$router.push({
-        path: "/login.page",
+        path: "/cmslogin.page",
       });
     },
     // 캐시 초기화
client/views/pages/App.vue
--- client/views/pages/App.vue
+++ client/views/pages/App.vue
@@ -10,7 +10,7 @@
     </main>
   </div> 
   <div v-else v-cloak class="user-wrap relative">
-    <UserHeader v-if="path != this.$filters.ctxPath('/login.page') && !$route.path.includes('/popup.page')"/>
+    <UserHeader v-if="path != this.$filters.ctxPath('/login.page') && path != this.$filters.ctxPath('/cmslogin.page') && !$route.path.includes('/popup.page')"/>
     <main class="main-wrap">
       <Breadcrumb v-if="$route.path !== this.$filters.ctxPath('/adm/main.page') && $route.path !== this.$filters.ctxPath('/main.page')" />
       <router-view />
client/views/pages/AppRouter.js
--- client/views/pages/AppRouter.js
+++ client/views/pages/AppRouter.js
@@ -169,6 +169,7 @@
 
   AppRouter.beforeEach(async (to, from, next) => {
     const contextPath = store.state.contextPath; // Context Path 정보
+    const admPath = to.path.includes('/adm'); // 관리자 페이지 여부 (true: 관리자 페이지, false: 사용자 페이지)
     // const routeExists = AppRouter.getRoutes().some(route => route.path === to.path || (route.name && route.name === to.name));
     // if (!routeExists) {
     //   next({ name: 'notfound' });
@@ -215,7 +216,7 @@
     sessionStorage.setItem("redirect", to.fullPath);
     
     // 메인 페이지 or 로그인 페이지
-    if (to.path === filters.ctxPath('/') || to.path.includes('/login.page') || to.path.startsWith(filters.ctxPath('/cmmn/')) || to.path.includes('/searchId.page') || to.path.includes('/resetPswd.page')) {
+    if (to.path === filters.ctxPath('/') || to.path.includes('/login.page') || to.path.includes('/cmslogin.page') || to.path.startsWith(filters.ctxPath('/cmmn/')) || to.path.includes('/searchId.page') || to.path.includes('/resetPswd.page')) {
       let path = to.path;
       // 게시판일 경우 .page로 끝나는 경로가 있으므로 마지막 '/' 이전 경로로 설정
       if (to.path.includes('BBS_MNG')) {
client/views/pages/AppStore.js
--- client/views/pages/AppStore.js
+++ client/views/pages/AppStore.js
@@ -92,6 +92,7 @@
     async logout({ commit }) {
       try {
         const ctx = this.state.contextPath; // 캐시 초기화 전 contextPath 저장
+        const admPath = this.state.path?.includes("/adm") // 캐시 초기화 전 경로 구분 (true: 관리자 페이지, false: 사용자 페이지)
         const res = await logOutProc();
         alert(res.data.message);
         if (res.status == 200) {
@@ -105,7 +106,11 @@
           document.cookie = "refresh=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
           document.cookie = "Authorization=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
           // 4. 로그인 페이지로 이동
-          window.location = ctx + "/login.page";
+          if(admPath) {
+            window.location = ctx + "/cmslogin.page";
+          } else {
+            window.location = ctx + "/login.page";
+          }
         }
       } catch(error) {
         const errorData = error.response.data;
client/views/pages/adm/system/LoginPolicy/LoginPolicy.vue
--- client/views/pages/adm/system/LoginPolicy/LoginPolicy.vue
+++ client/views/pages/adm/system/LoginPolicy/LoginPolicy.vue
@@ -123,7 +123,7 @@
         await saveByLoginPolicy(loginPolicy);
         alert('중복 로그인 설정이 저장되었습니다.');
         store.commit("setStoreReset");
-        window.location = this.$filters.ctxPath('/login.page');
+        window.location = this.$filters.ctxPath('/cmslogin.page');
       } catch (err) {
         alert('중복 로그인 설정 저장 실패'+ (err.response?.data?.message || err.message));
         this.allowMultipleLogin = this.previousAllowMultipleLogin;
@@ -144,7 +144,7 @@
         await saveByLoginMode(loginMode);
         alert('로그인 방식이 변경되었습니다.\n다시 로그인해주세요.');
         store.commit("setStoreReset");
-        window.location = this.$filters.ctxPath('/login.page');
+        window.location = this.$filters.ctxPath('/cmslogin.page');
       } catch (err) {
         alert('로그인 방식 저장 실패: ' + (err.response?.data?.message || err.message));
         this.lgnMode = this.previousLgnMode;
 
client/views/pages/login/AdminLogin.vue (added)
+++ client/views/pages/login/AdminLogin.vue
@@ -0,0 +1,195 @@
+<template>
+  <div class="login-page page">
+      <div>
+        <div class="admin-background-img">
+          <p>
+            콘텐츠 관리 시스템에 오신 것을 환영합니다.<br />
+            원활한 관리와 운영을 위해 로그인하세요.
+          </p>
+        </div>
+        <div class="login-wrap">
+            <div class="login">
+              <div
+                :class="{
+                  'login-title': true,
+                  'user-login': !isAdminPage,
+                }"
+              >
+                LOGIN
+              </div>
+              <div class="form-group">
+                <label for="id" class="login-label">아이디</label>
+                <input
+                  type="text"
+                  name=""
+                  id="id"
+                  class="form-control md"
+                  placeholder="아이디를 입력하세요"
+                  v-model="member['lgnId']"
+                />
+              </div>
+              <div class="form-group">
+                <label for="pw" class="login-label">비밀번호</label>
+                <input
+                  type="password"
+                  name=""
+                  id="pw"
+                  class="form-control md"
+                  placeholder="비밀번호를 입력하세요"
+                  v-model="member['pswd']"
+                  @keydown.enter="fnLogin"
+                />
+              </div>
+              <button
+                class="btn md main user-btn"
+                v-if="!isAdminPage"
+                @click="fnLogin"
+                   @keydown.enter="fnLogin"
+              >
+                로그인
+              </button>
+              <button
+                class="btn md main"
+                v-else
+                @click="fnLogin"
+                @keydown.enter="fnLogin"
+              >
+                로그인
+              </button>
+
+              <div
+                class="input-group"
+                v-if="!isAdminPage"
+              >
+                <p class="pl10 pr10 cursor" @click="moveSearchId">아이디찾기</p>
+                <p class="pl10 pr0 cursor" @click="moveResetPswd">비밀번호 초기화</p>
+              </div>
+            </div>
+        </div>
+      </div>
+  </div>
+</template>
+
+<script>
+import { useStore } from "vuex";
+import store from "../AppStore";
+import { loginProc } from "../../../resources/api/login";
+import queryParams from "../../../resources/js/queryParams";
+
+export default {
+  mixins: [queryParams],
+  data: () => {
+    return {
+      member: {
+        lgnId: null,
+        pswd: null,
+      },
+      store: useStore(),
+      isAdminPage: false,
+    };
+  },
+  methods: {
+    checkAdminPage() {
+      if (
+        this.restoreRedirect("redirect") &&
+        this.restoreRedirect("redirect").includes("/adm/")
+      ) {
+        this.isAdminPage = true;
+      } else {
+        this.isAdminPage = false;
+      }
+    },
+    async fnLogin() {
+      try {
+        const res = await loginProc(this.member);
+        if (res.status == 200) {
+          const loginType = res.headers['login-type']; // 세션/토큰 로그인 구분
+          if (loginType === 'J') {
+              // JWT 방식
+              store.commit("setAuthorization", res.headers.authorization);
+              store.commit("setLoginMode", "J");
+              localStorage.setItem("loginMode", "J");
+              const base64String = store.state.authorization.split(".")[1];
+              const base64 = base64String.replace(/-/g, "+").replace(/_/g, "/");
+              const jsonPayload = decodeURIComponent(
+                atob(base64).split("").map((c) => {
+                  return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
+                }).join("")
+              );
+              const mbr = JSON.parse(jsonPayload);
+              store.commit("setMbrId", mbr.mbrId);
+              store.commit("setMbrNm", mbr.mbrNm);
+              store.commit("setRoles", mbr.roles);
+          } else if (loginType === 'S') {
+              store.commit("setLoginMode", "S");
+              localStorage.setItem("loginMode", "S");
+              const mbr = res.data;
+              store.commit("setAuthorization", null);
+              store.commit("setMbrId", mbr.mbrId);
+              store.commit("setMbrNm", mbr.mbrNm);
+              const roles = mbr.roles.map(r => ({ authority: r.authrtCd }));
+              store.commit("setRoles", roles);
+          } else {
+              alert("알 수 없는 로그인 방식입니다.");
+              return;
+          }
+          const isAdmin = store.state.roles.some(role => role.authority === "ROLE_ADMIN");
+          let url = this.restoreRedirect("redirect");
+          if (url != null && url != "") {
+            const ctx = store.state.contextPath;
+            if (ctx !== "") {
+              // redirect 값에서 Context Path 추가
+              url = this.$filters.ctxPath(url);
+            } else {
+              // redirect 값에서 기존 Context Path 제거
+              url = url.replace(/^\/[^\/]+/, ""); // 첫 번째 '/' 이후의 경로만 남김
+            }
+            const routeExists = this.$router.getRoutes().some(route => route.path === url);
+            
+            if (url == this.$filters.ctxPath("/searchId.page") || url == this.$filters.ctxPath("/resetPswd.page")) {
+                this.$router.push({ path: this.$filters.ctxPath("/main.page") });
+              } else if (routeExists) {
+                this.$router.push({ path: url });
+              } else {
+                this.$router.push({
+                  path: isAdmin ? this.$filters.ctxPath("/adm/main.page") : this.$filters.ctxPath("/")
+                });
+              }
+          } else {
+            this.$router.push({
+                path: isAdmin ? this.$filters.ctxPath("/adm/main.page") : this.$filters.ctxPath("/")
+              });
+          }
+
+          
+        }
+      } catch (error) {
+        alert(error.response.data.message);
+      }
+    },
+    moveSearchId() {
+      this.$router.push({
+        path: this.$filters.ctxPath("/resetPswd.page"),
+        query: {
+          tab: "id",
+        },
+      });
+    },
+    moveResetPswd() { 
+      this.$router.push({
+        path: this.$filters.ctxPath("/resetPswd.page"),
+        query: {
+          tab: "pw",
+        },
+      });
+    },
+  },
+  watch: {},
+  computed: {},
+  components: {},
+  created() {
+    this.checkAdminPage();
+  },
+  mounted() {},
+};
+</script>
client/views/pages/login/Login.vue
--- client/views/pages/login/Login.vue
+++ client/views/pages/login/Login.vue
@@ -3,8 +3,8 @@
       <div>
         <div class="background-img">
           <p>
-            콘텐츠 관리 시스템에 오신 것을 환영합니다.<br />
-            원활한 관리와 운영을 위해 로그인하세요.
+            어서오세요.<br />
+            로그인하세요.
           </p>
         </div>
         <div class="login-wrap">
client/views/themes/tema_v2/css/style.css
--- client/views/themes/tema_v2/css/style.css
+++ client/views/themes/tema_v2/css/style.css
@@ -204,6 +204,11 @@
 }
 
 /* 기업전용 메인  */
+.admin-background-img{
+    width: 100%;
+    height: 100%;
+    object-position: top center;
+}
 .background-img{
     width: 100%;
     height: 100%;
Add a comment
List