fix: 修复前端多个 bug
1. 版本号闪烁问题 - 将版本信息缓存到 Pinia store,避免每次路由切换都重新请求 - 添加加载占位符,版本为空时显示骨架屏 2. 管理员登录跳转问题 - 管理员登录后现在正确跳转到 /admin/dashboard - 普通用户仍跳转到 /dashboard 3. Dashboard 页面空白报错 - 修复 API 返回 null 时访问 .length 导致的 TypeError - 为 computed 属性添加可选链操作符保护 - 为数据赋值添加空数组默认值
This commit is contained in:
@@ -6,14 +6,24 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref, computed } from 'vue';
|
||||
import type { Toast, ToastType } from '@/types';
|
||||
import { checkUpdates as checkUpdatesAPI, type VersionInfo, type ReleaseInfo } from '@/api/admin/system';
|
||||
|
||||
export const useAppStore = defineStore('app', () => {
|
||||
// ==================== State ====================
|
||||
|
||||
|
||||
const sidebarCollapsed = ref<boolean>(false);
|
||||
const loading = ref<boolean>(false);
|
||||
const toasts = ref<Toast[]>([]);
|
||||
|
||||
// Version cache state
|
||||
const versionLoaded = ref<boolean>(false);
|
||||
const versionLoading = ref<boolean>(false);
|
||||
const currentVersion = ref<string>('');
|
||||
const latestVersion = ref<string>('');
|
||||
const hasUpdate = ref<boolean>(false);
|
||||
const buildType = ref<string>('source');
|
||||
const releaseInfo = ref<ReleaseInfo | null>(null);
|
||||
|
||||
// Auto-incrementing ID for toasts
|
||||
let toastIdCounter = 0;
|
||||
|
||||
@@ -192,6 +202,56 @@ export const useAppStore = defineStore('app', () => {
|
||||
toasts.value = [];
|
||||
}
|
||||
|
||||
// ==================== Version Management ====================
|
||||
|
||||
/**
|
||||
* Fetch version info (uses cache unless force=true)
|
||||
* @param force - Force refresh from API
|
||||
*/
|
||||
async function fetchVersion(force = false): Promise<VersionInfo | null> {
|
||||
// Return cached data if available and not forcing refresh
|
||||
if (versionLoaded.value && !force) {
|
||||
return {
|
||||
current_version: currentVersion.value,
|
||||
latest_version: latestVersion.value,
|
||||
has_update: hasUpdate.value,
|
||||
build_type: buildType.value,
|
||||
release_info: releaseInfo.value || undefined,
|
||||
cached: true,
|
||||
};
|
||||
}
|
||||
|
||||
// Prevent duplicate requests
|
||||
if (versionLoading.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
versionLoading.value = true;
|
||||
try {
|
||||
const data = await checkUpdatesAPI(force);
|
||||
currentVersion.value = data.current_version;
|
||||
latestVersion.value = data.latest_version;
|
||||
hasUpdate.value = data.has_update;
|
||||
buildType.value = data.build_type || 'source';
|
||||
releaseInfo.value = data.release_info || null;
|
||||
versionLoaded.value = true;
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch version:', error);
|
||||
return null;
|
||||
} finally {
|
||||
versionLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear version cache (e.g., after update)
|
||||
*/
|
||||
function clearVersionCache(): void {
|
||||
versionLoaded.value = false;
|
||||
hasUpdate.value = false;
|
||||
}
|
||||
|
||||
// ==================== Return Store API ====================
|
||||
|
||||
return {
|
||||
@@ -199,10 +259,19 @@ export const useAppStore = defineStore('app', () => {
|
||||
sidebarCollapsed,
|
||||
loading,
|
||||
toasts,
|
||||
|
||||
|
||||
// Version state
|
||||
versionLoaded,
|
||||
versionLoading,
|
||||
currentVersion,
|
||||
latestVersion,
|
||||
hasUpdate,
|
||||
buildType,
|
||||
releaseInfo,
|
||||
|
||||
// Computed
|
||||
hasActiveToasts,
|
||||
|
||||
|
||||
// Actions
|
||||
toggleSidebar,
|
||||
setSidebarCollapsed,
|
||||
@@ -217,5 +286,9 @@ export const useAppStore = defineStore('app', () => {
|
||||
withLoading,
|
||||
withLoadingAndError,
|
||||
reset,
|
||||
|
||||
// Version actions
|
||||
fetchVersion,
|
||||
clearVersionCache,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user