Files
ylt_diy/public/static/js/history.js

365 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 = '<tr><td colspan="9" class="empty">暂无历史记录</td></tr>';
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 `
<tr>
<td><input type="checkbox" class="history-checkbox" value="${item.id}" data-status="${item.status}" data-name="${configName}"></td>
<td>${reportDate}</td>
<td>${timeRange}</td>
<td>${configName}</td>
<td>${splitValue}</td>
<td>${totalOrders}</td>
<td>¥${totalAmount}</td>
<td><span class="${statusClass}">${statusText}</span></td>
<td>
${item.status === 1 && item.file_path ?
`<a href="/api/download?path=${encodeURIComponent(item.file_path)}&token=${encodeURIComponent(getToken())}" class="btn btn-sm btn-success">下载</a>` :
'-'}
<button class="btn btn-sm btn-danger" onclick="deleteHistory(${item.id})">删除</button>
</td>
</tr>
`;
}).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 = '<div class="pagination">';
// 上一页
if (page > 1) {
html += `<button onclick="loadHistoryWithDate(${page - 1})">上一页</button>`;
}
// 页码最多显示7个页码
let startPage = Math.max(1, page - 3);
let endPage = Math.min(totalPages, startPage + 6);
if (endPage - startPage < 6) {
startPage = Math.max(1, endPage - 6);
}
if (startPage > 1) {
html += `<button onclick="loadHistoryWithDate(1)">1</button>`;
if (startPage > 2) {
html += `<span style="padding: 0 5px;">...</span>`;
}
}
for (let i = startPage; i <= endPage; i++) {
if (i === page) {
html += `<button class="active">${i}</button>`;
} else {
html += `<button onclick="loadHistoryWithDate(${i})">${i}</button>`;
}
}
if (endPage < totalPages) {
if (endPage < totalPages - 1) {
html += `<span style="padding: 0 5px;">...</span>`;
}
html += `<button onclick="loadHistoryWithDate(${totalPages})">${totalPages}</button>`;
}
// 下一页
if (page < totalPages) {
html += `<button onclick="loadHistoryWithDate(${page + 1})">下一页</button>`;
}
html += '</div>';
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);
}
}