diff --git a/src/api/login.js b/src/api/login.js new file mode 100644 index 0000000..0de6506 --- /dev/null +++ b/src/api/login.js @@ -0,0 +1,23 @@ +import request from '@/utils/request.js' + +export const getCodeImg = () => { + return request({ + url: '/auth/captchaImage', + method: 'get' + }) +} + +export const login = (data) => { + return request({ + url: '/auth/login', + method: 'post', + data + }) +} + +export const getUserInfo = () => { + return request({ + url: '/auth/info', + method: 'get', + }) +} diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index a2c3d13..7fd49d1 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -13,215 +13,3 @@ a { html, body, #app, .el-container, .el-aside, .el-main { height: 100%; } - -.logo { - height: 106px; - color: #EDC49A; - font-weight: bold; - font-size: 23px; - display: flex; - justify-content: center; - align-items: center; -} - -.el-menu { - border: none !important; -} - -.toggle { - line-height: 65px; - padding: 0 15px; - cursor: pointer; - - &:hover { - background-color: #79bbff; - } -} - -.icon { - width: 20px; - height: 20px; - vertical-align: middle; - transform: translateY(-2px); -} - -.el-main { - padding: 0 !important; -} - -.el-aside { - box-shadow: 4px 0 2px 1px rgb(171, 167, 167); - transition: width 0.3s; - overflow: hidden; - height: 100vh; - background-color: #211F31; -} - -.el-popover.el-popper { - padding: 10px !important; - min-width: 60px !important; - ul{ - li{ - height: 25px; - line-height: 25px; - cursor: pointer; - } - } -} - -.navbar { - height: 65px; - border-bottom: 1px solid #999999; - padding: 0 15px 0 0; - display: flex; - justify-content: flex-start; - align-items: center; - - .right-bar { - margin-left: auto; - display: flex; - justify-content: flex-start; - align-items: center; - - img { - width: 40px; - height: 40px; - border-radius: 50%; - cursor: pointer; - } - } -} - -.el-dialog { - border-radius: 12px !important; - border: none; - - .el-dialog__header { - border-top-left-radius: 12px; - border-top-right-radius: 12px; - // background-color: #262626; - margin: 0; - // .el-dialog__title{ - // color: white; - // } - } -} - - -.table-header-btn { - display: flex; - justify-content: flex-start; - align-items: center; - margin-bottom: 10px; -} - -.query-form { - .el-form-item__label { - font-weight: 700; - } - - .el-button { - font-size: 13px; - } -} - - -.query-btn { - margin-bottom: 10px; - - .el-button { - font-size: 13px; - } -} - - -.table { - thead .el-table-column--selection .cell { - display: none; - } - - margin-bottom: 20px; -} - -.dialog-form { - .el-form-item { - flex-direction: column; - margin-bottom: 10px; - - .el-form-item__content { - .el-select { - flex-grow: 1; - } - } - - .el-form-item__label { - justify-content: flex-start; - } - } -} - -.custom-dialog { - :deep .el-dialog__header { - padding: 10px 20px; - - .el-dialog__title { - font-size: 17px; - } - - .el-dialog__headerbtn { - top: 15px; - - .i { - font-size: large; - } - } - } - - :deep .el-dialog__footer { - padding: 10px 20px; - } -} - -.border { - :deep .el-dialog__header { - border-bottom: 1px solid #e8e8e8; - } - - :deep .el-dialog__footer { - border-top: 1px solid #e8e8e8; - } -} - -.layout { - display: flex; - justify-content: space-around; - - .layout-left { - width: 30%; - border: 1px solid #ebeef5; - padding: 10px; - - - .dict-tree { - width: 100%; - display: flex; - justify-content: space-between; - //:deep .el-button{ - // //border: 1px solid; - // background-color: #fff; - //} - .left-type { - margin-right: 20px; - font-size: 12px; - color: #999; - } - } - } - - .layout-right { - width: 70%; - border: 1px solid #ebeef5; - margin-left: 10px; - padding: 10px - } -} diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss deleted file mode 100644 index e69de29..0000000 diff --git a/src/layout/appmain/AppMain.vue b/src/layout/appmain/AppMain.vue deleted file mode 100644 index b5735af..0000000 --- a/src/layout/appmain/AppMain.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/layout/index.vue b/src/layout/index.vue deleted file mode 100644 index 617c3e4..0000000 --- a/src/layout/index.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/layout/navbar/Breadcrumb.vue b/src/layout/navbar/Breadcrumb.vue deleted file mode 100644 index 3e214a6..0000000 --- a/src/layout/navbar/Breadcrumb.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - - - {{ item.meta.title }} - - - {{ item.meta.title }} - - - - - - diff --git a/src/layout/navbar/Hamburger.vue b/src/layout/navbar/Hamburger.vue deleted file mode 100644 index a5683b6..0000000 --- a/src/layout/navbar/Hamburger.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - diff --git a/src/layout/navbar/index.vue b/src/layout/navbar/index.vue deleted file mode 100644 index 245e8bc..0000000 --- a/src/layout/navbar/index.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - 个人中心 - 退出登录 - - - - - - - - diff --git a/src/layout/siderbar/index.vue b/src/layout/siderbar/index.vue deleted file mode 100644 index 7ebe751..0000000 --- a/src/layout/siderbar/index.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - TUNNEL-CLOUD - - - - - 首页 - - - - - - diff --git a/src/layout/tagsview/index.vue b/src/layout/tagsview/index.vue deleted file mode 100644 index 209687f..0000000 --- a/src/layout/tagsview/index.vue +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - {{ item.meta.title }} - - - - - - - - - - diff --git a/src/main.js b/src/main.js index a84c95c..df116bd 100644 --- a/src/main.js +++ b/src/main.js @@ -11,7 +11,6 @@ import * as ElementPlusIconsVue from '@element-plus/icons-vue' import 'element-plus/dist/index.css' import '@/assets/styles/index.scss' -import '@/assets/styles/sidebar.scss' const app = createApp(App) for (const [key, component] of Object.entries(ElementPlusIconsVue)) { diff --git a/src/router/index.js b/src/router/index.js index b68066f..eb07e96 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,10 +1,7 @@ import { createRouter, createWebHashHistory } from 'vue-router'; import NProgress from 'nprogress'//进度条 import 'nprogress/nprogress.css' -import Layout from '@/layout/index.vue' -// import { getToken } from '../utils/auth' -// import { usePermissionStore } from '../store/permisstion.js' -// import { useAuthStore } from '../store/userstore.js' +import { getToken } from '../utils/auth' NProgress.configure({ showSpinner: false }) const routes = [ @@ -19,57 +16,38 @@ const routes = [ }, { path: '/', - name: 'layout', - component: Layout, - redirect: '/home', + name: 'home', + component: () => import('@/views/home/index.vue'), meta: { - hidden: false - }, - children: [ - { - path: '/home', - name: 'home', - component: () => import('@/views/home/index.vue'), - meta: { - title: '首页', - breadcrumb: true - } - } - ] - }, + title: '首页', + breadcrumb: true + } + } ]; const router = createRouter({ history: createWebHashHistory(), routes, }); -// router.beforeEach(async (to,form,next)=>{ -// const permissionStore = usePermissionStore() -// const authStore = useAuthStore() -// NProgress.start() -// if(!getToken()) { -// if(to.path === '/login') { -// next() -// NProgress.done() -// }else { -// next({path: '/login'}) -// } -// }else { -// if(to.path === '/login') { -// next('/') -// NProgress.done() -// }else { -// permissionStore.setIsLoadRoutes(true) -// if(permissionStore.isLoadRoutes && permissionStore.asyncRouters.length==0){ -// // await authStore.setUserInfo() -// next({...to, replace: true}) -// } else { -// next() -// } -// } -// -// } -// }) +router.beforeEach( (to,form,next)=>{ + NProgress.start() + if(!getToken()) { + if (to.path === '/login') { + next() + NProgress.done() + } else { + next({path: '/login'}) + } + }else { + console.log('有token') + if(to.path === '/login') { + next('/') + NProgress.done() + }else { + next() + } + } +}) router.afterEach(()=>{ NProgress.done() }) diff --git a/src/store/siderbar.js b/src/store/siderbar.js deleted file mode 100644 index 3b5ab88..0000000 --- a/src/store/siderbar.js +++ /dev/null @@ -1,19 +0,0 @@ -import { defineStore } from "pinia"; -export const useSiderBar = defineStore('siderbar',()=>{ - //定义控制侧边栏是否展开变量默认展开 - const isCollapse = ref(false) - //获取侧边栏状态 - const getSiderBarStatus = () => { - return isCollapse.value - } - //设置侧边栏状态 - const setSiderBarStatus = () => { - const status = getSiderBarStatus() - return isCollapse.value = !status - } - - return { - getSiderBarStatus, - setSiderBarStatus, - } -}) diff --git a/src/store/tagsview.js b/src/store/tagsview.js deleted file mode 100644 index 5b6017c..0000000 --- a/src/store/tagsview.js +++ /dev/null @@ -1,56 +0,0 @@ -import { defineStore } from "pinia"; -import { ref } from "vue"; -import { useRouter } from "vue-router"; - -export const useTagsView = defineStore('tagsView',()=>{ - const router = useRouter() - //已显示的标签页list - const visitedViews = ref([]) - - //添加标签页面 - const addVisitedViews = ({path,meta}) => { - if(visitedViews.value.length == 0) { - visitedViews.value.push({path,meta}) - }else { - const paths = visitedViews.value.map(item => item.path) - if(paths.includes(path) == false) { - visitedViews.value.push({path,meta}) - } - } - } - - //删除标签页 - const delVisitedViews = (path) => { - console.log('进入删除'); - if(visitedViews.value.length - 1 == 0) { - return - } - visitedViews.value.forEach((item,index)=>{ - if(item.path == path) { - visitedViews.value.splice(index,1) - } - }) - toLastTagView(visitedViews) - } - - //删除其他标签页 - const delOtherVisitedViews = ({path,meta}) => { - visitedViews.value = [] - visitedViews.value.push({path,meta}) - toLastTagView(visitedViews) - } - - //路由到末尾标签页 - const toLastTagView = (view) => { - console.log(view,'进入跳转末页'); - const lastTagView = view.value.slice(-1)[0] - router.push(lastTagView.path) - } - - return { - visitedViews, - addVisitedViews, - delVisitedViews, - delOtherVisitedViews, - } -}) diff --git a/src/store/userstore.js b/src/store/userstore.js new file mode 100644 index 0000000..e4db0fd --- /dev/null +++ b/src/store/userstore.js @@ -0,0 +1,42 @@ +import { defineStore } from "pinia"; +import { ref } from "vue"; +import { getUserInfo, login } from "../api/login"; +import { ElMessage } from "element-plus"; +import {getAuthInfo, removeToken, setAuthInfo, setToken} from "../utils/auth"; + +export const useAuthStore = defineStore('auth',()=>{ + const userinfo = ref({}) + const permisstions = ref([]) + const roles = ref([]) + const userLogin = async (data) => { + let flag + await login(data).then(res=>{ + if(res?.code === 1000) { + setToken(res.data) + flag = true + }else { + ElMessage.error(res.msg) + flag = false + } + }) + return flag + } + const userLogout = () => { + removeToken() + } + const setUserInfo = async () => { + await getUserInfo().then(res=>{ + userinfo.value = res.data.user + permisstions.value = res.data.permissions + roles.value = res.data.roles + }) + } + + return { + userinfo, + permisstions, + userLogin, + userLogout, + setUserInfo + } +}) diff --git a/src/utils/auth.js b/src/utils/auth.js new file mode 100644 index 0000000..55243e8 --- /dev/null +++ b/src/utils/auth.js @@ -0,0 +1,25 @@ +import Cookies from "js-cookie"; + +export const getToken = () => { + return Cookies.get('Authorization') +} + +export const setToken = (token) => { + return Cookies.set('Authorization', token) +} + +export const removeToken = () => { + return Cookies.remove('Authorization') +} + +export const getAuthInfo = () => { + return Cookies.get('authinfo') +} + +export const setAuthInfo = (info) => { + return Cookies.set('authinfo', info) +} + +export const removeAuthInfo = () => { + return Cookies.remove('authinfo') +} \ No newline at end of file diff --git a/src/utils/request.js b/src/utils/request.js new file mode 100644 index 0000000..10627aa --- /dev/null +++ b/src/utils/request.js @@ -0,0 +1,95 @@ +import axios from "axios"; +import { ElMessage, ElMessageBox } from "element-plus"; +import { getToken, removeToken } from "./auth"; + +axios.defaults.headers['Content-Type']='application/json' + +const serveice = axios.create({ + baseURL: import.meta.env.VITE_BASE_URL, + timeout: 6000 +}) + +serveice.interceptors.request.use(config=>{ + const ACCESS_TOKEN = getToken() || '' + if(ACCESS_TOKEN!==undefined && ACCESS_TOKEN!=='') { + config.headers['Authorization']=ACCESS_TOKEN + } + return config +},error=>{ + Promise.reject(error) +}) +serveice.interceptors.response.use(response=>{ + // const status = response.status || 200 + //二进制数据直接返回 + if(response.request.responseType === 'blob' || response.request.responseType === 'arraybuffer') { + return response.data + } + // switch(status) { + // case 401: + // ElMessageBox.confirm('登录状态已过期,请重新登录','系统提示',{ + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning', + // closeOnClickModal: false + // }).then(()=>{ + // removeToken() + // window.location = '/login' + // }) + // return Promise.reject('会话已过期,请重新登录') + // case 402: + // break; + // case 403: + // ElMessage.warning('禁止访问') + // break; + // case 404: + // ElMessage.warning('不存在的地址') + // break; + // case 405: + // ElMessage.warning('传输格式错误,请检查') + // break; + // case 500: + // ElMessage.error('系统未知错误') + // // return response.data + // break + // } + return response.data +},error=>{ + let response = error.response + const status = response.status; + switch(status) { + case 401: + ElMessageBox.confirm('登录状态已过期,请重新登录','系统提示',{ + confirmButtonText: '重新登录', + cancelButtonText: '取消', + type: 'warning', + closeOnClickModal: false + }).then(()=>{ + removeToken() + window.location = '/login' + }) + return Promise.reject('会话已过期,请重新登录') + case 402: + break; + case 403: + ElMessage.warning('禁止访问') + removeToken() + window.location = '/forbidden' + break; + case 404: + ElMessage.warning('不存在的地址') + break; + case 405: + ElMessage.warning('传输格式错误,请检查') + break; + case 500: + if (response.data){ + return response.data + }else { + ElMessage.error('系统未知错误') + break; + } + } + return Promise.reject(error) +}) + +export default serveice diff --git a/src/views/home/index.vue b/src/views/home/index.vue index 5a876d7..149c6f1 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -5,9 +5,6 @@