瀏覽代碼

引入svg和一些页面

tongshangming 3 年之前
父節點
當前提交
e109868b9e

+ 1 - 0
package.json

@@ -44,6 +44,7 @@
     "unplugin-vue-components": "^0.22.7",
     "unplugin-vue-define-options": "^0.11.2",
     "vite": "^3.1.3",
+    "vite-plugin-svg-icons": "^2.0.1",
     "vue-tsc": "^0.39.5"
   }
 }

文件差異過大導致無法顯示
+ 649 - 3
pnpm-lock.yaml


文件差異過大導致無法顯示
+ 0 - 0
src/assets/svg/not-found.svg


+ 1 - 0
src/components.d.ts

@@ -62,6 +62,7 @@ declare module '@vue/runtime-core' {
     ProTable: typeof import('./components/ProTable.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
+    SvgIcon: typeof import('./components/SvgIcon.vue')['default']
   }
   export interface ComponentCustomProperties {
     vLoading: typeof import('element-plus/es')['ElLoadingDirective']

+ 18 - 5
src/components/Exception.vue

@@ -1,9 +1,22 @@
-<script setup></script>
+<script setup lang="ts">
+import config from '@/config/defaultSetting'
+
+interface Props {
+  type?: '404' | '403' | '500'
+}
+
+defineProps<Props>()
+</script>
 
 <template>
-  <div class="w-full h-full flex justify-center items-center">
-    <router-link :to="{ name: 'home' }">
-      <el-button type="primary">回到首页</el-button>
-    </router-link>
+  <div class="w-full h-full flex justify-center items-center text-center">
+    <div>
+      <div style="color: var(--el-color-primary)">
+        <svg-icon size="400px" icon="not-found" v-if="type === '404'"></svg-icon>
+      </div>
+      <router-link :to="{ name: config.homeRouteName }">
+        <el-button type="primary">回到首页</el-button>
+      </router-link>
+    </div>
   </div>
 </template>

+ 1 - 1
src/components/GlobalHeader.vue

@@ -3,7 +3,7 @@ import { useMenuStore } from '@/stores/menu'
 import { useUserStore } from '@/stores/user'
 import config from '@/config/defaultSetting'
 import avatar from '@/assets/images/avatar.png'
-import type { RouteRecordRaw } from 'vue-router'
+import { ElMessageBox } from 'element-plus'
 
 const iconSize = ref('22')
 

+ 21 - 0
src/components/SvgIcon.vue

@@ -0,0 +1,21 @@
+<script lang="ts" setup>
+interface Props {
+  prefix?: string
+  size?: string
+  icon: string
+}
+const props = withDefaults(defineProps<Props>(), {
+  prefix: 'icon',
+  size: '1em'
+})
+
+const symbolId = computed(() => `#${props.prefix}-${props.icon}`)
+</script>
+
+<template>
+  <svg aria-hidden="true" :width="size" :height="size" class="inline-block">
+    <use :xlink:href="symbolId" fill="currentColor" />
+  </svg>
+</template>
+
+<style lang="scss" scoped></style>

+ 1 - 0
src/main.ts

@@ -15,6 +15,7 @@ import App from './App.vue'
 import router from './router'
 
 import './assets/main.css'
+import 'virtual:svg-icons-register'
 
 const app = createApp(App)
 

+ 33 - 2
src/router/asyncRouter.ts

@@ -7,7 +7,7 @@ const asyncRouter: RouteRecordRaw[] = [
     component: () => import('@/views/exception/403.vue'),
     meta: {
       title: '首页',
-      icon: 'icon-home'
+      icon: 'House'
     }
   },
   {
@@ -16,7 +16,7 @@ const asyncRouter: RouteRecordRaw[] = [
     component: () => import('@/views/exception/403.vue'),
     meta: {
       title: '设置',
-      icon: 'icon-setting'
+      icon: 'Setting'
     }
   },
   {
@@ -46,6 +46,37 @@ const asyncRouter: RouteRecordRaw[] = [
         }
       }
     ]
+  },
+  {
+    path: '/result',
+    name: 'result',
+    meta: {
+      title: '结果页',
+      icon: 'CircleCheck'
+    },
+    children: [
+      {
+        path: 'success',
+        name: 'resultSuccess',
+        component: () => import('@/views/result/Success.vue'),
+        meta: {
+          title: '成功页'
+        }
+      },
+      {
+        path: 'error',
+        name: 'resultError',
+        component: () => import('@/views/result/Error.vue'),
+        meta: {
+          title: '失败页'
+        }
+      }
+    ]
+  },
+  {
+    path: '/:pathMatch(.*)*',
+    redirect: '/exception/404',
+    hidden: true
   }
 ]
 

+ 0 - 8
src/router/constantRouter.ts

@@ -18,14 +18,6 @@ const constantRouter: RouteRecordRaw[] = [
       title: '登录'
     }
   },
-  {
-    path: '/:pathMatch(.*)*',
-    name: '404',
-    component: () => import('@/views/exception/404.vue'),
-    meta: {
-      title: '404'
-    }
-  },
   {
     path: '/exception',
     name: 'exception',

+ 6 - 6
src/router/router.d.ts

@@ -2,16 +2,16 @@ import 'vue-router'
 
 declare module 'vue-router' {
   interface RouteMeta {
-    permission?: any[],
-    role?: any[],
-    title: string,
+    permission?: any[]
+    role?: any[]
+    title: string
     icon?: string
   }
 }
 
 declare module 'vue-router' {
-  interface RouteRecordRaw {
-    hidden?: boolean,
+  interface _RouteRecordBase {
+    hidden?: boolean
     menuName?: string
   }
-}
+}

+ 23 - 4
src/stores/router.ts

@@ -1,5 +1,5 @@
 import type { RouteRecordRaw } from 'vue-router'
-import { constantRouter, asyncRouter } from '@/router'
+import { asyncRouter } from '@/router'
 
 function hasPermission(route: RouteRecordRaw, permission: any[]) {
   if (route.meta && route.meta.permission) {
@@ -29,6 +29,7 @@ function hasRole(route: RouteRecordRaw, role: any[]) {
   return true
 }
 
+// 根据角色过滤路由
 function filterAsyncRouter(routerMap: RouteRecordRaw[], role: any[]) {
   const accessedRouters = routerMap.filter(route => {
     if (hasRole(route, role)) {
@@ -42,16 +43,34 @@ function filterAsyncRouter(routerMap: RouteRecordRaw[], role: any[]) {
   return accessedRouters
 }
 
+// 过滤掉hidden为true的路由
+function filterMenuRouter(routerMap: RouteRecordRaw[]) {
+  const accessedRouters = routerMap.filter(route => {
+    console.log(route)
+    if (!route.hidden) {
+      if (route.children && route.children.length) {
+        route.children = filterMenuRouter(route.children)
+      }
+      return true
+    }
+    return false
+  })
+  return accessedRouters
+}
+
 export const useRouterStore = defineStore({
   id: 'router',
   state: () => ({
-    menuRouter: <any>[]
+    menuRouter: <any>[],
+    asyncRouter: <any>[]
   }),
   actions: {
     generatorRouter(role?: any[]): Promise<RouteRecordRaw[]> {
       return new Promise(resolve => {
-        this.menuRouter = role ? filterAsyncRouter(asyncRouter, role) : asyncRouter
-        resolve(this.menuRouter)
+        this.asyncRouter = role ? filterAsyncRouter(asyncRouter, role) : asyncRouter
+        this.menuRouter = filterMenuRouter(this.asyncRouter)
+        console.log(this.menuRouter)
+        resolve(this.asyncRouter)
       })
     }
   }

+ 0 - 1
src/stores/user.ts

@@ -25,7 +25,6 @@ export const useUserStore = defineStore({
       localStorage.removeItem('token')
       sessionStorage.removeItem('globalTabs')
       this.$reset()
-      console.log(router)
       router.push({ path: '/login', query: { redirect: router.currentRoute.value.fullPath } })
     }
   }

+ 1 - 0
src/utils/request.ts

@@ -22,6 +22,7 @@ const errorHandler = (error: any) => {
       center: true,
       confirmButtonText: '重新登录'
     }).then(() => {
+      console.log(router.currentRoute)
       userStore.logout()
     })
   } else if (status === 403) {

+ 20 - 0
src/views/result/Error.vue

@@ -0,0 +1,20 @@
+<script lang="ts" setup>
+import config from '@/config/defaultSetting'
+</script>
+
+<template>
+  <div class="h-full bg-white">
+    <el-result icon="error" sub-title="Please follow the instructions">
+      <template #title>
+        <h2>操作失败</h2>
+      </template>
+      <template #extra>
+        <router-link :to="{ name: config.homeRouteName }">
+          <el-button type="primary">回到首页</el-button>
+        </router-link>
+      </template>
+    </el-result>
+  </div>
+</template>
+
+<style lang="scss" scoped></style>

+ 20 - 0
src/views/result/Success.vue

@@ -0,0 +1,20 @@
+<script lang="ts" setup>
+import config from '@/config/defaultSetting'
+</script>
+
+<template>
+  <div class="h-full bg-white">
+    <el-result icon="success" sub-title="Please follow the instructions">
+      <template #title>
+        <h2>操作成功</h2>
+      </template>
+      <template #extra>
+        <router-link :to="{ name: config.homeRouteName }">
+          <el-button type="primary">回到首页</el-button>
+        </router-link>
+      </template>
+    </el-result>
+  </div>
+</template>
+
+<style lang="scss" scoped></style>

+ 6 - 0
vite.config.ts

@@ -1,4 +1,5 @@
 import { fileURLToPath, URL } from 'node:url'
+import path from 'path'
 
 import { defineConfig } from 'vite'
 import vue from '@vitejs/plugin-vue'
@@ -9,6 +10,7 @@ import DefineOptions from 'unplugin-vue-define-options/vite'
 import Icons from 'unplugin-icons/vite'
 import IconsResolver from 'unplugin-icons/resolver'
 import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
+import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
 import Unocss from 'unocss/vite'
 
 // https://vitejs.dev/config/
@@ -26,6 +28,10 @@ export default defineConfig({
       dirs: ['src/components'],
       extensions: ['vue'],
       dts: 'src/components.d.ts'
+    }),
+    createSvgIconsPlugin({
+      iconDirs: [path.resolve(process.cwd(), 'src/assets/svg')],
+      symbolId: 'icon-[dir]-[name]'
     })
   ],
   resolve: {

部分文件因文件數量過多而無法顯示