let historyStartDate = '';
let historyEndDate = '';
let historyStatus = '';
let historyPageSize = 10;
// 每页显示条数变化
function onHistoryPageSizeChange() {
historyPageSize = parseInt(document.getElementById('history-page-size').value) || 10;
loadHistoryWithDate(1);
}
// 状态筛选变化
function onHistoryStatusChange() {
historyStatus = document.getElementById('history-status-filter').value;
loadHistoryWithDate(1);
}
// 批量下载历史记录
async function batchDownloadHistory() {
const checkboxes = document.querySelectorAll('.history-checkbox:checked');
if (checkboxes.length === 0) {
alert('请至少选择一条记录');
return;
}
const ids = Array.from(checkboxes).map(cb => parseInt(cb.value));
// 检查是否有生成失败的记录
const failedCount = Array.from(checkboxes).filter(cb => cb.dataset.status !== '1').length;
const successCount = checkboxes.length - failedCount;
if (successCount === 0) {
alert('选中的记录都是生成失败的,无法下载');
return;
}
if (failedCount > 0) {
if (!confirm(`选中的 ${checkboxes.length} 条记录中有 ${failedCount} 条是生成失败的,无法下载。\n是否打包下载成功的 ${successCount} 条?`)) {
return;
}
}
try {
const response = await fetch('/api/download/batch', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ids: ids })
});
if (response.ok) {
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
const timestamp = new Date().toISOString().slice(0, 19).replace(/[-T:]/g, '');
a.download = `批量下载_${timestamp}.zip`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
} else {
try {
const result = await response.json();
alert('下载失败: ' + (result.message || '未知错误'));
} catch (e) {
alert('下载失败: 服务器返回错误');
}
}
} catch (error) {
alert('下载失败: ' + error.message);
}
}
// 按日期查询
function queryHistoryByDate() {
const startDate = document.getElementById('history-start-date').value;
const endDate = document.getElementById('history-end-date').value;
historyStartDate = startDate;
historyEndDate = endDate;
loadHistoryWithDate(1);
}
// 清除筛选
function clearHistoryFilter() {
document.getElementById('history-status-filter').value = '';
document.getElementById('history-start-date').value = '';
document.getElementById('history-end-date').value = '';
historyStatus = '';
historyStartDate = '';
historyEndDate = '';
loadHistory(1);
}
// 带日期参数加载历史记录
// 渲染历史记录列表
function renderHistory(list) {
const tbody = document.getElementById('history-list');
if (!list || list.length === 0) {
tbody.innerHTML = '
| 暂无历史记录 |
';
return;
}
// 解析日期字符串(支持多种格式)
const parseDate = (dateStr) => {
if (!dateStr) return null;
// 尝试匹配 "2026-07-12" 格式
let match = dateStr.match(/(\d{4})-(\d{1,2})-(\d{1,2})/);
if (match) {
return {
year: parseInt(match[1]),
month: parseInt(match[2]),
day: parseInt(match[3])
};
}
// 尝试匹配 "Sun, 12 Jul 2026 00:00:00 GMT" 格式
match = dateStr.match(/(\d{1,2})\s+(\w+)\s+(\d{4})/);
if (match) {
const months = {
'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12
};
return {
year: parseInt(match[3]),
month: months[match[2]] || 1,
day: parseInt(match[1])
};
}
return null;
};
// 解析时间字符串(支持多种格式)
const parseTime = (timeStr) => {
if (!timeStr) return null;
// 尝试匹配 "2026-07-12 08:00:00" 格式
let match = timeStr.match(/(\d{4})-(\d{1,2})-(\d{1,2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})/);
if (match) {
return {
year: match[1],
month: match[2].padStart(2, '0'),
day: match[3].padStart(2, '0'),
hour: match[4].padStart(2, '0'),
minute: match[5].padStart(2, '0'),
second: match[6].padStart(2, '0')
};
}
// 尝试匹配 "Sun, 12 Jul 2026 08:00:00 GMT" 格式
match = timeStr.match(/(\d{1,2})\s+(\w+)\s+(\d{4})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})/);
if (match) {
const months = {
'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06',
'Jul': '07', 'Aug': '08', 'Sep': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12'
};
return {
year: match[3],
month: months[match[2]] || '01',
day: match[1].padStart(2, '0'),
hour: match[4].padStart(2, '0'),
minute: match[5].padStart(2, '0'),
second: match[6].padStart(2, '0')
};
}
return null;
};
tbody.innerHTML = list.map(item => {
const statusText = item.status === 1 ? '成功' : '失败';
const statusClass = item.status === 1 ? 'status-success' : 'status-failed';
// 格式化报表日期为中文
let reportDate = '-';
const dateObj = parseDate(item.report_date);
if (dateObj) {
reportDate = `${dateObj.year}年${dateObj.month}月${dateObj.day}日`;
} else if (item.report_date) {
reportDate = item.report_date;
}
// 格式化时间范围
let timeRange = '-';
const startObj = parseTime(item.start_time);
const endObj = parseTime(item.end_time);
if (startObj && endObj) {
const formatTimeObj = (obj) => `${obj.year}-${obj.month}-${obj.day} ${obj.hour}:${obj.minute}:${obj.second}`;
timeRange = `${formatTimeObj(startObj)} 至 ${formatTimeObj(endObj)}`;
} else if (item.start_time && item.end_time) {
timeRange = `${item.start_time} 至 ${item.end_time}`;
}
const configName = item.config_name || '-';
const splitValue = item.split_name || '-';
const totalOrders = item.total_orders || 0;
const totalAmount = item.total_amount ? parseFloat(item.total_amount).toFixed(2) : '0.00';
return `
|
${reportDate} |
${timeRange} |
${configName} |
${splitValue} |
${totalOrders} |
¥${totalAmount} |
${statusText} |
${item.status === 1 && item.file_path ?
`下载` :
'-'}
|
`;
}).join('');
}
// 渲染分页控件
function renderPagination(page, total, pageSize) {
const container = document.getElementById('history-pagination');
if (!container) return;
const totalPages = Math.ceil(total / pageSize);
if (totalPages <= 1) {
container.innerHTML = '';
return;
}
let html = '';
container.innerHTML = html;
}
// 加载历史记录(无日期筛选)
async function loadHistory(page = 1) {
loadHistoryWithDate(page);
}
async function loadHistoryWithDate(page) {
try {
let url = `/api/report/history?page=${page}&page_size=${historyPageSize}`;
if (historyStatus) url += `&status=${historyStatus}`;
if (historyStartDate) url += `&start_date=${historyStartDate}`;
if (historyEndDate) url += `&end_date=${historyEndDate}`;
const response = await fetch(url);
const result = await response.json();
if (result.success) {
renderHistory(result.data.list);
renderPagination(result.data.page, result.data.total, result.data.page_size);
} else {
alert('加载失败: ' + (result.error || result.message || '未知错误'));
}
} catch (error) {
alert('加载失败: ' + error.message);
}
}
// 全选/取消全选历史记录
function toggleSelectAllHistory() {
const selectAllCheckbox = document.getElementById('select-all-history');
const checkboxes = document.querySelectorAll('#history-list input[type="checkbox"]');
checkboxes.forEach(cb => {
cb.checked = selectAllCheckbox.checked;
});
}
// 删除单条历史记录
async function deleteHistory(id) {
if (!confirm('确定要删除这条历史记录吗?对应的报表文件也会被删除。')) {
return;
}
try {
const response = await fetch('/api/report/history/batch-delete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ids: [id] })
});
const result = await response.json();
if (result.success) {
alert('删除成功');
loadHistoryWithDate();
} else {
alert('删除失败: ' + result.message);
}
} catch (error) {
alert('删除失败: ' + error.message);
}
}
// 批量删除历史记录
async function batchDeleteHistory() {
const checkboxes = document.querySelectorAll('.history-checkbox:checked');
if (checkboxes.length === 0) {
alert('请至少选择一条记录');
return;
}
if (!confirm(`确定要删除选中的 ${checkboxes.length} 条历史记录吗?对应的报表文件也会被删除。`)) {
return;
}
const ids = Array.from(checkboxes).map(cb => parseInt(cb.value));
try {
const response = await fetch('/api/report/history/batch-delete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ids: ids })
});
const result = await response.json();
if (result.success) {
alert(result.message);
loadHistoryWithDate();
} else {
alert('删除失败: ' + result.message);
}
} catch (error) {
alert('删除失败: ' + error.message);
}
}