美化系统设置页,登录页抑制浏览器自动填充账号密码。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+63
-19
@@ -1,19 +1,63 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}登录 · 期权中控{% endblock %}
|
||||
{% block body %}
|
||||
<div class="login-wrap">
|
||||
<section class="login-card">
|
||||
<h1>期权中控</h1>
|
||||
<p class="login-sub">多机期权持仓总览 · 内嵌打开客户端 · 本仓不下单</p>
|
||||
<form method="post" class="stack" autocomplete="on">
|
||||
<label>用户名
|
||||
<input name="username" autocomplete="username" required placeholder="admin">
|
||||
</label>
|
||||
<label>密码
|
||||
<input type="password" name="password" autocomplete="current-password" required placeholder="••••••••">
|
||||
</label>
|
||||
<button type="submit">登 录</button>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}登录 · 期权中控{% endblock %}
|
||||
{% block body %}
|
||||
<div class="login-wrap">
|
||||
<section class="login-card">
|
||||
<h1>期权中控</h1>
|
||||
<p class="login-sub">多机期权持仓总览 · 内嵌打开客户端 · 本仓不下单</p>
|
||||
{# 诱饵字段 + readonly/聚焦解锁,避免浏览器自动填入用户名密码 #}
|
||||
<form method="post" class="stack login-form" autocomplete="off" data-lpignore="true" data-1p-ignore="true">
|
||||
<input type="text" name="username_trap" tabindex="-1" aria-hidden="true" autocomplete="username" class="login-honeypot" value="">
|
||||
<input type="password" name="password_trap" tabindex="-1" aria-hidden="true" autocomplete="current-password" class="login-honeypot" value="">
|
||||
<label>用户名
|
||||
<input
|
||||
type="text"
|
||||
name="username"
|
||||
required
|
||||
value=""
|
||||
placeholder="请输入用户名"
|
||||
autocomplete="off"
|
||||
autocapitalize="off"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
readonly
|
||||
data-login-field="1"
|
||||
>
|
||||
</label>
|
||||
<label>密码
|
||||
<input
|
||||
type="password"
|
||||
name="password"
|
||||
required
|
||||
value=""
|
||||
placeholder="请输入密码"
|
||||
autocomplete="new-password"
|
||||
readonly
|
||||
data-login-field="1"
|
||||
>
|
||||
</label>
|
||||
<button type="submit">登 录</button>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script>
|
||||
(function () {
|
||||
function unlock(el) {
|
||||
if (!el) return;
|
||||
el.removeAttribute("readonly");
|
||||
}
|
||||
document.querySelectorAll("[data-login-field]").forEach(function (el) {
|
||||
el.addEventListener("focus", function () { unlock(el); }, { once: true });
|
||||
el.addEventListener("pointerdown", function () { unlock(el); }, { once: true });
|
||||
});
|
||||
// 延迟清一次,挡住部分密码管理器首屏写入
|
||||
setTimeout(function () {
|
||||
document.querySelectorAll("[data-login-field]").forEach(function (el) {
|
||||
if (document.activeElement !== el) el.value = "";
|
||||
});
|
||||
}, 50);
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
+70
-48
@@ -1,56 +1,78 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}系统设置 · 期权中控{% endblock %}
|
||||
{% block body %}
|
||||
<section class="page-head"><h1>系统设置</h1></section>
|
||||
<section class="page-head settings-head">
|
||||
<div>
|
||||
<p class="settings-eyebrow">Hub Settings</p>
|
||||
<h1>系统设置</h1>
|
||||
<p class="muted settings-lead">账号与中控告警在此维护,保存后立即生效。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="settings-grid">
|
||||
<section class="panel settings-card">
|
||||
<h2>登录账号</h2>
|
||||
<p class="muted">修改后立即生效,并写入服务器 <code>.env</code>(<code>HUB_USERNAME</code> / <code>HUB_PASSWORD</code>).</p>
|
||||
<form method="post" class="stack settings-form" autocomplete="off">
|
||||
<input type="hidden" name="form_action" value="account">
|
||||
<label>当前用户名
|
||||
<input type="text" value="{{ current_username }}" readonly class="readonly">
|
||||
</label>
|
||||
<label>当前密码
|
||||
<input type="password" name="current_password" required autocomplete="current-password" placeholder="验证身份">
|
||||
</label>
|
||||
<label>新用户名
|
||||
<input type="text" name="new_username" value="{{ current_username }}" required autocomplete="username" minlength="2" maxlength="64">
|
||||
</label>
|
||||
<label>新密码
|
||||
<input type="password" name="new_password" autocomplete="new-password" minlength="6" placeholder="至少 6 位;不改密码可留空">
|
||||
</label>
|
||||
<label>确认新密码
|
||||
<input type="password" name="confirm_password" autocomplete="new-password" minlength="6" placeholder="与新密码一致;不改密码可留空">
|
||||
</label>
|
||||
<button type="submit">保存账号</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="panel settings-card">
|
||||
<h2>企业微信告警</h2>
|
||||
<p class="muted">中控专用:客户端离线/故障与恢复时推送。与各交易机自身通知分开配置。</p>
|
||||
<form method="post" class="stack settings-form" autocomplete="off">
|
||||
<label class="check-row">
|
||||
<input type="checkbox" name="wechat_enabled" value="1"{% if wechat.enabled %} checked{% endif %}>
|
||||
启用企业微信推送
|
||||
</label>
|
||||
<label>Webhook 地址
|
||||
<input type="url" name="wechat_webhook" value="{{ wechat.webhook }}" placeholder="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=..." autocomplete="off">
|
||||
</label>
|
||||
<label>告警冷却(秒)
|
||||
<input type="number" name="alert_cooldown_sec" value="{{ wechat.cooldown_sec }}" min="60" max="86400" step="1">
|
||||
</label>
|
||||
<label>连续失败阈值
|
||||
<input type="number" name="health_fail_threshold" value="{{ wechat.fail_threshold }}" min="1" max="20" step="1">
|
||||
<span class="field-hint">连续拉失败达到次数后才告警,默认 2</span>
|
||||
</label>
|
||||
<div class="settings-actions">
|
||||
<button type="submit" name="form_action" value="wechat">保存告警配置</button>
|
||||
<button type="submit" name="form_action" value="wechat_test" class="btn-secondary">发送测试消息</button>
|
||||
<section class="panel settings-card settings-card--account">
|
||||
<div class="settings-card-head">
|
||||
<span class="settings-badge">Account</span>
|
||||
<h2>登录账号</h2>
|
||||
<p class="muted">修改后立即写入 <code>.env</code>,无需重启。</p>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
<form method="post" class="stack settings-form" autocomplete="off" data-lpignore="true" data-1p-ignore="true">
|
||||
<input type="hidden" name="form_action" value="account">
|
||||
<div class="settings-field">
|
||||
<span class="settings-label">当前用户名</span>
|
||||
<div class="settings-readonly">{{ current_username }}</div>
|
||||
</div>
|
||||
<label class="settings-field">当前密码
|
||||
<input type="password" name="current_password" required autocomplete="new-password" placeholder="验证身份后才能保存">
|
||||
</label>
|
||||
<div class="settings-divider"></div>
|
||||
<label class="settings-field">新用户名
|
||||
<input type="text" name="new_username" value="{{ current_username }}" required autocomplete="off" minlength="2" maxlength="64">
|
||||
</label>
|
||||
<div class="settings-row-2">
|
||||
<label class="settings-field">新密码
|
||||
<input type="password" name="new_password" autocomplete="new-password" minlength="6" placeholder="至少 6 位,不改可留空">
|
||||
</label>
|
||||
<label class="settings-field">确认新密码
|
||||
<input type="password" name="confirm_password" autocomplete="new-password" minlength="6" placeholder="再次输入">
|
||||
</label>
|
||||
</div>
|
||||
<button type="submit" class="settings-primary">保存账号</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="panel settings-card settings-card--wechat">
|
||||
<div class="settings-card-head">
|
||||
<span class="settings-badge settings-badge--alert">Notify</span>
|
||||
<h2>企业微信告警</h2>
|
||||
<p class="muted">中控专用:客户端离线 / 故障 / 恢复时推送,与交易机通知分开。</p>
|
||||
</div>
|
||||
<form method="post" class="stack settings-form" autocomplete="off">
|
||||
<label class="settings-switch">
|
||||
<input type="checkbox" name="wechat_enabled" value="1"{% if wechat.enabled %} checked{% endif %}>
|
||||
<span class="settings-switch-ui" aria-hidden="true"></span>
|
||||
<span class="settings-switch-text">
|
||||
<strong>启用企业微信推送</strong>
|
||||
<small>关闭后后台仍巡检,但不发消息</small>
|
||||
</span>
|
||||
</label>
|
||||
<label class="settings-field">Webhook 地址
|
||||
<input type="url" name="wechat_webhook" value="{{ wechat.webhook }}" placeholder="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=..." autocomplete="off">
|
||||
</label>
|
||||
<div class="settings-row-2">
|
||||
<label class="settings-field">告警冷却(秒)
|
||||
<input type="number" name="alert_cooldown_sec" value="{{ wechat.cooldown_sec }}" min="60" max="86400" step="1">
|
||||
</label>
|
||||
<label class="settings-field">连续失败阈值
|
||||
<input type="number" name="health_fail_threshold" value="{{ wechat.fail_threshold }}" min="1" max="20" step="1">
|
||||
</label>
|
||||
</div>
|
||||
<p class="field-hint settings-hint">连续拉取失败达到阈值后才告警,默认 2 次;同一机器在冷却期内不重复推送。</p>
|
||||
<div class="settings-actions">
|
||||
<button type="submit" name="form_action" value="wechat" class="settings-primary">保存告警配置</button>
|
||||
<button type="submit" name="form_action" value="wechat_test" class="btn-secondary">发送测试消息</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user