File size: 5,383 Bytes
ce0719e 02a8414 ce0719e 02a8414 ce0719e 02a8414 ce0719e 02a8414 ce0719e 02a8414 ce0719e 02a8414 7db57c0 02a8414 7db57c0 02a8414 7db57c0 02a8414 ce0719e | 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 | {% extends 'base.html' %}
{% block content %}
<section class="page-grid admin-page-grid users-admin-grid">
<article class="glass-card form-panel">
<div class="section-head">
<div>
<p class="eyebrow">Create User</p>
<h3>手动录入用户</h3>
</div>
</div>
<form method="post" action="/admin/users" class="form-stack">
<div class="form-grid cols-2">
<label>
<span>学号</span>
<input type="text" name="student_id" required />
</label>
<label>
<span>姓名</span>
<input type="text" name="full_name" required />
</label>
<label>
<span>登录密码</span>
<input type="text" name="password" required />
</label>
<label>
<span>所属小组</span>
<select name="group_id">
<option value="">暂不分组</option>
{% for group in groups %}
<option value="{{ group.id }}">{{ group.name }}({{ group.members|length }}/{{ group.max_members }})</option>
{% endfor %}
</select>
</label>
</div>
<button class="btn btn-primary" type="submit">保存用户</button>
</form>
</article>
<article class="glass-card form-panel">
<div class="section-head">
<div>
<p class="eyebrow">Batch Import</p>
<h3>批量导入用户</h3>
</div>
</div>
<form method="post" action="/admin/users/import" class="form-stack">
<label>
<span>每行一人,格式:姓名 学号</span>
<textarea name="import_text" rows="8" placeholder="张三 20230001 李四 20230002"></textarea>
</label>
<label>
<span>导入后分配到小组</span>
<select name="group_id">
<option value="">暂不分组</option>
{% for group in groups %}
<option value="{{ group.id }}">{{ group.name }}({{ group.members|length }}/{{ group.max_members }})</option>
{% endfor %}
</select>
</label>
<p class="mini-note">默认密码为学号后六位,不足六位则使用完整学号。</p>
<button class="btn btn-secondary" type="submit">开始导入</button>
</form>
</article>
</section>
<section class="glass-card table-panel">
<div class="section-head">
<div>
<p class="eyebrow">Users</p>
<h3>用户列表与批量操作</h3>
</div>
</div>
<form id="bulk-users-form" method="post" action="/admin/users/bulk" class="bulk-toolbar">
<label>
<span>批量操作</span>
<select name="bulk_action" required>
<option value="assign_group">批量分组</option>
<option value="delete">批量删除</option>
</select>
</label>
<label>
<span>目标小组</span>
<select name="group_id">
<option value="">未分组</option>
{% for group in groups %}
<option value="{{ group.id }}">{{ group.name }}</option>
{% endfor %}
</select>
</label>
<button class="btn btn-primary" type="submit">执行批量操作</button>
</form>
<div class="table-shell">
<table class="data-table">
<thead>
<tr>
<th>
<input class="table-checkbox" type="checkbox" data-check-all />
</th>
<th>学号</th>
<th>姓名</th>
<th>当前小组</th>
<th>调整小组</th>
</tr>
</thead>
<tbody>
{% for user_item in users %}
<tr>
<td>
<input class="table-checkbox" type="checkbox" name="user_ids" value="{{ user_item.id }}" data-user-check form="bulk-users-form" />
</td>
<td>{{ user_item.student_id }}</td>
<td>{{ user_item.full_name }}</td>
<td>{{ user_item.group.name if user_item.group else '未分组' }}</td>
<td>
<form method="post" action="/admin/users/{{ user_item.id }}/group" class="inline-form table-inline-form">
<select name="group_id">
<option value="">未分组</option>
{% for group in groups %}
<option value="{{ group.id }}" {% if user_item.group_id == group.id %}selected{% endif %}>{{ group.name }}</option>
{% endfor %}
</select>
<button class="btn btn-secondary small-btn" type="submit">保存</button>
</form>
</td>
</tr>
{% else %}
<tr>
<td colspan="5">还没有用户,请先录入。</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</section>
<script>
(() => {
const checkAll = document.querySelector('[data-check-all]');
const checks = Array.from(document.querySelectorAll('[data-user-check]'));
if (!checkAll || checks.length === 0) return;
checkAll.addEventListener('change', () => {
checks.forEach((checkbox) => {
checkbox.checked = checkAll.checked;
});
});
})();
</script>
{% endblock %}
|