wxd 4 달 전
부모
커밋
2df383bb32

+ 1 - 1
.env.development

@@ -1,5 +1,5 @@
 # 页面标题
-VITE_APP_TITLE = 英才卡申请平台
+VITE_APP_TITLE = 英才卡申请平台管理系统
 
 # 开发环境配置
 VITE_APP_ENV = 'development'

+ 1 - 1
index.html

@@ -11,7 +11,7 @@
       content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
     />
     <link rel="icon" href="/favicon.ico" />
-    <title>英才卡申请平台</title>
+    <title>英才卡申请平台管理系统</title>
     <!--[if lt IE 11
       ]><script>
         window.location.href = "/html/ie.html";

+ 9 - 6
src/api/menu.js

@@ -1,9 +1,12 @@
-import request from '@/utils/request'
+/** @format */
+
+import request from "@/utils/request";
 
 // 获取路由
-export const getRouters = () => {
+export const getRouters = (params) => {
   return request({
-    url: '/getRouters',
-    method: 'get'
-  })
-}
+    url: "/getRouters",
+    method: "get",
+    params,
+  });
+};

+ 5 - 3
src/assets/styles/element-ui.scss

@@ -1,3 +1,5 @@
+/** @format */
+
 // cover some element-ui styles
 
 .el-breadcrumb__inner,
@@ -69,7 +71,7 @@
 // dropdown
 .el-dropdown-menu {
   a {
-    display: block
+    display: block;
   }
 }
 
@@ -91,6 +93,6 @@
   display: none;
 }
 
-.el-dropdown .el-dropdown-link{
+.el-dropdown .el-dropdown-link {
   color: var(--el-color-primary) !important;
-}
+}

+ 30 - 12
src/assets/styles/index.scss

@@ -1,18 +1,29 @@
-@import './variables.module.scss';
-@import './mixin.scss';
-@import './transition.scss';
-@import './element-ui.scss';
-@import './sidebar.scss';
-@import './btn.scss';
-@import './ruoyi.scss';
-
+/** @format */
+
+@import "./variables.module.scss";
+@import "./mixin.scss";
+@import "./transition.scss";
+@import "./element-ui.scss";
+@import "./sidebar.scss";
+@import "./btn.scss";
+@import "./ruoyi.scss";
+
+.no-redirect,
+.el-breadcrumb__inner,
+.el-breadcrumb__separator {
+  a {
+    color: #fff !important;
+  }
+  color: #fff !important;
+}
 body {
   height: 100%;
   margin: 0;
   -moz-osx-font-smoothing: grayscale;
   -webkit-font-smoothing: antialiased;
   text-rendering: optimizeLegibility;
-  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
+    Microsoft YaHei, Arial, sans-serif;
 }
 
 label {
@@ -106,7 +117,8 @@ aside {
   display: block;
   line-height: 32px;
   font-size: 16px;
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
+    Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
   color: #2c3e50;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
@@ -136,7 +148,7 @@ aside {
 }
 
 .text-center {
-  text-align: center
+  text-align: center;
 }
 
 .sub-navbar {
@@ -147,7 +159,13 @@ aside {
   text-align: right;
   padding-right: 20px;
   transition: 600ms ease position;
-  background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
+  background: linear-gradient(
+    90deg,
+    rgba(32, 182, 249, 1) 0%,
+    rgba(32, 182, 249, 1) 0%,
+    rgba(33, 120, 241, 1) 100%,
+    rgba(33, 120, 241, 1) 100%
+  );
 
   .subtitle {
     font-size: 20px;

+ 29 - 21
src/components/Breadcrumb/index.vue

@@ -1,8 +1,14 @@
+<!-- @format -->
+
 <template>
   <el-breadcrumb class="app-breadcrumb" separator="/">
     <transition-group name="breadcrumb">
-      <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
-        <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
+      <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
+        <span
+          v-if="item.redirect === 'noRedirect' || index == levelList.length - 1"
+          class="no-redirect"
+          >{{ item.meta.title }}</span
+        >
         <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
       </el-breadcrumb-item>
     </transition-group>
@@ -12,46 +18,48 @@
 <script setup>
 const route = useRoute();
 const router = useRouter();
-const levelList = ref([])
+const levelList = ref([]);
 
 function getBreadcrumb() {
   // only show routes with meta.title
-  let matched = route.matched.filter(item => item.meta && item.meta.title);
-  const first = matched[0]
+  let matched = route.matched.filter((item) => item.meta && item.meta.title);
+  const first = matched[0];
   // 判断是否为首页
   if (!isDashboard(first)) {
-    matched = [{ path: '/index', meta: { title: '首页' } }].concat(matched)
+    matched = [{ path: "/index", meta: { title: "首页" } }].concat(matched);
   }
 
-  levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
+  levelList.value = matched.filter(
+    (item) => item.meta && item.meta.title && item.meta.breadcrumb !== false
+  );
 }
 function isDashboard(route) {
-  const name = route && route.name
+  const name = route && route.name;
   if (!name) {
-    return false
+    return false;
   }
-  return name.trim() === 'Index'
+  return name.trim() === "Index";
 }
 function handleLink(item) {
-  const { redirect, path } = item
+  const { redirect, path } = item;
   if (redirect) {
-    router.push(redirect)
-    return
+    router.push(redirect);
+    return;
   }
-  router.push(path)
+  router.push(path);
 }
 
 watchEffect(() => {
   // if you go to the redirect page, do not update the breadcrumbs
-  if (route.path.startsWith('/redirect/')) {
-    return
+  if (route.path.startsWith("/redirect/")) {
+    return;
   }
-  getBreadcrumb()
-})
+  getBreadcrumb();
+});
 getBreadcrumb();
 </script>
 
-<style lang='scss' scoped>
+<style lang="scss" scoped>
 .app-breadcrumb.el-breadcrumb {
   display: inline-block;
   font-size: 14px;
@@ -59,8 +67,8 @@ getBreadcrumb();
   margin-left: 8px;
 
   .no-redirect {
-    color: #97a8be;
+    color: #fff;
     cursor: text;
   }
 }
-</style>
+</style>

+ 14 - 9
src/components/Hamburger/index.vue

@@ -1,14 +1,19 @@
+<!-- @format -->
+
 <template>
-  <div style="padding: 0 15px;" @click="toggleClick">
+  <div style="padding: 0 15px" @click="toggleClick">
     <svg
-      :class="{'is-active':isActive}"
+      :class="{ 'is-active': isActive }"
       class="hamburger"
       viewBox="0 0 1024 1024"
       xmlns="http://www.w3.org/2000/svg"
       width="64"
       height="64"
     >
-      <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
+      <path
+        fill="#fff"
+        d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"
+      />
     </svg>
   </div>
 </template>
@@ -17,14 +22,14 @@
 defineProps({
   isActive: {
     type: Boolean,
-    default: false
-  }
-})
+    default: false,
+  },
+});
 
-const emit = defineEmits()
+const emit = defineEmits();
 const toggleClick = () => {
-  emit('toggleClick');
-}
+  emit("toggleClick");
+};
 </script>
 
 <style scoped>

+ 8 - 5
src/layout/components/Navbar.vue

@@ -20,7 +20,7 @@
     />
 
     <div class="right-menu">
-      <template v-if="appStore.device !== 'mobile'">
+      <!-- <template v-if="appStore.device !== 'mobile'">
         <header-search id="header-search" class="right-menu-item" />
 
         <el-tooltip content="源码地址" effect="dark" placement="bottom">
@@ -36,7 +36,7 @@
         <el-tooltip content="布局大小" effect="dark" placement="bottom">
           <size-select id="size-select" class="right-menu-item hover-effect" />
         </el-tooltip>
-      </template>
+      </template> -->
       <div class="avatar-container">
         <el-dropdown
           @command="handleCommand"
@@ -52,12 +52,12 @@
               <router-link to="/user/profile">
                 <el-dropdown-item>个人中心</el-dropdown-item>
               </router-link>
-              <el-dropdown-item
+              <!-- <el-dropdown-item
                 command="setLayout"
                 v-if="settingsStore.showSettings"
               >
                 <span>布局设置</span>
-              </el-dropdown-item>
+              </el-dropdown-item> -->
               <el-dropdown-item divided command="logout">
                 <span>退出登录</span>
               </el-dropdown-item>
@@ -131,7 +131,7 @@ function setLayout() {
   position: relative;
   background: #fff;
   box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
-
+  background: #0e62fe;
   .hamburger-container {
     line-height: 46px;
     height: 100%;
@@ -143,6 +143,9 @@ function setLayout() {
     &:hover {
       background: rgba(0, 0, 0, 0.025);
     }
+    svg {
+      color: #fff !important;
+    }
   }
 
   .breadcrumb-container {

+ 51 - 13
src/layout/components/Sidebar/Logo.vue

@@ -1,29 +1,66 @@
+<!-- @format -->
+
 <template>
-  <div class="sidebar-logo-container" :class="{ 'collapse': collapse }" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
+  <div
+    class="sidebar-logo-container"
+    :class="{ collapse: collapse }"
+    :style="{
+      backgroundColor:
+        sideTheme === 'theme-dark'
+          ? variables.menuBackground
+          : variables.menuLightBackground,
+    }"
+  >
     <transition name="sidebarLogoFade">
-      <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
+      <router-link
+        v-if="collapse"
+        key="collapse"
+        class="sidebar-logo-link"
+        to="/"
+      >
         <img v-if="logo" :src="logo" class="sidebar-logo" />
-        <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }}</h1>
+        <h1
+          v-else
+          class="sidebar-title"
+          :style="{
+            color:
+              sideTheme === 'theme-dark'
+                ? variables.logoTitleColor
+                : variables.logoLightTitleColor,
+          }"
+        >
+          {{ title }}
+        </h1>
       </router-link>
       <router-link v-else key="expand" class="sidebar-logo-link" to="/">
         <img v-if="logo" :src="logo" class="sidebar-logo" />
-        <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }}</h1>
+        <h1
+          class="sidebar-title"
+          :style="{
+            color:
+              sideTheme === 'theme-dark'
+                ? variables.logoTitleColor
+                : variables.logoLightTitleColor,
+          }"
+        >
+          {{ title }}
+        </h1>
       </router-link>
     </transition>
   </div>
 </template>
 
 <script setup>
-import variables from '@/assets/styles/variables.module.scss'
-import logo from '@/assets/logo/logo.png'
-import useSettingsStore from '@/store/modules/settings'
+import variables from "@/assets/styles/variables.module.scss";
+import logo from "@/assets/logo/logo.png";
+import useSettingsStore from "@/store/modules/settings";
 
 defineProps({
   collapse: {
     type: Boolean,
-    required: true
-  }
-})
+    required: true,
+  },
+});
 
 const title = import.meta.env.VITE_APP_TITLE;
 const settingsStore = useSettingsStore();
@@ -45,7 +82,7 @@ const sideTheme = computed(() => settingsStore.sideTheme);
   width: 100%;
   height: 50px;
   line-height: 50px;
-  background: #2b2f3a;
+  background: #0e62fe !important;
   text-align: center;
   overflow: hidden;
 
@@ -55,6 +92,7 @@ const sideTheme = computed(() => settingsStore.sideTheme);
 
     & .sidebar-logo {
       width: 32px;
+      display: none;
       height: 32px;
       vertical-align: middle;
       margin-right: 12px;
@@ -63,7 +101,7 @@ const sideTheme = computed(() => settingsStore.sideTheme);
     & .sidebar-title {
       display: inline-block;
       margin: 0;
-      color: #fff;
+      color: #fff !important;
       font-weight: 600;
       line-height: 50px;
       font-size: 14px;
@@ -78,4 +116,4 @@ const sideTheme = computed(() => settingsStore.sideTheme);
     }
   }
 }
-</style>
+</style>

+ 5 - 3
src/settings.js

@@ -1,3 +1,5 @@
+/** @format */
+
 export default {
   /**
    * 网页标题
@@ -6,7 +8,7 @@ export default {
   /**
    * 侧边栏主题 深色主题theme-dark,浅色主题theme-light
    */
-  sideTheme: 'theme-dark',
+  sideTheme: "theme-light",
   /**
    * 是否系统布局配置
    */
@@ -43,5 +45,5 @@ export default {
    * The default is only used in the production env
    * If you want to also use it in dev, you can pass ['production', 'development']
    */
-  errorLog: 'production'
-}
+  errorLog: "production",
+};

+ 93 - 91
src/store/modules/permission.js

@@ -1,142 +1,144 @@
-import auth from '@/plugins/auth'
-import router, { constantRoutes, dynamicRoutes } from '@/router'
-import { getRouters } from '@/api/menu'
-import Layout from '@/layout/index'
-import ParentView from '@/components/ParentView'
-import InnerLink from '@/layout/components/InnerLink'
+/** @format */
 
+import auth from "@/plugins/auth";
+import router, { constantRoutes, dynamicRoutes } from "@/router";
+import { getRouters } from "@/api/menu";
+import Layout from "@/layout/index";
+import ParentView from "@/components/ParentView";
+import InnerLink from "@/layout/components/InnerLink";
+import { getJToken } from "@/utils/auth";
 // 匹配views里面所有的.vue文件
-const modules = import.meta.glob('./../../views/**/*.vue')
+const modules = import.meta.glob("./../../views/**/*.vue");
 
-const usePermissionStore = defineStore(
-  'permission',
-  {
-    state: () => ({
-      routes: [],
-      addRoutes: [],
-      defaultRoutes: [],
-      topbarRouters: [],
-      sidebarRouters: []
-    }),
-    actions: {
-      setRoutes(routes) {
-        this.addRoutes = routes
-        this.routes = constantRoutes.concat(routes)
-      },
-      setDefaultRoutes(routes) {
-        this.defaultRoutes = constantRoutes.concat(routes)
-      },
-      setTopbarRoutes(routes) {
-        this.topbarRouters = routes
-      },
-      setSidebarRouters(routes) {
-        this.sidebarRouters = routes
-      },
-      generateRoutes(roles) {
-        return new Promise(resolve => {
-          // 向后端请求路由数据
-          getRouters().then(res => {
-            const sdata = JSON.parse(JSON.stringify(res.data))
-            const rdata = JSON.parse(JSON.stringify(res.data))
-            const defaultData = JSON.parse(JSON.stringify(res.data))
-            const sidebarRoutes = filterAsyncRouter(sdata)
-            const rewriteRoutes = filterAsyncRouter(rdata, false, true)
-            const defaultRoutes = filterAsyncRouter(defaultData)
-            const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
-            asyncRoutes.forEach(route => { router.addRoute(route) })
-            this.setRoutes(rewriteRoutes)
-            this.setSidebarRouters(constantRoutes.concat(sidebarRoutes))
-            this.setDefaultRoutes(sidebarRoutes)
-            this.setTopbarRoutes(defaultRoutes)
-            resolve(rewriteRoutes)
-          })
-        })
-      }
-    }
-  })
+const usePermissionStore = defineStore("permission", {
+  state: () => ({
+    routes: [],
+    addRoutes: [],
+    defaultRoutes: [],
+    topbarRouters: [],
+    sidebarRouters: [],
+  }),
+  actions: {
+    setRoutes(routes) {
+      this.addRoutes = routes;
+      this.routes = constantRoutes.concat(routes);
+    },
+    setDefaultRoutes(routes) {
+      this.defaultRoutes = constantRoutes.concat(routes);
+    },
+    setTopbarRoutes(routes) {
+      this.topbarRouters = routes;
+    },
+    setSidebarRouters(routes) {
+      this.sidebarRouters = routes;
+    },
+    generateRoutes(roles) {
+      return new Promise((resolve) => {
+        // 向后端请求路由数据
+        getRouters({ "J-Token": getJToken() }).then((res) => {
+          const sdata = JSON.parse(JSON.stringify(res.data));
+          const rdata = JSON.parse(JSON.stringify(res.data));
+          const defaultData = JSON.parse(JSON.stringify(res.data));
+          const sidebarRoutes = filterAsyncRouter(sdata);
+          const rewriteRoutes = filterAsyncRouter(rdata, false, true);
+          const defaultRoutes = filterAsyncRouter(defaultData);
+          const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
+          asyncRoutes.forEach((route) => {
+            router.addRoute(route);
+          });
+          this.setRoutes(rewriteRoutes);
+          this.setSidebarRouters(constantRoutes.concat(sidebarRoutes));
+          this.setDefaultRoutes(sidebarRoutes);
+          this.setTopbarRoutes(defaultRoutes);
+          resolve(rewriteRoutes);
+        });
+      });
+    },
+  },
+});
 
 // 遍历后台传来的路由字符串,转换为组件对象
 function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
-  return asyncRouterMap.filter(route => {
+  return asyncRouterMap.filter((route) => {
     if (type && route.children) {
-      route.children = filterChildren(route.children)
+      route.children = filterChildren(route.children);
     }
     if (route.component) {
       // Layout ParentView 组件特殊处理
-      if (route.component === 'Layout') {
-        route.component = Layout
-      } else if (route.component === 'ParentView') {
-        route.component = ParentView
-      } else if (route.component === 'InnerLink') {
-        route.component = InnerLink
+      if (route.component === "Layout") {
+        route.component = Layout;
+      } else if (route.component === "ParentView") {
+        route.component = ParentView;
+      } else if (route.component === "InnerLink") {
+        route.component = InnerLink;
       } else {
-        route.component = loadView(route.component)
+        route.component = loadView(route.component);
       }
     }
     if (route.children != null && route.children && route.children.length) {
-      route.children = filterAsyncRouter(route.children, route, type)
+      route.children = filterAsyncRouter(route.children, route, type);
     } else {
-      delete route['children']
-      delete route['redirect']
+      delete route["children"];
+      delete route["redirect"];
     }
-    return true
-  })
+    return true;
+  });
 }
 
 function filterChildren(childrenMap, lastRouter = false) {
-  var children = []
+  var children = [];
   childrenMap.forEach((el, index) => {
     if (el.children && el.children.length) {
-      if (el.component === 'ParentView' && !lastRouter) {
-        el.children.forEach(c => {
-          c.path = el.path + '/' + c.path
+      if (el.component === "ParentView" && !lastRouter) {
+        el.children.forEach((c) => {
+          c.path = el.path + "/" + c.path;
           if (c.children && c.children.length) {
-            children = children.concat(filterChildren(c.children, c))
-            return
+            children = children.concat(filterChildren(c.children, c));
+            return;
           }
-          children.push(c)
-        })
-        return
+          children.push(c);
+        });
+        return;
       }
     }
     if (lastRouter) {
-      el.path = lastRouter.path + '/' + el.path
+      el.path = lastRouter.path + "/" + el.path;
       if (el.children && el.children.length) {
-        children = children.concat(filterChildren(el.children, el))
-        return
+        children = children.concat(filterChildren(el.children, el));
+        return;
       }
     }
-    children = children.concat(el)
-  })
-  return children
+    children = children.concat(el);
+  });
+  return children;
 }
 
 // 动态路由遍历,验证是否具备权限
 export function filterDynamicRoutes(routes) {
-  const res = []
-  routes.forEach(route => {
+  const res = [];
+  routes.forEach((route) => {
     if (route.permissions) {
       if (auth.hasPermiOr(route.permissions)) {
-        res.push(route)
+        res.push(route);
       }
     } else if (route.roles) {
       if (auth.hasRoleOr(route.roles)) {
-        res.push(route)
+        res.push(route);
       }
     }
-  })
-  return res
+  });
+  return res;
 }
 
 export const loadView = (view) => {
   let res;
   for (const path in modules) {
-    const dir = path.split('views/')[1].split('.vue')[0];
+    const dir = path.split("views/")[1].split(".vue")[0];
     if (dir === view) {
       res = () => modules[path]();
     }
   }
   return res;
-}
+};
 
-export default usePermissionStore
+export default usePermissionStore;

+ 54 - 33
src/store/modules/settings.js

@@ -1,38 +1,59 @@
-import defaultSettings from '@/settings'
-import { useDynamicTitle } from '@/utils/dynamicTitle'
+/** @format */
 
-const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
+import defaultSettings from "@/settings";
+import { useDynamicTitle } from "@/utils/dynamicTitle";
 
-const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
+const {
+  sideTheme,
+  showSettings,
+  topNav,
+  tagsView,
+  fixedHeader,
+  sidebarLogo,
+  dynamicTitle,
+} = defaultSettings;
 
-const useSettingsStore = defineStore(
-  'settings',
-  {
-    state: () => ({
-      title: '',
-      theme: storageSetting.theme || '#409EFF',
-      sideTheme: storageSetting.sideTheme || sideTheme,
-      showSettings: showSettings,
-      topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
-      tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
-      fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
-      sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
-      dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
-    }),
-    actions: {
-      // 修改布局设置
-      changeSetting(data) {
-        const { key, value } = data
-        if (this.hasOwnProperty(key)) {
-          this[key] = value
-        }
-      },
-      // 设置网页标题
-      setTitle(title) {
-        this.title = title
-        useDynamicTitle();
+const storageSetting = JSON.parse(localStorage.getItem("layout-setting")) || "";
+
+const useSettingsStore = defineStore("settings", {
+  state: () => ({
+    title: "",
+    theme: "#0E62FE",
+    sideTheme: storageSetting.sideTheme || sideTheme,
+    showSettings: showSettings,
+    topNav:
+      storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
+    tagsView:
+      storageSetting.tagsView === undefined
+        ? tagsView
+        : storageSetting.tagsView,
+    fixedHeader:
+      storageSetting.fixedHeader === undefined
+        ? fixedHeader
+        : storageSetting.fixedHeader,
+    sidebarLogo:
+      storageSetting.sidebarLogo === undefined
+        ? sidebarLogo
+        : storageSetting.sidebarLogo,
+    dynamicTitle:
+      storageSetting.dynamicTitle === undefined
+        ? dynamicTitle
+        : storageSetting.dynamicTitle,
+  }),
+  actions: {
+    // 修改布局设置
+    changeSetting(data) {
+      const { key, value } = data;
+      if (this.hasOwnProperty(key)) {
+        this[key] = value;
       }
-    }
-  })
+    },
+    // 设置网页标题
+    setTitle(title) {
+      this.title = title;
+      useDynamicTitle();
+    },
+  },
+});
 
-export default useSettingsStore
+export default useSettingsStore;

+ 86 - 64
src/store/modules/user.js

@@ -1,72 +1,94 @@
-import { login, logout, getInfo } from '@/api/login'
-import { getToken, setToken, removeToken } from '@/utils/auth'
-import defAva from '@/assets/images/profile.jpg'
+/** @format */
 
-const useUserStore = defineStore(
-  'user',
-  {
-    state: () => ({
-      token: getToken(),
-      id: '',
-      name: '',
-      avatar: '',
-      roles: [],
-      permissions: []
-    }),
-    actions: {
-      // 登录
-      login(userInfo) {
-        const username = userInfo.username.trim()
-        const password = userInfo.password
-        const code = userInfo.code
-        const uuid = userInfo.uuid
-        return new Promise((resolve, reject) => {
-          login(username, password, code, uuid).then(res => {
-            setToken(res.token)
-            this.token = res.token
-            resolve()
-          }).catch(error => {
-            reject(error)
+import { login, logout, getInfo } from "@/api/login";
+import {
+  getToken,
+  setToken,
+  removeToken,
+  getJToken,
+  setJToken,
+  removeJToken,
+} from "@/utils/auth";
+import defAva from "@/assets/images/profile.jpg";
+
+const useUserStore = defineStore("user", {
+  state: () => ({
+    token: getToken(),
+    id: "",
+    name: "",
+    avatar: "",
+    roles: [],
+    permissions: [],
+    "J-Token": getJToken(),
+  }),
+  actions: {
+    // 登录
+    login(userInfo) {
+      const username = userInfo.username.trim();
+      const password = userInfo.password;
+      const code = userInfo.code;
+      const uuid = userInfo.uuid;
+      return new Promise((resolve, reject) => {
+        login(username, password, code, uuid)
+          .then((res) => {
+            setToken(res.token);
+            setJToken(res.jtoken);
+
+            this.token = res.token;
+            resolve();
           })
-        })
-      },
-      // 获取用户信息
-      getInfo() {
-        return new Promise((resolve, reject) => {
-          getInfo().then(res => {
-            const user = res.user
-            const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
+          .catch((error) => {
+            reject(error);
+          });
+      });
+    },
+    // 获取用户信息
+    getInfo() {
+      return new Promise((resolve, reject) => {
+        getInfo()
+          .then((res) => {
+            const user = res.user;
+            const avatar =
+              user.avatar == "" || user.avatar == null
+                ? defAva
+                : import.meta.env.VITE_APP_BASE_API + user.avatar;
 
-            if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
-              this.roles = res.roles
-              this.permissions = res.permissions
+            if (res.roles && res.roles.length > 0) {
+              // 验证返回的roles是否是一个非空数组
+              this.roles = res.roles;
+              this.permissions = res.permissions;
             } else {
-              this.roles = ['ROLE_DEFAULT']
+              this.roles = ["ROLE_DEFAULT"];
             }
-            this.id = user.userId
-            this.name = user.userName
-            this.avatar = avatar
-            resolve(res)
-          }).catch(error => {
-            reject(error)
+            this.id = user.userId;
+            this.name = user.userName;
+            this.avatar = avatar;
+            resolve(res);
           })
-        })
-      },
-      // 退出系统
-      logOut() {
-        return new Promise((resolve, reject) => {
-          logout(this.token).then(() => {
-            this.token = ''
-            this.roles = []
-            this.permissions = []
-            removeToken()
-            resolve()
-          }).catch(error => {
-            reject(error)
+          .catch((error) => {
+            reject(error);
+          });
+      });
+    },
+    // 退出系统
+    logOut() {
+      return new Promise((resolve, reject) => {
+        logout(this.token)
+          .then(() => {
+            this.token = "";
+            this.roles = [];
+            this.permissions = [];
+            removeToken();
+            removeJToken();
+
+            resolve();
           })
-        })
-      }
-    }
-  })
+          .catch((error) => {
+            reject(error);
+          });
+      });
+    },
+  },
+});
 
-export default useUserStore
+export default useUserStore;

+ 18 - 5
src/utils/auth.js

@@ -1,15 +1,28 @@
-import Cookies from 'js-cookie'
+/** @format */
 
-const TokenKey = 'Admin-Token'
+import Cookies from "js-cookie";
 
+const TokenKey = "Admin-Token";
+const JToken = "J-Token";
 export function getToken() {
-  return Cookies.get(TokenKey)
+  return Cookies.get(TokenKey);
 }
 
 export function setToken(token) {
-  return Cookies.set(TokenKey, token)
+  return Cookies.set(TokenKey, token);
 }
 
 export function removeToken() {
-  return Cookies.remove(TokenKey)
+  return Cookies.remove(TokenKey);
+}
+
+export function removeJToken() {
+  return Cookies.remove(JToken);
+}
+
+export function getJToken() {
+  return Cookies.get(JToken);
+}
+export function setJToken(token) {
+  return Cookies.set(JToken, token);
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 3 - 1078
src/views/index.vue