/** * API客户端 - 处理所有AJAX请求 */ class APIClient { constructor(baseURL = '/api') { this.baseURL = baseURL; this.defaultHeaders = { 'Content-Type': 'application/json', 'Accept': 'application/json' }; this.cache = new Map(); this.cacheTimeout = 5 * 60 * 1000; // 5分钟缓存 } /** * 获取所有数据表列表 */ async getTables() { const cacheKey = 'tables'; // 检查缓存 if (this.cache.has(cacheKey)) { const cached = this.cache.get(cacheKey); if (Date.now() - cached.timestamp < this.cacheTimeout) { return cached.data; } } const response = await fetch(`${this.baseURL}/tables`); if (!response.ok) throw new Error('Failed to fetch tables'); const data = await response.json(); this.cache.set(cacheKey, { data, timestamp: Date.now() }); return data; } /** * 获取数据表数据 * @param {string} tableAlias - 表别名 * @param {Object} params - 查询参数 */ async getTableData(tableAlias, params = {}) { const url = new URL(`${this.baseURL}/data/${tableAlias}`, window.location.origin); // 添加查询参数 Object.keys(params).forEach(key => { if (params[key] !== undefined && params[key] !== '') { url.searchParams.append(key, params[key]); } }); const cacheKey = url.toString(); // 检查缓存(搜索参数相关的缓存) if (this.cache.has(cacheKey) && !params.search) { const cached = this.cache.get(cacheKey); if (Date.now() - cached.timestamp < this.cacheTimeout) { return cached.data; } } // 使用 AbortController 支持请求取消 const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时 try { const response = await fetch(url, { signal: controller.signal, headers: this.defaultHeaders }); clearTimeout(timeoutId); if (!response.ok) throw new Error('Failed to fetch table data'); const data = await response.json(); // 缓存非搜索请求的结果 if (!params.search) { this.cache.set(cacheKey, { data, timestamp: Date.now() }); } return data; } catch (error) { clearTimeout(timeoutId); throw error; } } /** * 获取数据详情 * @param {string} tableAlias - 表别名 * @param {string|number} id - 记录ID */ async getRecordDetail(tableAlias, id) { const cacheKey = `detail:${tableAlias}:${id}`; // 检查缓存 if (this.cache.has(cacheKey)) { const cached = this.cache.get(cacheKey); if (Date.now() - cached.timestamp < this.cacheTimeout) { return cached.data; } } const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); try { const response = await fetch(`${this.baseURL}/data/${tableAlias}/detail/${id}`, { signal: controller.signal }); clearTimeout(timeoutId); if (!response.ok) throw new Error('Failed to fetch record detail'); const data = await response.json(); this.cache.set(cacheKey, { data, timestamp: Date.now() }); return data; } catch (error) { clearTimeout(timeoutId); throw error; } } /** * 获取可用模板列表 * @param {string} tableName - 表名 */ async getAvailableTemplates(tableName) { const cacheKey = `templates:${tableName}`; // 检查缓存 if (this.cache.has(cacheKey)) { const cached = this.cache.get(cacheKey); if (Date.now() - cached.timestamp < this.cacheTimeout) { return cached.data; } } const response = await fetch(`/api/templates/${tableName}/available`); if (!response.ok) throw new Error('Failed to fetch templates'); const data = await response.json(); this.cache.set(cacheKey, { data, timestamp: Date.now() }); return data; } /** * 验证模板 * @param {string} tableName - 表名 * @param {string} templateType - 模板类型 */ async validateTemplate(tableName, templateType) { const response = await fetch(`/api/templates/${tableName}/validate?type=${templateType}`); return response.json(); } /** * 获取模板预览 * @param {string} tableName - 表名 * @param {string} templateType - 模板类型 */ async getTemplatePreview(tableName, templateType) { const response = await fetch(`/api/templates/${tableName}/preview?type=${templateType}`); if (!response.ok) throw new Error('Failed to fetch template preview'); return response.text(); } /** * 清空缓存 */ clearCache() { this.cache.clear(); } } // 全局API客户端实例 window.apiClient = new APIClient();