File size: 6,120 Bytes
f256f5b a30f196 f256f5b a30f196 f256f5b a30f196 f256f5b a30f196 f256f5b a30f196 f256f5b a30f196 f256f5b a30f196 f256f5b a30f196 f256f5b a30f196 f256f5b a30f196 e28c9e4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | {% extends "admin_layout.html" %}
{% block admin_title %}后台总览{% endblock %}
{% block admin_page_content %}
<section class="metric-grid reveal-up delay-2">
<article class="metric-card">
<span>用户数</span>
<strong id="stat-users">{{ stats.users_count }}</strong>
<small>已录入的学生账号</small>
</article>
<article class="metric-card">
<span>运行中任务</span>
<strong id="stat-running">{{ stats.running_count }}</strong>
<small>排队中:<span id="stat-pending">{{ stats.pending_count }}</span></small>
</article>
<article class="metric-card">
<span>总课程目标</span>
<strong>{{ stats.courses_count }}</strong>
<small>管理员可见全部课程号与课序号</small>
</article>
<article class="metric-card">
<span>有效定时任务</span>
<strong>{{ stats.active_schedule_count }}</strong>
<small>管理员配置的每日自动启动与停止</small>
</article>
<article class="metric-card">
<span>注册码总数</span>
<strong>{{ stats.registration_code_count }}</strong>
<small>支持用户按注册码自助注册</small>
</article>
</section>
<section class="content-grid admin-grid">
<article class="card reveal-up delay-2">
<div class="card-head">
<span class="kicker">分页面管理</span>
<h2>功能入口</h2>
<p>不同功能已经拆分到独立页面,避免全部堆在首页。</p>
</div>
<div class="button-row wrap-row">
<a href="{{ url_for('admin_users') }}" class="btn btn-primary">进入用户管理</a>
<a href="{{ url_for('admin_schedules') }}" class="btn btn-secondary">进入定时任务</a>
<a href="{{ url_for('admin_registration_codes') }}" class="btn btn-secondary">进入注册码</a>
<a href="{{ url_for('admin_logs') }}" class="btn btn-ghost">查看运行日志</a>
</div>
</article>
<article class="card reveal-up delay-2">
<div class="card-head">
<span class="kicker">调度设置</span>
<h2>并行数</h2>
<p>默认并行数已调整为 4,建议根据 Hugging Face Space 的资源情况适当调节。</p>
</div>
<form method="post" action="{{ url_for('update_parallel_limit') }}" class="form-grid form-grid-compact">
<label class="field">
<span>当前并行数</span>
<input type="number" id="parallel-limit-input" name="parallel_limit" min="1" max="8" value="{{ parallel_limit }}" required>
</label>
<button type="submit" class="btn btn-primary">更新并行数</button>
</form>
</article>
{% if is_super_admin %}
<article class="card reveal-up delay-2">
<div class="card-head">
<span class="kicker">管理员管理</span>
<h2>新增管理员</h2>
<p>只有超级管理员可以继续创建普通管理员。</p>
</div>
<form method="post" action="{{ url_for('create_admin') }}" class="form-grid form-grid-compact">
<label class="field">
<span>管理员账号</span>
<input type="text" name="username" placeholder="输入管理员账号" required>
</label>
<label class="field">
<span>管理员密码</span>
<input type="password" name="password" placeholder="输入管理员密码" required>
</label>
<button type="submit" class="btn btn-ghost">创建管理员</button>
</form>
<div class="chip-row">
<span class="chip highlight">超级管理员:{{ admin_identity.username }}</span>
{% for admin in admins %}
<span class="chip">{{ admin.username }}</span>
{% endfor %}
</div>
</article>
{% endif %}
<article class="card reveal-up delay-3 span-2">
<div class="card-head split">
<div>
<span class="kicker">任务总览</span>
<h2>最近任务</h2>
<p>用于快速确认任务是否正在排队、执行、停止或失败。</p>
</div>
<span class="status-pill status-running">实时刷新</span>
</div>
<div class="course-table-wrap">
<table class="data-table">
<thead>
<tr>
<th>任务</th>
<th>学号</th>
<th>状态</th>
<th>尝试</th>
<th>错误</th>
<th>刷新间隔</th>
<th>触发者</th>
<th>更新时间</th>
</tr>
</thead>
<tbody>
{% if recent_tasks %}
{% for task in recent_tasks %}
<tr>
<td>#{{ task.id }}</td>
<td>{{ task.student_id }}</td>
<td><span class="status-pill status-{{ task.status }}">{{ task_labels.get(task.status, task.status) }}</span></td>
<td>{{ task.total_attempts }}</td>
<td>{{ task.total_errors }}</td>
<td>{{ task.refresh_interval_seconds or default_refresh_interval_seconds }} 秒</td>
<td>{{ task.requested_by_role }}:{{ task.requested_by }}</td>
<td>{{ task.updated_at }}</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="8" class="empty-cell">还没有任务记录。</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</article>
</section>
{% endblock %}
|