feat: 用户登录/管理 + 操作日志模块
- tb_user 用户表、tb_log 日志表 - Flask-Login 认证(login/logout/权限装饰器) - 用户管理页(admin 专有):增删改查、改密、角色设置 - 操作日志页:分页查询、按用户/类型筛选 - 测试操作区指令自动记录日志 - 所有页面加 @login_required 保护 - 默认管理员 admin/admin123(首次启动自动创建)
This commit is contained in:
112
edc-web/app/templates/users.html
Normal file
112
edc-web/app/templates/users.html
Normal file
@@ -0,0 +1,112 @@
|
||||
{% 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="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="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 %}
|
||||
Reference in New Issue
Block a user