

231030 류윤주 login 커밋
@bf3367e22a27325750186533e83c4d9c08b9a5db
--- client/views/layout/AdminHeader.vue
+++ client/views/layout/AdminHeader.vue
... | ... | @@ -51,7 +51,7 @@ |
51 | 51 |
computed: {}, |
52 | 52 |
components: {}, |
53 | 53 |
mounted() { |
54 |
- console.log("Header mounted"); |
|
54 |
+ console.log("adminHeader mounted"); |
|
55 | 55 |
console.log("Header route: ", this.route); |
56 | 56 |
}, |
57 | 57 |
}; |
--- client/views/layout/AdminMenu.vue
+++ client/views/layout/AdminMenu.vue
... | ... | @@ -1,7 +1,7 @@ |
1 | 1 |
<template> |
2 | 2 |
<nav class="main-menu"> |
3 | 3 |
<div class="logo-wrap"> |
4 |
- <h1 class="logo"><router-link to="/">AI 디지털교과서 통합지원센터</router-link></h1> |
|
4 |
+ <h1 class="logo"><router-link to="/adm/main">AI 디지털교과서 통합지원센터</router-link></h1> |
|
5 | 5 |
</div> |
6 | 6 |
<ul> |
7 | 7 |
<li v-for="(menu, index) in menuList" :key="index" @click="toggleMenu(menu)"> |
... | ... | @@ -22,10 +22,10 @@ |
22 | 22 |
return { |
23 | 23 |
menuList: [ |
24 | 24 |
{ path: "/adm.page", pathName: "대시보드" }, |
25 |
- { path: "/adm/notice.page", pathName: "커뮤니티", subMenu: [{ path: "/notice.page", pathName: "공지사항" }, { path: "/new.page", pathName: "홍보/뉴스" }], icon: "<i class='fa-solid fa-angle-right'></i>", isOpen: false }, |
|
26 |
- { path: "/adm/document.page", pathName: "자료실", subMenu: [{ path: "/document.page", pathName: "기술문서" }, { path: "/reference.page", pathName: "자료집" }], icon: "<i class='fa-solid fa-angle-right'></i>", isOpen: false }, |
|
25 |
+ { path: "/adm/noticeSelectList.page", pathName: "커뮤니티", subMenu: [{ path: "/adm/noticeSelectList.page", pathName: "공지사항" }, { path: "/adm/new.page", pathName: "홍보/뉴스" }], icon: "<i class='fa-solid fa-angle-right'></i>", isOpen: false }, |
|
26 |
+ { path: "/adm/document.page", pathName: "자료실", subMenu: [{ path: "/adm/document.page", pathName: "기술문서" }, { path: "/adm/reference.page", pathName: "자료집" }], icon: "<i class='fa-solid fa-angle-right'></i>", isOpen: false }, |
|
27 | 27 |
{ path: "/adm/statistics.page", pathName: "통계서비스" }, |
28 |
- { path: "/adm/corporatePR.page", pathName: "네트워킹", subMenu: [{ path: "/corporatePR.page", pathName: "기업홍보관" }], icon: "<i class='fa-solid fa-angle-right'></i>", isOpen: false }, |
|
28 |
+ { path: "/adm/corporatePR.page", pathName: "네트워킹", subMenu: [{ path: "/adm/corporatePR.page", pathName: "기업홍보관" }], icon: "<i class='fa-solid fa-angle-right'></i>", isOpen: false }, |
|
29 | 29 |
{ path: "/adm/modal.page", pathName: "팝업관리" }, |
30 | 30 |
{ path: "/adm/email.page", pathName: "메일발송" }, |
31 | 31 |
{ path: "/adm/userSelectList.page", pathName: "사용자관리" }, |
... | ... | @@ -36,7 +36,7 @@ |
36 | 36 |
methods: { |
37 | 37 |
//토글 메뉴 |
38 | 38 |
toggleMenu(menu) { |
39 |
- console.log(menu); |
|
39 |
+ |
|
40 | 40 |
if (menu.hasOwnProperty('isOpen')) { |
41 | 41 |
menu.isOpen = !menu.isOpen; |
42 | 42 |
if (menu.isOpen) { |
... | ... | @@ -55,7 +55,7 @@ |
55 | 55 |
computed: {}, |
56 | 56 |
components: {}, |
57 | 57 |
mounted() { |
58 |
- console.log("Header mounted"); |
|
58 |
+ console.log("admin menu mounted"); |
|
59 | 59 |
}, |
60 | 60 |
}; |
61 | 61 |
</script> |
--- client/views/pages/App.vue
+++ client/views/pages/App.vue
... | ... | @@ -1,11 +1,16 @@ |
1 | 1 |
<template> |
2 |
- <div v-if="isUserPage" :class="{ 'layout-wrap': true }"> |
|
3 |
- <AdminHeader></AdminHeader> |
|
4 |
- <AdminMenu></AdminMenu> |
|
5 |
- <div class="main-warp"> |
|
6 |
- <router-view /> |
|
2 |
+ <div v-if="isAdminPage" class="admin-wrap"> |
|
3 |
+ <div :class="{ 'layout-wrap': true }" v-show="isLogin"> |
|
4 |
+ <AdminHeader></AdminHeader> |
|
5 |
+ <AdminMenu></AdminMenu> |
|
6 |
+ <div class="main-warp"> |
|
7 |
+ <router-view /> |
|
8 |
+ </div> |
|
9 |
+ <AdminFooter></AdminFooter> |
|
7 | 10 |
</div> |
8 |
- <AdminFooter></AdminFooter> |
|
11 |
+ <div> |
|
12 |
+ <AdminLogin @updateIsLogin="updateIsLogin"/> |
|
13 |
+ </div> |
|
9 | 14 |
</div> |
10 | 15 |
<div v-else> |
11 | 16 |
<Header></Header> |
... | ... | @@ -26,6 +31,7 @@ |
26 | 31 |
import AdminHeader from '../layout/AdminHeader.vue'; |
27 | 32 |
import AdminMenu from '../layout/AdminMenu.vue'; |
28 | 33 |
import AdminFooter from '../layout/AdminFooter.vue'; |
34 |
+import AdminLogin from '../pages/admin/login/Login.vue' |
|
29 | 35 |
|
30 | 36 |
const App = { |
31 | 37 |
data() { |
... | ... | @@ -39,6 +45,10 @@ |
39 | 45 |
}; |
40 | 46 |
}, |
41 | 47 |
methods: { |
48 |
+ // 로그인 |
|
49 |
+ updateIsLogin(newValue) { |
|
50 |
+ this.isLogin = newValue; |
|
51 |
+ }, |
|
42 | 52 |
//로그인 사용자 조회 |
43 | 53 |
loginUserSelectOne: function (callback) { |
44 | 54 |
let vm = this; |
... | ... | @@ -72,7 +82,7 @@ |
72 | 82 |
|
73 | 83 |
}, |
74 | 84 |
computed: { |
75 |
- isUserPage() { |
|
85 |
+ isAdminPage() { |
|
76 | 86 |
// 현재 URL을 기반으로 사용자와 관리자 페이지 여부를 판단 |
77 | 87 |
return this.$route.path.startsWith('/adm'); |
78 | 88 |
} |
... | ... | @@ -84,6 +94,7 @@ |
84 | 94 |
'AdminMenu': AdminMenu, |
85 | 95 |
'Footer': Footer, |
86 | 96 |
'AdminFooter': AdminFooter, |
97 |
+ 'AdminLogin': AdminLogin |
|
87 | 98 |
}, |
88 | 99 |
mounted() { |
89 | 100 |
console.log('Vue mounted'); |
... | ... | @@ -135,6 +146,11 @@ |
135 | 146 |
</script> |
136 | 147 |
|
137 | 148 |
<style scoped> |
149 |
+.admin-wrap { |
|
150 |
+ width: 100%; |
|
151 |
+ height: 100%; |
|
152 |
+} |
|
153 |
+ |
|
138 | 154 |
.layout-wrap { |
139 | 155 |
width: 100%; |
140 | 156 |
height: 100%; |
--- client/views/pages/AppRouter.js
+++ client/views/pages/AppRouter.js
... | ... | @@ -1,4 +1,5 @@ |
1 | 1 |
import { createWebHistory, createRouter } from "vue-router"; |
2 |
+import { useStore } from "vuex"; |
|
2 | 3 |
|
3 | 4 |
import Main from "../pages/user/main/Main.vue"; |
4 | 5 |
import Matching from "../pages/user/networking/Matching.vue"; |
... | ... | @@ -18,8 +19,9 @@ |
18 | 19 |
|
19 | 20 |
/* 관리자 */ |
20 | 21 |
import AdminLogin from "../pages/admin/login/Login.vue"; |
21 |
-import AdminMain from "../pages/admin/main/Main.vue"; |
|
22 |
+import AdminMain from "../pages/admin/main/Amain.vue"; |
|
22 | 23 |
import AdminUser from "../pages/admin/user/UserSelectList.vue"; |
24 |
+import AdminNotice from "../pages/admin/notice/noticeSelectList.vue"; |
|
23 | 25 |
|
24 | 26 |
const routes = [ |
25 | 27 |
/* 메인화면 */ |
... | ... | @@ -43,9 +45,10 @@ |
43 | 45 |
component: TechnologyDtail, |
44 | 46 |
}, |
45 | 47 |
/* 관리자 */ |
46 |
- { path: "/adm.page", name: "AdminMain", component: AdminMain }, |
|
47 |
- { path: "/adm/login.page", name: "AdminMain", component: AdminLogin }, |
|
48 |
+ { path: "/adm.page", name: "AdminMain", component: AdminMain,meta: { requiresAuth: true }}, |
|
49 |
+ { path: "/adm/login.page", name: "AdminLogin", component: AdminLogin }, |
|
48 | 50 |
{ path: "/adm/userSelectList.page", name: "AdminUser", component: AdminUser }, |
51 |
+ { path: "/adm/noticeSelectList.page", name: "AdminNotice", component: AdminNotice }, |
|
49 | 52 |
]; |
50 | 53 |
|
51 | 54 |
const AppRouter = createRouter({ |
--- client/views/pages/AppStore.js
+++ client/views/pages/AppStore.js
... | ... | @@ -4,7 +4,8 @@ |
4 | 4 |
export default createStore ({ |
5 | 5 |
state: { |
6 | 6 |
loginUser: null, |
7 |
- key:null |
|
7 |
+ key:null, |
|
8 |
+ isLogin: false, |
|
8 | 9 |
|
9 | 10 |
}, |
10 | 11 |
getters: { |
--- client/views/pages/admin/login/Login.vue
+++ client/views/pages/admin/login/Login.vue
... | ... | @@ -1,34 +1,66 @@ |
1 | 1 |
<template> |
2 |
- |
|
2 |
+ <div> |
|
3 |
+ <label for="id"> |
|
4 |
+ <input type="text" name="" id="id" v-model="mngrLogin.mngr_id"> |
|
5 |
+ </label> |
|
6 |
+ <label for="pw"> |
|
7 |
+ <input type="password" name="" id="pw" v-model="mngrLogin.mngr_pw"> |
|
8 |
+ </label> |
|
9 |
+ <button class="blue-btn" @click="login"> |
|
10 |
+ 로그인 |
|
11 |
+ </button> |
|
12 |
+ </div> |
|
3 | 13 |
</template> |
4 | 14 |
|
5 | 15 |
<script> |
6 | 16 |
import axios from 'axios'; |
7 |
- |
|
17 |
+import crypto from "crypto-js"; |
|
18 |
+import { useStore } from 'vuex'; |
|
8 | 19 |
|
9 | 20 |
export default { |
10 | 21 |
data() { |
11 |
- return {}; |
|
22 |
+ return { |
|
23 |
+ mngrLogin: { |
|
24 |
+ mngr_id: null, |
|
25 |
+ mngr_pw: null |
|
26 |
+ }, |
|
27 |
+ store: useStore(), |
|
28 |
+ }; |
|
12 | 29 |
}, |
13 | 30 |
methods: { |
14 |
- async login() { |
|
15 |
- // TODO: store에서 키 불러오기 |
|
16 |
- let response = await axios({ |
|
17 |
- url: "/manager/login.json", |
|
18 |
- method: "post", |
|
31 |
+ //로그인 |
|
32 |
+ login: function () { |
|
33 |
+ let vm = this; |
|
34 |
+ |
|
35 |
+ axios({ |
|
36 |
+ url: '/manager/login.json', |
|
37 |
+ method: 'post', |
|
19 | 38 |
headers: { |
20 |
- "Content-Type": "application/json; charset=UTF-8", |
|
39 |
+ 'Content-Type': 'application/json; charset=UTF-8' |
|
21 | 40 |
}, |
22 |
- data: { |
|
23 |
- mngr_id: 'asdf', mngr_pw: '1234' |
|
41 |
+ data: vm.mngrLogin |
|
42 |
+ }).then(function (response) { |
|
43 |
+ // console.log("login - response : ", response); |
|
44 |
+ if (response.data == true) { |
|
45 |
+ this.$emit("updateIsLogin", !this.isLogin); |
|
46 |
+ vm.$router.push({ path: '/adm.page', query: {} }); |
|
47 |
+ } else { |
|
48 |
+ alert('로그인 정보를 다시 확인해주세요.'); |
|
49 |
+ vm.mngrLogin.mngr_id = null; |
|
50 |
+ vm.mngrLogin.mngr_pw = null; |
|
24 | 51 |
} |
52 |
+ }).catch(function (error) { |
|
53 |
+ console.log("login - error : ", error); |
|
54 |
+ vm.mngrLogin.mngr_id = null; |
|
55 |
+ vm.mngrLogin.mngr_pw = null; |
|
25 | 56 |
}); |
26 |
- console.log(response.data.key); |
|
27 |
- }}, |
|
57 |
+ }, |
|
58 |
+ }, |
|
28 | 59 |
watch: {}, |
29 | 60 |
computed: {}, |
30 | 61 |
components: {}, |
31 | 62 |
mounted() { |
63 |
+ console.log("login::::::::::") |
|
32 | 64 |
}, |
33 | 65 |
}; |
34 | 66 |
</script> |
+++ client/views/pages/admin/main/Amain.vue
... | ... | @@ -0,0 +1,61 @@ |
1 | +<template> | |
2 | + <div class="admin-wrap"> | |
3 | + <div class="content-box"> | |
4 | + <div class="title-wrap"> | |
5 | + <h2 class="main-title">대시보드</h2> | |
6 | + </div> | |
7 | + <div class="content-wrap"> | |
8 | + | |
9 | + </div> | |
10 | + </div> | |
11 | + </div> | |
12 | +</template> | |
13 | +<script> | |
14 | +import { useStore } from "vuex"; | |
15 | + | |
16 | +export default { | |
17 | + | |
18 | + data() { | |
19 | + return { | |
20 | + isLogin: false, | |
21 | + userInfo: { | |
22 | + user_id: null, | |
23 | + }, | |
24 | + store: useStore(), | |
25 | + }; | |
26 | + }, | |
27 | + methods: {}, | |
28 | + watch: {}, | |
29 | + computed: {}, | |
30 | + components: {}, | |
31 | + mounted() { | |
32 | + this.$router.beforeEach((to, from, next) => { | |
33 | + const isLogin = this.store.state.loginUser != null; | |
34 | + // 로그인한 상태일 때 | |
35 | + if (isLogin) { | |
36 | + // 로그인 페이지로 이동하려는 경우 | |
37 | + if (to.path === '/adm/login.page') { | |
38 | + next('/adm.page'); // 로그인 페이지로 이동하지 않고 admin main 페이지로 리다이렉트 | |
39 | + } else { | |
40 | + next(); // 다른 페이지로 이동을 허용 | |
41 | + } | |
42 | + } else { // 로그인하지 않은 상태일 때 | |
43 | + // 로그인 페이지로 이동하려는 경우 | |
44 | + if (to.path === '/adm/login.page') { | |
45 | + next(); // 로그인 페이지로 이동 허용 | |
46 | + } else { | |
47 | + next('/adm/login.page'); // 다른 페이지로 이동하지 않고 로그인 페이지로 리다이렉트 | |
48 | + } | |
49 | + } | |
50 | + }); | |
51 | + } | |
52 | +}; | |
53 | +</script> | |
54 | +<style scoped> | |
55 | +.admin-wrap, | |
56 | +.content-box { | |
57 | + width: 100%; | |
58 | + height: 100%; | |
59 | + font-size: 1.3rem; | |
60 | +} | |
61 | +</style> |
--- client/views/pages/admin/main/Main.vue
... | ... | @@ -1,34 +0,0 @@ |
1 | -<template> | |
2 | -TEST2 | |
3 | -</template> | |
4 | - | |
5 | -<script> | |
6 | -import axios from "axios"; | |
7 | - | |
8 | - | |
9 | -export default { | |
10 | - data() { | |
11 | - return {} | |
12 | - }, | |
13 | - methods: {}, | |
14 | - watch: {}, | |
15 | - computed: {}, | |
16 | - components: {}, | |
17 | - mounted() { | |
18 | - // TODO: 로그인 체크 | |
19 | - // axios({ | |
20 | - // url: "/user/loginUserSelectOne.json", // TODO: managerSelectOne | |
21 | - // method: "post", | |
22 | - // headers: { | |
23 | - // "Content-Type": "application/json; charset=UTF-8", | |
24 | - // }, | |
25 | - // }).then(function (response) { | |
26 | - // console.log(response.data); | |
27 | - // // TODO: check manager.mngr_id | |
28 | - // let key = new common.AesKey(response.data.key); | |
29 | - // // TODO: store에 key 저장 | |
30 | - // alert(key.encrypt('asdf')); | |
31 | - // }); | |
32 | - } | |
33 | -} | |
34 | -</script> |
+++ client/views/pages/admin/notice/NoticeSelectList.vue
... | ... | @@ -0,0 +1,37 @@ |
1 | +<template> | |
2 | + <div class="admin-wrap"> | |
3 | + <div class="content-box"> | |
4 | + <div class="title-wrap"> | |
5 | + <h2 class="main-title">공지사항</h2> | |
6 | + </div> | |
7 | + <div class="content-wrap"> | |
8 | + | |
9 | + </div> | |
10 | + </div> | |
11 | + </div> | |
12 | +</template> | |
13 | +<script> | |
14 | + | |
15 | +export default { | |
16 | + | |
17 | + data() { | |
18 | + return {}; | |
19 | + }, | |
20 | + methods: {}, | |
21 | + watch: {}, | |
22 | + computed: {}, | |
23 | + components: {}, | |
24 | + mounted() { | |
25 | +console.log("main mounted") | |
26 | + }, | |
27 | +}; | |
28 | +</script> | |
29 | +<style scoped> | |
30 | +.admin-wrap, | |
31 | +.content-box { | |
32 | + width: 100%; | |
33 | + height: 100%; | |
34 | + font-size: 1.3rem; | |
35 | +} | |
36 | + | |
37 | +</style>(No newline at end of file) |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?