1,修复驿来特没有数据,只特来电有,不生成报表的问题。

2,增加历史记录,每页显示多少条的功能。
This commit is contained in:
2026-07-21 13:30:04 +08:00
parent 404450b779
commit d2ba256889
4 changed files with 96 additions and 31 deletions

View File

@@ -53,7 +53,8 @@ def get_report_history():
page_size = int(request.args.get('page_size', 20)) page_size = int(request.args.get('page_size', 20))
start_date = request.args.get('start_date') start_date = request.args.get('start_date')
end_date = request.args.get('end_date') end_date = request.args.get('end_date')
log_info(f'[报表API] 获取历史记录,第{page}页,日期范围: {start_date or "开始"} ~ {end_date or "结束"}', 'api') status = request.args.get('status')
log_info(f'[报表API] 获取历史记录,第{page}页,状态: {status or "全部"},日期范围: {start_date or "开始"} ~ {end_date or "结束"}', 'api')
offset = (page - 1) * page_size offset = (page - 1) * page_size
@@ -69,6 +70,10 @@ def get_report_history():
where_clauses.append('DATE(end_time) <= %s') where_clauses.append('DATE(end_time) <= %s')
params.append(end_date) params.append(end_date)
if status is not None and status != '':
where_clauses.append('status = %s')
params.append(int(status))
where_sql = ' AND '.join(where_clauses) if where_clauses else '1=1' where_sql = ' AND '.join(where_clauses) if where_clauses else '1=1'
# 查询总数 # 查询总数

View File

@@ -370,6 +370,8 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
# 执行查询 # 执行查询
orders = execute_query(sql, tuple(params)) orders = execute_query(sql, tuple(params))
# 转换为列表,方便后续添加特来电数据
orders = list(orders) if orders else []
log_info(f"[日报生成] 驿来特查询到 {len(orders)} 条订单", 'report') log_info(f"[日报生成] 驿来特查询到 {len(orders)} 条订单", 'report')
@@ -383,8 +385,8 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
log_info(f"[日报生成] 检测到补单记录,将在文件名中添加标记", 'report') log_info(f"[日报生成] 检测到补单记录,将在文件名中添加标记", 'report')
# 检查是否需要合并特来电数据 # 检查是否需要合并特来电数据
merge_telecom = config.get('merge_telecom', 0) merge_telecom = config.get('merge_telecom') or 0
telecom_vehicle_no = config.get('telecom_vehicle_no', '') telecom_vehicle_no = config.get('telecom_vehicle_no') or ''
if merge_telecom and config['split_type'] == 'company_id' and telecom_vehicle_no: if merge_telecom and config['split_type'] == 'company_id' and telecom_vehicle_no:
# 解析车量自编号(支持逗号分隔的多个) # 解析车量自编号(支持逗号分隔的多个)
@@ -392,6 +394,7 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
if vehicle_nos: if vehicle_nos:
log_info(f"[日报生成] 开始合并特来电数据,车量自编号: {vehicle_nos}", 'report') log_info(f"[日报生成] 开始合并特来电数据,车量自编号: {vehicle_nos}", 'report')
telecom_orders = query_telecom_orders(vehicle_nos, start_time_str, end_time_str) telecom_orders = query_telecom_orders(vehicle_nos, start_time_str, end_time_str)
log_info(f"[日报生成] 特来电查询到 {len(telecom_orders)} 条订单", 'report')
if telecom_orders: if telecom_orders:
# 将特来电数据添加到订单列表 # 将特来电数据添加到订单列表
orders.extend(telecom_orders) orders.extend(telecom_orders)
@@ -447,15 +450,19 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
# 计算求和(保留三位小数) # 计算求和(保留三位小数)
sum_results = {} sum_results = {}
for field in sum_fields: for field in sum_fields:
if field in orders[0]: # 检查是否至少有一条订单包含该字段
has_field = any(field in order for order in orders)
if has_field:
total = sum(float(order.get(field, 0) or 0) for order in orders) total = sum(float(order.get(field, 0) or 0) for order in orders)
sum_results[field] = round(total, 3) sum_results[field] = round(total, 3)
# 强制采集充电电量charge_degree即使不在求和字段配置中也要采集 # 强制采集充电电量charge_degree即使不在求和字段配置中也要采集
if 'charge_degree' not in sum_results and orders and 'charge_degree' in orders[0]: if 'charge_degree' not in sum_results and orders:
total_charge_degree = sum(float(order.get('charge_degree', 0) or 0) for order in orders) has_charge_degree = any('charge_degree' in order for order in orders)
sum_results['charge_degree'] = round(total_charge_degree, 3) if has_charge_degree:
log_info(f"[日报生成] 强制采集充电电量: {sum_results['charge_degree']} kWh", 'report') total_charge_degree = sum(float(order.get('charge_degree', 0) or 0) for order in orders)
sum_results['charge_degree'] = round(total_charge_degree, 3)
log_info(f"[日报生成] 强制采集充电电量: {sum_results['charge_degree']} kWh", 'report')
# 构建ID到名称的映射 # 构建ID到名称的映射
id_name_maps = build_id_to_name_map(orders, selected_fields) id_name_maps = build_id_to_name_map(orders, selected_fields)

View File

@@ -1,3 +1,20 @@
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() { async function batchDownloadHistory() {
const checkboxes = document.querySelectorAll('.history-checkbox:checked'); const checkboxes = document.querySelectorAll('.history-checkbox:checked');
@@ -18,18 +35,19 @@ async function batchDownloadHistory() {
function queryHistoryByDate() { function queryHistoryByDate() {
const startDate = document.getElementById('history-start-date').value; const startDate = document.getElementById('history-start-date').value;
const endDate = document.getElementById('history-end-date').value; const endDate = document.getElementById('history-end-date').value;
if (!startDate && !endDate) { historyStartDate = startDate;
alert('请至少选择一个日期'); historyEndDate = endDate;
return; loadHistoryWithDate(1);
}
// 重新加载历史记录,带上日期参数
loadHistoryWithDate(1, startDate, endDate);
} }
// 清除日期查询 // 清除筛选
function clearDateQuery() { function clearHistoryFilter() {
document.getElementById('history-status-filter').value = '';
document.getElementById('history-start-date').value = ''; document.getElementById('history-start-date').value = '';
document.getElementById('history-end-date').value = ''; document.getElementById('history-end-date').value = '';
historyStatus = '';
historyStartDate = '';
historyEndDate = '';
loadHistory(1); loadHistory(1);
} }
@@ -161,7 +179,7 @@ function renderHistory(list) {
} }
// 渲染分页控件 // 渲染分页控件
function renderPagination(page, pageSize, total) { function renderPagination(page, total, pageSize) {
const container = document.getElementById('history-pagination'); const container = document.getElementById('history-pagination');
if (!container) return; if (!container) return;
@@ -178,8 +196,21 @@ function renderPagination(page, pageSize, total) {
html += `<button onclick="loadHistoryWithDate(${page - 1})">上一页</button>`; html += `<button onclick="loadHistoryWithDate(${page - 1})">上一页</button>`;
} }
// 页码 // 页码最多显示7个页码
for (let i = 1; i <= totalPages; i++) { 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) { if (i === page) {
html += `<button class="active">${i}</button>`; html += `<button class="active">${i}</button>`;
} else { } else {
@@ -187,6 +218,13 @@ function renderPagination(page, pageSize, total) {
} }
} }
if (endPage < totalPages) {
if (endPage < totalPages - 1) {
html += `<span style="padding: 0 5px;">...</span>`;
}
html += `<button onclick="loadHistoryWithDate(${totalPages})">${totalPages}</button>`;
}
// 下一页 // 下一页
if (page < totalPages) { if (page < totalPages) {
html += `<button onclick="loadHistoryWithDate(${page + 1})">下一页</button>`; html += `<button onclick="loadHistoryWithDate(${page + 1})">下一页</button>`;
@@ -201,18 +239,19 @@ async function loadHistory(page = 1) {
loadHistoryWithDate(page); loadHistoryWithDate(page);
} }
async function loadHistoryWithDate(page, startDate, endDate) { async function loadHistoryWithDate(page) {
try { try {
let url = `/api/report/history?page=${page}&page_size=10`; let url = `/api/report/history?page=${page}&page_size=${historyPageSize}`;
if (startDate) url += `&start_date=${startDate}`; if (historyStatus) url += `&status=${historyStatus}`;
if (endDate) url += `&end_date=${endDate}`; if (historyStartDate) url += `&start_date=${historyStartDate}`;
if (historyEndDate) url += `&end_date=${historyEndDate}`;
const response = await fetch(url); const response = await fetch(url);
const result = await response.json(); const result = await response.json();
if (result.success) { if (result.success) {
renderHistory(result.data.list); renderHistory(result.data.list);
renderPagination(result.data.total, page); renderPagination(result.data.page, result.data.total, result.data.page_size);
} else { } else {
alert('加载失败: ' + (result.error || '未知错误')); alert('加载失败: ' + (result.error || result.message || '未知错误'));
} }
} catch (error) { } catch (error) {
alert('加载失败: ' + error.message); alert('加载失败: ' + error.message);
@@ -243,7 +282,7 @@ async function deleteHistory(id) {
const result = await response.json(); const result = await response.json();
if (result.success) { if (result.success) {
alert('删除成功'); alert('删除成功');
loadHistory(); loadHistoryWithDate();
} else { } else {
alert('删除失败: ' + result.message); alert('删除失败: ' + result.message);
} }
@@ -275,7 +314,7 @@ async function batchDeleteHistory() {
const result = await response.json(); const result = await response.json();
if (result.success) { if (result.success) {
alert(result.message); alert(result.message);
loadHistory(); loadHistoryWithDate();
} else { } else {
alert('删除失败: ' + result.message); alert('删除失败: ' + result.message);
} }

View File

@@ -91,13 +91,27 @@
<!-- 历史记录 --> <!-- 历史记录 -->
<div id="history-tab" class="tab-content"> <div id="history-tab" class="tab-content">
<div class="card"> <div class="card">
<div style="display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap;"> <div style="display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; align-items: center;">
<select id="history-status-filter" class="form-control" style="width: auto;" onchange="onHistoryStatusChange()">
<option value="">全部状态</option>
<option value="1">成功</option>
<option value="0">失败</option>
</select>
<input type="date" id="history-start-date" class="form-control" style="width: auto;"> <input type="date" id="history-start-date" class="form-control" style="width: auto;">
<span style="line-height: 38px;"></span> <span style="line-height: 38px;"></span>
<input type="date" id="history-end-date" class="form-control" style="width: auto;"> <input type="date" id="history-end-date" class="form-control" style="width: auto;">
<button class="btn btn-primary" onclick="queryHistoryByDate()">查询</button> <button class="btn btn-primary" onclick="queryHistoryByDate()">查询</button>
<button class="btn" onclick="clearDateQuery()">清除</button> <button class="btn" onclick="clearHistoryFilter()">清除</button>
<button class="btn btn-danger" onclick="batchDeleteHistory()" style="margin-left: auto;">批量删除</button> <div style="margin-left: auto; display: flex; gap: 10px; align-items: center;">
<span style="font-size: 14px; color: #666;">每页显示:</span>
<select id="history-page-size" class="form-control" style="width: auto;" onchange="onHistoryPageSizeChange()">
<option value="10">10条</option>
<option value="20">20条</option>
<option value="50">50条</option>
<option value="100">100条</option>
</select>
</div>
<button class="btn btn-danger" onclick="batchDeleteHistory()">批量删除</button>
<button class="btn btn-danger" onclick="batchDownloadHistory()">批量下载</button> <button class="btn btn-danger" onclick="batchDownloadHistory()">批量下载</button>
</div> </div>
@@ -359,7 +373,7 @@
<script src="/public/static/js/config.js?v=2026071507"></script> <script src="/public/static/js/config.js?v=2026071507"></script>
<script src="/public/static/js/entity.js?v=2026071507"></script> <script src="/public/static/js/entity.js?v=2026071507"></script>
<script src="/public/static/js/report.js?v=2026071507"></script> <script src="/public/static/js/report.js?v=2026071507"></script>
<script src="/public/static/js/history.js?v=2026071507"></script> <script src="/public/static/js/history.js?v=2026072103"></script>
<script src="/public/static/js/sum_data.js?v=2026071507"></script> <script src="/public/static/js/sum_data.js?v=2026071507"></script>
</body> </body>
</html> </html>