mirror of
https://github.com/adminlove520/AI-Account-Toolkit.git
synced 2026-05-16 09:26:46 +08:00
308 lines
14 KiB
HTML
308 lines
14 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN" class="precheck-hide">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>用户管理 - iDing's临时邮箱</title>
|
||
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate" />
|
||
<meta http-equiv="Pragma" content="no-cache" />
|
||
<meta http-equiv="Expires" content="0" />
|
||
<noscript>
|
||
<meta http-equiv="refresh" content="0; url=/templates/loading.html?redirect=%2Fhtml%2Fadmin.html" />
|
||
</noscript>
|
||
<style>.precheck-hide body{ visibility: hidden !important; }</style>
|
||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||
<link rel="shortcut icon" href="/favicon.svg" type="image/svg+xml" />
|
||
<link rel="stylesheet" href="/css/app.css" />
|
||
<link rel="stylesheet" href="/css/admin.css" />
|
||
<script src="/js/auth-guard.js" defer></script>
|
||
<script>
|
||
// 访问管理页先做前端快速鉴权,避免内容闪现;未登录或权限不足均进入 loading 或回首页
|
||
(function(){
|
||
fetch('/api/session', { headers: { 'Cache-Control': 'no-cache' } })
|
||
.then(r => r.ok ? r.json() : Promise.reject('unauth'))
|
||
.then(s => {
|
||
if (s && (s.role === 'admin' || s.role === 'guest' || s.strictAdmin)){
|
||
try{ document.documentElement.classList.remove('precheck-hide'); }catch(_){ }
|
||
return;
|
||
}
|
||
// 已登录但无权限:回首页
|
||
location.replace('/');
|
||
})
|
||
.catch(() => {
|
||
// 未登录:进入加载页做鉴权
|
||
if (window.AuthGuard) { window.AuthGuard.goLoading('/html/admin.html', '正在校验权限…'); }
|
||
else { location.replace('/templates/loading.html?redirect=%2Fhtml%2Fadmin.html&status=' + encodeURIComponent('正在校验权限…')); }
|
||
});
|
||
})();
|
||
</script>
|
||
</head>
|
||
<body class="admin-page">
|
||
<div class="topbar">
|
||
<div class="brand">
|
||
<span class="brand-icon">🚀</span>
|
||
<span>iDing's临时邮箱 - 用户管理</span>
|
||
</div>
|
||
<div class="nav-actions">
|
||
<button id="back" class="btn btn-ghost" title="返回邮箱">
|
||
<span>📧</span>
|
||
<span>返回邮箱</span>
|
||
</button>
|
||
<button id="logout" class="btn btn-secondary" title="退出登录">
|
||
<span>👋</span>
|
||
<span>退出登录</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div id="demo-banner" class="demo-banner" style="display:none">当前为演示管理页:所有改动仅在浏览器会话中模拟</div>
|
||
<div class="admin-container">
|
||
<div class="admin-left">
|
||
<div class="card">
|
||
<h2><span class="card-icon">👤</span><span>用户管理</span></h2>
|
||
<div class="generate-action">
|
||
<button id="u-open" class="btn btn-primary">
|
||
<span>➕</span>
|
||
<span>创建用户</span>
|
||
</button>
|
||
</div>
|
||
<div class="generate-action generate-action-row">
|
||
<button id="unassign-open" class="btn btn-secondary">
|
||
<span>📭</span>
|
||
<span>取消分配</span>
|
||
</button>
|
||
<button id="a-open" class="btn btn-primary">
|
||
<span>📬</span>
|
||
<span>分配邮箱</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h2><span class="card-icon">📋</span><span>用户列表</span><span id="users-count" class="users-count">(0 用户)</span></h2>
|
||
<button id="users-refresh" class="btn btn-ghost btn-sm" title="刷新用户列表">
|
||
<span>🔄</span>
|
||
<span>刷新</span>
|
||
</button>
|
||
</div>
|
||
<div id="users-loading" class="loading-indicator" style="margin: 4px 0 8px 0">
|
||
<div class="spinner"></div>
|
||
<span>加载中…</span>
|
||
</div>
|
||
<div class="table-container">
|
||
<table class="table">
|
||
<thead>
|
||
<tr>
|
||
<th class="col-id">ID</th>
|
||
<th class="col-username">用户名</th>
|
||
<th class="col-role">角色</th>
|
||
<th class="col-mailbox">邮箱数量</th>
|
||
<th class="col-can">发件</th>
|
||
<th class="col-created">创建时间</th>
|
||
<th class="col-actions">操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="users-tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
<div class="pagination-container" id="users-pagination" style="display:none">
|
||
<div class="pagination-info">
|
||
<span id="pagination-text">显示 1-50 条,共 0 条</span>
|
||
</div>
|
||
<div class="pagination-controls">
|
||
<button id="prev-page" class="btn btn-ghost btn-sm" disabled>上一页</button>
|
||
<span id="page-info">1 / 1</span>
|
||
<button id="next-page" class="btn btn-ghost btn-sm" disabled>下一页</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="admin-right">
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h2><span class="card-icon">📦</span><span>用户的邮箱列表</span><span id="mailboxes-count" class="mailboxes-count">(0 邮箱)</span></h2>
|
||
<button id="mailboxes-refresh" class="btn btn-ghost btn-sm" title="刷新邮箱列表" style="display:none">
|
||
<span>🔄</span>
|
||
<span>刷新</span>
|
||
</button>
|
||
</div>
|
||
<div id="user-mailboxes-loading" class="loading-indicator" style="margin: 4px 0 8px 0; display:none">
|
||
<div class="spinner"></div>
|
||
<span>加载中…</span>
|
||
</div>
|
||
<div id="user-mailboxes">
|
||
<div class="mailbox-list"></div>
|
||
</div>
|
||
<div class="pagination-container" id="mailboxes-pagination" style="display:none">
|
||
<div class="pagination-info">
|
||
<span id="mailboxes-pagination-text">显示 1-20 条,共 0 条</span>
|
||
</div>
|
||
<div class="pagination-controls">
|
||
<button id="mailboxes-prev-page" class="btn btn-ghost btn-sm" disabled>上一页</button>
|
||
<span id="mailboxes-page-info">1 / 1</span>
|
||
<button id="mailboxes-next-page" class="btn btn-ghost btn-sm" disabled>下一页</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="toast" class="toast"></div>
|
||
|
||
<!-- 编辑用户 二级页面 -->
|
||
<div class="modal" id="edit-modal">
|
||
<div class="modal-card">
|
||
<div class="modal-header">
|
||
<div>
|
||
<span class="modal-icon">✏️</span>
|
||
<span>编辑用户</span>
|
||
<span id="edit-user-display" class="user-chip"></span>
|
||
</div>
|
||
<button id="edit-close" class="close">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-grid">
|
||
<div>
|
||
<label class="config-label">新密码</label>
|
||
<input id="edit-pass" class="input" type="password" placeholder="留空则不修改" />
|
||
</div>
|
||
<div>
|
||
<label class="config-label">新用户名</label>
|
||
<input id="edit-new-name" class="input" placeholder="留空则不修改" />
|
||
</div>
|
||
<div>
|
||
<label class="config-label">邮箱上限</label>
|
||
<input id="edit-limit" class="input" type="number" min="0" />
|
||
</div>
|
||
</div>
|
||
<div class="checks-row">
|
||
<label class="toggle"><input id="edit-role-check" type="checkbox" /><span>高级用户</span></label>
|
||
<label class="toggle"><input id="edit-send-check" type="checkbox" /><span>允许发件</span></label>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer" style="display:flex;gap:8px;justify-content:flex-end;padding:12px 16px">
|
||
<button id="edit-cancel" class="btn btn-secondary">取消</button>
|
||
<button id="edit-save" class="btn btn-primary">保存</button>
|
||
<button id="edit-delete" class="btn btn-danger">删除用户</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 自定义确认对话框(删除用户) -->
|
||
<div class="modal" id="admin-confirm-modal">
|
||
<div class="modal-card confirm-card">
|
||
<div class="modal-header confirm-header">
|
||
<div>
|
||
<span class="modal-icon">🔔</span>
|
||
<span>确认操作</span>
|
||
</div>
|
||
<button id="admin-confirm-close" class="close">✕</button>
|
||
</div>
|
||
<div class="modal-body confirm-body">
|
||
<div id="admin-confirm-message" class="confirm-message"></div>
|
||
<div class="confirm-actions">
|
||
<button id="admin-confirm-cancel" class="btn btn-secondary">取消</button>
|
||
<button id="admin-confirm-ok" class="btn btn-danger">确定</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal" id="u-modal">
|
||
<div class="modal-card">
|
||
<div class="modal-header">
|
||
<div>
|
||
<span class="modal-icon">👤</span>
|
||
<span>创建用户</span>
|
||
</div>
|
||
<button id="u-close" class="close">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="config-form">
|
||
<div class="config-item"><label class="config-label">用户名</label><input id="u-name" class="input" placeholder="username" /></div>
|
||
<div class="config-item"><label class="config-label">密码</label><input id="u-pass" class="input" type="password" placeholder="password" /></div>
|
||
<div class="config-item"><label class="config-label">角色</label><select id="u-role" class="select"><option value="user">普通用户</option><option value="admin">高级用户</option></select></div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer" style="display:flex;gap:8px;justify-content:flex-end;padding:12px 16px">
|
||
<button id="u-cancel" class="btn btn-secondary">取消</button>
|
||
<button id="u-create" class="btn btn-primary">创建</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal" id="a-modal">
|
||
<div class="modal-card">
|
||
<div class="modal-header">
|
||
<div>
|
||
<span class="modal-icon">📬</span>
|
||
<span>分配邮箱</span>
|
||
</div>
|
||
<button id="a-close" class="close">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="config-form">
|
||
<div class="config-item"><label class="config-label">用户名</label><input id="a-name" class="input" placeholder="username" /></div>
|
||
<div class="config-item">
|
||
<label class="config-label">邮箱地址</label>
|
||
<textarea id="a-mail" class="input" placeholder="foo@example.com bar@example.com baz@example.com" rows="4"></textarea>
|
||
<div class="help-text">每行一个邮箱地址,支持批量分配</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer" style="display:flex;gap:8px;justify-content:flex-end;padding:12px 16px">
|
||
<button id="a-cancel" class="btn btn-secondary">取消</button>
|
||
<button id="a-assign" class="btn btn-primary">分配</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal" id="unassign-modal">
|
||
<div class="modal-card">
|
||
<div class="modal-header">
|
||
<div>
|
||
<span class="modal-icon">📬</span>
|
||
<span>取消分配邮箱</span>
|
||
</div>
|
||
<button id="unassign-close" class="close">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="config-form">
|
||
<div class="config-item"><label class="config-label">用户名</label><input id="unassign-name" class="input" placeholder="username" /></div>
|
||
<div class="config-item">
|
||
<label class="config-label">邮箱地址</label>
|
||
<textarea id="unassign-mail" class="input" placeholder="foo@example.com bar@example.com baz@example.com" rows="4"></textarea>
|
||
<div class="help-text">每行一个邮箱地址,支持批量取消分配</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer" style="display:flex;gap:8px;justify-content:flex-end;padding:12px 16px">
|
||
<button id="unassign-cancel" class="btn btn-secondary">取消</button>
|
||
<button id="unassign-submit" class="btn btn-danger">取消分配</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="footer-slot"></div>
|
||
<script src="/js/toast-utils.js"></script>
|
||
<script type="module" src="/js/admin.js"></script>
|
||
<script>
|
||
// 动态加载公共 footer 模板,并在宿主页面设置年份,确保执行
|
||
(async function(){
|
||
try{
|
||
const res = await fetch('/templates/footer.html', { cache: 'no-cache' });
|
||
const html = await res.text();
|
||
const slot = document.getElementById('footer-slot');
|
||
if (slot){
|
||
slot.outerHTML = html;
|
||
// 等 DOM 更新后填充年份
|
||
setTimeout(() => {
|
||
const y = document.getElementById('footer-year');
|
||
if (y) y.textContent = new Date().getFullYear();
|
||
}, 0);
|
||
}
|
||
}catch(_){ }
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
|
||
|