From 543d169827a2418a4a83b604fac923d29781c6ef Mon Sep 17 00:00:00 2001
From: RuoYi <yzz_ivy@163.com>
Date: Sun, 22 Mar 2026 21:13:35 +0800
Subject: [PATCH] 添加持久化标签页开关功能

---
 ruoyi-ui/src/store/modules/tagsView.js |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/ruoyi-ui/src/store/modules/tagsView.js b/ruoyi-ui/src/store/modules/tagsView.js
index 9a88c2b..d3f52fb 100644
--- a/ruoyi-ui/src/store/modules/tagsView.js
+++ b/ruoyi-ui/src/store/modules/tagsView.js
@@ -1,3 +1,26 @@
+import store from '@/store'
+import cache from '@/plugins/cache'
+
+const PERSIST_KEY = 'tags-view-visited'
+
+function isPersistEnabled() {
+  return store.state.settings.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 state = {
   visitedViews: [],
   cachedViews: [],
@@ -20,6 +43,15 @@
         title: view.meta.title || 'no-name'
       })
     )
+    saveVisitedViews(state.visitedViews)
+  },
+  ADD_VISITED_VIEW_FIRST: (state, view) => {
+    if (state.visitedViews.some(v => v.path === view.path)) return
+    state.visitedViews.unshift(
+      Object.assign({}, view, {
+        title: view.meta.title || 'no-name'
+      })
+    )
   },
   ADD_CACHED_VIEW: (state, view) => {
     if (state.cachedViews.includes(view.name)) return
@@ -35,6 +67,7 @@
       }
     }
     state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
+    saveVisitedViews(state.visitedViews)
   },
   DEL_IFRAME_VIEW: (state, view) => {
     state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
@@ -49,6 +82,7 @@
       return v.meta.affix || v.path === view.path
     })
     state.iframeViews = state.iframeViews.filter(item => item.path === view.path)
+    saveVisitedViews(state.visitedViews)
   },
   DEL_OTHERS_CACHED_VIEWS: (state, view) => {
     const index = state.cachedViews.indexOf(view.name)
@@ -63,6 +97,7 @@
     const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
     state.visitedViews = affixTags
     state.iframeViews = []
+    clearVisitedViews()
   },
   DEL_ALL_CACHED_VIEWS: state => {
     state.cachedViews = []
@@ -94,6 +129,7 @@
       }
       return false
     })
+    saveVisitedViews(state.visitedViews)
   },
   DEL_LEFT_VIEWS: (state, view) => {
     const index = state.visitedViews.findIndex(v => v.path === view.path)
@@ -114,6 +150,7 @@
       }
       return false
     })
+    saveVisitedViews(state.visitedViews)
   }
 }
 
@@ -127,6 +164,9 @@
   },
   addVisitedView({ commit }, view) {
     commit('ADD_VISITED_VIEW', view)
+  },
+  addAffixView({ commit }, view) {
+    commit('ADD_VISITED_VIEW_FIRST', view)
   },
   addCachedView({ commit }, view) {
     commit('ADD_CACHED_VIEW', view)
@@ -218,6 +258,13 @@
       resolve([...state.visitedViews])
     })
   },
+  // 恢复持久化的 tags
+  loadPersistedViews({ commit }) {
+    const views = loadVisitedViews()
+    views.forEach(view => {
+      commit('ADD_VISITED_VIEW', view)
+    })
+  },
 }
 
 export default {

--
Gitblit v1.9.3