update
This commit is contained in:
@@ -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<string, any> = {
|
||||
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<AuditLogApiResponse>('/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<AuditLogApiResponse>('/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
|
||||
|
||||
@@ -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<CommandHistoryEntryBE[]>('/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<CommandHistoryEntryBE[]>('/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);
|
||||
|
||||
@@ -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<ConnectionInfo[]>('/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<ConnectionInfo[]>('/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);
|
||||
|
||||
@@ -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<QuickCommandFE[]>('/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<QuickCommandFE[]>('/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<boolean> => {
|
||||
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<boolean> => {
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -15,33 +15,65 @@ export const useTagsStore = defineStore('tags', () => {
|
||||
const isLoading = ref(false);
|
||||
const error = ref<string | null>(null);
|
||||
|
||||
// 获取标签列表
|
||||
// 获取标签列表 (带缓存)
|
||||
async function fetchTags() {
|
||||
isLoading.value = true;
|
||||
error.value = null;
|
||||
const cacheKey = 'tagsCache';
|
||||
error.value = null; // 重置错误
|
||||
|
||||
// 1. 尝试从 localStorage 加载缓存
|
||||
try {
|
||||
const response = await apiClient.get<TagInfo[]>('/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<TagInfo[]>('/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<boolean> {
|
||||
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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user