feat: update auto render
This commit is contained in:
180
web/static/js/api-client.js
Normal file
180
web/static/js/api-client.js
Normal file
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* 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();
|
||||
Reference in New Issue
Block a user