import { createWebHistory, createRouter } from "vue-router"; import store from "./AppStore"; /** * NICE테스트 * * */ import NiceTestPopup from "../pages/user/nicepage/NiceTestPopup.vue"; import Inspection from "../pages/user/etc/Inspection.vue"; import NiceTest from "../pages/user/nicepage/NiceTest.vue"; import NiceRequest from "../pages/user/nicepage/NiceRequest.vue"; import PdfView from "./viewer/PdfView.vue"; import ReportView from "./viewer/ReportViewer.vue"; import NotFound from "../pages/user/etc/NotFound.vue" import VueCookies from "vue-cookies"; const beforeRoutes = [ /* NICE 인증 */ { path: "/cmmn/NiceTestPopup.page", name: "NiceTestPopup", component: NiceTestPopup, }, { path: "/cmmn/NiceTest.page", name: "NiceTest", component: NiceTest }, { path: "/cmmn/NiceRequest.page", name: "NiceRequest", component: NiceRequest }, { path: "/cmmn/pdfView.page", name: "PdfView", component: PdfView }, { path: "/cmmn/ReportViewer.page", name: "ReportView", component: ReportView }, { path: "/inspection.page", name: "Inspection", component: Inspection }, { path: "/notFound.page", name: "NotFound", component: NotFound }, ]; import { findAll, accessCheck } from "../../resources/api/router"; import { save } from "../../resources/api/cntnStats"; // 라우터 정보 호출 async function fetchRoutes() { try { const res = await findAll(); // console.log('res : ', res.data.data); if(res.status == 200) { const newRoutes = res.data.data.map(route => ({ path: route.pagePathNm, name: route.contsEngNm, component: () => import(`${ route.cmpntPathNm }`), meta: { authrt: route.authrtList, typeId: route.contsId } })); return newRoutes; } } catch(error) { console.log(error); return []; } } function setToken(authorization, refresh) { store.commit("setAuthorization", authorization); // store.commit("setRefresh", refresh); //this.$cookies.set('refresh',refresh); /** jwt토큰 복호화 **/ const base64String = authorization.split('.')[1]; const base64 = base64String.replace(/-/g, '+').replace(/_/g, '/'); const mbr = JSON.parse(decodeURIComponent(window.atob(base64).split('').map(function (c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join(''))); store.commit("setMbrId", mbr.mbrId); store.commit("setMbrNm", mbr.mbrEncptFlnm); store.commit("setAuthrtNm", mbr.authrtNm); store.commit("setAuthrtTypeLvl", mbr.authrtTypeLvl); store.commit('setRoles', mbr.roles); return mbr.roles; } // 접근 제어 확인 async function accessUrl (path , auth) { try { const params = { 'path' : path, 'auth' : auth[0] } const res = await accessCheck(params); if(res.status == 200) { return res.data.data; } } catch(error) { console.log(error); return false; } } function checkMenu(path){ if(store.state.menuList != null){ for(let i = 0 ; i < store.state.menuList.length ; i++){ if(store.state.menuList[i].childList.length > 0){ for(let j = 0 ; j < store.state.menuList[i].childList.length ; j++){ if(store.state.menuList[i].childList[j].routerUrl == path.path || store.state.menuList[i].childList[j].routerUrl == path.path.replace('view','list') || store.state.menuList[i].childList[j].routerUrl == path.path.replace('insert','list')) { store.commit('setMenuInfo', { 'menuNm': store.state.menuList[i].childList[j].menuNm, 'menuCn': store.state.menuList[i].childList[j].menuCn }); store.commit('setPageNaviInfo', { 'main': store.state.menuList[i].menuNm, 'sub': store.state.menuList[i].childList[j].menuNm }); return true; } // 관리자 3depth 처리 if(path.path.startsWith('/kdm/')){ if(store.state.menuList[i].childList[j].childList.length > 0){ for(let k = 0 ; k < store.state.menuList[i].childList[j].childList.length ; k++){ if(store.state.menuList[i].childList[j].childList[k].routerUrl == path.path || store.state.menuList[i].childList[j].childList[k].routerUrl == path.path.replace('view','list') || store.state.menuList[i].childList[j].childList[k].routerUrl == path.path.replace('insert','list')){ store.commit('setMenuInfo', { 'menuNm': store.state.menuList[i].childList[j].childList[k].menuNm, 'menuCn': store.state.menuList[i].childList[j].childList[k].menuCn }); store.commit('setPageNaviInfo', { 'main': store.state.menuList[i].menuNm, 'sub': store.state.menuList[i].childList[j].menuNm , 'third' : store.state.menuList[i].childList[j].childList[k].menuNm }); return true; } } } } } } } } if(path.path == '/cmmn/join.page'){ store.commit('setPageNaviInfo', { 'main':'회원가입'}); }else if(path.path == '/aidt/terms/view.page?type=use'){ store.commit('setPageNaviInfo', { 'main':'약관'}); }else{ store.commit('setPageNaviInfo', { 'main':'', 'sub': '' }); } } // 사용자 권한과 라우터에 포함되어 있는 권한을 비교하여 최종 권한 추출 function mergeAuth(userRoles, to) { const routeMeta = to.meta; const result = { rdAuthrtYn: 'N', // 읽기 권한 wrAuthrtYn: 'N', // 쓰기 권한 mdfcnAuthrtYn: 'N', // 수정 권한 delAuthrtYn: 'N', // 삭제 권한 fileDwnldAuthrtYn: 'N', // 파일 다운로드 권한 } // 관리자 기능인지 확인 const pathAdmin = to.path.startsWith('/kdm') ? 'A' : 'U'; if (!routeMeta || !routeMeta.authrt || routeMeta.authrt.length === 0) { return result; } routeMeta.authrt.forEach(auth => { if(userRoles.includes(auth.authrtId)) { if(auth.rdAuthrtYn === 'Y' && auth.menuUserCode === pathAdmin) result.rdAuthrtYn = 'Y'; if(auth.wrAuthrtYn === 'Y' && auth.menuUserCode === pathAdmin) result.wrAuthrtYn = 'Y'; if(auth.mdfcnAuthrtYn === 'Y' && auth.menuUserCode === pathAdmin) result.mdfcnAuthrtYn = 'Y'; if(auth.delAuthrtYn === 'Y' && auth.menuUserCode === pathAdmin) result.delAuthrtYn = 'Y'; if(auth.fileDwnldAuthrtYn === 'Y' && auth.menuUserCode === pathAdmin) result.fileDwnldAuthrtYn = 'Y'; } }); return result; } // 통계 등록 async function cntnStatsSave(typeId, roles) { try { const cntnStats = { 'typeId' : typeId, 'mbrAuthList' : roles } await save(cntnStats); } catch(error) { console.log(error); } } // 통계 등록 async function bbsStatsSave(typeId, roles, bbsId, bbsMngId) { try { const cntnStats = { 'typeId' : typeId, 'mbrAuthList' : roles, 'bbsId' : bbsId, 'bbsMngId' : bbsMngId } await save(cntnStats); } catch(error) { console.log(error); } } // 권한 검증 function isValidRole() { const roles = store.state.roles; if(!Array.isArray(roles)) { store.commit("setStoreReset"); return false; } for(const role of roles) { if(typeof role !== 'object' || !role.hasOwnProperty('authority')) { store.commit("setStoreReset"); return false; } } return true; } export default async function createAppRouter() { const dynamicRoutes = await fetchRoutes(); // DB에 적재된 라우터 정보 호출 const newRoutes = beforeRoutes.concat(dynamicRoutes); // 기존 라우터 정보와 합치기 //console.log('newRoutes : ' , newRoutes); const AppRouter = createRouter({ history: createWebHistory(), routes: newRoutes, scrollBehavior(to, from, savedPosition) { if(store.state.topScrollerFlag){ return { left: 0, top: 0 }; // if (savedPosition) { // return savedPosition; // } else { // return { left: 0, top: 0 }; // } }else{ store.commit('setTopScrollerFlag', true); } } }); AppRouter.beforeEach(async (to, from, next) => { // 초기 로딩 무조건 취소 store.commit('setLoading', false); store.commit('setRouterFlag', true); checkMenu(to); // 접근 제어 확인(미확인 시 이전 페이지로 이동) const accesCheck = await accessUrl(to.path , store.state.roles.map(auth => auth.authority)); // 권한 변경 정보 체크 if(accesCheck.result === 'reset') { const tempRole = setToken(accesCheck.authorization, accesCheck.refresh); alert('권한 정보가 갱신되었습니다.') location.href = to.path; }else if(accesCheck.result === 'clear'){ store.commit("setStoreReset"); location.href = "/"; } const roleCheck = isValidRole(); if(!roleCheck) { alert('접근이 불가합니다.\n관리자에게 문의하세요.'); next('/'); } // 경로에 따른 사용자 타입 설정 if(to.path === '/') { store.commit('setUserType', null) next('/aidt/main.page'); } else if(to.path.startsWith('/kdm')) { store.commit('setUserType', 'adm'); } else if(to.path.startsWith('/aidt')) { store.commit('setUserType', null); } if(to.path === '/login.page') { store.commit('setPath', to.path); next(); return; } const isLogin = store.state.authorization; // 토큰 정보 호출(로그인 유무 확인) const mbrAuth = store.state.roles.map(auth => auth.authority); // 사용자 권한 정보 const pageAuth = mergeAuth(mbrAuth, to); if(to.path.includes('/login.page')){ if(mbrAuth[0] !== 'ROLE_NONE') { alert("잘못된 요청입니다.") mbrAuth[0] === 'ROLE_ADMIN' ? next('/kdm/main.page') : next('/'); } } // 메인 페이지 or 기업 페이지 or 로그인 페이지 if(to.path === '/' || to.path === '/aidt/main.page' ||to.path.startsWith('/login.page') || to.path.startsWith('/cmmn/') || to.path.startsWith('/aidt/findInfo.page') || to.path.startsWith('/aidt/terms/view.page') || to.path.includes('/aidt/search/view.page') || to.path === '/notFound.page' || to.path === '/inspection.page' ) { //to.path.startsWith('/aidt/') || /** * /aidt/findInfo.page : 아이디/비밀번호 찾기 * /aidt/terms/view.page : 이용약관 전문보기 / 개인정보 처리방침 전문보기 * * */ store.commit('setPath', to.path); store.commit('setPageAuth', pageAuth); // 게시판 // if(to.path.includes('/BBS_')) { // const lastSlashIndex = to.path.lastIndexOf('/'); // 마지막 '/' 인덱스 // const path = to.path.substring(0, lastSlashIndex); // 마지막 '/' 이전 경로 // store.commit('setPath', path); // }else{ // } if(to.path.includes('/main.page')) { await cntnStatsSave(null, mbrAuth); // 메인 페이지 접속 시 사용자 접속 통계 증가 } else if(to.path.startsWith('/company/')) { await cntnStatsSave(to.meta.typeId, mbrAuth); // 기업 페이지의 각 종류(게시판, 콘텐츠)에 맞는 통계 증가 } next(); }else { // 로그인 상태이고, 권한이 허용인 경우 검사 // const hasAcc = true; const hasAcc = to.matched.some(record => { if(!record.meta.authrt) return false; return record.meta.authrt.some(auth => { // 경로별 권한 검사 if(to.path.includes('/list.page')) { // 목록 권한 검증 return pageAuth.rdAuthrtYn === 'Y' } else if(to.path.includes('/insert.page')) { // 등록 및 수정 권한 검증 return pageAuth.wrAuthrtYn === 'Y' } else if(to.path.includes('/view.page')) { // 상세조회 권한 검증 if(mbrAuth[0] == 'ROLE_NONE' || mbrAuth[0] == 'ROLE_USER' ){ return pageAuth.rdAuthrtYn === 'Y' && pageAuth.fileDwnldAuthrtYn === 'Y' } else{ return pageAuth.rdAuthrtYn === 'Y'; } } else if(to.path.includes('/main.page')) { // 메인 페이지 권한 검증 return pageAuth.rdAuthrtYn === 'Y'; } else if(to.path.includes('/update.page')) { // 수정 페이지 권한 검증 return pageAuth.wrAuthrtYn === 'Y'; } else { return false; } }); }); // 권한이 있고 접근 가능한 경우 if(hasAcc) { if(to.path.includes('.page')) { const lastSlashIndex = to.path.lastIndexOf('/'); // 마지막 '/' 인덱스 const path = to.path.substring(0, lastSlashIndex); // 마지막 '/' 이전 경로 store.commit('setPath', path); } // 접속 통계 if(to.path.includes('/main.page')) { store.commit('setPageNaviInfo', { 'main': '' , 'sub': '' }); await cntnStatsSave(null, mbrAuth); // 메인 페이지 접속 시 사용자 접속 통계 증가 } else { await cntnStatsSave(to.meta.typeId, mbrAuth); // 그외에는 각 종류(게시판, 콘텐츠)에 맞는 통계 증가 } store.commit('setPageAuth', pageAuth); //게시글 별 통계 if(to.query.pageId) { let bbsMngId = to.meta.typeId; let bbsId = to.query.pageId; if(bbsId.includes("BBS_") && !to.path.startsWith('/kdm/')) { if(bbsMngId.includes("CONTS_")) { bbsMngId = 'BBS_MNG_0000000004'; } await bbsStatsSave('POST', mbrAuth, bbsId, bbsMngId); } } next(); // 페이지 최상단 이동 if( store.state.topScrollerFlag){ window.scrollTo({ top: 0, // behavior: 'smooth' // 부드럽게 스크롤 }); }else{ store.commit('setTopScrollerFlag', true); } // 권한이 없는 경우 이전 페이지 or / 이동 } else { if(!isLogin && to.path.startsWith('/kdm/')){ store.commit('setRedirect', to.path); next({ path: "/login.page" }); }else{ if(mbrAuth[0] == 'ROLE_NONE' || mbrAuth[0] == 'ROLE_USER' ){ alert('기업 전용 페이지 입니다.'); }else{ alert('접근 권한이 없습니다.'); } store.commit('setTopScrollerFlag', false); next(from.fullPath ? from.fullPath : '/'); } } } }); return AppRouter; }