feat(历史记录): 添加历史记录查询功能及PDF导出
新增历史记录查询页面,支持按时间范围筛选阅读记录、感悟记录、汇总记录、家庭事项和今日计划 添加历史记录PDF导出功能,生成包含所有记录的格式化PDF报告
This commit is contained in:
344
core/templates/core/history_pdf.html
Normal file
344
core/templates/core/history_pdf.html
Normal file
@@ -0,0 +1,344 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>历史记录 - {{ start_date|date:"Y-m-d" }} 至 {{ end_date|date:"Y-m-d" }}</title>
|
||||
<style>
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 1.5cm;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Microsoft YaHei", "SimHei", sans-serif;
|
||||
font-size: 12pt;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
border-bottom: 3px solid #2c3e50;
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
color: #2c3e50;
|
||||
font-size: 24pt;
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
.header .date-range {
|
||||
color: #666;
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 30px;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 10px 15px;
|
||||
font-size: 14pt;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.section-title.reading { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
|
||||
.section-title.insight { background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); }
|
||||
.section-title.summary { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); }
|
||||
.section-title.task { background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); }
|
||||
.section-title.plan { background: linear-gradient(135deg, #8e9eab 0%, #eef2f3 100%); color: #333; }
|
||||
|
||||
.record-item {
|
||||
background: #f8f9fa;
|
||||
border-left: 4px solid #667eea;
|
||||
padding: 12px 15px;
|
||||
margin-bottom: 12px;
|
||||
border-radius: 0 5px 5px 0;
|
||||
}
|
||||
|
||||
.record-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.record-date {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
padding: 3px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.record-meta {
|
||||
color: #666;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.record-content {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.record-content p {
|
||||
margin: 0 0 8px 0;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
font-size: 9pt;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.badge-primary { background: #667eea; color: white; }
|
||||
.badge-secondary { background: #6c757d; color: white; }
|
||||
.badge-success { background: #28a745; color: white; }
|
||||
.badge-warning { background: #ffc107; color: #333; }
|
||||
.badge-info { background: #17a2b8; color: white; }
|
||||
.badge-danger { background: #dc3545; color: white; }
|
||||
|
||||
.empty-notice {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-style: italic;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px solid #dee2e6;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #f8f9fa;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
background: #e9ecef;
|
||||
border-radius: 10px;
|
||||
height: 8px;
|
||||
width: 100px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
background: #667eea;
|
||||
height: 100%;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #dee2e6;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 10pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>历史记录汇总</h1>
|
||||
<div class="date-range">
|
||||
{{ start_date|date:"Y年m月d日" }} 至 {{ end_date|date:"Y年m月d日" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 阅读记录 -->
|
||||
<div class="section">
|
||||
<div class="section-title reading">阅读记录 ({{ reading_records|length }} 条)</div>
|
||||
{% if reading_records %}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日期</th>
|
||||
<th>类型</th>
|
||||
<th>标题</th>
|
||||
<th>来源</th>
|
||||
<th>进度</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for record in reading_records %}
|
||||
<tr>
|
||||
<td>{{ record.date|date:"Y-m-d" }}</td>
|
||||
<td><span class="badge badge-info">{{ record.type.name }}</span></td>
|
||||
<td>{{ record.title }}</td>
|
||||
<td>{{ record.source|default:"-" }}</td>
|
||||
<td>
|
||||
{% if record.progress %}
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: {{ record.progress }}%"></div>
|
||||
</div>
|
||||
<small>{{ record.progress }}%</small>
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="empty-notice">该时间段没有阅读记录</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- 感悟记录 -->
|
||||
<div class="section">
|
||||
<div class="section-title insight">感悟记录 ({{ insight_records|length }} 条)</div>
|
||||
{% if insight_records %}
|
||||
{% for record in insight_records %}
|
||||
<div class="record-item">
|
||||
<div class="record-header">
|
||||
<span class="record-date">{{ record.date|date:"Y-m-d" }}</span>
|
||||
<span class="record-meta">发言人: {{ record.speaker.name }}</span>
|
||||
</div>
|
||||
<div class="record-content">
|
||||
{{ record.content|linebreaks }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="empty-notice">该时间段没有感悟记录</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- 汇总记录 -->
|
||||
<div class="section">
|
||||
<div class="section-title summary">汇总记录 ({{ summary_records|length }} 条)</div>
|
||||
{% if summary_records %}
|
||||
{% for record in summary_records %}
|
||||
<div class="record-item">
|
||||
<div class="record-header">
|
||||
<span class="record-date">{{ record.date|date:"Y-m-d" }}</span>
|
||||
<span class="record-meta">
|
||||
<span class="badge badge-secondary">{{ record.category.name }}</span>
|
||||
发言人: {{ record.speaker.name }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="record-content">
|
||||
{{ record.content|linebreaks }}
|
||||
{% if record.source %}
|
||||
<p><small>来源: {{ record.source }}</small></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="empty-notice">该时间段没有汇总记录</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- 家庭事项 -->
|
||||
<div class="section">
|
||||
<div class="section-title task">家庭事项 ({{ family_tasks|length }} 条)</div>
|
||||
{% if family_tasks %}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>创建时间</th>
|
||||
<th>类型</th>
|
||||
<th>内容</th>
|
||||
<th>优先级</th>
|
||||
<th>状态</th>
|
||||
<th>截止日期</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for task in family_tasks %}
|
||||
<tr>
|
||||
<td>{{ task.created_at|date:"Y-m-d H:i" }}</td>
|
||||
<td><span class="badge badge-secondary">{{ task.type.name }}</span></td>
|
||||
<td>{{ task.content|truncatechars:50 }}</td>
|
||||
<td>
|
||||
<span class="badge {% if task.priority.name == '高' %}badge-danger{% elif task.priority.name == '中' %}badge-warning{% else %}badge-info{% endif %}">
|
||||
{{ task.priority.name }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge {% if task.status.name == 'completed' %}badge-success{% else %}badge-warning{% endif %}">
|
||||
{{ task.status.name }}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ task.deadline|date:"Y-m-d"|default:"-" }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="empty-notice">该时间段没有家庭事项</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- 今日计划 -->
|
||||
<div class="section">
|
||||
<div class="section-title plan">今日计划 ({{ today_plans|length }} 条)</div>
|
||||
{% if today_plans %}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日期</th>
|
||||
<th>发言人</th>
|
||||
<th>内容</th>
|
||||
<th>类型</th>
|
||||
<th>优先级</th>
|
||||
<th>状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for plan in today_plans %}
|
||||
<tr>
|
||||
<td>{{ plan.date|date:"Y-m-d" }}</td>
|
||||
<td>{{ plan.speaker.name }}</td>
|
||||
<td>{{ plan.content|truncatechars:50 }}</td>
|
||||
<td><span class="badge badge-info">{{ plan.type.name }}</span></td>
|
||||
<td>
|
||||
<span class="badge {% if plan.priority.name == '高' %}badge-danger{% elif plan.priority.name == '中' %}badge-warning{% else %}badge-info{% endif %}">
|
||||
{{ plan.priority.name }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge {% if plan.status.name == 'completed' %}badge-success{% else %}badge-warning{% endif %}">
|
||||
{{ plan.status.name }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="empty-notice">该时间段没有今日计划</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>家庭日报系统 - 历史记录导出</p>
|
||||
<p>生成时间: {% now "Y-m-d H:i:s" %}</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
293
core/templates/core/history_records.html
Normal file
293
core/templates/core/history_records.html
Normal file
@@ -0,0 +1,293 @@
|
||||
{% extends 'core/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<!-- 页面标题 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card" style="background: linear-gradient(135deg, #2c3e50 0%, #4ca1af 100%); color: white;">
|
||||
<div class="card-body d-flex align-items-center justify-content-between py-4">
|
||||
<div>
|
||||
<h3 class="mb-1"><i class="bi bi-clock-history me-2"></i>历史记录查询</h3>
|
||||
<p class="mb-0 opacity-75">
|
||||
<i class="bi bi-calendar-range me-2"></i>
|
||||
{{ start_date|date:"Y年m月d日" }} 至 {{ end_date|date:"Y年m月d日" }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-end d-none d-md-block">
|
||||
<i class="bi bi-archive" style="font-size: 4rem; opacity: 0.3;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 阅读记录 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0"><i class="bi bi-book me-2"></i>阅读记录</h5>
|
||||
<span class="badge bg-light text-primary">{{ reading_records|length }} 条</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if reading_records %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日期</th>
|
||||
<th>类型</th>
|
||||
<th>标题</th>
|
||||
<th>来源</th>
|
||||
<th>进度</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for record in reading_records %}
|
||||
<tr>
|
||||
<td>{{ record.date|date:"Y-m-d" }}</td>
|
||||
<td><span class="badge bg-info">{{ record.type.name }}</span></td>
|
||||
<td>{{ record.title }}</td>
|
||||
<td>{{ record.source|default:"-" }}</td>
|
||||
<td>
|
||||
{% if record.progress %}
|
||||
<div class="progress" style="height: 6px; width: 100px;">
|
||||
<div class="progress-bar bg-primary" role="progressbar" style="width: {{ record.progress }}%"></div>
|
||||
</div>
|
||||
<small class="text-muted">{{ record.progress }}%</small>
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-inbox text-muted" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mt-2">该时间段没有阅读记录</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 感悟记录 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0"><i class="bi bi-lightbulb me-2"></i>感悟记录</h5>
|
||||
<span class="badge bg-light text-success">{{ insight_records|length }} 条</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if insight_records %}
|
||||
<div class="list-group">
|
||||
{% for record in insight_records %}
|
||||
<div class="list-group-item">
|
||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||
<div>
|
||||
<span class="badge bg-success me-2">{{ record.date|date:"Y-m-d" }}</span>
|
||||
<span class="text-muted"><i class="bi bi-person me-1"></i>{{ record.speaker.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mb-2">{{ record.content|linebreaks }}</p>
|
||||
{% if record.file %}
|
||||
<a href="{{ record.file.url }}" class="file-link small" target="_blank">
|
||||
<i class="bi bi-paperclip me-1"></i>查看附件
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-inbox text-muted" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mt-2">该时间段没有感悟记录</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 汇总记录 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-info text-white d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0"><i class="bi bi-collection me-2"></i>汇总记录</h5>
|
||||
<span class="badge bg-light text-info">{{ summary_records|length }} 条</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if summary_records %}
|
||||
<div class="list-group">
|
||||
{% for record in summary_records %}
|
||||
<div class="list-group-item">
|
||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||
<div>
|
||||
<span class="badge bg-primary me-2">{{ record.date|date:"Y-m-d" }}</span>
|
||||
<span class="badge bg-secondary me-2">{{ record.category.name }}</span>
|
||||
<span class="text-muted"><i class="bi bi-person me-1"></i>{{ record.speaker.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mb-2">{{ record.content|linebreaks }}</p>
|
||||
{% if record.source %}
|
||||
<div class="small text-muted mb-2">
|
||||
<i class="bi bi-link-45deg me-1"></i>{{ record.source }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if record.file %}
|
||||
<a href="{{ record.file.url }}" class="file-link small" target="_blank">
|
||||
<i class="bi bi-paperclip me-1"></i>查看附件
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-inbox text-muted" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mt-2">该时间段没有汇总记录</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 家庭事项 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-warning text-white d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0"><i class="bi bi-list-check me-2"></i>家庭事项</h5>
|
||||
<span class="badge bg-light text-warning">{{ family_tasks|length }} 条</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if family_tasks %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>创建时间</th>
|
||||
<th>类型</th>
|
||||
<th>内容</th>
|
||||
<th>优先级</th>
|
||||
<th>状态</th>
|
||||
<th>截止日期</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for task in family_tasks %}
|
||||
<tr>
|
||||
<td>{{ task.created_at|date:"Y-m-d H:i" }}</td>
|
||||
<td><span class="badge bg-secondary">{{ task.type.name }}</span></td>
|
||||
<td>{{ task.content|truncatechars:50 }}</td>
|
||||
<td>
|
||||
<span class="badge {% if task.priority.name == '高' %}bg-danger{% elif task.priority.name == '中' %}bg-warning{% else %}bg-info{% endif %}">
|
||||
{{ task.priority.name }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge {% if task.status.name == 'completed' %}bg-success{% else %}bg-warning{% endif %}">
|
||||
{{ task.status.name }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
{% if task.deadline %}
|
||||
{% if task.is_overdue %}
|
||||
<span class="text-danger">{{ task.deadline|date:"Y-m-d" }} (已逾期)</span>
|
||||
{% else %}
|
||||
{{ task.deadline|date:"Y-m-d" }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-inbox text-muted" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mt-2">该时间段没有家庭事项</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 今日计划 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-secondary text-white d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0"><i class="bi bi-calendar-check me-2"></i>今日计划</h5>
|
||||
<span class="badge bg-light text-secondary">{{ today_plans|length }} 条</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if today_plans %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日期</th>
|
||||
<th>发言人</th>
|
||||
<th>内容</th>
|
||||
<th>类型</th>
|
||||
<th>优先级</th>
|
||||
<th>状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for plan in today_plans %}
|
||||
<tr>
|
||||
<td>{{ plan.date|date:"Y-m-d" }}</td>
|
||||
<td>{{ plan.speaker.name }}</td>
|
||||
<td>{{ plan.content|truncatechars:50 }}</td>
|
||||
<td><span class="badge bg-info">{{ plan.type.name }}</span></td>
|
||||
<td>
|
||||
<span class="badge {% if plan.priority.name == '高' %}bg-danger{% elif plan.priority.name == '中' %}bg-warning{% else %}bg-info{% endif %}">
|
||||
{{ plan.priority.name }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge {% if plan.status.name == 'completed' %}bg-success{% else %}bg-warning{% endif %}">
|
||||
{{ plan.status.name }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-inbox text-muted" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mt-2">该时间段没有今日计划</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 返回按钮 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<a href="{% url 'index' %}" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left me-1"></i>返回首页
|
||||
</a>
|
||||
<a href="{% url 'history_pdf' %}?start_date={{ start_date|date:'Y-m-d' }}&end_date={{ end_date|date:'Y-m-d' }}" class="btn btn-success">
|
||||
<i class="bi bi-file-earmark-pdf me-1"></i>导出PDF
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -279,4 +279,97 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 历史记录查询 -->
|
||||
<div class="row mt-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-dark text-white d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0"><i class="bi bi-clock-history me-2"></i>历史记录查询</h5>
|
||||
<span class="badge bg-light text-dark">导出PDF</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="historyForm" method="GET" action="{% url 'history_records' %}">
|
||||
<div class="row align-items-end">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label"><i class="bi bi-calendar-minus me-1"></i>开始时间</label>
|
||||
<input type="date" class="form-control" id="start_date" name="start_date" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label"><i class="bi bi-calendar-plus me-1"></i>结束时间</label>
|
||||
<input type="date" class="form-control" id="end_date" name="end_date" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="d-flex gap-2 flex-wrap">
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="setCurrentQuarter()">
|
||||
<i class="bi bi-calendar3 me-1"></i>当季
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="setCurrentYear()">
|
||||
<i class="bi bi-calendar-year me-1"></i>本年度
|
||||
</button>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="bi bi-search me-1"></i>查询记录
|
||||
</button>
|
||||
<button type="button" class="btn btn-success" onclick="exportHistoryPDF()">
|
||||
<i class="bi bi-file-earmark-pdf me-1"></i>导出PDF
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 设置当季时间范围(最近3个月)
|
||||
function setCurrentQuarter() {
|
||||
const today = new Date();
|
||||
const threeMonthsAgo = new Date(today.getFullYear(), today.getMonth() - 2, 1);
|
||||
|
||||
document.getElementById('start_date').value = formatDate(threeMonthsAgo);
|
||||
document.getElementById('end_date').value = formatDate(today);
|
||||
}
|
||||
|
||||
// 设置本年度时间范围
|
||||
function setCurrentYear() {
|
||||
const today = new Date();
|
||||
const yearStart = new Date(today.getFullYear(), 0, 1);
|
||||
|
||||
document.getElementById('start_date').value = formatDate(yearStart);
|
||||
document.getElementById('end_date').value = formatDate(today);
|
||||
}
|
||||
|
||||
// 格式化日期为 YYYY-MM-DD
|
||||
function formatDate(date) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
// 导出历史记录PDF
|
||||
function exportHistoryPDF() {
|
||||
const startDate = document.getElementById('start_date').value;
|
||||
const endDate = document.getElementById('end_date').value;
|
||||
|
||||
if (!startDate || !endDate) {
|
||||
alert('请先选择开始时间和结束时间');
|
||||
return;
|
||||
}
|
||||
|
||||
if (new Date(startDate) > new Date(endDate)) {
|
||||
alert('开始时间不能晚于结束时间');
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = `{% url 'history_pdf' %}?start_date=${startDate}&end_date=${endDate}`;
|
||||
}
|
||||
|
||||
// 页面加载时默认设置为本年度
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
setCurrentYear();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user