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); } }