历史记录中,增加按配置名称搜索

This commit is contained in:
2026-08-02 09:14:59 +08:00
parent c04b3b6b5d
commit 9516078b1d
4 changed files with 208 additions and 1 deletions

View File

@@ -202,3 +202,123 @@ def batch_download():
import traceback
traceback.print_exc()
return jsonify({'success': False, 'message': str(e)}), 500
@download_bp.route('/download/batch-filter', methods=['POST'])
def batch_download_by_filter():
"""按筛选条件批量打包下载
接收筛选条件(config_name, start_date, end_date, status),
将所有匹配的成功记录的报表文件打包成zip后下载。
与历史记录列表的搜索条件保持同步。
"""
try:
data = request.get_json(silent=True) or {}
config_name = data.get('config_name', '').strip()
start_date = data.get('start_date', '').strip()
end_date = data.get('end_date', '').strip()
status = data.get('status', '')
log_info(f'[下载API] 按筛选批量下载,配置名称: {config_name or "全部"},日期范围: {start_date or "开始"} ~ {end_date or "结束"},状态: {status or "全部"}', 'download')
# 清理旧的临时文件
cleanup_old_temp_zips()
# 构建查询条件(与历史记录列表查询条件完全一致)
where_clauses = ['status = 1'] # 只下载成功的记录
params = []
if start_date:
where_clauses.append('DATE(start_time) >= %s')
params.append(start_date)
if end_date:
where_clauses.append('DATE(end_time) <= %s')
params.append(end_date)
if status is not None and status != '':
where_clauses.append('status = %s')
params.append(int(status))
if config_name:
where_clauses.append('config_name LIKE %s')
params.append(f'%{config_name}%')
where_sql = ' AND '.join(where_clauses)
# 查询所有匹配的成功记录
result = execute_query(
f'SELECT id, file_path, config_name, report_date, status FROM t_daily_report_history WHERE {where_sql} ORDER BY create_time DESC',
tuple(params)
)
if not result:
return jsonify({'success': False, 'message': '未找到符合条件的历史记录'}), 404
reports_dir = get_reports_dir()
temp_dir = get_temp_dir()
# 收集要打包的文件
files_to_zip = []
failed_names = []
for item in result:
file_path = item.get('file_path')
if not file_path:
failed_names.append(f"{item.get('config_name', '未知')} (无文件)")
continue
# 提取文件名
if file_path.startswith('/public/reports/'):
filename = file_path.replace('/public/reports/', '')
elif file_path.startswith('/reports/'):
filename = file_path.replace('/reports/', '')
else:
filename = os.path.basename(file_path)
full_path = os.path.join(reports_dir, filename)
if not os.path.exists(full_path):
failed_names.append(f"{item.get('config_name', '未知')} (文件不存在)")
continue
# 使用配置名作为zip内的文件名,避免重名
config_name_val = item.get('config_name', '未知')
report_date = item.get('report_date', '')
ext = os.path.splitext(filename)[1]
if report_date:
zip_inner_name = f"{config_name_val}_{report_date}{ext}"
else:
zip_inner_name = f"{config_name_val}{ext}"
files_to_zip.append({
'full_path': full_path,
'inner_name': zip_inner_name
})
if len(files_to_zip) == 0:
return jsonify({'success': False, 'message': '没有可下载的文件'}), 400
# 生成zip文件名
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
zip_filename = f'批量导出_{timestamp}.zip'
zip_path = os.path.join(temp_dir, zip_filename)
# 打包
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
for file_info in files_to_zip:
zf.write(file_info['full_path'], file_info['inner_name'])
log_info(f'[下载API] 按筛选批量打包完成,共 {len(files_to_zip)} 个文件,失败 {len(failed_names)} 个', 'download')
# 返回zip文件
from flask import send_file
return send_file(
zip_path,
as_attachment=True,
download_name=zip_filename,
mimetype='application/zip'
)
except Exception as e:
log_error(f'[下载API] 按筛选批量下载错误: {e}', 'download')
import traceback
traceback.print_exc()
return jsonify({'success': False, 'message': str(e)}), 500

View File

@@ -54,7 +54,8 @@ def get_report_history():
start_date = request.args.get('start_date')
end_date = request.args.get('end_date')
status = request.args.get('status')
log_info(f'[报表API] 获取历史记录,第{page}页,状态: {status or "全部"},日期范围: {start_date or "开始"} ~ {end_date or "结束"}', 'api')
config_name = request.args.get('config_name')
log_info(f'[报表API] 获取历史记录,第{page}页,状态: {status or "全部"},配置名称: {config_name or "全部"},日期范围: {start_date or "开始"} ~ {end_date or "结束"}', 'api')
offset = (page - 1) * page_size
@@ -74,6 +75,11 @@ def get_report_history():
where_clauses.append('status = %s')
params.append(int(status))
# 支持按配置名称模糊搜索
if config_name is not None and config_name.strip() != '':
where_clauses.append('config_name LIKE %s')
params.append(f'%{config_name.strip()}%')
where_sql = ' AND '.join(where_clauses) if where_clauses else '1=1'
# 查询总数