Files
ylt_diy/lib/api/report_api.py
user9994793890 f84aa8a4a9 refactor: 重构项目结构,按功能模块拆分文件
- 后端:将 app.py 拆分为 lib/api/ 目录下的多个蓝图模块
  - config_api.py: 配置管理 API
  - entity_api.py: 实体管理 API
  - field_api.py: 字段列表 API
  - report_api.py: 日报生成和历史记录 API
  - init_api.py: 数据库初始化 API
  - download_api.py: 文件下载 API
- 前端:将 index.html 拆分为多个文件
  - static/css/style.css: CSS 样式
  - static/js/common.js: 通用工具函数
  - static/js/config.js: 配置管理
  - static/js/entity.js: 实体管理
  - static/js/report.js: 日报生成
  - static/js/history.js: 历史记录
- 更新 app.py 使用蓝图注册 API
- 创建 AGENTS.md 项目文档

Coze-Commit-Type: user
Coze-User-ID: 3722323274763196
Coze-Conversation-ID: 9894087
2026-07-13 15:43:03 +08:00

200 lines
7.1 KiB
Python

"""
日报生成和历史记录 API
"""
import os
import json
from datetime import datetime
from flask import request, jsonify, send_from_directory
from lib.db import execute_query, execute_update
from lib.report_generator import generate_daily_report
from . import report_bp
@report_bp.route('/report/generate', methods=['POST'])
def generate_report():
"""生成日报"""
try:
data = request.json
config_id = data.get('config_id')
if not config_id:
return jsonify({'success': False, 'message': '请选择配置'}), 400
# 解析时间参数
start_time = None
end_time = None
if data.get('start_time'):
start_time = datetime.strptime(data['start_time'], '%Y-%m-%d %H:%M:%S')
if data.get('end_time'):
end_time = datetime.strptime(data['end_time'], '%Y-%m-%d %H:%M:%S')
result = generate_daily_report(config_id, start_time, end_time)
if result['success']:
return jsonify(result)
else:
return jsonify(result), 400
except Exception as e:
return jsonify({'success': False, 'message': str(e)}), 500
@report_bp.route('/report/history', methods=['GET'])
def get_report_history():
"""获取日报生成历史"""
try:
page = int(request.args.get('page', 1))
page_size = int(request.args.get('page_size', 20))
start_date = request.args.get('start_date')
end_date = request.args.get('end_date')
offset = (page - 1) * page_size
# 构建查询条件
where_clauses = []
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)
where_sql = ' AND '.join(where_clauses) if where_clauses else '1=1'
# 查询总数
total_result = execute_query(
f'SELECT COUNT(*) as total FROM t_daily_report_history WHERE {where_sql}',
tuple(params)
)
total = total_result[0]['total']
# 查询数据
history = execute_query(
f'SELECT * FROM t_daily_report_history WHERE {where_sql} ORDER BY create_time DESC LIMIT %s OFFSET %s',
tuple(params) + (page_size, offset)
)
# 解析 JSON 字段并确保 file_path 正确
for item in history:
item['sum_results'] = json.loads(item['sum_results']) if item['sum_results'] else {}
# 确保 file_path 是字符串
if item['file_path'] is None:
item['file_path'] = ''
# 调试日志
print(f"[历史记录] ID: {item['id']}, status: {item['status']}, file_path: '{item['file_path']}'")
return jsonify({
'success': True,
'data': {
'list': history,
'total': total,
'page': page,
'page_size': page_size
}
})
except Exception as e:
print(f"[历史记录 API] 错误:{e}")
import traceback
traceback.print_exc()
return jsonify({'success': False, 'message': str(e)}), 500
@report_bp.route('/report/history/<int:history_id>', methods=['DELETE'])
def delete_report_history(history_id):
"""删除单个历史记录"""
try:
# 先查询文件路径
result = execute_query(
'SELECT file_path FROM t_daily_report_history WHERE id = %s',
(history_id,)
)
if result:
file_path = result[0].get('file_path', '')
# 删除文件
if file_path and os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'public', file_path.lstrip('/'))):
os.remove(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'public', file_path.lstrip('/')))
# 删除数据库记录
execute_update('DELETE FROM t_daily_report_history WHERE id = %s', (history_id,))
return jsonify({'success': True, 'message': '删除成功'})
except Exception as e:
print(f"[删除历史记录] 错误:{e}")
import traceback
traceback.print_exc()
return jsonify({'success': False, 'message': str(e)}), 500
@report_bp.route('/report/history/batch-delete', methods=['POST'])
def batch_delete_report_history():
"""批量删除历史记录"""
try:
data = request.get_json()
ids = data.get('ids', [])
if not ids:
return jsonify({'success': False, 'message': '请选择要删除的记录'}), 400
# 查询文件路径
results = execute_query(
f'SELECT file_path FROM t_daily_report_history WHERE id IN ({",".join(["%s"] * len(ids))})',
tuple(ids)
)
# 删除文件
for result in results:
file_path = result.get('file_path', '')
if file_path and os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'public', file_path.lstrip('/'))):
os.remove(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'public', file_path.lstrip('/')))
# 删除数据库记录
execute_update(
f'DELETE FROM t_daily_report_history WHERE id IN ({",".join(["%s"] * len(ids))})',
tuple(ids)
)
return jsonify({'success': True, 'message': f'成功删除 {len(ids)} 条记录'})
except Exception as e:
print(f"[批量删除历史记录] 错误:{e}")
import traceback
traceback.print_exc()
return jsonify({'success': False, 'message': str(e)}), 500
@report_bp.route('/report/history/<int:history_id>/download', methods=['GET'])
def download_report_by_id(history_id):
"""根据 ID 下载历史记录"""
try:
# 查询历史记录
result = execute_query(
'SELECT file_path, split_name, report_date FROM t_daily_report_history WHERE id = %s',
(history_id,)
)
if not result:
return jsonify({'success': False, 'message': '记录不存在'}), 404
file_path = result[0]['file_path']
if not file_path:
return jsonify({'success': False, 'message': '文件不存在'}), 404
# 构建完整路径
full_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'public', file_path.lstrip('/'))
if not os.path.exists(full_path):
return jsonify({'success': False, 'message': '文件不存在'}), 404
# 返回文件
directory = os.path.dirname(full_path)
filename = os.path.basename(full_path)
return send_from_directory(directory, filename, as_attachment=True)
except Exception as e:
print(f"[下载历史记录] 错误:{e}")
import traceback
traceback.print_exc()
return jsonify({'success': False, 'message': str(e)}), 500