diff --git a/build/proxy.ts b/build/proxy.ts
index d11829d..19fe5fd 100644
--- a/build/proxy.ts
+++ b/build/proxy.ts
@@ -3,7 +3,7 @@ import type { ProxyOptions } from 'vite'
 /** 不同请求服务的环境配置 */
 export const proxyConfig: Record<ServiceEnvType, ServiceEnvConfig> = {
   dev: {
-    url: 'http://localhost:3000',
+    url: 'https://mock.apifox.com/m1/4071143-0-default',
     urlPattern: '/url-pattern',
   },
   test: {
@@ -11,7 +11,7 @@ export const proxyConfig: Record<ServiceEnvType, ServiceEnvConfig> = {
     urlPattern: '/url-pattern',
   },
   prod: {
-    url: 'http://localhost:8080',
+    url: 'https://mock.apifox.com/m1/4071143-0-default',
     urlPattern: '/url-pattern',
   },
 }
diff --git a/src/layouts/components/tab/TabBar.vue b/src/layouts/components/tab/TabBar.vue
index 3cb5d85..8d1f885 100644
--- a/src/layouts/components/tab/TabBar.vue
+++ b/src/layouts/components/tab/TabBar.vue
@@ -1,7 +1,8 @@
 <script setup lang="ts">
 import type { RouteLocationNormalized } from 'vue-router'
-import { useAppStore, useTabStore } from '@/store'
+import { NIcon } from 'naive-ui'
 import { renderIcon } from '@/utils'
+import { useAppStore, useTabStore } from '@/store'
 
 const tabStore = useTabStore()
 const appStore = useAppStore()
@@ -90,6 +91,17 @@ function handleContextMenu(e: MouseEvent, route: RouteLocationNormalized) {
 function onClickoutside() {
   showDropdown.value = false
 }
+
+function renderDropTabsLabel(option: any) {
+  return option.meta.title
+}
+function renderDropTabsIcon(option: any) {
+  return renderIcon(option.meta.icon)!()
+}
+
+function handleDropTabs(key: string, option: any) {
+  router.push(option.path)
+}
 </script>
 
 <template>
@@ -121,6 +133,20 @@ function onClickoutside() {
           <e-icon :icon="item.meta.icon" /> {{ item.meta.title }}
         </div>
       </n-tab>
+      <template #suffix>
+        <n-dropdown
+          :options="tabStore.allTabs"
+          :render-label="renderDropTabsLabel"
+          :render-icon="renderDropTabsIcon"
+          trigger="click"
+          size="small"
+          @select="handleDropTabs"
+        >
+          <n-button tertiary circle type="primary">
+            <i-icon-park-outline-application-menu />
+          </n-button>
+        </n-dropdown>
+      </template>
     </n-tabs>
     <n-dropdown
       placement="bottom-start"
diff --git a/src/service/api/test.ts b/src/service/api/test.ts
index 69c64c4..3690e33 100644
--- a/src/service/api/test.ts
+++ b/src/service/api/test.ts
@@ -11,7 +11,7 @@ export function fetchPost(data: any) {
 }
 /* formPost方法测试 */
 export function fetchFormPost(data: any) {
-  const methodInstance = alovaInstance.Post('/postAPI', data)
+  const methodInstance = alovaInstance.Post('/postFormAPI', data)
   methodInstance.meta = {
     isFormPost: true,
   }
@@ -49,10 +49,20 @@ export function dictData() {
 export function getBlob() {
   const methodInstance = blankInstance.Get('https://images.unsplash.com/photo-1663529628961-80aa6ebcd157?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80')
   methodInstance.meta = {
-    isDownload: true,
+    // 标识为bolb数据
+    isBlob: true,
   }
   return methodInstance
 }
+
+/* 带进度的下载文件 */
+export function downloadFile(url: string) {
+  const methodInstance = blankInstance.Get(url, {
+    // 开启下载进度
+    enableDownload: true,
+  })
+  return methodInstance
+}
 /* 测试状态码500失败 */
 export function FailedRequest() {
   return alovaInstance.Get('/serverError')
diff --git a/src/service/http/alova.ts b/src/service/http/alova.ts
index 4a42f3e..4db0613 100644
--- a/src/service/http/alova.ts
+++ b/src/service/http/alova.ts
@@ -63,7 +63,7 @@ export function createAlovaInstance(
 
         if (status === 200) {
           // 返回blob数据
-          if (method.meta?.isDownload)
+          if (method.meta?.isBlob)
             return response.blob()
 
           // 返回json数据
diff --git a/src/service/http/index.ts b/src/service/http/index.ts
index 763ea15..0aacb51 100644
--- a/src/service/http/index.ts
+++ b/src/service/http/index.ts
@@ -5,12 +5,8 @@ const { url, urlPattern } = proxyConfig[import.meta.env.MODE]
 
 const isHttpProxy = import.meta.env.VITE_HTTP_PROXY === 'Y' || false
 
-export const request = createAlovaInstance({
-  baseURL: isHttpProxy ? urlPattern : url,
-})
-
 export const alovaInstance = createAlovaInstance({
-  baseURL: 'https://mock.apifox.com/m1/4071143-0-default',
+  baseURL: isHttpProxy ? urlPattern : url,
 })
 
 export const blankInstance = createAlovaInstance({
diff --git a/src/store/auth.ts b/src/store/auth.ts
index 0f99982..ab33c06 100644
--- a/src/store/auth.ts
+++ b/src/store/auth.ts
@@ -4,20 +4,15 @@ import { fetchLogin, fetchUserInfo } from '@/service'
 import { router } from '@/router'
 import { local } from '@/utils'
 
-const emptyInfo: Auth.UserInfo = {
-  id: 0,
-  userName: '',
-  nickName: '',
-  avatar: '',
-  role: 'user',
+interface AuthStatus {
+  userInfo: Auth.UserInfo | null
+  token: string
 }
 export const useAuthStore = defineStore('auth-store', {
-  state: () => {
+  state: (): AuthStatus => {
     return {
-      userInfo: local.get('userInfo') || emptyInfo,
+      userInfo: local.get('userInfo'),
       token: local.get('token') || '',
-      refreshToken: local.get('refreshToken') || '',
-      loginLoading: false,
     }
   },
   getters: {
@@ -58,16 +53,12 @@ export const useAuthStore = defineStore('auth-store', {
 
     /* 用户登录 */
     async login(username: string, password: string) {
-      this.loginLoading = true
       const { error, data } = await fetchLogin({ username, password })
-      if (error) {
-        this.loginLoading = false
+      if (error)
         return
-      }
+
       // 处理登录信息
       await this.handleAfterLogin(data)
-
-      this.loginLoading = false
     },
 
     /* 登录后的处理函数 */
@@ -91,7 +82,7 @@ export const useAuthStore = defineStore('auth-store', {
         // 触发用户提示
         window.$notification?.success({
           title: '登录成功!',
-          content: `欢迎回来😊,${this.userInfo.nickName}!`,
+          content: `欢迎回来😊,${this.userInfo?.nickName}!`,
           duration: 3000,
         })
         return
@@ -108,7 +99,6 @@ export const useAuthStore = defineStore('auth-store', {
       local.set('token', accessToken)
       local.set('refreshToken', refreshToken)
       this.token = accessToken
-      this.refreshToken = refreshToken
       const { error, data } = await fetchUserInfo({ id })
       if (error)
         return catchSuccess
diff --git a/src/store/route.ts b/src/store/route.ts
index 629abba..98d970c 100644
--- a/src/store/route.ts
+++ b/src/store/route.ts
@@ -13,19 +13,17 @@ import { BasicLayout } from '@/layouts/index'
 interface RoutesStatus {
   isInitAuthRoute: boolean
   menus: any
-  userRoutes: AppRoute.RowRoute[]
+  rowRoutes: AppRoute.RowRoute[]
   activeMenu: string | null
-  authRouteMode: ImportMetaEnv['VITE_AUTH_ROUTE_MODE']
   cacheRoutes: string[]
 }
 export const useRouteStore = defineStore('route-store', {
   state: (): RoutesStatus => {
     return {
-      userRoutes: [],
       isInitAuthRoute: false,
       menus: [],
+      rowRoutes: [],
       activeMenu: null,
-      authRouteMode: import.meta.env.VITE_AUTH_ROUTE_MODE,
       cacheRoutes: [],
     }
   },
@@ -38,30 +36,12 @@ export const useRouteStore = defineStore('route-store', {
       /* 删除后面添加的路由 */
       router.removeRoute('appRoot')
     },
-    /* 判断当前路由和子路由中是否存在为routeName的路由 */
-    hasPathinAllPath(routeName: string, userRoutes: AppRoute.Route) {
-      if (userRoutes.name === routeName)
-        return true
-
-      if (userRoutes.children && userRoutes.children.length !== 0) {
-        const arr: boolean[] = []
-        userRoutes.children.forEach((item) => {
-          arr.push(this.hasPathinAllPath(routeName, item))
-        })
-        return arr.some((item) => {
-          return item
-        })
-      }
-      return false
-    },
     /* 设置当前高亮的菜单key */
     setActiveMenu(key: string) {
       this.activeMenu = key
     },
     /* 生成侧边菜单的数据 */
     createMenus(userRoutes: AppRoute.RowRoute[]) {
-      this.userRoutes = userRoutes
-
       const resultMenus = clone(userRoutes).map(i => construct(i)) as AppRoute.Route[]
       /** 过滤不需要显示的菜单 */
       const visibleMenus = resultMenus.filter(route => !route.meta.hide)
@@ -139,7 +119,7 @@ export const useRouteStore = defineStore('route-store', {
         }
       })
     },
-    createDynamicRoutes(routes: AppRoute.RowRoute[]) {
+    createRoutes(routes: AppRoute.RowRoute[]) {
       const { hasPermission } = usePermission()
       // 结构化meta字段
       let resultRouter = clone(routes).map(i => construct(i)) as AppRoute.Route[]
@@ -175,44 +155,38 @@ export const useRouteStore = defineStore('route-store', {
       }
       // 根据角色过滤后的插入根路由中
       appRootRoute.children = resultRouter as unknown as RouteRecordRaw[]
-      return appRootRoute
-    },
-    /* 初始化动态路由 */
-    async initDynamicRoute() {
-      // 根据用户id来获取用户的路由
-      const userInfo = local.get('userInfo')
-
-      if (!userInfo || !userInfo.id)
-        return
-
-      const { data } = await fetchUserRoutes({
-        id: userInfo.id,
-      })
-
-      if (!data)
-        return
-      // 根据用户返回的路由表来生成真实路由
-      const appRoutes = this.createDynamicRoutes(data)
-      // 生成侧边菜单
-      this.createMenus(data)
       // 插入路由表
-      router.addRoute(appRoutes)
-    },
-    /* 初始化静态路由 */
-    initStaticRoute() {
-      // 根据静态路由表来生成真实路由
-      const appRoutes = this.createDynamicRoutes(staticRoutes)
-      // 生成侧边菜单
-      this.createMenus(staticRoutes)
-      // 插入路由表
-      router.addRoute(appRoutes)
+      router.addRoute(appRootRoute)
     },
+    async initRouteInfo() {
+      if (import.meta.env.VITE_AUTH_ROUTE_MODE === 'dynamic') {
+        // 根据用户id来获取用户的路由
+        const userInfo = local.get('userInfo')
 
+        if (!userInfo || !userInfo.id)
+          return
+
+        const { data } = await fetchUserRoutes({
+          id: userInfo.id,
+        })
+
+        if (!data)
+          return
+
+        this.rowRoutes = data
+      }
+      else {
+        this.rowRoutes = staticRoutes
+      }
+    },
     async initAuthRoute() {
       this.isInitAuthRoute = false
-      if (this.authRouteMode === 'dynamic')
-        await this.initDynamicRoute()
-      else this.initStaticRoute()
+      // 初始化路由信息
+      await this.initRouteInfo()
+      // 生成真实路由并插入
+      this.createRoutes(this.rowRoutes)
+      // 生成侧边菜单
+      this.createMenus(this.rowRoutes)
 
       this.isInitAuthRoute = true
     },
diff --git a/src/store/tab.ts b/src/store/tab.ts
index 7d6b748..7116d9a 100644
--- a/src/store/tab.ts
+++ b/src/store/tab.ts
@@ -14,6 +14,9 @@ export const useTabStore = defineStore('tab-store', {
       currentTabPath: '',
     }
   },
+  getters: {
+    allTabs: state => [...state.pinTabs, ...state.tabs],
+  },
   actions: {
     addTab(route: RouteLocationNormalized) {
       // 根据meta确定是否不添加,可用于错误页,登录页等
diff --git a/src/typings/service.d.ts b/src/typings/service.d.ts
index f96cef6..f4b04ce 100644
--- a/src/typings/service.d.ts
+++ b/src/typings/service.d.ts
@@ -20,7 +20,7 @@ declare namespace Service {
     successCode?: number | string
   }
 
-  type RequestErrorType = 'Alova' | 'Response' | 'Business'
+  type RequestErrorType = 'Response' | 'Business'
   type RequestCode = string | number
 
   interface RequestError {
diff --git a/src/views/login/components/Login/index.vue b/src/views/login/components/Login/index.vue
index 3185094..df7d507 100644
--- a/src/views/login/components/Login/index.vue
+++ b/src/views/login/components/Login/index.vue
@@ -1,5 +1,6 @@
 <script setup lang="ts">
 import type { FormInst } from 'naive-ui'
+import { useRequest } from 'alova'
 import { local } from '@/utils'
 import { useAuthStore } from '@/store'
 
@@ -34,20 +35,23 @@ const formValue = ref({
   code: '1234',
 })
 const isRemember = ref(false)
+const isLoading = ref(false)
 
 const formRef = ref<FormInst | null>(null)
 function handleLogin() {
-  formRef.value?.validate((errors) => {
+  formRef.value?.validate(async (errors) => {
     if (errors)
       return
 
+    isLoading.value = true
     const { account, pwd } = formValue.value
 
     if (isRemember.value)
       local.set('login_account', { account, pwd })
     else local.remove('login_account')
 
-    authStore.login(account, pwd)
+    await authStore.login(account, pwd)
+    isLoading.value = false
   })
 }
 function checkUserAccount() {
@@ -95,7 +99,7 @@ checkUserAccount()
             忘记密码?
           </n-button>
         </div>
-        <n-button block type="primary" size="large" :loading="authStore.loginLoading" @click="handleLogin">
+        <n-button block type="primary" size="large" :loading="isLoading" @click="handleLogin">
           登录
         </n-button>
         <n-button type="primary" text @click="toOtherForm('register')">
diff --git a/src/views/test/test1/index.vue b/src/views/test/test1/index.vue
index edbc169..6f31559 100644
--- a/src/views/test/test1/index.vue
+++ b/src/views/test/test1/index.vue
@@ -5,6 +5,7 @@ import {
   FailedResponse,
   FailedResponseWithoutTip,
   dictData,
+  downloadFile,
   expiredTokenRequest,
   fetachGet,
   fetchDelete,
@@ -17,14 +18,14 @@ import {
 } from '@/service'
 
 const msg = ref()
-const { data, send } = useRequest(fetachGet({ a: 112211 }), {
+const { data: fetachGetData, send: sendFetachGet } = useRequest(fetachGet({ a: 112211 }), {
   // 当immediate为false时,默认不发出
   immediate: false,
 })
 
 function handleRequestHook() {
-  send()
-  msg.value = data.value
+  sendFetachGet()
+  msg.value = fetachGetData.value
 }
 function pinterEnv() {
   msg.value = import.meta.env
@@ -126,6 +127,17 @@ function getBlobFile() {
     document.body.removeChild(eleLink)
   })
 }
+// 下载大文件获取进度
+const downloadPath = ref('https://suqiqi.oss-cn-beijing.aliyuncs.com/test/video/1.mp4')
+const { downloading, abort: abortDownloadFile, send: sendDownloadFile } = useRequest(downloadFile(downloadPath.value), {
+  // 当immediate为false时,默认不发出
+  immediate: false,
+})
+const downloadProcess = computed(() => {
+  if (!downloading.value.loaded)
+    return 0
+  return Math.floor(downloading.value.loaded / downloading.value.total * 100)
+})
 </script>
 
 <template>
@@ -180,6 +192,18 @@ function getBlobFile() {
             click
           </n-button>
         </n-descriptions-item>
+        <n-descriptions-item label="带进度的下载文件" span="3">
+          <n-input v-model:value="downloadPath" />
+          <div>文件大小:{{ downloading.total }}B</div>
+          <div>已下载:{{ downloading.loaded }}B</div>
+          <n-progress type="line" indicator-placement="inside" :percentage="downloadProcess" />
+          <n-button strong secondary @click="sendDownloadFile">
+            开始下载
+          </n-button>
+          <n-button strong secondary type="warning" @click="abortDownloadFile">
+            中断下载
+          </n-button>
+        </n-descriptions-item>
         <n-descriptions-item label="转换请求数据">
           <n-button strong secondary type="success" @click="getDictData">
             click