diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..89450d6
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018-2024 little3201
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/src/assets/bg.json b/public/bg.json
similarity index 100%
rename from src/assets/bg.json
rename to public/bg.json
diff --git a/quasar.config.js b/quasar.config.js
index e55cf08..b66aba7 100644
--- a/quasar.config.js
+++ b/quasar.config.js
@@ -127,7 +127,7 @@ module.exports = configure(function (ctx) {
       // directives: [],
 
       // Quasar plugins
-      plugins: []
+      plugins: ['Notify', 'SessionStorage']
     },
 
     // animations: 'all', // --- includes all animations
diff --git a/src/boot/axios.ts b/src/boot/axios.ts
index 468ea0f..27b52e1 100644
--- a/src/boot/axios.ts
+++ b/src/boot/axios.ts
@@ -1,5 +1,5 @@
 import { boot } from 'quasar/wrappers'
-import axios, { AxiosInstance } from 'axios'
+import axios, { AxiosInstance, AxiosError } from 'axios'
 
 declare module '@vue/runtime-core' {
   interface ComponentCustomProperties {
@@ -13,11 +13,41 @@ declare module '@vue/runtime-core' {
 // good idea to move this instance creation inside of the
 // "export default () => {}" function below (which runs individually
 // for each client)
-const api = axios.create({ baseURL: '/api' })
+const api = axios.create({ baseURL: process.env.API })
 
 export default boot(({ app }) => {
   // for use inside Vue files (Options API) through this.$api
 
+  // 创建 AbortController 实例
+  const abortController = new AbortController()
+
+  // 获取 AbortController 的信号
+  const signal = abortController.signal
+
+  // 请求拦截器
+  api.interceptors.request.use(
+    config => {
+      // 将 signal 添加到请求配置中
+      config.signal = signal
+      return config
+    },
+    error => {
+      return Promise.reject(error)
+    }
+  )
+
+  // 响应拦截器
+  api.interceptors.response.use(
+    response => {
+      return response
+    },
+    (error: AxiosError) => {
+      // 如果请求失败,取消后续请求
+      abortController.abort()
+      return Promise.reject(error)
+    }
+  )
+
   app.config.globalProperties.$api = api
   // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form)
   //       so you can easily perform requests against your app's API
diff --git a/src/components/EssentialLink.vue b/src/components/EssentialLink.vue
index 46ec9de..843ef53 100644
--- a/src/components/EssentialLink.vue
+++ b/src/components/EssentialLink.vue
@@ -5,7 +5,7 @@
     </q-item-section>
 
     <q-item-section>
-      <q-item-label>{{ title }}</q-item-label>
+      <q-item-label>{{ $t(title) }}</q-item-label>
     </q-item-section>
   </q-item>
 </template>
diff --git a/src/i18n/en-US/index.ts b/src/i18n/en-US/index.ts
index 19105c5..2df7f14 100644
--- a/src/i18n/en-US/index.ts
+++ b/src/i18n/en-US/index.ts
@@ -81,6 +81,7 @@ export default {
   grant: 'Grants',
   members: 'memberss',
 
+  home: 'Home',
   dashboard: 'Dashboard',
   system: 'System',
   groups: 'Groups',
diff --git a/src/i18n/index.ts b/src/i18n/index.ts
index 26e966b..63b26bd 100644
--- a/src/i18n/index.ts
+++ b/src/i18n/index.ts
@@ -1,9 +1,9 @@
+import enUS from './en-US'
 import zhCN from './zh-CN'
 import zhTW from './zh-TW'
-import enUS from './en-US'
 
 export default {
+  'en-US': enUS,
   'zh-CN': zhCN,
-  'zh-TW': zhTW,
-  'en-US': enUS
+  'zh-TW': zhTW
 }
diff --git a/src/i18n/zh-CN/index.ts b/src/i18n/zh-CN/index.ts
index a2efd13..7bdadae 100644
--- a/src/i18n/zh-CN/index.ts
+++ b/src/i18n/zh-CN/index.ts
@@ -81,6 +81,7 @@ export default {
   grant: '授权',
   members: '成员',
 
+  home: '首页',
   dashboard: '控制台',
   system: '系统管理',
   groups: '分组',
diff --git a/src/i18n/zh-TW/index.ts b/src/i18n/zh-TW/index.ts
index e281c9a..938bfc8 100644
--- a/src/i18n/zh-TW/index.ts
+++ b/src/i18n/zh-TW/index.ts
@@ -81,6 +81,7 @@ export default {
   grant: '授權',
   members: '成員',
 
+  home: '首頁',
   dashboard: '控制台',
   system: '系統管理',
   groups: '分組',
diff --git a/src/layouts/BlankLayout.vue b/src/layouts/BlankLayout.vue
new file mode 100644
index 0000000..5e1bb62
--- /dev/null
+++ b/src/layouts/BlankLayout.vue
@@ -0,0 +1,3 @@
+<template>
+    <router-view />
+</template>
diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index ccd95fd..f09aeba 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -1,29 +1,52 @@
 <template>
   <q-layout view="hHh LpR lFf">
-
     <q-header elevated>
       <q-toolbar>
-        <q-btn id="btn-drawer" title="btn-drawer" dense flat round icon="sym_r_menu" @click="toggleLeftDrawer"
-          aria-disabled="false" />
 
         <q-toolbar-title :shrink="true">
-          <q-img alt="logo" src="/logo-only.svg" style="width: 46px; height: 46px;" />
-          {{ $t('Application') }}
+          <q-img alt="logo" src="/logo-only.svg" style="width: 38px; height: 38px;" />
         </q-toolbar-title>
+        <q-toolbar-title :shrink="true">
+          <span>Management System</span>
+        </q-toolbar-title>
+        <q-btn id="btn-drawer" title="btn-drawer" dense flat round icon="sym_r_menu" @click="toggleLeftDrawer"
+          aria-disabled="false" />
 
-        <q-separator color="white" vertical inset />
-
-        <q-breadcrumbs class="text-grey q-ma-sm" active-color="white" style="font-size: 16px">
-          <q-breadcrumbs-el label="Home" icon="sym_r_home" />
-          <q-breadcrumbs-el label="Components" icon="sym_r_widgets" />
-          <q-breadcrumbs-el label="Breadcrumbs" />
+        <q-breadcrumbs class="q-ma-sm" active-color="white" style="font-size: 16px">
+          <q-breadcrumbs-el v-for="(route, index) in $route.matched" :key="index"
+            :label="$t(route.name ? route.name.toString() : '')"
+            :icon="route.meta.icon ? route.meta.icon.toString() : undefined" />
         </q-breadcrumbs>
 
         <q-space />
+
         <q-toolbar-title :shrink="true">
+          <q-btn icon="sym_r_language" round flat>
+            <q-menu>
+              <q-list dense separator>
+                <q-item clickable v-close-popup :active="locale === 'en-US'" @click="locale = 'en-US'">
+                  <q-item-section>English(US)</q-item-section>
+                </q-item>
+                <q-item clickable v-close-popup :active="locale === 'zh-CN'" @click="locale = 'zh-CN'">
+                  <q-item-section>中文(简体)</q-item-section>
+                </q-item>
+                <q-item clickable v-close-popup :active="locale === 'zh-TW'" @click="locale = 'zh-TW'">
+                  <q-item-section>中文(繁體)</q-item-section>
+                </q-item>
+              </q-list>
+            </q-menu>
+          </q-btn>
+
+          <q-toggle v-model="darkTheme" icon="sym_r_dark_mode" unchecked-icon="sym_r_light_mode"
+            :color="darkTheme ? 'black' : ''" />
+
+          <q-btn flat dense round icon="sym_r_notifications" class="q-mr-md">
+            <q-badge floating color="red" rounded style="top: 0px; right: 0px;" />
+          </q-btn>
           <q-avatar size="md">
             <img alt="avatar" src="https://cdn.quasar.dev/img/avatar.png">
           </q-avatar>
+          <span class="q-ml-sm" style="font-size: 16px;">{{ userStore.getUsername }}</span>
         </q-toolbar-title>
       </q-toolbar>
 
@@ -50,11 +73,18 @@
 
 <script setup lang="ts">
 import { ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useUserStore } from 'stores/user-store'
 import SideBarLeft from './SideBarLeft.vue'
 
+const userStore = useUserStore()
+
+const { locale } = useI18n({ useScope: 'global' })
+const darkTheme = ref(false)
 const leftDrawerOpen = ref(false)
 
 function toggleLeftDrawer() {
   leftDrawerOpen.value = !leftDrawerOpen.value
 }
 </script>
+src/stores/user-store
diff --git a/src/layouts/SideBarLeft.vue b/src/layouts/SideBarLeft.vue
index 4574eea..ddb6194 100644
--- a/src/layouts/SideBarLeft.vue
+++ b/src/layouts/SideBarLeft.vue
@@ -2,17 +2,17 @@
   <q-list>
     <q-list>
       <EssentialLink v-bind="{
-        title: 'Dashboard',
+        title: 'dashboard',
         icon: 'sym_r_dashboard',
         link: '/dashboard'
       }" />
 
       <EssentialLink v-bind="{
-        title: 'Home',
-        icon: 'sym_r_dashboard',
+        title: 'home',
+        icon: 'sym_r_home',
         link: '/'
       }" />
-      <q-expansion-item expand-separator icon="sym_r_settings" label="System" default-opened>
+      <q-expansion-item expand-separator icon="sym_r_settings" :label="$t('system')" default-opened>
         <q-card>
           <q-card-section>
             <EssentialLink v-for="link in essentialLinks" :key="link.title" v-bind="link" />
@@ -29,29 +29,29 @@ import EssentialLink, { EssentialLinkProps } from 'components/EssentialLink.vue'
 
 const essentialLinks: EssentialLinkProps[] = [
   {
-    title: 'User',
+    title: 'users',
     icon: 'sym_r_manage_accounts',
-    link: '/system/user'
+    link: '/system/users'
   },
   {
-    title: 'Group',
+    title: 'groups',
     icon: 'sym_r_group',
-    link: '/system/group'
+    link: '/system/groups'
   },
   {
-    title: 'Role',
+    title: 'roles',
     icon: 'sym_r_admin_panel_settings',
-    link: '/system/role'
+    link: '/system/roles'
   },
   {
-    title: 'Dictionary',
+    title: 'dictionaries',
     icon: 'sym_r_library_books',
-    link: '/system/dictionary'
+    link: '/system/dictionaries'
   },
   {
-    title: 'Region',
+    title: 'regions',
     icon: 'sym_r_public',
-    link: '/system/region'
+    link: '/system/regions'
   }
 ]
 </script>
diff --git a/src/pages/DashboardIndex.vue b/src/pages/DashboardPage.vue
similarity index 100%
rename from src/pages/DashboardIndex.vue
rename to src/pages/DashboardPage.vue
diff --git a/src/pages/LoginPage.vue b/src/pages/LoginPage.vue
index 39ea517..77d4916 100644
--- a/src/pages/LoginPage.vue
+++ b/src/pages/LoginPage.vue
@@ -10,17 +10,15 @@
         <q-toolbar-title :shrink="true">
           <q-btn icon="sym_r_language" round flat>
             <q-menu>
-              <q-list dense>
-                <q-item clickable v-close-popup>
-                  <q-item-section>简体中文</q-item-section>
+              <q-list dense separator>
+                <q-item clickable v-close-popup :active="locale === 'en-US'" @click="locale = 'en-US'">
+                  <q-item-section>English(US)</q-item-section>
                 </q-item>
-                <q-separator />
-                <q-item clickable v-close-popup>
-                  <q-item-section>繁體中文</q-item-section>
+                <q-item clickable v-close-popup :active="locale === 'zh-CN'" @click="locale = 'zh-CN'">
+                  <q-item-section>中文(简体)</q-item-section>
                 </q-item>
-                <q-separator />
-                <q-item clickable v-close-popup>
-                  <q-item-section>English(US)</q-item-section>
+                <q-item clickable v-close-popup :active="locale === 'zh-TW'" @click="locale = 'zh-TW'">
+                  <q-item-section>中文(繁體)</q-item-section>
                 </q-item>
               </q-list>
             </q-menu>
@@ -105,10 +103,10 @@
                           {{ $t('signinTo') }}
                         </div>
                         <q-form @submit="onSubmit" class="q-mt-md">
-                          <q-input :disable="loading" dense no-error-icon v-model.trim="form.username" color="black"
+                          <q-input :disable="loading" dense no-error-icon v-model.trim="form.username"
                             :placeholder="$t('username')" :rules="[(val) => (val && val.length > 0) || $t('username')]" />
                           <q-input :disable="loading" dense no-error-icon :type="isPwd ? 'password' : 'text'"
-                            v-model.trim="form.password" :placeholder="$t('password')" color="black"
+                            v-model.trim="form.password" :placeholder="$t('password')"
                             :rules="[(val) => (val && val.length > 0) || $t('password')]">
                             <template v-slot:append>
                               <q-icon size="xs" :name="isPwd ? 'sym_r_visibility_off' : 'sym_r_visibility'"
@@ -138,46 +136,71 @@
   </q-layout>
 </template>
 
-<script setup>
+<script setup lang="ts">
 import { onBeforeMount, ref, onMounted } from 'vue'
-// import { useQuasar } from 'quasar'
+import { useI18n } from 'vue-i18n'
+import { useRouter } from 'vue-router'
 import lottie from 'lottie-web'
+import { api } from 'boot/axios'
+import { useUserStore } from 'stores/user-store'
 
-// const $q = useQuasar()
+const router = useRouter()
+const userStore = useUserStore()
 
 onBeforeMount(() => {
 })
+
+const { locale } = useI18n({ useScope: 'global' })
 const isPwd = ref(true)
 const rememberMe = ref(true)
+const darkTheme = ref(false)
+const loading = ref(false)
+const lottieRef = ref<HTMLDivElement | null>(null)
+
 const form = ref({
   username: '',
-  password: '',
-  captcha: '',
-  captcha_id: ''
+  password: ''
 })
-const loading = ref(false)
-const changeRememberMe = (value) => {
+
+onMounted(() => {
+  show()
+})
+
+function changeRememberMe(value: boolean) {
   return value
 }
 
-const openLink = (url) => {
+function openLink(url: string) {
   window.open(url)
 }
-const darkTheme = ref(false)
 
-const onSubmit = async () => { }
+function onSubmit() {
+  loading.value = true
 
-const lottieRef = ref(null)
-onMounted(() => {
-  show()
-})
-const show = () => {
-  lottie.loadAnimation({
-    container: lottieRef.value,
-    renderer: 'svg',
-    loop: true,
-    autoplay: true,
-    path: 'src/assets/bg.json'
+  api.post('/login', new URLSearchParams(form.value)).then(res => {
+    console.log(res.data)
+    userStore.updateUser(form.value.username)
+    // 获取之前路由
+    const redirectRoute = router.currentRoute.value.query.redirect as string | undefined
+    router.replace(redirectRoute || '/')
+  }).catch(error => {
+    console.error('Request failed:', error.message)
+  }).finally(() => {
+    // 在请求结束后执行
+    loading.value = false
   })
 }
+
+function show() {
+  if (lottieRef.value) {
+    lottie.loadAnimation({
+      container: lottieRef.value,
+      renderer: 'svg',
+      loop: true,
+      autoplay: true,
+      path: '/bg.json'
+    })
+  }
+}
 </script>
+src/stores/user-store
diff --git a/src/pages/system/dictionary/IndexPage.vue b/src/pages/system/dictionary/IndexPage.vue
index 06ed257..c712698 100644
--- a/src/pages/system/dictionary/IndexPage.vue
+++ b/src/pages/system/dictionary/IndexPage.vue
@@ -53,11 +53,10 @@
 import { ref, onMounted } from 'vue'
 import { exportFile, useQuasar, date } from 'quasar'
 import type { QTableProps } from 'quasar'
-
-import type { Dictionary } from 'src/api/models.type'
-
 import { api } from 'boot/axios'
+
 import { SERVER_URL } from 'src/api/paths'
+import type { Dictionary } from 'src/api/models.type'
 
 const $q = useQuasar()
 
@@ -102,7 +101,8 @@ async function onRequest(props: Parameters<NonNullable<QTableProps['onRequest']>
   const { page, rowsPerPage, sortBy, descending } = props.pagination
 
   const params = { page: page - 1, size: rowsPerPage }
-  await api.get(SERVER_URL.DICTIONARY, { params }).then(res => {
+  try {
+    const res = await api.get(SERVER_URL.DICTIONARY, { params })
     rows.value = res.data.content
     pagination.value.page = page
     pagination.value.sortBy = sortBy
@@ -110,10 +110,11 @@ async function onRequest(props: Parameters<NonNullable<QTableProps['onRequest']>
     pagination.value.rowsPerPage = rowsPerPage
     pagination.value.sortBy = res.data.sortBy
     pagination.value.descending = descending
-  }).catch(error => console.log(error))
-    .finally(function () {
-      loading.value = false
-    })
+  } catch (error) {
+    console.log(error)
+  } finally {
+    loading.value = false
+  }
 }
 
 function addRow() {
diff --git a/src/pages/system/group/IndexPage.vue b/src/pages/system/group/IndexPage.vue
index d58e902..f764850 100644
--- a/src/pages/system/group/IndexPage.vue
+++ b/src/pages/system/group/IndexPage.vue
@@ -62,11 +62,10 @@
 import { ref, onMounted } from 'vue'
 import type { QTableProps } from 'quasar'
 import { exportFile, useQuasar, date } from 'quasar'
-
-import type { Group } from 'src/api/models.type'
-
 import { api } from 'boot/axios'
+
 import { SERVER_URL } from 'src/api/paths'
+import type { Group } from 'src/api/models.type'
 
 const $q = useQuasar()
 
@@ -112,7 +111,8 @@ async function onRequest(props: Parameters<NonNullable<QTableProps['onRequest']>
   const { page, rowsPerPage, sortBy, descending } = props.pagination
 
   const params = { page: page - 1, size: rowsPerPage }
-  await api.get(SERVER_URL.GROUP, { params }).then(res => {
+  try {
+    const res = await api.get(SERVER_URL.GROUP, { params })
     rows.value = res.data.content
     pagination.value.page = page
     pagination.value.sortBy = sortBy
@@ -120,10 +120,11 @@ async function onRequest(props: Parameters<NonNullable<QTableProps['onRequest']>
     pagination.value.rowsPerPage = rowsPerPage
     pagination.value.sortBy = res.data.sortBy
     pagination.value.descending = descending
-  }).catch(error => console.log(error))
-    .finally(function () {
-      loading.value = false
-    })
+  } catch (error) {
+    console.log(error)
+  } finally {
+    loading.value = false
+  }
 }
 
 function addRow() {
diff --git a/src/pages/system/region/IndexPage.vue b/src/pages/system/region/IndexPage.vue
index e4f4dbb..c7433d0 100644
--- a/src/pages/system/region/IndexPage.vue
+++ b/src/pages/system/region/IndexPage.vue
@@ -53,11 +53,10 @@
 import { ref, onMounted } from 'vue'
 import type { QTableProps } from 'quasar'
 import { exportFile, useQuasar, date } from 'quasar'
-
-import type { Region } from 'src/api/models.type'
-
 import { api } from 'boot/axios'
+
 import { SERVER_URL } from 'src/api/paths'
+import type { Region } from 'src/api/models.type'
 
 const $q = useQuasar()
 
@@ -104,7 +103,8 @@ async function onRequest(props: Parameters<NonNullable<QTableProps['onRequest']>
   const { page, rowsPerPage, sortBy, descending } = props.pagination
 
   const params = { page: page - 1, size: rowsPerPage }
-  await api.get(SERVER_URL.REGION, { params }).then(res => {
+  try {
+    const res = await api.get(SERVER_URL.REGION, { params })
     rows.value = res.data.content
     pagination.value.page = page
     pagination.value.sortBy = sortBy
@@ -112,10 +112,11 @@ async function onRequest(props: Parameters<NonNullable<QTableProps['onRequest']>
     pagination.value.rowsPerPage = rowsPerPage
     pagination.value.sortBy = res.data.sortBy
     pagination.value.descending = descending
-  }).catch(error => console.log(error))
-    .finally(function () {
-      loading.value = false
-    })
+  } catch (error) {
+    console.log(error)
+  } finally {
+    loading.value = false
+  }
 }
 
 function addRow() {
diff --git a/src/pages/system/role/IndexPage.vue b/src/pages/system/role/IndexPage.vue
index 7b37b7a..d9e0e1d 100644
--- a/src/pages/system/role/IndexPage.vue
+++ b/src/pages/system/role/IndexPage.vue
@@ -62,11 +62,10 @@
 import { ref, onMounted } from 'vue'
 import { exportFile, useQuasar, date } from 'quasar'
 import type { QTableProps } from 'quasar'
-
-import type { Role } from 'src/api/models.type'
-
 import { api } from 'boot/axios'
+
 import { SERVER_URL } from 'src/api/paths'
+import type { Role } from 'src/api/models.type'
 
 const $q = useQuasar()
 
@@ -112,7 +111,8 @@ async function onRequest(props: Parameters<NonNullable<QTableProps['onRequest']>
   const { page, rowsPerPage, sortBy, descending } = props.pagination
 
   const params = { page: page - 1, size: rowsPerPage }
-  await api.get(SERVER_URL.ROLE, { params }).then(res => {
+  try {
+    const res = await api.get(SERVER_URL.ROLE, { params })
     rows.value = res.data.content
     pagination.value.page = page
     pagination.value.sortBy = sortBy
@@ -120,10 +120,11 @@ async function onRequest(props: Parameters<NonNullable<QTableProps['onRequest']>
     pagination.value.rowsPerPage = rowsPerPage
     pagination.value.sortBy = res.data.sortBy
     pagination.value.descending = descending
-  }).catch(error => console.log(error))
-    .finally(function () {
-      loading.value = false
-    })
+  } catch (error) {
+    console.log(error)
+  } finally {
+    loading.value = false
+  }
 }
 
 function addRow() {
diff --git a/src/pages/system/user/IndexPage.vue b/src/pages/system/user/IndexPage.vue
index 66c96bd..07a123a 100644
--- a/src/pages/system/user/IndexPage.vue
+++ b/src/pages/system/user/IndexPage.vue
@@ -73,11 +73,10 @@
 import { ref, onMounted } from 'vue'
 import type { QTableProps } from 'quasar'
 import { exportFile, useQuasar, date } from 'quasar'
-
-import type { User } from 'src/api/models.type'
-
 import { api } from 'boot/axios'
+
 import { SERVER_URL } from 'src/api/paths'
+import type { User } from 'src/api/models.type'
 
 const $q = useQuasar()
 
@@ -128,7 +127,9 @@ async function onRequest(props: Parameters<NonNullable<QTableProps['onRequest']>
   const { page, rowsPerPage, sortBy, descending } = props.pagination
 
   const params = { page: page - 1, size: rowsPerPage }
-  await api.get(SERVER_URL.USER, { params }).then(res => {
+
+  try {
+    const res = await api.get(SERVER_URL.USER, { params })
     rows.value = res.data.content
     pagination.value.page = page
     pagination.value.sortBy = sortBy
@@ -136,10 +137,11 @@ async function onRequest(props: Parameters<NonNullable<QTableProps['onRequest']>
     pagination.value.rowsPerPage = rowsPerPage
     pagination.value.sortBy = res.data.sortBy
     pagination.value.descending = descending
-  }).catch(error => console.log(error))
-    .finally(() => {
-      loading.value = false
-    })
+  } catch (error) {
+    console.log(error)
+  } finally {
+    loading.value = false
+  }
 }
 
 function addRow() {
diff --git a/src/router/routes.ts b/src/router/routes.ts
index 0f5a0c3..eb86d0c 100644
--- a/src/router/routes.ts
+++ b/src/router/routes.ts
@@ -3,19 +3,59 @@ import { RouteRecordRaw } from 'vue-router'
 const routes: RouteRecordRaw[] = [
   {
     path: '/',
+    name: 'application',
     component: () => import('layouts/MainLayout.vue'),
+    meta: { icon: 'sym_r_grid_view' },
     children: [
-      { path: '', component: () => import('pages/IndexPage.vue') },
-      { path: 'dashboard', component: () => import('pages/DashboardIndex.vue') },
+      {
+        path: '',
+        name: 'home',
+        component: () => import('pages/IndexPage.vue'),
+        meta: { icon: 'sym_r_home' }
+      },
+      {
+        path: 'dashboard',
+        name: 'dashboard',
+        component: () => import('pages/DashboardPage.vue'),
+        meta: { icon: 'sym_r_dashboard_customize' }
+      },
       {
         path: 'system',
-        redirect: { path: 'user' },
+        name: 'system',
+        component: () => import('layouts/BlankLayout.vue'),
+        meta: { icon: 'sym_r_settings' },
+        redirect: { path: 'users' },
         children: [
-          { path: 'user', component: () => import('pages/system/user/IndexPage.vue') },
-          { path: 'group', component: () => import('pages/system/group/IndexPage.vue') },
-          { path: 'role', component: () => import('pages/system/role/IndexPage.vue') },
-          { path: 'dictionary', component: () => import('pages/system/dictionary/IndexPage.vue') },
-          { path: 'region', component: () => import('pages/system/region/IndexPage.vue') }
+          {
+            path: 'users',
+            name: 'users',
+            component: () => import('pages/system/user/IndexPage.vue'),
+            meta: { icon: 'sym_r_manage_accounts' }
+          },
+          {
+            path: 'groups',
+            name: 'groups',
+            component: () => import('pages/system/group/IndexPage.vue'),
+            meta: { icon: 'sym_r_group' }
+          },
+          {
+            path: 'roles',
+            name: 'roles',
+            component: () => import('pages/system/role/IndexPage.vue'),
+            meta: { icon: 'sym_r_admin_panel_settings' }
+          },
+          {
+            path: 'dictionaries',
+            name: 'dictionaries',
+            component: () => import('pages/system/dictionary/IndexPage.vue'),
+            meta: { icon: 'sym_r_menu_book' }
+          },
+          {
+            path: 'regions',
+            name: 'regions',
+            component: () => import('pages/system/region/IndexPage.vue'),
+            meta: { icon: 'sym_r_public' }
+          }
         ]
       }
     ]
diff --git a/src/stores/example-store.ts b/src/stores/example-store.ts
deleted file mode 100644
index b1543ca..0000000
--- a/src/stores/example-store.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { defineStore } from 'pinia'
-
-export const useCounterStore = defineStore('counter', {
-  state: () => ({
-    counter: 0
-  }),
-  getters: {
-    doubleCount: (state) => state.counter * 2
-  },
-  actions: {
-    increment() {
-      this.counter++
-    }
-  }
-})
diff --git a/src/stores/user-store.ts b/src/stores/user-store.ts
new file mode 100644
index 0000000..ca59622
--- /dev/null
+++ b/src/stores/user-store.ts
@@ -0,0 +1,34 @@
+import { defineStore } from 'pinia'
+import { SessionStorage } from 'quasar'
+
+interface User {
+  username: string;
+}
+
+export const useUserStore = defineStore('user', {
+  state: () => ({
+    isLoggedIn: false,
+    user: null as User | null
+  }),
+  getters: {
+    getUsername(): string | null {
+      const user = JSON.parse(SessionStorage.getItem('user') || '{}') as User | null
+      return this.user ? this.user.username : (user ? user.username : null)
+    }
+  },
+  actions: {
+    updateUser(username: string) {
+      // 更新用户状态
+      this.isLoggedIn = true
+      this.user = { username }
+      SessionStorage.set('user', JSON.stringify(this.user))
+    },
+
+    clearUser() {
+      // 清除用户状态
+      this.isLoggedIn = false
+      this.user = null
+      SessionStorage.remove('user')
+    }
+  }
+})