feat: update auto render
This commit is contained in:
162
web/templates/builtin/layout.html
Normal file
162
web/templates/builtin/layout.html
Normal file
@@ -0,0 +1,162 @@
|
||||
{{define "layout"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{.Title}} - 数据管理</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<style>
|
||||
.tag {
|
||||
@apply inline-block px-2 py-1 text-xs font-medium rounded-full;
|
||||
}
|
||||
.modal {
|
||||
@apply fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden;
|
||||
}
|
||||
.modal-content {
|
||||
@apply bg-white rounded-lg max-w-4xl w-full mx-4 max-h-[80vh] overflow-y-auto;
|
||||
}
|
||||
.loading {
|
||||
@apply animate-pulse bg-gray-200 rounded;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-50">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<!-- 表选择器 -->
|
||||
<div class="mb-6">
|
||||
<select id="tableSelector" class="border rounded px-3 py-2" onchange="changeTable(this.value)">
|
||||
<option value="">选择数据表...</option>
|
||||
{{range .Tables}}
|
||||
<option value="{{.Alias}}" {{if eq .Alias $.CurrentTable}}selected{{end}}>
|
||||
{{.Alias}}
|
||||
</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- 主要内容区域 -->
|
||||
<div id="mainContent">
|
||||
{{template "content" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 详情弹窗 -->
|
||||
<div id="detailModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="p-6">
|
||||
<h3 class="text-lg font-medium mb-4">详情信息</h3>
|
||||
<div id="detailContent"></div>
|
||||
<div class="mt-4 flex justify-end">
|
||||
<button onclick="closeModal()" class="px-4 py-2 bg-gray-300 rounded">
|
||||
关闭
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 通用JavaScript -->
|
||||
<script>
|
||||
// 全局配置
|
||||
const CONFIG = {
|
||||
apiBase: '/api',
|
||||
templates: {
|
||||
builtin: '/templates/builtin',
|
||||
custom: '/templates/custom'
|
||||
}
|
||||
};
|
||||
|
||||
// 模板系统核心
|
||||
class TemplateSystem {
|
||||
static async loadTemplate(path) {
|
||||
const response = await fetch(path);
|
||||
return response.text();
|
||||
}
|
||||
|
||||
static async render(data, templateName, tableName) {
|
||||
// 优先使用自定义模板,回退到默认模板
|
||||
const customPath = `${CONFIG.templates.custom}/${tableName}/${templateName}.html`;
|
||||
const defaultPath = `${CONFIG.templates.builtin}/${templateName}.html`;
|
||||
|
||||
try {
|
||||
return await this.loadTemplate(customPath);
|
||||
} catch {
|
||||
return await this.loadTemplate(defaultPath);
|
||||
}
|
||||
}
|
||||
|
||||
static async renderField(value, type, column) {
|
||||
const fieldMap = {
|
||||
'raw': v => v,
|
||||
'time': v => new Date(v).toLocaleString('zh-CN'),
|
||||
'tag': (v, col) => {
|
||||
const tag = col.values[v];
|
||||
return tag ? `<span class="tag" style="background-color: ${tag.color}; color: white;">${tag.label}</span>` : v;
|
||||
},
|
||||
'markdown': v => marked.parse(v || ''),
|
||||
'category': v => v
|
||||
};
|
||||
|
||||
return fieldMap[type]?.(value, column) || value;
|
||||
}
|
||||
}
|
||||
|
||||
// 数据加载器
|
||||
class DataLoader {
|
||||
static async loadTableData(tableAlias, page = 1, perPage = 20, search = '', sort = '', order = 'desc') {
|
||||
const params = new URLSearchParams({
|
||||
page,
|
||||
per_page: perPage,
|
||||
search,
|
||||
sort,
|
||||
order
|
||||
});
|
||||
|
||||
const response = await fetch(`${CONFIG.apiBase}/data/${tableAlias}?${params}`);
|
||||
return response.json();
|
||||
}
|
||||
|
||||
static async loadTableDetail(tableAlias, id) {
|
||||
const response = await fetch(`${CONFIG.apiBase}/data/${tableAlias}/detail/${id}`);
|
||||
return response.json();
|
||||
}
|
||||
}
|
||||
|
||||
// 通用函数
|
||||
function changeTable(tableAlias) {
|
||||
if (!tableAlias) return;
|
||||
window.location.href = `/?table=${tableAlias}&page=1`;
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
document.getElementById('detailModal').classList.add('hidden');
|
||||
}
|
||||
|
||||
function showLoading() {
|
||||
document.getElementById('mainContent').innerHTML =
|
||||
'<div class="text-center py-8"><div class="loading h-4 w-32 mx-auto"></div></div>';
|
||||
}
|
||||
|
||||
// 初始化
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// 绑定全局事件
|
||||
window.closeModal = closeModal;
|
||||
window.changeTable = changeTable;
|
||||
window.TemplateSystem = TemplateSystem;
|
||||
window.DataLoader = DataLoader;
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- 页面特定内容占位符 -->
|
||||
{{template "scripts" .}}
|
||||
|
||||
<!-- 性能监控JS -->
|
||||
<script src="/static/js/performance-monitor.js"></script>
|
||||
<script src="/static/js/api-client.js"></script>
|
||||
<script src="/static/js/template-engine.js"></script>
|
||||
<script src="/static/js/ui-controller.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user