CA详情页证书列表分页支持
This commit is contained in:
parent
0001c8f0d3
commit
35eea7a803
25
app.py
25
app.py
@ -1400,9 +1400,11 @@ def create_ca_view():
|
||||
|
||||
from datetime import timedelta # 确保顶部已导入
|
||||
|
||||
|
||||
@app.route('/cas/<int:ca_id>')
|
||||
@login_required
|
||||
def ca_detail(ca_id):
|
||||
page = request.args.get('page', 1, type=int)
|
||||
ca = get_ca_by_id(ca_id)
|
||||
if not ca:
|
||||
flash('CA不存在', 'danger')
|
||||
@ -1413,16 +1415,28 @@ def ca_detail(ca_id):
|
||||
flash('无权访问此CA', 'danger')
|
||||
return redirect(url_for('ca_list'))
|
||||
|
||||
# 获取该CA颁发的证书
|
||||
# 获取该CA颁发的证书(分页)
|
||||
conn = get_db_connection()
|
||||
if conn:
|
||||
try:
|
||||
cursor = conn.cursor(dictionary=True)
|
||||
|
||||
# 获取证书总数
|
||||
cursor.execute("""
|
||||
SELECT COUNT(*) as total FROM certificates
|
||||
WHERE ca_id = %s
|
||||
""", (ca_id,))
|
||||
total = cursor.fetchone()['total']
|
||||
total_pages = ceil(total / PER_PAGE)
|
||||
|
||||
# 获取分页数据
|
||||
offset = (page - 1) * PER_PAGE
|
||||
cursor.execute("""
|
||||
SELECT * FROM certificates
|
||||
WHERE ca_id = %s
|
||||
ORDER BY created_at DESC
|
||||
""", (ca_id,))
|
||||
LIMIT %s OFFSET %s
|
||||
""", (ca_id, PER_PAGE, offset))
|
||||
certificates = cursor.fetchall()
|
||||
|
||||
# 获取CRL信息
|
||||
@ -1437,8 +1451,11 @@ def ca_detail(ca_id):
|
||||
ca=ca,
|
||||
certificates=certificates,
|
||||
crl=crl,
|
||||
timedelta=timedelta, # 传递timedelta到模板
|
||||
get_username=get_username # 确保这个函数已定义
|
||||
page=page,
|
||||
total_pages=total_pages,
|
||||
total=total,
|
||||
timedelta=timedelta,
|
||||
get_username=get_username
|
||||
)
|
||||
except Error as e:
|
||||
print(f"Database error: {e}")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>证书管理系统 - {% block title %}{% endblock %}</title>
|
||||
<title>自签证书管理系统 - {% block title %}{% endblock %}</title>
|
||||
<link rel="icon" href="{{ url_for('static', filename='favicon.svg') }}" type="image/svg+xml">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
|
||||
|
||||
@ -112,11 +112,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 证书列表部分 -->
|
||||
<div class="card">
|
||||
<div class="card-header bg-light d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="fas fa-certificate text-primary me-2"></i> 颁发的证书
|
||||
<span class="badge bg-primary rounded-pill ms-2">{{ certificates|length }}</span>
|
||||
<span class="badge bg-primary rounded-pill ms-2">{{ total }}</span>
|
||||
</h5>
|
||||
<div>
|
||||
<a href="{{ url_for('create_certificate_view') }}?ca_id={{ ca.id }}"
|
||||
@ -168,27 +169,53 @@
|
||||
<td>{{ cert.expires_at.strftime('%Y-%m-%d') }}</td>
|
||||
<td>{{ cert.created_at.strftime('%Y-%m-%d') }}</td>
|
||||
<td class="pe-4">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<a href="{{ url_for('certificate_detail', cert_id=cert.id) }}"
|
||||
class="btn btn-outline-primary"
|
||||
data-bs-toggle="tooltip"
|
||||
title="查看证书详情">
|
||||
<i class="fas fa-eye me-1"></i> 详情
|
||||
</a>
|
||||
<a href="{{ url_for('export_certificate_view', cert_id=cert.id) }}"
|
||||
class="btn btn-outline-success"
|
||||
data-bs-toggle="tooltip"
|
||||
title="导出证书">
|
||||
<i class="fas fa-download me-1"></i> 导出
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<a href="{{ url_for('certificate_detail', cert_id=cert.id) }}"
|
||||
class="btn btn-outline-primary"
|
||||
data-bs-toggle="tooltip"
|
||||
title="查看证书详情">
|
||||
<i class="fas fa-eye me-1"></i> 详情
|
||||
</a>
|
||||
<a href="{{ url_for('export_certificate_view', cert_id=cert.id) }}"
|
||||
class="btn btn-outline-success"
|
||||
data-bs-toggle="tooltip"
|
||||
title="导出证书">
|
||||
<i class="fas fa-download me-1"></i> 导出
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% if total_pages > 1 %}
|
||||
<div class="card-footer bg-white">
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination justify-content-center mb-0">
|
||||
<li class="page-item {% if page == 1 %}disabled{% endif %}">
|
||||
<a class="page-link" href="{{ url_for('ca_detail', ca_id=ca.id, page=page-1) }}" aria-label="Previous">
|
||||
<span aria-hidden="true">«</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% for p in range(1, total_pages + 1) %}
|
||||
<li class="page-item {% if p == page %}active{% endif %}">
|
||||
<a class="page-link" href="{{ url_for('ca_detail', ca_id=ca.id, page=p) }}">{{ p }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
<li class="page-item {% if page == total_pages %}disabled{% endif %}">
|
||||
<a class="page-link" href="{{ url_for('ca_detail', ca_id=ca.id, page=page+1) }}" aria-label="Next">
|
||||
<span aria-hidden="true">»</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-certificate fa-4x text-muted mb-4"></i>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user