Files
ylt_diy/templates/index.html
user9994793890 9debeb12b5 fix: 修复历史记录加载问题
问题:历史记录一直显示"加载中..."

原因:
- switchTab 函数中使用了 event.target
- 在某些情况下 event 对象未定义
- 导致JavaScript错误,整个脚本停止执行

修复:
- 添加 event 参数到 switchTab 函数
- 检查 event 和 event.target 是否存在
- 避免JavaScript错误中断执行

现在历史记录应该能正常加载了。

Coze-Commit-Type: user
Coze-User-ID: 3722323274763196
Coze-Conversation-ID: 9894087
2026-07-10 10:37:33 +08:00

1013 lines
36 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>订单日报系统</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
background: #f5f7fa;
color: #333;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
h1 {
text-align: center;
margin-bottom: 30px;
color: #2c3e50;
}
.tabs {
display: flex;
border-bottom: 2px solid #e1e8ed;
margin-bottom: 20px;
}
.tab {
padding: 12px 24px;
cursor: pointer;
border: none;
background: none;
font-size: 16px;
color: #666;
transition: all 0.3s;
}
.tab:hover {
color: #3498db;
}
.tab.active {
color: #3498db;
border-bottom: 2px solid #3498db;
margin-bottom: -2px;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.card {
background: white;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 500;
color: #555;
}
.form-control {
width: 100%;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.form-control:focus {
outline: none;
border-color: #3498db;
}
select {
background: white;
}
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s;
}
.btn-primary {
background: #3498db;
color: white;
}
.btn-primary:hover {
background: #2980b9;
}
.btn-success {
background: #27ae60;
color: white;
}
.btn-success:hover {
background: #229954;
}
.btn-danger {
background: #e74c3c;
color: white;
}
.btn-danger:hover {
background: #c0392b;
}
.btn-warning {
background: #f39c12;
color: white;
}
.btn-warning:hover {
background: #d35400;
}
.btn-sm {
padding: 4px 8px;
font-size: 12px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #e1e8ed;
}
th {
background: #f8f9fa;
font-weight: 600;
color: #555;
}
tr:hover {
background: #f8f9fa;
}
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 10px;
max-height: 300px;
overflow-y: auto;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
.checkbox-item {
display: flex;
align-items: center;
gap: 5px;
min-width: 200px;
}
.status-badge {
display: inline-block;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: 500;
}
.status-active {
background: #d4edda;
color: #155724;
}
.status-inactive {
background: #f8d7da;
color: #721c24;
}
.alert {
padding: 12px 16px;
border-radius: 4px;
margin-bottom: 15px;
}
.alert-success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.alert-error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.alert-info {
background: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
.loading {
text-align: center;
padding: 20px;
color: #666;
}
.empty {
text-align: center;
padding: 40px;
color: #999;
}
.action-buttons {
display: flex;
gap: 5px;
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 1000;
}
.modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
background: white;
border-radius: 8px;
padding: 30px;
max-width: 800px;
width: 90%;
max-height: 90vh;
overflow-y: auto;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.modal-title {
font-size: 20px;
font-weight: 600;
}
.close-btn {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
color: #999;
}
.close-btn:hover {
color: #333;
}
.pagination {
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
margin-top: 20px;
}
.pagination button {
padding: 6px 12px;
border: 1px solid #ddd;
background: white;
cursor: pointer;
border-radius: 4px;
}
.pagination button:hover:not(:disabled) {
background: #f0f0f0;
}
.pagination button:disabled {
cursor: not-allowed;
opacity: 0.5;
}
.pagination span {
color: #666;
}
</style>
</head>
<body>
<div class="container">
<h1>订单日报系统</h1>
<div class="tabs">
<button class="tab active" onclick="switchTab('config')">配置管理</button>
<button class="tab" onclick="switchTab('generate')">日报生成</button>
<button class="tab" onclick="switchTab('history')">历史记录</button>
</div>
<!-- 配置管理 -->
<div id="config-tab" class="tab-content active">
<div class="card">
<button class="btn btn-primary" onclick="showCreateModal()">创建配置</button>
</div>
<div class="card">
<table>
<thead>
<tr>
<th>配置名称</th>
<th>拆分方式</th>
<th>拆分值</th>
<th>字段数</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody id="config-list">
<tr><td colspan="6" class="loading">加载中...</td></tr>
</tbody>
</table>
</div>
</div>
<!-- 日报生成 -->
<div id="generate-tab" class="tab-content">
<div class="card">
<div class="alert alert-info" style="margin-bottom: 20px;">
<strong>💡 使用说明:</strong><br>
1. 选择已创建的配置<br>
2. 选择时间范围(可点击预设按钮快速选择)<br>
3. 点击"生成日报"按钮<br>
4. 生成成功后,点击"立即下载Excel文件"按钮下载,或切换到"历史记录"标签页查看和下载
</div>
<h3 style="margin-bottom: 20px;">生成日报</h3>
<div class="form-group">
<label>选择配置 *</label>
<select id="generate-config" class="form-control">
<option value="">请选择配置</option>
</select>
</div>
<div class="form-group">
<label>时间范围</label>
<div style="display: flex; gap: 10px; margin-bottom: 10px;">
<button class="btn btn-sm btn-primary" onclick="setPresetTime('yesterday')">昨天</button>
<button class="btn btn-sm btn-primary" onclick="setPresetTime('last3days')">最近3天</button>
<button class="btn btn-sm btn-primary" onclick="setPresetTime('last7days')">最近7天</button>
</div>
<div style="display: flex; gap: 10px;">
<div style="flex: 1;">
<input type="datetime-local" id="start-time" class="form-control">
</div>
<div style="flex: 1;">
<input type="datetime-local" id="end-time" class="form-control">
</div>
</div>
</div>
<button class="btn btn-success" onclick="generateReport()">生成日报</button>
<div id="generate-result" style="margin-top: 20px;"></div>
</div>
</div>
<!-- 历史记录 -->
<div id="history-tab" class="tab-content">
<div class="card">
<button class="btn btn-primary" onclick="refreshHistory()">刷新</button>
</div>
<div class="card">
<table>
<thead>
<tr>
<th>报表日期</th>
<th>时间范围</th>
<th>配置名称</th>
<th>拆分值</th>
<th>订单数</th>
<th>总金额</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody id="history-list">
<tr><td colspan="8" class="loading">加载中...</td></tr>
</tbody>
</table>
<div class="pagination" id="pagination"></div>
</div>
</div>
</div>
<!-- 创建/编辑配置模态框 -->
<div id="config-modal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="modal-title">创建配置</h3>
<button class="close-btn" onclick="closeModal()">&times;</button>
</div>
<div class="form-group">
<label>配置名称 *</label>
<input type="text" id="config-name" class="form-control" placeholder="请输入配置名称">
</div>
<div class="form-group">
<label>拆分方式 *</label>
<select id="split-type" class="form-control" onchange="loadEntities()">
<option value="">请选择拆分方式</option>
<option value="company_id">按企业ID</option>
<option value="user_id">按用户ID</option>
</select>
</div>
<div class="form-group">
<label>选择企业/用户 *</label>
<select id="split-value" class="form-control">
<option value="">请先选择拆分方式</option>
</select>
</div>
<div class="form-group">
<label>选择字段 *</label>
<div class="checkbox-group" id="fields-list">
<div class="loading">加载中...</div>
</div>
</div>
<div class="form-group">
<label>求和字段(可选)</label>
<div class="checkbox-group" id="sum-fields-list">
<div class="loading">加载中...</div>
</div>
</div>
<div style="display: flex; gap: 10px; justify-content: flex-end;">
<button class="btn" onclick="closeModal()">取消</button>
<button class="btn btn-primary" onclick="saveConfig()">保存</button>
</div>
</div>
</div>
<script>
let editingConfigId = null;
let allFields = [];
let currentPage = 1;
const pageSize = 20;
// 切换标签页
function switchTab(tabName, event) {
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(t => t.classList.remove('active'));
if (event && event.target) {
event.target.classList.add('active');
}
document.getElementById(`${tabName}-tab`).classList.add('active');
if (tabName === 'config') {
loadConfigs();
} else if (tabName === 'generate') {
loadGenerateConfigs();
} else if (tabName === 'history') {
loadHistory();
}
}
// 加载配置列表
async function loadConfigs() {
try {
const response = await fetch('/api/config');
const result = await response.json();
if (result.success) {
renderConfigList(result.data);
} else {
alert('加载配置失败: ' + result.message);
}
} catch (error) {
alert('加载配置失败: ' + error.message);
}
}
// 渲染配置列表
function renderConfigList(configs) {
const tbody = document.getElementById('config-list');
if (configs.length === 0) {
tbody.innerHTML = '<tr><td colspan="6" class="empty">暂无配置,请点击"创建配置"按钮</td></tr>';
return;
}
tbody.innerHTML = configs.map(config => `
<tr>
<td>${config.config_name}</td>
<td>${config.split_type === 'company_id' ? '按企业ID' : '按用户ID'}</td>
<td>${config.split_name || config.split_value}</td>
<td>${config.selected_fields.length}</td>
<td>
<span class="status-badge ${config.is_active ? 'status-active' : 'status-inactive'}">
${config.is_active ? '已启用' : '已禁用'}
</span>
</td>
<td>
<div class="action-buttons">
<button class="btn btn-sm btn-warning" onclick="toggleConfig(${config.id})">
${config.is_active ? '禁用' : '启用'}
</button>
<button class="btn btn-sm btn-primary" onclick="editConfig(${config.id})">编辑</button>
<button class="btn btn-sm btn-danger" onclick="deleteConfig(${config.id})">删除</button>
<button class="btn btn-sm" onclick="moveConfig(${config.id}, 'up')">↑</button>
<button class="btn btn-sm" onclick="moveConfig(${config.id}, 'down')">↓</button>
</div>
</td>
</tr>
`).join('');
}
// 显示创建模态框
function showCreateModal() {
editingConfigId = null;
document.getElementById('modal-title').textContent = '创建配置';
document.getElementById('config-name').value = '';
document.getElementById('split-type').value = '';
document.getElementById('split-value').innerHTML = '<option value="">请先选择拆分方式</option>';
loadFields();
document.getElementById('config-modal').classList.add('active');
}
// 加载字段列表
async function loadFields() {
try {
const response = await fetch('/api/fields');
const result = await response.json();
if (result.success) {
allFields = result.data;
renderFields();
}
} catch (error) {
console.error('加载字段失败:', error);
}
}
// 渲染字段列表
function renderFields(selectedFields = [], sumFields = []) {
const fieldsList = document.getElementById('fields-list');
const sumFieldsList = document.getElementById('sum-fields-list');
fieldsList.innerHTML = allFields.map(field => `
<label class="checkbox-item">
<input type="checkbox" value="${field.field}"
${selectedFields.includes(field.field) ? 'checked' : ''}>
${field.display}
</label>
`).join('');
sumFieldsList.innerHTML = allFields.map(field => `
<label class="checkbox-item">
<input type="checkbox" value="${field.field}"
${sumFields.includes(field.field) ? 'checked' : ''}>
${field.display}
</label>
`).join('');
}
// 加载企业/用户列表
async function loadEntities() {
const splitType = document.getElementById('split-type').value;
const select = document.getElementById('split-value');
if (!splitType) {
select.innerHTML = '<option value="">请先选择拆分方式</option>';
return;
}
select.innerHTML = '<option value="">加载中...</option>';
try {
const response = await fetch(`/api/entities?type=${splitType === 'company_id' ? 'company' : 'user'}`);
const result = await response.json();
if (result.success) {
const entities = result.data;
select.innerHTML = '<option value="">请选择</option>' +
entities.map(e => {
const value = splitType === 'company_id' ? e.company_id : e.user_id;
const name = splitType === 'company_id' ? e.company_name : e.user_name;
const type = e.order_type === 3 ? '(企业用户)' : '(普通用户)';
return `<option value="${value}" data-name="${name}">${name} ${splitType === 'user_id' ? type : ''}</option>`;
}).join('');
}
} catch (error) {
console.error('加载列表失败:', error);
}
}
// 保存配置
async function saveConfig() {
const configName = document.getElementById('config-name').value;
const splitType = document.getElementById('split-type').value;
const splitValueSelect = document.getElementById('split-value');
const splitValue = splitValueSelect.value;
const splitName = splitValueSelect.options[splitValueSelect.selectedIndex].dataset.name || '';
const selectedFields = Array.from(document.querySelectorAll('#fields-list input:checked')).map(cb => cb.value);
const sumFields = Array.from(document.querySelectorAll('#sum-fields-list input:checked')).map(cb => cb.value);
if (!configName || !splitType || !splitValue) {
alert('请填写所有必填字段');
return;
}
if (selectedFields.length === 0) {
alert('请至少选择一个字段');
return;
}
const data = {
config_name: configName,
split_type: splitType,
split_value: splitValue,
split_name: splitName,
selected_fields: selectedFields,
sum_fields: sumFields
};
try {
let response;
if (editingConfigId) {
response = await fetch(`/api/config/${editingConfigId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
} else {
response = await fetch('/api/config', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
}
const result = await response.json();
if (result.success) {
alert(editingConfigId ? '配置更新成功' : '配置创建成功');
closeModal();
loadConfigs();
} else {
alert('保存失败: ' + result.message);
}
} catch (error) {
alert('保存失败: ' + error.message);
}
}
// 编辑配置
async function editConfig(configId) {
try {
const response = await fetch('/api/config');
const result = await response.json();
if (result.success) {
const config = result.data.find(c => c.id === configId);
if (config) {
editingConfigId = configId;
document.getElementById('modal-title').textContent = '编辑配置';
document.getElementById('config-name').value = config.config_name;
document.getElementById('split-type').value = config.split_type;
await loadEntities();
document.getElementById('split-value').value = config.split_value;
await loadFields();
renderFields(config.selected_fields, config.sum_fields);
document.getElementById('config-modal').classList.add('active');
}
}
} catch (error) {
alert('加载配置失败: ' + error.message);
}
}
// 删除配置
async function deleteConfig(configId) {
if (!confirm('确定要删除这个配置吗?')) {
return;
}
try {
const response = await fetch(`/api/config/${configId}`, {
method: 'DELETE'
});
const result = await response.json();
if (result.success) {
alert('配置删除成功');
loadConfigs();
} else {
alert('删除失败: ' + result.message);
}
} catch (error) {
alert('删除失败: ' + error.message);
}
}
// 启用/禁用配置
async function toggleConfig(configId) {
try {
const response = await fetch(`/api/config/${configId}/toggle`, {
method: 'POST'
});
const result = await response.json();
if (result.success) {
loadConfigs();
} else {
alert('操作失败: ' + result.message);
}
} catch (error) {
alert('操作失败: ' + error.message);
}
}
// 移动配置
async function moveConfig(configId, direction) {
try {
const response = await fetch(`/api/config/${configId}/move`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ direction })
});
const result = await response.json();
if (result.success) {
loadConfigs();
} else {
alert('移动失败: ' + result.message);
}
} catch (error) {
alert('移动失败: ' + error.message);
}
}
// 关闭模态框
function closeModal() {
document.getElementById('config-modal').classList.remove('active');
}
// 加载生成配置列表
async function loadGenerateConfigs() {
try {
const response = await fetch('/api/config');
const result = await response.json();
if (result.success) {
const select = document.getElementById('generate-config');
select.innerHTML = '<option value="">请选择配置</option>' +
result.data.map(c => `<option value="${c.id}">${c.config_name}</option>`).join('');
}
} catch (error) {
console.error('加载配置失败:', error);
}
}
// 设置预设时间
function setPresetTime(preset) {
const now = new Date();
let start, end;
if (preset === 'yesterday') {
end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 0, 0);
start = new Date(end.getTime() - 24 * 60 * 60 * 1000);
} else if (preset === 'last3days') {
end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 0, 0);
start = new Date(end.getTime() - 3 * 24 * 60 * 60 * 1000);
} else if (preset === 'last7days') {
end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 0, 0);
start = new Date(end.getTime() - 7 * 24 * 60 * 60 * 1000);
}
document.getElementById('start-time').value = formatDateTimeLocal(start);
document.getElementById('end-time').value = formatDateTimeLocal(end);
}
// 格式化日期时间
function formatDateTimeLocal(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day}T${hours}:${minutes}`;
}
// 生成日报
async function generateReport() {
const configId = document.getElementById('generate-config').value;
const startTime = document.getElementById('start-time').value;
const endTime = document.getElementById('end-time').value;
if (!configId) {
alert('请选择配置');
return;
}
if (!startTime || !endTime) {
alert('请选择时间范围');
return;
}
const resultDiv = document.getElementById('generate-result');
resultDiv.innerHTML = '<div class="alert alert-info">正在生成日报,请稍候...</div>';
try {
const response = await fetch('/api/report/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
config_id: parseInt(configId),
start_time: startTime.replace('T', ' ') + ':00',
end_time: endTime.replace('T', ' ') + ':00'
})
});
const result = await response.json();
if (result.success) {
resultDiv.innerHTML = `
<div class="alert alert-success">
<strong>✓ 日报生成成功!</strong><br><br>
<div style="margin-left: 20px;">
<strong>统计信息:</strong><br>
• 订单数量: ${result.total_orders} 条<br>
• 总金额: ¥${result.total_amount.toFixed(2)}<br>
${result.sum_results && Object.keys(result.sum_results).length > 0 ?
'<strong>求和结果:</strong><br>' +
Object.entries(result.sum_results).map(([field, value]) =>
`• ${field}: ${typeof value === 'number' ? value.toFixed(2) : value}`
).join('<br>')
: ''}
</div>
<br>
<div style="display: flex; gap: 10px; margin-top: 15px;">
<a href="/api/download?path=${result.file_path}" target="_blank" class="btn btn-success">
📥 立即下载Excel文件
</a>
<button class="btn btn-primary" onclick="switchTab('history'); document.querySelectorAll('.tab')[2].click();">
📋 查看历史记录
</button>
</div>
<br>
<div style="font-size: 12px; color: #666; margin-top: 10px;">
💡 提示:生成的日报也会保存在"历史记录"标签页中,可以随时下载。
</div>
</div>
`;
} else {
resultDiv.innerHTML = `
<div class="alert alert-error">
<strong>✗ 生成失败</strong><br><br>
<strong>错误信息:</strong><br>
${result.message}<br><br>
<strong>可能的原因:</strong><br>
• 选择的时间范围内没有符合条件的订单<br>
• 数据库连接失败<br>
• 配置信息有误<br><br>
<strong>建议:</strong><br>
• 检查时间范围是否正确<br>
• 确认配置中的企业/用户是否有订单数据<br>
• 查看服务器日志获取详细错误信息
</div>
`;
}
} catch (error) {
resultDiv.innerHTML = `<div class="alert alert-error">生成失败: ${error.message}</div>`;
}
}
// 加载历史记录
async function loadHistory(page = 1) {
currentPage = page;
try {
const response = await fetch(`/api/report/history?page=${page}&page_size=${pageSize}`);
const result = await response.json();
if (result.success) {
renderHistory(result.data.list);
renderPagination(result.data.total, page);
}
} catch (error) {
console.error('加载历史记录失败:', error);
}
}
// 渲染历史记录
function renderHistory(history) {
const tbody = document.getElementById('history-list');
if (history.length === 0) {
tbody.innerHTML = '<tr><td colspan="8" class="empty">暂无历史记录<br><br>生成日报后,记录会显示在这里</td></tr>';
return;
}
tbody.innerHTML = history.map(item => {
// 调试信息
console.log('历史记录项:', item);
console.log(' status:', item.status, '类型:', typeof item.status);
console.log(' file_path:', item.file_path, '类型:', typeof item.file_path);
console.log(' 是否有文件:', !!(item.status === 1 && item.file_path));
const hasFile = item.status === 1 && item.file_path && item.file_path.trim() !== '';
return `
<tr>
<td>${item.report_date}</td>
<td style="font-size: 12px;">${item.start_time || '-'}<br>至<br>${item.end_time || '-'}</td>
<td>${item.config_name || '-'}</td>
<td>${item.split_name || item.split_value}</td>
<td><strong>${item.total_orders}</strong></td>
<td><strong>¥${(item.total_amount || 0).toFixed(2)}</strong></td>
<td>
<span class="status-badge ${item.status === 1 ? 'status-active' : 'status-inactive'}">
${item.status === 1 ? '✓ 成功' : '✗ 失败'}
</span>
</td>
<td>
${hasFile ?
`<a href="/api/download?path=${encodeURIComponent(item.file_path)}" target="_blank" class="btn btn-sm btn-success">📥 下载</a>` :
`<span style="color: #999;" title="文件路径: ${item.file_path || '无'}">-</span>`}
</td>
</tr>
`}).join('');
}
// 渲染分页
function renderPagination(total, currentPage) {
const totalPages = Math.ceil(total / pageSize);
const pagination = document.getElementById('pagination');
if (totalPages <= 1) {
pagination.innerHTML = '';
return;
}
pagination.innerHTML = `
<button ${currentPage === 1 ? 'disabled' : ''} onclick="loadHistory(${currentPage - 1})">上一页</button>
<span>第 ${currentPage} / ${totalPages} 页,共 ${total} 条</span>
<button ${currentPage === totalPages ? 'disabled' : ''} onclick="loadHistory(${currentPage + 1})">下一页</button>
`;
}
// 刷新历史记录
function refreshHistory() {
loadHistory(currentPage);
}
// 初始化
loadConfigs();
loadFields();
</script>
</body>
</html>