Initial commit

This commit is contained in:
XOF
2025-11-20 12:12:26 +08:00
commit 179a58b55a
169 changed files with 64463 additions and 0 deletions

65
web/static/js/api.js Normal file
View File

@@ -0,0 +1,65 @@
// 全局Promise缓存现在被封装在模块作用域内不再污染全局
const apiPromiseCache = new Map();
/**
* 具备缓存、认证处理和自动JSON解析的apiFetch函数
*/
export async function apiFetch(url, options = {}) {
// [修正] 不再使用 window.apiPromiseCache
if (apiPromiseCache.has(url) && !options.noCache) {
return apiPromiseCache.get(url);
}
const token = localStorage.getItem('bearerToken');
const headers = {
'Content-Type': 'application/json',
...options.headers,
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const requestPromise = fetch(url, {
...options,
headers,
}).then(response => {
if (response.status === 401) {
apiPromiseCache.delete(url);
localStorage.removeItem('bearerToken');
if (window.location.pathname !== '/login') {
window.location.href = '/login?error=会话已过期,请重新登录。';
}
throw new Error('Unauthorized');
}
if (!response.ok) {
throw new Error(`API请求失败: ${response.status}`);
}
return response;
});
apiPromiseCache.set(url, requestPromise);
return requestPromise;
}
/**
* 更安全的apiFetch包装器直接返回解析后的JSON数据
*/
export async function apiFetchJson(url, options = {}) {
const response = await apiFetch(url, options);
return response.clone().json();
}
export async function fetchVersionInfo() {
console.log("Placeholder for fetchVersionInfo function.");
// 示例: 如果您有一个/version的API端点
/*
fetch('/version')
.then(res => res.json())
.then(data => {
const versionElement = document.getElementById('system-version');
if (versionElement) {
versionElement.textContent = data.version || 'N/A';
}
});
*/
}