Spaces:
Paused
Paused
File size: 8,056 Bytes
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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | {% extends "base.html" %}
{% block title %}用户控制台 | SCU 选课控制台{% endblock %}
{% block content %}
<section class="dashboard-shell" data-log-stream-url="{{ url_for('stream_user_logs', last_id=recent_logs[-1].id if recent_logs else 0) }}" data-status-url="{{ url_for('user_status') }}">
<header class="topbar reveal-up">
<div>
<span class="eyebrow">User Console</span>
<h1>{{ current_user.display_name or current_user.student_id }} 的选课面板</h1>
<p>登录账号:{{ current_user.student_id }},你的课程目标与运行日志会实时同步到这里。</p>
</div>
<form method="post" action="{{ url_for('logout') }}">
<button type="submit" class="btn btn-ghost">退出登录</button>
</form>
</header>
<section class="metric-grid reveal-up delay-1">
<article class="metric-card">
<span>当前任务</span>
<strong id="task-status-text">{{ task_labels.get(task.status, '未启动') if task else '未启动' }}</strong>
<small>最近更新时间:{{ task.updated_at if task else '暂无' }}</small>
</article>
<article class="metric-card">
<span>待选课程</span>
<strong id="course-count">{{ courses|length }}</strong>
<small>管理员可看到全部课程内容</small>
</article>
<article class="metric-card">
<span>最近任务编号</span>
<strong>{{ task.id if task else '--' }}</strong>
<small>{{ task.last_error if task and task.last_error else '当前没有错误提示' }}</small>
</article>
</section>
<section class="content-grid dashboard-grid">
<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('update_profile') }}" class="form-grid">
<label class="field">
<span>显示名称</span>
<input type="text" name="display_name" value="{{ current_user.display_name }}" placeholder="可选昵称">
</label>
<label class="field">
<span>教务密码</span>
<input type="password" name="password" value="" placeholder="重新输入当前有效密码" required>
</label>
<button type="submit" class="btn btn-primary">保存账号信息</button>
</form>
</article>
<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('add_course') }}" class="form-grid form-grid-compact">
<label class="field">
<span>选课类型</span>
<select name="category">
<option value="free">自由选课</option>
<option value="plan">方案选课</option>
</select>
</label>
<label class="field">
<span>课程号</span>
<input type="text" name="course_id" inputmode="numeric" placeholder="课程号" required>
</label>
<label class="field">
<span>课序号</span>
<input type="text" name="course_index" inputmode="numeric" placeholder="例如 01" maxlength="2" required>
</label>
<button type="submit" class="btn btn-secondary">加入抢课队列</button>
</form>
</article>
<article class="card reveal-up delay-3 span-2">
<div class="card-head split">
<div>
<span class="kicker">执行控制</span>
<h2>启动与停止任务</h2>
<p>后台会按照管理员设置的并行数进行排队和执行。</p>
</div>
<div class="button-row">
<form method="post" action="{{ url_for('start_task') }}">
<button type="submit" class="btn btn-primary">启动任务</button>
</form>
<form method="post" action="{{ url_for('stop_task') }}">
<button type="submit" class="btn btn-ghost danger">停止任务</button>
</form>
</div>
</div>
<div class="status-strip">
<span class="status-pill status-{{ task.status if task else 'idle' }}" id="task-status-pill">{{ task_labels.get(task.status, '未启动') if task else '未启动' }}</span>
<span>创建时间:{{ task.created_at if task else '暂无任务' }}</span>
<span>触发者:{{ task.requested_by if task else '暂无' }}</span>
</div>
<div class="course-table-wrap">
<table class="data-table">
<thead>
<tr>
<th>类型</th>
<th>课程号</th>
<th>课序号</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% if courses %}
{% for course in courses %}
<tr>
<td>{{ category_labels.get(course.category, course.category) }}</td>
<td>{{ course.course_id }}</td>
<td>{{ course.course_index }}</td>
<td>
<form method="post" action="{{ url_for('delete_course', course_target_id=course.id) }}">
<button type="submit" class="inline-action">移除</button>
</form>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="4" class="empty-cell">还没有课程目标,先添加课程号和课序号吧。</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</article>
<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="live-dot">LIVE</span>
</div>
<div class="log-console" id="log-console">
{% if recent_logs %}
{% for log in recent_logs %}
<div class="log-line level-{{ log.level|lower }}">
<span class="log-meta">{{ log.created_at }} · {{ log.scope }} · {{ log.level }}</span>
<span>{{ log.message }}</span>
</div>
{% endfor %}
{% else %}
<div class="log-line level-info muted">暂无日志,启动任务后这里会自动刷新。</div>
{% endif %}
</div>
</article>
</section>
</section>
{% endblock %}
|