diff --git a/packages/frontend/src/stores/audit.store.ts b/packages/frontend/src/stores/audit.store.ts index 69d7d44..f88cb4e 100644 --- a/packages/frontend/src/stores/audit.store.ts +++ b/packages/frontend/src/stores/audit.store.ts @@ -11,54 +11,103 @@ export const useAuditLogStore = defineStore('auditLog', () => { const currentPage = ref(1); const logsPerPage = ref(50); // Default page size - // fetchLogs 现在接受一个选项对象作为参数 + // fetchLogs 现在接受一个选项对象作为参数,并增加了缓存逻辑 const fetchLogs = async (options: { page?: number; - limit?: number; // 新增 limit 参数 + limit?: number; searchTerm?: string; actionType?: AuditLogActionType | ''; - sortOrder?: 'asc' | 'desc'; // 新增 sortOrder 参数 + sortOrder?: 'asc' | 'desc'; + // 新增一个标志,明确指示是否为仪表盘调用,以启用缓存 + isDashboardRequest?: boolean; } = {}) => { const { page = 1, - limit = logsPerPage.value, // 优先使用传入的 limit,否则使用 store 的默认值 + limit = logsPerPage.value, searchTerm, actionType, - sortOrder + sortOrder, + isDashboardRequest = false // 默认为 false } = options; - isLoading.value = true; - error.value = null; - currentPage.value = page; // 仍然更新当前页码状态 - const offset = (page - 1) * limit; // offset 计算基于实际使用的 limit + const cacheKey = 'dashboardAuditLogsCache'; + error.value = null; // 重置错误 + // --- 缓存逻辑 (仅当 isDashboardRequest 为 true 时触发) --- + if (isDashboardRequest) { + try { + const cachedData = localStorage.getItem(cacheKey); + if (cachedData) { + console.log('[AuditLogStore] Loading dashboard logs from cache.'); + // 仪表盘只关心日志列表,不关心 totalLogs 或 currentPage + logs.value = JSON.parse(cachedData); + isLoading.value = false; // 先显示缓存 + } else { + isLoading.value = true; // 无缓存,初始加载 + } + } catch (e) { + console.error('[AuditLogStore] Failed to load or parse dashboard logs cache:', e); + localStorage.removeItem(cacheKey); + isLoading.value = true; // 缓存无效,需要加载 + } + } else { + // 非仪表盘请求(如完整日志页),总是显示加载状态 + isLoading.value = true; + currentPage.value = page; // 更新分页状态 + } + + // --- API 请求逻辑 --- + isLoading.value = true; // 标记正在获取(或后台获取) + const offset = (page - 1) * limit; try { const params: Record = { - limit: limit, // 使用实际的 limit + limit: limit, offset: offset, - // 条件性添加其他参数 ...(searchTerm && { search: searchTerm }), ...(actionType && { action_type: actionType }), - ...(sortOrder && { sort_order: sortOrder }), // 添加 sort_order 参数 + ...(sortOrder && { sort_order: sortOrder }), }; - const response = await apiClient.get('/audit-logs', { params }); // 使用 apiClient - // 注意:如果 fetchLogs 被用于分页,这里直接赋值 logs.value 可能不是最佳实践 - // 但对于仪表盘只获取少量最新日志的场景是可行的。 - // 如果需要支持加载更多,需要修改这里的逻辑为追加或替换。 - logs.value = response.data.logs; - totalLogs.value = response.data.total; + console.log(`[AuditLogStore] Fetching logs from server (isDashboard: ${isDashboardRequest}). Params:`, params); + const response = await apiClient.get('/audit-logs', { params }); + const freshLogs = response.data.logs; + const freshTotal = response.data.total; + + // --- 更新状态和缓存 --- + if (isDashboardRequest) { + const freshLogsString = JSON.stringify(freshLogs); + const currentLogsString = JSON.stringify(logs.value); + + if (currentLogsString !== freshLogsString) { + console.log('[AuditLogStore] Dashboard logs data changed, updating state and cache.'); + logs.value = freshLogs; + localStorage.setItem(cacheKey, freshLogsString); // 更新缓存 + } else { + console.log('[AuditLogStore] Dashboard logs data is up-to-date.'); + } + // 仪表盘请求不更新 totalLogs 或 currentPage + } else { + // 非仪表盘请求,直接更新日志和总数 + console.log('[AuditLogStore] Updating logs for full view.'); + logs.value = freshLogs; + totalLogs.value = freshTotal; + } + error.value = null; // 清除错误 + } catch (err: any) { - console.error('Error fetching audit logs:', err); + console.error('[AuditLogStore] Error fetching audit logs:', err); error.value = err.response?.data?.message || '获取审计日志失败'; - logs.value = []; - totalLogs.value = 0; + // 如果是仪表盘请求失败,保留缓存数据;否则清空 + if (!isDashboardRequest) { + logs.value = []; + totalLogs.value = 0; + } } finally { - isLoading.value = false; + isLoading.value = false; // 加载完成 } }; - // Function to change page size and refetch + // Function to change page size and refetch (非仪表盘场景) const setLogsPerPage = (size: number) => { logsPerPage.value = size; fetchLogs({ page: 1 }); // 重置到第一页,使用默认 limit diff --git a/packages/frontend/src/stores/commandHistory.store.ts b/packages/frontend/src/stores/commandHistory.store.ts index 913dbff..686edaf 100644 --- a/packages/frontend/src/stores/commandHistory.store.ts +++ b/packages/frontend/src/stores/commandHistory.store.ts @@ -58,26 +58,57 @@ export const useCommandHistoryStore = defineStore('commandHistory', () => { selectedIndex.value = (selectedIndex.value - 1 + history.length) % history.length; }; - // 从后端获取历史记录 + // 从后端获取历史记录 (带缓存) const fetchHistory = async () => { - isLoading.value = true; - error.value = null; + const cacheKey = 'commandHistoryCache'; + error.value = null; // 重置错误 + + // 1. 尝试从 localStorage 加载缓存 try { - const response = await apiClient.get('/command-history'); // 使用 apiClient - // 后端返回的是按时间戳升序 (旧->新) - // 前端需要按时间戳降序 (新->旧),所以反转数组 - historyList.value = response.data.reverse(); + const cachedData = localStorage.getItem(cacheKey); + if (cachedData) { + console.log('[CmdHistoryStore] Loading history from cache.'); + historyList.value = JSON.parse(cachedData); // 缓存中已是降序 + isLoading.value = false; // 先显示缓存 + } else { + isLoading.value = true; // 无缓存,初始加载 + } + } catch (e) { + console.error('[CmdHistoryStore] Failed to load or parse history cache:', e); + localStorage.removeItem(cacheKey); // 解析失败则移除缓存 + isLoading.value = true; // 缓存无效,需要加载 + } + + // 2. 后台获取最新数据 + isLoading.value = true; // 标记正在后台获取 + try { + console.log('[CmdHistoryStore] Fetching latest history from server...'); + const response = await apiClient.get('/command-history'); + // 后端返回升序,前端需要降序 + const freshData = response.data.reverse(); + const freshDataString = JSON.stringify(freshData); + + // 3. 对比并更新 + const currentDataString = JSON.stringify(historyList.value); + if (currentDataString !== freshDataString) { + console.log('[CmdHistoryStore] History data changed, updating state and cache.'); + historyList.value = freshData; + localStorage.setItem(cacheKey, freshDataString); // 更新缓存 (存降序) + } else { + console.log('[CmdHistoryStore] History data is up-to-date.'); + } + error.value = null; // 清除错误 } catch (err: any) { - console.error('获取命令历史记录失败:', err); + console.error('[CmdHistoryStore] 获取命令历史记录失败:', err); error.value = err.response?.data?.message || '获取历史记录时发生错误'; - // 确保传递给 showError 的是字符串 - uiNotificationsStore.showError(error.value ?? '未知错误'); // 显示错误通知 + // 保留缓存数据,仅设置错误状态 + uiNotificationsStore.showError(error.value ?? '未知错误'); } finally { - isLoading.value = false; + isLoading.value = false; // 加载完成 } }; - // 添加命令到历史记录 (由 CommandInputBar 调用) + // 添加命令到历史记录 (由 CommandInputBar 调用, 添加后清除缓存) const addCommand = async (command: string) => { if (!command || command.trim().length === 0) { return; // 不添加空命令 @@ -85,8 +116,9 @@ export const useCommandHistoryStore = defineStore('commandHistory', () => { try { const response = await apiClient.post<{ id: number }>('/command-history', { command: command.trim() }); // 使用 apiClient // 添加成功后,重新获取列表以保证顺序和 ID 正确 - // 或者,可以在本地模拟添加,但为了简单和一致性,重新获取更好 - await fetchHistory(); + // 添加成功后,清除缓存并重新获取 + localStorage.removeItem('commandHistoryCache'); + await fetchHistory(); // fetchHistory 会处理获取和缓存更新 } catch (err: any) { console.error('添加命令历史记录失败:', err); const message = err.response?.data?.message || '添加历史记录时发生错误'; @@ -98,8 +130,9 @@ export const useCommandHistoryStore = defineStore('commandHistory', () => { // 删除单条历史记录 const deleteCommand = async (id: number) => { try { - await apiClient.delete(`/command-history/${id}`); // 使用 apiClient - // 从本地列表中移除 + await apiClient.delete(`/command-history/${id}`); + // 删除成功后,清除缓存并更新本地列表 + localStorage.removeItem('commandHistoryCache'); const index = historyList.value.findIndex(entry => entry.id === id); if (index !== -1) { historyList.value.splice(index, 1); @@ -116,8 +149,10 @@ export const useCommandHistoryStore = defineStore('commandHistory', () => { const clearAllHistory = async () => { // 可以在调用前添加确认逻辑 (例如在组件层) try { - await apiClient.delete('/command-history'); // 使用 apiClient - historyList.value = []; // 清空本地列表 + await apiClient.delete('/command-history'); + // 清空成功后,清除缓存并清空本地列表 + localStorage.removeItem('commandHistoryCache'); + historyList.value = []; uiNotificationsStore.showSuccess('所有历史记录已清空'); } catch (err: any) { console.error('清空命令历史记录失败:', err); diff --git a/packages/frontend/src/stores/connections.store.ts b/packages/frontend/src/stores/connections.store.ts index 65709ca..2d5cfc6 100644 --- a/packages/frontend/src/stores/connections.store.ts +++ b/packages/frontend/src/stores/connections.store.ts @@ -31,28 +31,60 @@ export const useConnectionsStore = defineStore('connections', { error: null, }), actions: { - // 获取连接列表 Action + // 获取连接列表 Action (带缓存) async fetchConnections() { - this.isLoading = true; - this.error = null; + const cacheKey = 'connectionsCache'; + this.error = null; // 重置错误状态 + + // 1. 尝试从 localStorage 加载缓存 try { - // 注意:axios 默认会携带 cookie,因此如果用户已登录,会话 cookie 会被发送 - const response = await apiClient.get('/connections'); // 使用 apiClient - this.connections = response.data; + const cachedData = localStorage.getItem(cacheKey); + if (cachedData) { + console.log('[ConnectionsStore] Loading connections from cache.'); + this.connections = JSON.parse(cachedData); + this.isLoading = false; // 先显示缓存,设置为 false + } else { + // 没有缓存时,初始加载状态设为 true + this.isLoading = true; + } + } catch (e) { + console.error('[ConnectionsStore] Failed to load or parse connections cache:', e); + localStorage.removeItem(cacheKey); // 解析失败则移除缓存 + this.isLoading = true; // 缓存无效,需要加载 + } + + // 2. 后台获取最新数据 + this.isLoading = true; // 标记正在后台获取 + try { + console.log('[ConnectionsStore] Fetching latest connections from server...'); + const response = await apiClient.get('/connections'); + const freshData = response.data; + const freshDataString = JSON.stringify(freshData); + + // 3. 对比并更新 + const currentDataString = JSON.stringify(this.connections); + if (currentDataString !== freshDataString) { + console.log('[ConnectionsStore] Connections data changed, updating state and cache.'); + this.connections = freshData; + localStorage.setItem(cacheKey, freshDataString); // 更新缓存 + } else { + console.log('[ConnectionsStore] Connections data is up-to-date.'); + } + this.error = null; // 清除之前的错误(如果有) } catch (err: any) { - console.error('获取连接列表失败:', err); + console.error('[ConnectionsStore] 获取连接列表失败:', err); this.error = err.response?.data?.message || err.message || '获取连接列表时发生未知错误。'; - // 如果是 401 未授权,可能需要触发重新登录逻辑 + // 保留缓存数据,仅设置错误状态 if (err.response?.status === 401) { - // TODO: 处理未授权情况,例如跳转到登录页 - console.warn('未授权,需要登录才能获取连接列表。'); + console.warn('[ConnectionsStore] 未授权,需要登录才能获取连接列表。'); + // 可能需要触发全局的未授权处理逻辑 } } finally { - this.isLoading = false; + this.isLoading = false; // 无论成功失败,最终加载完成 } }, - // 添加新连接 Action + // 添加新连接 Action (添加后应清除缓存或重新获取) // 更新参数类型以接受新的认证字段 async addConnection(newConnectionData: { name: string; @@ -70,8 +102,11 @@ export const useConnectionsStore = defineStore('connections', { this.error = null; try { const response = await apiClient.post<{ message: string; connection: ConnectionInfo }>('/connections', newConnectionData); // 使用 apiClient - // 添加成功后,将新连接添加到列表前面 (或重新获取整个列表) - this.connections.unshift(response.data.connection); + // 添加成功后,清除缓存以便下次获取最新数据 + localStorage.removeItem('connectionsCache'); + // 可以选择重新获取整个列表,或者仅在本地添加 + // this.connections.unshift(response.data.connection); // 本地添加可能导致与缓存不一致,建议重新获取 + await this.fetchConnections(); // 推荐重新获取以保证数据一致性 return true; // 表示成功 } catch (err: any) { console.error('添加连接失败:', err); @@ -102,8 +137,14 @@ export const useConnectionsStore = defineStore('connections', { // 注意:后端返回的 connection 可能不包含敏感信息,但应包含更新后的非敏感字段 this.connections[index] = { ...this.connections[index], ...response.data.connection }; } else { - // 如果本地找不到,可能需要重新获取列表 - await this.fetchConnections(); + // 如果本地找不到,fetchConnections 会处理 + // await this.fetchConnections(); // fetchConnections 内部会处理 + } + // 更新成功后,清除缓存以便下次获取最新数据 + localStorage.removeItem('connectionsCache'); + // 重新获取以确保数据同步(如果上面没有找到 index 并调用 fetchConnections) + if (index !== -1) { // 只有在本地找到并更新后才需要手动触发刷新缓存 + await this.fetchConnections(); // 重新获取以更新缓存和状态 } return true; // 表示成功 } catch (err: any) { @@ -126,8 +167,12 @@ export const useConnectionsStore = defineStore('connections', { // 发送 DELETE 请求到 /api/v1/connections/:id await apiClient.delete(`/connections/${connectionId}`); // 使用 apiClient - // 删除成功后,从本地列表中移除该连接 + // 删除成功后,清除缓存以便下次获取最新数据 + localStorage.removeItem('connectionsCache'); + // 从本地列表中移除该连接 this.connections = this.connections.filter(conn => conn.id !== connectionId); + // 可以选择重新获取,但 filter 已经更新了本地状态,下次 fetch 会自动更新缓存 + // await this.fetchConnections(); return true; // 表示成功 } catch (err: any) { console.error(`删除连接 ${connectionId} 失败:`, err); diff --git a/packages/frontend/src/stores/quickCommands.store.ts b/packages/frontend/src/stores/quickCommands.store.ts index f217ae0..a4467a1 100644 --- a/packages/frontend/src/stores/quickCommands.store.ts +++ b/packages/frontend/src/stores/quickCommands.store.ts @@ -74,29 +74,75 @@ export const useQuickCommandsStore = defineStore('quickCommands', () => { selectedIndex.value = (selectedIndex.value - 1 + commands.length) % commands.length; }; - // 从后端获取快捷指令 (带排序) + // 从后端获取快捷指令 (带缓存和排序) const fetchQuickCommands = async () => { - isLoading.value = true; - error.value = null; + const cacheKey = 'quickCommandsCache'; + // 将排序方式加入缓存键,确保不同排序有不同缓存 + const cacheKeyWithSort = `${cacheKey}_${sortBy.value}`; + error.value = null; // 重置错误 + + // 1. 尝试从 localStorage 加载缓存 try { - const response = await apiClient.get('/quick-commands', { // 使用 apiClient - params: { sortBy: sortBy.value } // 将排序参数传递给后端 + const cachedData = localStorage.getItem(cacheKeyWithSort); + if (cachedData) { + console.log(`[QuickCmdStore] Loading commands from cache (sort: ${sortBy.value}).`); + quickCommandsList.value = JSON.parse(cachedData); + isLoading.value = false; // 先显示缓存 + } else { + isLoading.value = true; // 无缓存,初始加载 + } + } catch (e) { + console.error('[QuickCmdStore] Failed to load or parse commands cache:', e); + localStorage.removeItem(cacheKeyWithSort); // 解析失败则移除缓存 + isLoading.value = true; // 缓存无效,需要加载 + } + + // 2. 后台获取最新数据 + isLoading.value = true; // 标记正在后台获取 + try { + console.log(`[QuickCmdStore] Fetching latest commands from server (sort: ${sortBy.value})...`); + const response = await apiClient.get('/quick-commands', { + params: { sortBy: sortBy.value } }); - quickCommandsList.value = response.data; + const freshData = response.data; + const freshDataString = JSON.stringify(freshData); + + // 3. 对比并更新 + const currentDataString = JSON.stringify(quickCommandsList.value); + if (currentDataString !== freshDataString) { + console.log('[QuickCmdStore] Commands data changed, updating state and cache.'); + quickCommandsList.value = freshData; + localStorage.setItem(cacheKeyWithSort, freshDataString); // 更新对应排序的缓存 + } else { + console.log('[QuickCmdStore] Commands data is up-to-date.'); + } + error.value = null; // 清除错误 } catch (err: any) { - console.error('获取快捷指令失败:', err); + console.error('[QuickCmdStore] 获取快捷指令失败:', err); error.value = err.response?.data?.message || '获取快捷指令时发生错误'; + // 保留缓存数据,仅设置错误状态 uiNotificationsStore.showError(error.value ?? '未知错误'); } finally { - isLoading.value = false; + isLoading.value = false; // 加载完成 } }; - // 添加快捷指令 + // 清除所有排序的快捷指令缓存 + const clearQuickCommandsCache = () => { + const cacheKeyBase = 'quickCommandsCache'; + // 移除两种排序的缓存 + localStorage.removeItem(`${cacheKeyBase}_name`); + localStorage.removeItem(`${cacheKeyBase}_usage_count`); + console.log('[QuickCmdStore] Cleared all quick commands caches.'); + }; + + + // 添加快捷指令 (添加后清除缓存) const addQuickCommand = async (name: string | null, command: string): Promise => { try { - await apiClient.post('/quick-commands', { name, command }); // 使用 apiClient - await fetchQuickCommands(); // 添加成功后刷新列表 + await apiClient.post('/quick-commands', { name, command }); + clearQuickCommandsCache(); // 清除所有排序缓存 + await fetchQuickCommands(); // 刷新当前排序的列表和缓存 uiNotificationsStore.showSuccess('快捷指令已添加'); return true; } catch (err: any) { @@ -110,8 +156,9 @@ export const useQuickCommandsStore = defineStore('quickCommands', () => { // 更新快捷指令 const updateQuickCommand = async (id: number, name: string | null, command: string): Promise => { try { - await apiClient.put(`/quick-commands/${id}`, { name, command }); // 使用 apiClient - await fetchQuickCommands(); // 更新成功后刷新列表 + await apiClient.put(`/quick-commands/${id}`, { name, command }); + clearQuickCommandsCache(); // 清除所有排序缓存 + await fetchQuickCommands(); // 刷新当前排序的列表和缓存 uiNotificationsStore.showSuccess('快捷指令已更新'); return true; } catch (err: any) { @@ -125,8 +172,9 @@ export const useQuickCommandsStore = defineStore('quickCommands', () => { // 删除快捷指令 const deleteQuickCommand = async (id: number) => { try { - await apiClient.delete(`/quick-commands/${id}`); // 使用 apiClient - // 从本地列表中移除,避免重新请求 + await apiClient.delete(`/quick-commands/${id}`); + clearQuickCommandsCache(); // 清除所有排序缓存 + // 从本地列表中移除 const index = quickCommandsList.value.findIndex(cmd => cmd.id === id); if (index !== -1) { quickCommandsList.value.splice(index, 1); @@ -149,7 +197,8 @@ export const useQuickCommandsStore = defineStore('quickCommands', () => { command.usage_count += 1; // 如果当前是按使用次数排序,可能需要重新排序或刷新列表 if (sortBy.value === 'usage_count') { - // 简单起见,重新获取并排序 + // 清除所有排序缓存并重新获取当前排序 + clearQuickCommandsCache(); await fetchQuickCommands(); } } @@ -169,7 +218,8 @@ export const useQuickCommandsStore = defineStore('quickCommands', () => { const setSortBy = async (newSortBy: QuickCommandSortByType) => { if (sortBy.value !== newSortBy) { sortBy.value = newSortBy; - await fetchQuickCommands(); // 排序方式改变,重新获取数据 + // 排序方式改变,不需要清除缓存,fetchQuickCommands 会读取对应排序的缓存或重新获取 + await fetchQuickCommands(); } }; diff --git a/packages/frontend/src/stores/tags.store.ts b/packages/frontend/src/stores/tags.store.ts index cfec085..a52b6b6 100644 --- a/packages/frontend/src/stores/tags.store.ts +++ b/packages/frontend/src/stores/tags.store.ts @@ -15,33 +15,65 @@ export const useTagsStore = defineStore('tags', () => { const isLoading = ref(false); const error = ref(null); - // 获取标签列表 + // 获取标签列表 (带缓存) async function fetchTags() { - isLoading.value = true; - error.value = null; + const cacheKey = 'tagsCache'; + error.value = null; // 重置错误 + + // 1. 尝试从 localStorage 加载缓存 try { - const response = await apiClient.get('/tags'); // 使用 apiClient 并移除 base URL - tags.value = response.data; - return true; + const cachedData = localStorage.getItem(cacheKey); + if (cachedData) { + console.log('[TagsStore] Loading tags from cache.'); + tags.value = JSON.parse(cachedData); + isLoading.value = false; // 先显示缓存 + } else { + isLoading.value = true; // 无缓存,初始加载 + } + } catch (e) { + console.error('[TagsStore] Failed to load or parse tags cache:', e); + localStorage.removeItem(cacheKey); // 解析失败则移除缓存 + isLoading.value = true; // 缓存无效,需要加载 + } + + // 2. 后台获取最新数据 + isLoading.value = true; // 标记正在后台获取 + try { + console.log('[TagsStore] Fetching latest tags from server...'); + const response = await apiClient.get('/tags'); + const freshData = response.data; + const freshDataString = JSON.stringify(freshData); + + // 3. 对比并更新 + const currentDataString = JSON.stringify(tags.value); + if (currentDataString !== freshDataString) { + console.log('[TagsStore] Tags data changed, updating state and cache.'); + tags.value = freshData; + localStorage.setItem(cacheKey, freshDataString); // 更新缓存 + } else { + console.log('[TagsStore] Tags data is up-to-date.'); + } + error.value = null; // 清除错误 + return true; // 表示获取成功(即使数据未变) } catch (err: any) { - console.error('Failed to fetch tags:', err); + console.error('[TagsStore] Failed to fetch tags:', err); error.value = err.response?.data?.message || err.message || '获取标签列表失败'; - return false; + // 保留缓存数据,仅设置错误状态 + return false; // 表示获取失败 } finally { - isLoading.value = false; + isLoading.value = false; // 加载完成 } } - // 添加新标签 + // 添加新标签 (添加后清除缓存) async function addTag(name: string): Promise { isLoading.value = true; error.value = null; try { const response = await apiClient.post<{ message: string, tag: TagInfo }>('/tags', { name }); // 使用 apiClient 并移除 base URL - // 添加成功后,重新获取列表以保证数据同步 (或者直接将新标签添加到 ref) - await fetchTags(); // 简单起见,重新获取 - // tags.value.push(response.data.tag); // 另一种方式 - // tags.value.sort((a, b) => a.name.localeCompare(b.name)); // 保持排序 + // 添加成功后,清除缓存并重新获取 + localStorage.removeItem('tagsCache'); + await fetchTags(); // fetchTags 会处理获取和缓存更新 return true; } catch (err: any) { console.error('Failed to add tag:', err); @@ -58,7 +90,8 @@ export const useTagsStore = defineStore('tags', () => { error.value = null; try { await apiClient.put(`/tags/${id}`, { name }); // 使用 apiClient 并移除 base URL - // 更新成功后,重新获取列表 + // 更新成功后,清除缓存并重新获取 + localStorage.removeItem('tagsCache'); await fetchTags(); return true; } catch (err: any) { @@ -76,7 +109,8 @@ export const useTagsStore = defineStore('tags', () => { error.value = null; try { await apiClient.delete(`/tags/${id}`); // 使用 apiClient 并移除 base URL - // 删除成功后,重新获取列表 + // 删除成功后,清除缓存并重新获取 + localStorage.removeItem('tagsCache'); await fetchTags(); return true; } catch (err: any) { diff --git a/packages/frontend/src/views/DashboardView.vue b/packages/frontend/src/views/DashboardView.vue index ebed3c6..c6b76fd 100644 --- a/packages/frontend/src/views/DashboardView.vue +++ b/packages/frontend/src/views/DashboardView.vue @@ -68,10 +68,12 @@ onMounted(async () => { // 加载最新的审计日志 try { // 只需要加载少量日志用于摘要,并按时间倒序 + // 调用 fetchLogs 并明确指示这是仪表盘请求以启用缓存 await auditLogStore.fetchLogs({ page: 1, - limit: maxRecentLogs, // 传递 limit - sortOrder: 'desc' // 传递 sortOrder + limit: maxRecentLogs, + sortOrder: 'desc', + isDashboardRequest: true // <--- 添加此标志 }); } catch (error) { console.error("加载审计日志失败:", error);