Просмотр исходного кода

添加持久化标签页开关功能

RuoYi 2 месяцев назад
Родитель
Сommit
943cb1815d

+ 18 - 0
src/layout/components/Settings/index.vue

@@ -63,6 +63,13 @@
       </span>
     </div>
 
+    <div class="drawer-item">
+      <span>持久化标签页</span>
+      <span class="comp-style">
+        <el-switch v-model="settingsStore.tagsViewPersist" :disabled="!settingsStore.tagsView" @change="tagsViewPersistChange" class="drawer-switch" />
+      </span>
+    </div>
+
     <div class="drawer-item">
       <span>显示页签图标</span>
       <span class="comp-style">
@@ -120,6 +127,7 @@ const showSettings = ref(false)
 const navType = ref(settingsStore.navType)
 const theme = ref(settingsStore.theme)
 const sideTheme = ref(settingsStore.sideTheme)
+const tagsViewPersist = ref(settingsStore.tagsViewPersist)
 const storeSettings = computed(() => settingsStore)
 const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"])
 
@@ -128,6 +136,11 @@ function dynamicTitleChange() {
   useSettingsStore().setTitle(useSettingsStore().title)
 }
 
+function tagsViewPersistChange(val) {
+  settingsStore.tagsViewPersist = val
+  tagsViewPersist.value = val
+}
+
 function themeChange(val) {
   settingsStore.theme = val
   handleThemeStyle(val)
@@ -164,10 +177,14 @@ watch(() => navType, val => {
 
 function saveSetting() {
   proxy.$modal.loading("正在保存到本地,请稍候...")
+  if (!tagsViewPersist.value) {
+    proxy.$cache.local.remove('tags-view-visited')
+  }
   let layoutSetting = {
     "navType": storeSettings.value.navType,
     "tagsView": storeSettings.value.tagsView,
     "tagsIcon": storeSettings.value.tagsIcon,
+    "tagsViewPersist": storeSettings.value.tagsViewPersist,
     "fixedHeader": storeSettings.value.fixedHeader,
     "sidebarLogo": storeSettings.value.sidebarLogo,
     "dynamicTitle": storeSettings.value.dynamicTitle,
@@ -180,6 +197,7 @@ function saveSetting() {
 }
 
 function resetSetting() {
+  proxy.$cache.local.remove('tags-view-visited')
   proxy.$modal.loading("正在清除设置缓存并刷新,请稍候...")
   localStorage.removeItem("layout-setting")
   setTimeout("window.location.reload()", 1000)

+ 5 - 1
src/layout/components/TagsView/index.vue

@@ -117,6 +117,7 @@ const visitedViews = computed(() => useTagsViewStore().visitedViews)
 const routes = computed(() => usePermissionStore().routes)
 const theme = computed(() => useSettingsStore().theme)
 const tagsIcon = computed(() => useSettingsStore().tagsIcon)
+const tagsViewPersist = computed(() => useSettingsStore().tagsViewPersist)
 
 // 下拉菜单针对当前激活的 tag
 const selectedDropdownTag = computed(() => visitedViews.value.find(v => isActive(v)) || {})
@@ -207,11 +208,14 @@ function filterAffixTags(routes, basePath = '') {
 }
 
 function initTags() {
+  if (tagsViewPersist) {
+    useTagsViewStore().loadPersistedViews()
+  }
   const res = filterAffixTags(routes.value)
   affixTags.value = res
   for (const tag of res) {
     if (tag.name) {
-      useTagsViewStore().addVisitedView(tag)
+      useTagsViewStore().addAffixView(tag)
     }
   }
 }

+ 6 - 1
src/settings.js

@@ -23,7 +23,12 @@ export default {
    * 是否显示 tagsView
    */
   tagsView: true,
-  
+
+  /**
+   * 持久化标签页
+   */
+  tagsViewPersist: false,
+
   /**
    * 显示页签图标
    */

+ 2 - 1
src/store/modules/settings.js

@@ -5,7 +5,7 @@ import { useDynamicTitle } from '@/utils/dynamicTitle'
 const isDark = useDark()
 const toggleDark = useToggle(isDark)
 
-const { sideTheme, showSettings, navType, tagsView, tagsIcon, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
+const { sideTheme, showSettings, navType, tagsView, tagsViewPersist, tagsIcon, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
 
 const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
 
@@ -19,6 +19,7 @@ const useSettingsStore = defineStore(
       showSettings: showSettings,
       navType: storageSetting.navType === undefined ? navType : storageSetting.navType,
       tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
+      tagsViewPersist: storageSetting.tagsViewPersist === undefined ? tagsViewPersist : storageSetting.tagsViewPersist,
       tagsIcon: storageSetting.tagsIcon === undefined ? tagsIcon : storageSetting.tagsIcon,
       fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
       sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,

+ 45 - 0
src/store/modules/tagsView.js

@@ -1,3 +1,26 @@
+import cache from '@/plugins/cache'
+import useSettingsStore from '@/store/modules/settings'
+
+const PERSIST_KEY = 'tags-view-visited'
+
+function isPersistEnabled() {
+  return useSettingsStore().tagsViewPersist
+}
+
+function saveVisitedViews(views) {
+  if (!isPersistEnabled()) return
+  const toSave = views.filter(v => !(v.meta && v.meta.affix)).map(v => ({ path: v.path, fullPath: v.fullPath, name: v.name, title: v.title, query: v.query, meta: v.meta }))
+  cache.local.setJSON(PERSIST_KEY, toSave)
+}
+
+function loadVisitedViews() {
+  return cache.local.getJSON(PERSIST_KEY) || []
+}
+
+function clearVisitedViews() {
+  cache.local.remove(PERSIST_KEY)
+}
+
 const useTagsViewStore = defineStore(
   'tags-view',
   {
@@ -26,6 +49,15 @@ const useTagsViewStore = defineStore(
             title: view.meta.title || 'no-name'
           })
         )
+        saveVisitedViews(this.visitedViews)
+      },
+      addAffixView(view) {
+        if (this.visitedViews.some(v => v.path === view.path)) return
+        this.visitedViews.unshift(
+          Object.assign({}, view, {
+            title: view.meta.title || 'no-name'
+          })
+        )
       },
       addCachedView(view) {
         if (this.cachedViews.includes(view.name)) return
@@ -52,6 +84,7 @@ const useTagsViewStore = defineStore(
             }
           }
           this.iframeViews = this.iframeViews.filter(item => item.path !== view.path)
+          saveVisitedViews(this.visitedViews)
           resolve([...this.visitedViews])
         })
       },
@@ -84,6 +117,7 @@ const useTagsViewStore = defineStore(
             return v.meta.affix || v.path === view.path
           })
           this.iframeViews = this.iframeViews.filter(item => item.path === view.path)
+          saveVisitedViews(this.visitedViews)
           resolve([...this.visitedViews])
         })
       },
@@ -95,6 +129,7 @@ const useTagsViewStore = defineStore(
           } else {
             this.cachedViews = []
           }
+          saveVisitedViews(this.visitedViews)
           resolve([...this.cachedViews])
         })
       },
@@ -113,6 +148,7 @@ const useTagsViewStore = defineStore(
           const affixTags = this.visitedViews.filter(tag => tag.meta.affix)
           this.visitedViews = affixTags
           this.iframeViews = []
+          clearVisitedViews()
           resolve([...this.visitedViews])
         })
       },
@@ -150,6 +186,7 @@ const useTagsViewStore = defineStore(
             }
             return false
           })
+          saveVisitedViews(this.visitedViews)
           resolve([...this.visitedViews])
         })
       },
@@ -173,8 +210,16 @@ const useTagsViewStore = defineStore(
             }
             return false
           })
+          saveVisitedViews(this.visitedViews)
           resolve([...this.visitedViews])
         })
+      },
+      // 恢复持久化的 tags
+      loadPersistedViews() {
+        const views = loadVisitedViews()
+        views.forEach(view => {
+          this.addVisitedView(view)
+        })
       }
     }
   })