151 lines
5.0 KiB
Python
151 lines
5.0 KiB
Python
|
|
from django.shortcuts import render
|
|||
|
|
from django.http import HttpResponse
|
|||
|
|
from django.utils import timezone
|
|||
|
|
from django.contrib.auth.decorators import login_required
|
|||
|
|
from django.conf import settings
|
|||
|
|
from datetime import datetime, timedelta
|
|||
|
|
from loguru import logger
|
|||
|
|
import os
|
|||
|
|
|
|||
|
|
from .models import (
|
|||
|
|
ReadingRecord,
|
|||
|
|
InsightRecord,
|
|||
|
|
Summary,
|
|||
|
|
FamilyTask,
|
|||
|
|
TodayPlan,
|
|||
|
|
)
|
|||
|
|
from .views import is_weasyprint_available
|
|||
|
|
|
|||
|
|
|
|||
|
|
@login_required
|
|||
|
|
def history_records(request):
|
|||
|
|
"""历史记录查询页面"""
|
|||
|
|
logger.info("用户访问历史记录查询页面")
|
|||
|
|
|
|||
|
|
start_date_str = request.GET.get('start_date')
|
|||
|
|
end_date_str = request.GET.get('end_date')
|
|||
|
|
|
|||
|
|
if not start_date_str or not end_date_str:
|
|||
|
|
today = timezone.now().date()
|
|||
|
|
start_date = datetime(today.year, 1, 1).date()
|
|||
|
|
end_date = today
|
|||
|
|
else:
|
|||
|
|
start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
|
|||
|
|
end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()
|
|||
|
|
|
|||
|
|
# 查询各个类型的记录
|
|||
|
|
reading_records = ReadingRecord.objects.filter(
|
|||
|
|
date__range=[start_date, end_date]
|
|||
|
|
).order_by('-date')
|
|||
|
|
|
|||
|
|
insight_records = InsightRecord.objects.filter(
|
|||
|
|
date__range=[start_date, end_date]
|
|||
|
|
).order_by('-date')
|
|||
|
|
|
|||
|
|
summary_records = Summary.objects.filter(
|
|||
|
|
date__range=[start_date, end_date]
|
|||
|
|
).order_by('-date')
|
|||
|
|
|
|||
|
|
family_tasks = FamilyTask.objects.filter(
|
|||
|
|
created_at__date__range=[start_date, end_date]
|
|||
|
|
).order_by('-created_at')
|
|||
|
|
|
|||
|
|
today_plans = TodayPlan.objects.filter(
|
|||
|
|
date__range=[start_date, end_date]
|
|||
|
|
).order_by('-date')
|
|||
|
|
|
|||
|
|
context = {
|
|||
|
|
'start_date': start_date,
|
|||
|
|
'end_date': end_date,
|
|||
|
|
'reading_records': reading_records,
|
|||
|
|
'insight_records': insight_records,
|
|||
|
|
'summary_records': summary_records,
|
|||
|
|
'family_tasks': family_tasks,
|
|||
|
|
'today_plans': today_plans,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return render(request, 'core/history_records.html', context)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@login_required
|
|||
|
|
def history_pdf(request):
|
|||
|
|
"""导出历史记录PDF"""
|
|||
|
|
if not is_weasyprint_available():
|
|||
|
|
logger.error("WeasyPrint库不可用,无法生成PDF报告")
|
|||
|
|
return HttpResponse("PDF功能不可用,请检查WeasyPrint库是否正确安装", status=500)
|
|||
|
|
|
|||
|
|
start_date_str = request.GET.get('start_date')
|
|||
|
|
end_date_str = request.GET.get('end_date')
|
|||
|
|
|
|||
|
|
if not start_date_str or not end_date_str:
|
|||
|
|
return HttpResponse("请提供开始时间和结束时间", status=400)
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
|
|||
|
|
end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()
|
|||
|
|
except ValueError:
|
|||
|
|
return HttpResponse("日期格式错误", status=400)
|
|||
|
|
|
|||
|
|
if start_date > end_date:
|
|||
|
|
return HttpResponse("开始时间不能晚于结束时间", status=400)
|
|||
|
|
|
|||
|
|
logger.info(f"用户导出历史记录PDF: {start_date} 至 {end_date}")
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
# 查询各个类型的记录
|
|||
|
|
reading_records = ReadingRecord.objects.filter(
|
|||
|
|
date__range=[start_date, end_date]
|
|||
|
|
).order_by('-date')
|
|||
|
|
|
|||
|
|
insight_records = InsightRecord.objects.filter(
|
|||
|
|
date__range=[start_date, end_date]
|
|||
|
|
).order_by('-date')
|
|||
|
|
|
|||
|
|
summary_records = Summary.objects.filter(
|
|||
|
|
date__range=[start_date, end_date]
|
|||
|
|
).order_by('-date')
|
|||
|
|
|
|||
|
|
family_tasks = FamilyTask.objects.filter(
|
|||
|
|
created_at__date__range=[start_date, end_date]
|
|||
|
|
).order_by('-created_at')
|
|||
|
|
|
|||
|
|
today_plans = TodayPlan.objects.filter(
|
|||
|
|
date__range=[start_date, end_date]
|
|||
|
|
).order_by('-date')
|
|||
|
|
|
|||
|
|
context = {
|
|||
|
|
'start_date': start_date,
|
|||
|
|
'end_date': end_date,
|
|||
|
|
'reading_records': reading_records,
|
|||
|
|
'insight_records': insight_records,
|
|||
|
|
'summary_records': summary_records,
|
|||
|
|
'family_tasks': family_tasks,
|
|||
|
|
'today_plans': today_plans,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 渲染HTML模板
|
|||
|
|
html_string = render(request, 'core/history_pdf.html', context).content.decode('utf-8')
|
|||
|
|
|
|||
|
|
# 生成PDF
|
|||
|
|
pdf_file = f"history_{start_date_str}_to_{end_date_str}.pdf"
|
|||
|
|
pdf_path = os.path.join(settings.REPORTS_ROOT, pdf_file)
|
|||
|
|
|
|||
|
|
# 确保报告目录存在
|
|||
|
|
os.makedirs(settings.REPORTS_ROOT, exist_ok=True)
|
|||
|
|
|
|||
|
|
# 动态导入WeasyPrint
|
|||
|
|
from weasyprint import HTML
|
|||
|
|
HTML(string=html_string).write_pdf(pdf_path)
|
|||
|
|
|
|||
|
|
logger.info(f"历史记录PDF生成成功: {pdf_path}")
|
|||
|
|
|
|||
|
|
# 返回PDF文件
|
|||
|
|
with open(pdf_path, 'rb') as f:
|
|||
|
|
response = HttpResponse(f.read(), content_type='application/pdf')
|
|||
|
|
response['Content-Disposition'] = f'attachment; filename="{pdf_file}"'
|
|||
|
|
return response
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
logger.error(f"生成历史记录PDF失败: {str(e)}")
|
|||
|
|
return HttpResponse(f"生成PDF失败: {str(e)}", status=500)
|