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)