This commit is contained in:
beabigegg
2025-08-28 08:59:46 +08:00
parent b9557250a4
commit 4f7f46b07a
42 changed files with 4992 additions and 494 deletions

View File

@@ -1,9 +1,9 @@
{% extends "base.html" %}
{% block title %}帳號管理{% endblock %}
{% block title %}權限管理{% endblock %}
{% block content %}
<h2 class="mb-4">帳號管理</h2>
<h2 class="mb-4">權限管理</h2>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
@@ -16,76 +16,219 @@
{% endif %}
{% endwith %}
<!-- 新增使用者表單 -->
<!-- 設定新管理員 -->
<div class="card mb-4">
<div class="card-header">
新增使用者
<div class="card-header bg-primary text-white">
<i class="bi bi-person-plus-fill"></i> 設定管理員權限
</div>
<div class="card-body">
<form action="{{ url_for('admin.create_user') }}" method="post" class="row g-3">
<div class="col-md-4">
<input type="text" name="username" class="form-control" placeholder="使用者名稱" required>
<form action="{{ url_for('admin.set_admin') }}" method="post" class="row g-3">
<div class="col-md-8">
<label for="username" class="form-label">AD 帳號</label>
<input type="text" name="username" class="form-control" id="username"
placeholder="例如user@panjit.com.tw 或 username" required>
<div class="form-text">輸入需要設定為管理員的 AD 帳號</div>
</div>
<div class="col-md-4">
<input type="password" name="password" class="form-control" placeholder="密碼" required>
</div>
<div class="col-md-2">
<select name="role" class="form-select" required>
<option value="viewer">Viewer</option>
<option value="editor">Editor</option>
<option value="admin">Admin</option>
</select>
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary w-100">建立</button>
<div class="col-md-4 d-flex align-items-end">
<button type="submit" class="btn btn-primary w-100">
<i class="bi bi-shield-check"></i> 設定為管理員
</button>
</div>
</form>
</div>
</div>
<!-- 使用者列表 -->
<!-- 現有使用者權限管理 -->
<div class="card">
<div class="card-header">
現有使用者列表
<div class="card-header bg-secondary text-white">
<i class="bi bi-people-fill"></i> 現有使用者權限管理
</div>
<div class="card-body">
<table class="table table-striped table-hover align-middle">
<thead>
<tr>
<th>ID</th>
<th>使用者名稱</th>
<th>權限</th>
<th>上次登入</th>
<th colspan="2">操作</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.username }}</td>
<form action="{{ url_for('admin.edit_user', user_id=user.id) }}" method="post" class="d-inline">
{% if users %}
<div class="table-responsive">
<table class="table table-striped table-hover align-middle">
<thead>
<tr>
<th>ID</th>
<th>AD 帳號</th>
<th>目前權限</th>
<th>上次登入</th>
<th>權限管理</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr {% if user.id == current_user.id %}class="table-warning"{% endif %}>
<td>{{ user.id }}</td>
<td>
<select name="role" class="form-select form-select-sm">
<option value="viewer" {% if user.role == 'viewer' %}selected{% endif %}>Viewer</option>
<option value="editor" {% if user.role == 'editor' %}selected{% endif %}>Editor</option>
<option value="admin" {% if user.role == 'admin' %}selected{% endif %}>Admin</option>
</select>
{{ user.username }}
{% if user.id == current_user.id %}
<span class="badge bg-info ms-1">目前使用者</span>
{% endif %}
</td>
<td>{{ user.last_login.strftime('%Y-%m-%d %H:%M') if user.last_login else '從未' }}</td>
<td>
<button type="submit" class="btn btn-sm btn-success">更新</button>
<span class="badge
{% if user.role == 'admin' %}bg-danger
{% elif user.role == 'editor' %}bg-warning text-dark
{% else %}bg-secondary
{% endif %}">
{% if user.role == 'admin' %}
<i class="bi bi-shield-fill"></i> 管理員
{% elif user.role == 'editor' %}
<i class="bi bi-pencil-fill"></i> 編輯者
{% else %}
<i class="bi bi-eye-fill"></i> 檢視者
{% endif %}
</span>
</td>
</form>
<td>
<form action="{{ url_for('admin.delete_user', user_id=user.id) }}" method="post" onsubmit="return confirm('確定要刪除這位使用者嗎?');" class="d-inline">
<button type="submit" class="btn btn-sm btn-danger" {% if user.id == current_user.id %}disabled{% endif %}>刪除</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<td>
{% if user.last_login %}
{{ user.last_login.strftime('%Y-%m-%d %H:%M') }}
{% else %}
<span class="text-muted">從未登入</span>
{% endif %}
</td>
<td>
<form action="{{ url_for('admin.edit_user_role', user_id=user.id) }}"
method="post" class="d-inline">
<div class="input-group input-group-sm">
<select name="role" class="form-select form-select-sm">
<option value="viewer" {% if user.role == 'viewer' %}selected{% endif %}>
檢視者 (Viewer)
</option>
<option value="editor" {% if user.role == 'editor' %}selected{% endif %}>
編輯者 (Editor)
</option>
<option value="admin" {% if user.role == 'admin' %}selected{% endif %}>
管理員 (Admin)
</option>
</select>
<button type="submit" class="btn btn-outline-primary btn-sm">
<i class="bi bi-check-lg"></i>
</button>
</div>
</form>
</td>
<td>
{% if user.id != current_user.id %}
<form action="{{ url_for('admin.delete_user', user_id=user.id) }}"
method="post"
onsubmit="return confirm('確定要刪除使用者 {{ user.username }} 嗎?此操作無法復原!');"
class="d-inline">
<button type="submit" class="btn btn-outline-danger btn-sm">
<i class="bi bi-trash"></i>
</button>
</form>
{% else %}
<button type="button" class="btn btn-outline-secondary btn-sm" disabled
title="無法刪除自己的帳號">
<i class="bi bi-shield-x"></i>
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="alert alert-info">
<i class="bi bi-info-circle"></i>
目前沒有任何使用者記錄。使用者會在首次透過 AD 登入時自動建立。
</div>
{% endif %}
</div>
</div>
<!-- 權限說明 -->
<div class="card mt-4">
<div class="card-header">
<i class="bi bi-info-circle"></i> 權限等級說明
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4">
<h6><span class="badge bg-secondary"><i class="bi bi-eye-fill"></i> 檢視者 (Viewer)</span></h6>
<ul class="small">
<li>登入系統</li>
<li>檢視規範列表</li>
<li>下載已生效的 PDF 文件</li>
<li>查看歷史記錄</li>
</ul>
</div>
<div class="col-md-4">
<h6><span class="badge bg-warning text-dark"><i class="bi bi-pencil-fill"></i> 編輯者 (Editor)</span></h6>
<ul class="small">
<li>包含 Viewer 所有權限</li>
<li>建立新的暫時規範</li>
<li>編輯規範內容</li>
<li>展延規範</li>
<li>終止規範</li>
<li>下載 Word 編輯檔案</li>
</ul>
</div>
<div class="col-md-4">
<h6><span class="badge bg-danger"><i class="bi bi-shield-fill"></i> 管理員 (Admin)</span></h6>
<ul class="small">
<li>包含 Editor 所有權限</li>
<li>啟用待生效的規範</li>
<li>管理使用者權限</li>
<li>刪除規範</li>
<li>系統設定管理</li>
</ul>
</div>
</div>
</div>
</div>
<!-- LDAP 整合說明 -->
<div class="card mt-4">
<div class="card-header bg-info text-white">
<i class="bi bi-diagram-3"></i> LDAP/AD 整合說明
</div>
<div class="card-body">
<p><strong>系統運作方式:</strong></p>
<ol>
<li>使用者首次使用 AD 帳號登入時,系統會自動建立本地使用者記錄,預設權限為 <code>viewer</code></li>
<li>管理員可以在此頁面調整使用者權限等級</li>
<li>使用者的身份認證完全由 Active Directory 處理,本系統不儲存密碼</li>
<li>刪除本地使用者記錄不會影響 AD 帳號,使用者仍可重新登入(但會重置為 viewer 權限)</li>
</ol>
<div class="alert alert-warning mt-3">
<i class="bi bi-exclamation-triangle"></i>
<strong>重要提醒:</strong>確保至少保留一個管理員帳號,避免無法進行權限管理。
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
// 自動提交表單當選擇權限改變時的確認
document.addEventListener('DOMContentLoaded', function() {
const roleSelects = document.querySelectorAll('select[name="role"]');
roleSelects.forEach(select => {
select.addEventListener('change', function() {
const form = this.closest('form');
const username = form.closest('tr').querySelector('td:nth-child(2)').textContent.trim();
const newRole = this.value;
if (confirm(`確定要將使用者 "${username}" 的權限變更為 "${newRole}" 嗎?`)) {
// 使用者確認後自動提交
setTimeout(() => {
form.submit();
}, 100);
} else {
// 使用者取消,恢復原來的選擇
this.selectedIndex = this.getAttribute('data-original-index') || 0;
}
});
// 記錄原始選擇索引
select.setAttribute('data-original-index', select.selectedIndex);
});
});
</script>
{% endblock %}