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 迁移
This commit is contained in:
@@ -10,14 +10,17 @@
|
||||
<nav class="top-menu">
|
||||
<a href="/" class="{% if request.path == '/' %}active{% endif %}">设备</a>
|
||||
<a href="/test-data" class="{% if request.path == '/test-data' %}active{% endif %}">测试信息</a>
|
||||
{% if current_user.is_authenticated and current_user.role == 'admin' %}
|
||||
{% if current_user.is_authenticated and current_user.role in ('admin', 'manager') %}
|
||||
<a href="/device-logs" class="{% if request.path == '/device-logs' %}active{% endif %}">设备日志</a>
|
||||
<a href="/logs/" class="{% if request.path == '/logs/' %}active{% endif %}">操作日志</a>
|
||||
{% endif %}
|
||||
{% if current_user.is_authenticated and current_user.role == 'admin' %}
|
||||
<a href="/users/" class="{% if request.path == '/users/' %}active{% endif %}">用户管理</a>
|
||||
{% endif %}
|
||||
<span class="user-info">
|
||||
{% if current_user.is_authenticated %}
|
||||
{{ current_user.username }} ({{ current_user.role }})
|
||||
<a href="/change-password">修改密码</a>
|
||||
<a href="/logout">退出</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
38
edc-web/app/templates/change_password.html
Normal file
38
edc-web/app/templates/change_password.html
Normal file
@@ -0,0 +1,38 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}修改密码 - EDC 工装管理系统{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div style="max-width:400px;margin:40px auto;">
|
||||
<h2>修改密码</h2>
|
||||
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{% if messages %}
|
||||
<div style="background:#fef3e2;color:#b45309;padding:10px;border-radius:6px;margin-bottom:16px;">
|
||||
{% for msg in messages %}{{ msg }}{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<form method="POST" style="display:flex;flex-direction:column;gap:16px;">
|
||||
<div>
|
||||
<label>当前密码</label>
|
||||
<input type="password" name="old_password" required
|
||||
style="width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;">
|
||||
</div>
|
||||
<div>
|
||||
<label>新密码(至少6位)</label>
|
||||
<input type="password" name="new_password" required minlength="6"
|
||||
style="width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;">
|
||||
</div>
|
||||
<div>
|
||||
<label>确认新密码</label>
|
||||
<input type="password" name="confirm_password" required minlength="6"
|
||||
style="width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;">
|
||||
</div>
|
||||
<div style="display:flex;justify-content:space-between;">
|
||||
<a href="/" style="line-height:36px;">← 返回</a>
|
||||
<button type="submit" class="btn-search" style="padding:8px 24px;">确认修改</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -27,7 +27,7 @@
|
||||
</label>
|
||||
<button onclick="searchLogs(1)" class="btn-search">查询</button>
|
||||
<button onclick="exportCSV()" class="btn-export">导出 CSV</button>
|
||||
{% if current_user.role == 'admin' %}
|
||||
{% if current_user.role in ('admin', 'manager') %}
|
||||
<button onclick="confirmDeleteLogs()" class="btn-delete">🗑 删除</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
</select>
|
||||
</label>
|
||||
<button id="btn-chart" class="btn-chart" onclick="toggleChart()">📈 图表</button>
|
||||
{% if current_user.role == 'admin' %}
|
||||
{% if current_user.role in ('admin', 'manager') %}
|
||||
<button id="btn-delete" class="btn-delete" onclick="confirmDelete()">🗑 删除</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<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>
|
||||
@@ -51,6 +52,7 @@ async function loadUsers() {
|
||||
<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">
|
||||
|
||||
Reference in New Issue
Block a user