Files
vd_test_fixture/edc-web/app/templates/users.html
wangfq 000e4f8d3a feat: 增加 manager 角色,admin+manager 共享管理权限(用户管理除外),所有用户可自行修改密码
- auth.py: 新增 privileged_required 装饰器 (admin+manager),admin_required 仅限用户管理
- 路由权限: fixture/logs/device_logs/test_data 的 admin 检查改为 admin+manager
- 前端: 导航栏/删除按钮/配置按钮扩展为 admin+manager 可见
- 用户管理: 角色下拉增加 manager 选项,仍仅 admin 可访问
- 新增 /change-password 路由+模板,所有登录用户可自行修改密码
- edc_server models.py: role COMMENT 更新 + ALTER TABLE 迁移
2026-06-11 09:11:54 +08:00

115 lines
4.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}用户管理 - EDC 工装管理系统{% endblock %}
{% block content %}
<h2>用户管理</h2>
<div style="margin-bottom:16px;">
<button onclick="showAddForm()" class="btn-search">新增用户</button>
<div id="add-form" style="display:none;margin-top:12px;background:#fff;padding:16px;border-radius:8px;">
<label>用户名:<input type="text" id="new-username" style="margin:0 8px;"></label>
<label>密码:<input type="password" id="new-password" style="margin:0 8px;"></label>
<label>角色:
<select id="new-role" style="margin:0 8px;">
<option value="operator">operator</option>
<option value="manager">manager</option>
<option value="admin">admin</option>
</select>
</label>
<button onclick="addUser()" class="btn-search">确认</button>
<button onclick="document.getElementById('add-form').style.display='none'" class="btn-export">取消</button>
</div>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>用户名</th>
<th>角色</th>
<th>状态</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="user-tbody"></tbody>
</table>
{% endblock %}
{% block scripts %}
<script>
async function loadUsers() {
const resp = await fetch("/users/api/users");
const users = await resp.json();
const tbody = document.getElementById("user-tbody");
tbody.innerHTML = users.map(u => `
<tr>
<td>${u.id}</td>
<td>${u.username}</td>
<td>${u.role}</td>
<td>${u.is_active ? '启用' : '禁用'}</td>
<td>${u.create_time || '-'}</td>
<td>
<select onchange="updateUser(${u.id}, this, 'role')" data-field="role">
<option value="operator" ${u.role==='operator'?'selected':''}>operator</option>
<option value="manager" ${u.role==='manager'?'selected':''}>manager</option>
<option value="admin" ${u.role==='admin'?'selected':''}>admin</option>
</select>
<select onchange="updateUser(${u.id}, this, 'is_active')" data-field="is_active">
<option value="1" ${u.is_active?'selected':''}>启用</option>
<option value="0" ${!u.is_active?'selected':''}>禁用</option>
</select>
<button onclick="resetPwd(${u.id})" class="btn-search" style="font-size:11px;">改密</button>
</td>
</tr>
`).join("");
}
function showAddForm() {
document.getElementById("add-form").style.display = "block";
document.getElementById("new-username").value = "";
document.getElementById("new-password").value = "";
}
async function addUser() {
const username = document.getElementById("new-username").value.trim();
const password = document.getElementById("new-password").value;
const role = document.getElementById("new-role").value;
if (!username || !password) { alert("用户名和密码不能为空"); return; }
const resp = await fetch("/users/api/users", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({username, password, role}),
});
const data = await resp.json();
if (data.ok) { document.getElementById("add-form").style.display = "none"; loadUsers(); }
else { alert(data.error || "创建失败"); }
}
async function updateUser(id, el, field) {
const value = el.value;
const body = {};
body[field] = field === 'is_active' ? parseInt(value) : value;
await fetch(`/users/api/users/${id}`, {
method: "PUT",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(body),
});
loadUsers();
}
async function resetPwd(id) {
const pwd = prompt("输入新密码至少6位");
if (!pwd || pwd.length < 6) { alert("密码至少6位"); return; }
await fetch(`/users/api/users/${id}`, {
method: "PUT",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({password: pwd}),
});
alert("密码已更新");
}
loadUsers();
</script>
{% endblock %}