Files
office365manage/office365_admin/templates/index.html

320 lines
14 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.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Office 365 User Management Platform</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<div class="background-glow glow-a"></div>
<div class="background-glow glow-b"></div>
<div class="shell">
<header class="hero">
<div class="hero-copy">
<p class="eyebrow">Microsoft Graph + Web Console</p>
<h1>Office 365 账号管理平台</h1>
<p class="hero-text">
基于你提供的 <code>office365-tools</code> 能力升级而来,当前默认按国际版 Microsoft 365 / Microsoft Graph 工作,支持账号单个与批量增删改查、许可证查看、密码重置与批处理回显。
</p>
</div>
<div class="hero-side">
<div class="status-card">
<span class="status-label">平台状态</span>
<strong id="platform-status">检测中</strong>
<span id="platform-substatus" class="muted">正在读取配置</span>
</div>
<div class="hero-actions">
<button id="refresh-all-btn" class="btn btn-secondary">刷新数据</button>
<button id="logout-btn" class="btn btn-ghost">退出</button>
</div>
</div>
</header>
<main class="dashboard">
<section id="login-section" class="panel panel-login hidden">
<div class="panel-head">
<div>
<h2>后台登录</h2>
<p>如果启用了平台登录保护,请先输入后台管理员账号。</p>
</div>
</div>
<form id="login-form" class="inline-form">
<label>
<span>用户名</span>
<input id="login-username" name="username" autocomplete="username" required>
</label>
<label>
<span>密码</span>
<input id="login-password" name="password" type="password" autocomplete="current-password" required>
</label>
<button class="btn btn-primary" type="submit">登录平台</button>
</form>
</section>
<section class="metrics">
<article class="metric-card">
<span class="metric-label">匹配用户数</span>
<strong id="metric-total">0</strong>
<span class="metric-foot" id="metric-total-foot">当前筛选结果</span>
</article>
<article class="metric-card">
<span class="metric-label">启用账号</span>
<strong id="metric-active">0</strong>
<span class="metric-foot">accountEnabled = true</span>
</article>
<article class="metric-card">
<span class="metric-label">停用账号</span>
<strong id="metric-disabled">0</strong>
<span class="metric-foot">便于快速排查离职或冻结账号</span>
</article>
<article class="metric-card">
<span class="metric-label">可用许可证</span>
<strong id="metric-license">0</strong>
<span class="metric-foot">来自当前租户订阅</span>
</article>
</section>
<section class="panel panel-users">
<div class="panel-head">
<div>
<h2>用户列表</h2>
<p>支持搜索、查看详情、全选当前页或全部搜索结果,并执行批量删除 / 启停 / 改密。</p>
</div>
<form id="search-form" class="search-form">
<input id="search-input" placeholder="搜索邮箱、显示名、部门、职位">
<button class="btn btn-secondary" type="submit">搜索</button>
</form>
</div>
<div class="selection-toolbar">
<div class="selection-meta">
<span id="selected-count" class="tag">未选择账号</span>
<button id="select-all-results-btn" class="btn btn-ghost" type="button">选中全部搜索结果</button>
<button id="clear-selection-btn" class="btn btn-ghost" type="button">清空选择</button>
</div>
<div class="selection-actions">
<button id="bulk-enable-btn" class="btn btn-secondary" type="button">批量启用</button>
<button id="bulk-disable-btn" class="btn btn-secondary" type="button">批量停用</button>
<button id="bulk-reset-btn" class="btn btn-secondary" type="button">批量改密</button>
<button id="bulk-delete-btn" class="btn btn-danger" type="button">批量删除</button>
</div>
</div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th class="check-col">
<label class="table-checkbox">
<input id="select-page-checkbox" type="checkbox">
<span>全选</span>
</label>
</th>
<th>显示名</th>
<th>登录名</th>
<th>部门 / 职位</th>
<th>状态</th>
<th>许可证</th>
<th>操作</th>
</tr>
</thead>
<tbody id="users-table-body">
<tr>
<td colspan="7" class="empty-cell">暂无数据</td>
</tr>
</tbody>
</table>
</div>
<div class="table-footer">
<span id="pagination-info" class="muted">第 1 页</span>
<div class="pager">
<button id="prev-page-btn" class="btn btn-ghost" type="button">上一页</button>
<button id="next-page-btn" class="btn btn-ghost" type="button">下一页</button>
</div>
</div>
</section>
<section class="panel panel-editor">
<div class="panel-head">
<div>
<h2>单个账号维护</h2>
<p>新建账号时支持只填用户名;若配置了 <code>DEFAULT_DOMAIN</code>,系统会自动补全 UPN。</p>
</div>
<div class="editor-actions">
<button id="new-user-btn" class="btn btn-secondary" type="button">新建用户</button>
<button id="delete-user-btn" class="btn btn-danger" type="button">删除当前</button>
</div>
</div>
<form id="user-form" class="user-form">
<input id="selected-user-id" type="hidden">
<label>
<span>账号 / 邮箱</span>
<input id="userPrincipalName" name="userPrincipalName" required>
</label>
<label>
<span>显示名</span>
<input id="displayName" name="displayName">
</label>
<label>
<span>名字</span>
<input id="givenName" name="givenName">
</label>
<label>
<span>姓氏</span>
<input id="surname" name="surname">
</label>
<label>
<span>部门</span>
<input id="department" name="department">
</label>
<label>
<span>职位</span>
<input id="jobTitle" name="jobTitle">
</label>
<label>
<span>办公地点</span>
<input id="officeLocation" name="officeLocation">
</label>
<label>
<span>手机号</span>
<input id="mobilePhone" name="mobilePhone">
</label>
<label>
<span>使用地区</span>
<input id="usageLocation" name="usageLocation" placeholder="US">
</label>
<label>
<span>许可证 SKU</span>
<input id="skuPartNumber" name="skuPartNumber" placeholder="如 O365_BUSINESS">
</label>
<label>
<span>临时密码</span>
<input id="password" name="password" type="password" placeholder="不填则使用默认密码">
</label>
<label class="checkbox">
<input id="accountEnabled" name="accountEnabled" type="checkbox" checked>
<span>启用账号</span>
</label>
<label class="checkbox">
<input id="forceChangePasswordNextSignIn" name="forceChangePasswordNextSignIn" type="checkbox" checked>
<span>首次登录强制改密</span>
</label>
<div class="form-actions">
<button id="save-user-btn" class="btn btn-primary" type="submit">保存用户</button>
<button id="reset-password-btn" class="btn btn-secondary" type="button">重置密码</button>
<button id="clear-form-btn" class="btn btn-ghost" type="button">清空表单</button>
</div>
</form>
</section>
<section class="panel panel-license">
<div class="panel-head">
<div>
<h2>许可证概览</h2>
<p>实时读取租户已订阅 SKU 和剩余席位。</p>
</div>
</div>
<div id="license-list" class="license-list">
<div class="empty-card">正在加载许可证信息...</div>
</div>
</section>
<section class="panel panel-batch">
<div class="panel-head">
<div>
<h2>批量管理中心</h2>
<p>支持 CSV 或 JSON。删除也支持纯文本一行一个账号。</p>
</div>
</div>
<div class="batch-grid">
<article class="batch-card">
<div class="batch-card-top">
<div>
<h3>批量创建</h3>
<p>先下载示例 CSV编辑后再上传执行。</p>
</div>
<a class="btn btn-ghost" href="{{ url_for('static', filename='examples/batch-create-template.csv') }}" download>下载示例 CSV</a>
</div>
<p>CSV 表头示例:<code>userPrincipalName,displayName,givenName,surname,department,jobTitle,usageLocation,skuPartNumber,password</code></p>
<input data-target="batch-create-content" class="file-input" type="file" accept=".csv,.json,.txt">
<textarea id="batch-create-content" placeholder='或直接粘贴 JSON 数组 / CSV 内容'></textarea>
<button data-batch-action="create" class="btn btn-primary" type="button">执行批量创建</button>
</article>
<article class="batch-card">
<div class="batch-card-top">
<div>
<h3>批量更新</h3>
<p>下载模板后只改需要更新的列,再上传执行。</p>
</div>
<a class="btn btn-ghost" href="{{ url_for('static', filename='examples/batch-update-template.csv') }}" download>下载示例 CSV</a>
</div>
<p>CSV 至少需要一列账号标识。空值默认忽略,不会清空原字段。</p>
<input data-target="batch-update-content" class="file-input" type="file" accept=".csv,.json,.txt">
<textarea id="batch-update-content" placeholder='示例userPrincipalName,department,jobTitle,accountEnabled'></textarea>
<button data-batch-action="update" class="btn btn-primary" type="button">执行批量更新</button>
</article>
<article class="batch-card">
<div class="batch-card-top">
<div>
<h3>批量删除</h3>
<p>可以直接下载删除模板,编辑后上传执行。</p>
</div>
<a class="btn btn-ghost" href="{{ url_for('static', filename='examples/batch-delete-template.csv') }}" download>下载示例 CSV</a>
</div>
<p>支持 CSV/JSON也支持纯文本一行一个 UPN 或用户名。</p>
<input data-target="batch-delete-content" class="file-input" type="file" accept=".csv,.json,.txt">
<textarea id="batch-delete-content" placeholder="alice&#10;bob@contoso.com"></textarea>
<button data-batch-action="delete" class="btn btn-danger" type="button">执行批量删除</button>
</article>
<article class="batch-card">
<div class="batch-card-top">
<div>
<h3>批量重置密码</h3>
<p>可先下载模板,编辑密码后上传执行。</p>
</div>
<a class="btn btn-ghost" href="{{ url_for('static', filename='examples/batch-reset-password-template.csv') }}" download>下载示例 CSV</a>
</div>
<p>可使用纯文本账号列表,也可传入 CSV<code>userPrincipalName,password,forceChangePasswordNextSignIn</code></p>
<input data-target="batch-reset-content" class="file-input" type="file" accept=".csv,.json,.txt">
<textarea id="batch-reset-content" placeholder="一行一个账号,默认使用系统默认密码"></textarea>
<button data-batch-action="reset-password" class="btn btn-secondary" type="button">执行批量改密</button>
</article>
</div>
</section>
<section class="panel panel-console">
<div class="panel-head">
<div>
<h2>执行结果</h2>
<p>界面只展示简要摘要,详细逐条处理信息写入服务日志。</p>
</div>
</div>
<div id="task-status-card" class="task-status-card hidden">
<div class="task-status-head">
<strong id="task-status-title">暂无任务</strong>
<span id="task-status-state" class="tag">待命</span>
</div>
<div class="task-progress-track">
<div id="task-progress-fill" class="task-progress-fill"></div>
</div>
<div id="task-status-text" class="muted">等待任务提交</div>
</div>
<pre id="result-console" class="console">等待操作...</pre>
</section>
</main>
</div>
<script>
window.APP_BOOTSTRAP = {{ bootstrap | tojson }};
</script>
<script src="{{ url_for('static', filename='app.js') }}"></script>
</body>
</html>