Add global autofill guard for hub, env, and transfer inputs.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* 全局防浏览器自动填充登录账号/密码进业务输入框.
|
||||
* 跳过真正的登录/改密字段;对划转数量等易中招框用 readonly 到聚焦.
|
||||
*/
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var GUARD_ATTRS = {
|
||||
autocomplete: "off",
|
||||
autocorrect: "off",
|
||||
autocapitalize: "off",
|
||||
spellcheck: "false",
|
||||
"data-lpignore": "true",
|
||||
"data-1p-ignore": "true",
|
||||
"data-bwignore": "true",
|
||||
"data-form-type": "other",
|
||||
};
|
||||
|
||||
function looksLikeUsername(v) {
|
||||
return /^[a-z][a-z0-9._-]{1,31}$/i.test(String(v || "").trim());
|
||||
}
|
||||
|
||||
function isAuthField(el) {
|
||||
if (!el || !el.getAttribute) return true;
|
||||
var t = String(el.type || "").toLowerCase();
|
||||
if (t === "hidden" || t === "checkbox" || t === "radio" || t === "file" || t === "submit" || t === "button") {
|
||||
return true;
|
||||
}
|
||||
if (el.getAttribute("aria-hidden") === "true") return true;
|
||||
if (el.tabIndex === -1 && String(el.getAttribute("autocomplete") || "").toLowerCase() === "username") {
|
||||
return true; // 诱饵账号框
|
||||
}
|
||||
var idName = String(el.id || "") + " " + String(el.name || "");
|
||||
if (/^(pwd-|hub-pwd-|login-)/i.test(String(el.id || ""))) return true;
|
||||
if (el.closest) {
|
||||
if (el.closest(".login-form, #login-form, form.login-form, .password-settings, [data-password-settings]")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// env API Key 等 type=password 仍要防登录密码灌入,不在此跳过
|
||||
if (t === "password" && /^(username|password)$/i.test(String(el.name || ""))) {
|
||||
if (el.closest && el.closest("form[method='post'], form[method='POST']")) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isAmountLike(el) {
|
||||
var key = String(el.id || "") + " " + String(el.name || "") + " " + String(el.placeholder || "");
|
||||
return /amount|xfer|transfer|划转|数量|金额/i.test(key);
|
||||
}
|
||||
|
||||
function wipeBad(el) {
|
||||
if (!el || isAuthField(el)) return;
|
||||
var v = String(el.value || "").trim();
|
||||
if (!looksLikeUsername(v)) return;
|
||||
var t = String(el.type || "text").toLowerCase();
|
||||
if (t === "number" || isAmountLike(el) || /price|sheets|qty|sl|tp|target|entry|strike/i.test(String(el.id || "") + String(el.name || ""))) {
|
||||
el.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
function harden(el) {
|
||||
if (!el || el.nodeType !== 1) return;
|
||||
if (isAuthField(el)) return;
|
||||
if (el.getAttribute("aria-hidden") === "true") return;
|
||||
if (el.dataset && el.dataset.autofillGuarded === "1") {
|
||||
wipeBad(el);
|
||||
return;
|
||||
}
|
||||
if (el.dataset) el.dataset.autofillGuarded = "1";
|
||||
|
||||
Object.keys(GUARD_ATTRS).forEach(function (k) {
|
||||
var cur = el.getAttribute(k);
|
||||
if (k === "autocomplete" && cur && /^(username|current-password)/i.test(cur)) {
|
||||
return;
|
||||
}
|
||||
// env 密钥框用 new-password 更抗登录密码灌入
|
||||
if (k === "autocomplete" && String(el.type || "").toLowerCase() === "password") {
|
||||
el.setAttribute(k, "new-password");
|
||||
return;
|
||||
}
|
||||
if (!cur || cur === "on") el.setAttribute(k, GUARD_ATTRS[k]);
|
||||
});
|
||||
|
||||
if (String(el.type || "").toLowerCase() === "password" || isAmountLike(el)) {
|
||||
el.setAttribute("readonly", "readonly");
|
||||
el.addEventListener("focus", function () {
|
||||
el.removeAttribute("readonly");
|
||||
});
|
||||
el.addEventListener("blur", function () {
|
||||
if (!el.value) el.setAttribute("readonly", "readonly");
|
||||
});
|
||||
}
|
||||
|
||||
wipeBad(el);
|
||||
setTimeout(function () {
|
||||
wipeBad(el);
|
||||
}, 250);
|
||||
setTimeout(function () {
|
||||
wipeBad(el);
|
||||
}, 900);
|
||||
setTimeout(function () {
|
||||
wipeBad(el);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function scan(root) {
|
||||
var scope = root && root.querySelectorAll ? root : document;
|
||||
var list = scope.querySelectorAll(
|
||||
'input[type="text"], input[type="number"], input[type="search"], input[type="url"], input[type="email"], input[type="tel"], input[type="password"], input:not([type]), textarea'
|
||||
);
|
||||
for (var i = 0; i < list.length; i++) harden(list[i]);
|
||||
}
|
||||
|
||||
function boot() {
|
||||
scan(document);
|
||||
if (typeof MutationObserver === "undefined") return;
|
||||
var obs = new MutationObserver(function (mutations) {
|
||||
for (var i = 0; i < mutations.length; i++) {
|
||||
var m = mutations[i];
|
||||
if (m.type === "childList") {
|
||||
for (var j = 0; j < m.addedNodes.length; j++) {
|
||||
var n = m.addedNodes[j];
|
||||
if (!n || n.nodeType !== 1) continue;
|
||||
if (n.matches && n.matches("input, textarea")) harden(n);
|
||||
else if (n.querySelectorAll) scan(n);
|
||||
}
|
||||
} else if (m.type === "attributes" && m.target) {
|
||||
harden(m.target);
|
||||
}
|
||||
}
|
||||
});
|
||||
obs.observe(document.documentElement, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
attributeFilter: ["value"],
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", boot);
|
||||
} else {
|
||||
boot();
|
||||
}
|
||||
|
||||
window.cmAutofillGuardScan = scan;
|
||||
})();
|
||||
@@ -61,6 +61,7 @@ def install_instance_theme_static(app) -> None:
|
||||
"records_review_page.js": "application/javascript; charset=utf-8",
|
||||
"ai_review_render.js": "application/javascript; charset=utf-8",
|
||||
"form_submit_guard.js": "application/javascript; charset=utf-8",
|
||||
"autofill_guard.js": "application/javascript; charset=utf-8",
|
||||
"key_monitor_form.js": "application/javascript; charset=utf-8",
|
||||
"time_close_ui.js": "application/javascript; charset=utf-8",
|
||||
"manual_order_rr_preview.js": "application/javascript; charset=utf-8",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<script src="/static/instance_theme.js?v=50"></script>
|
||||
<script src="/static/autofill_guard.js?v=1"></script>
|
||||
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
||||
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
|
||||
<link rel="stylesheet" href="/static/instance_page.css?v=11">
|
||||
@@ -117,7 +118,7 @@ const ORDER_ENTRY_MODEL_CODE_TO_CATEGORY = {{ entry_model_code_to_category | toj
|
||||
<script>
|
||||
window.__INSTANCE_DISPLAY__ = {{ display | tojson }};
|
||||
</script>
|
||||
<script src="/static/instance_settings_prefs.js?v=14"></script>
|
||||
<script src="/static/instance_settings_prefs.js?v=15"></script>
|
||||
<script src="/static/instance_live.js?v=6"></script>
|
||||
<script src="/static/instance_embed.js?v=27"></script>
|
||||
</body>
|
||||
|
||||
@@ -64,7 +64,13 @@
|
||||
type="password"
|
||||
data-env-key="{{ field.key }}"
|
||||
placeholder="{% if field.has_value %}修改时填写新值,留空不修改{% else %}请输入{% endif %}"
|
||||
autocomplete="off"
|
||||
autocomplete="new-password"
|
||||
data-lpignore="true"
|
||||
data-1p-ignore="true"
|
||||
data-bwignore="true"
|
||||
data-form-type="other"
|
||||
readonly
|
||||
onfocus="this.removeAttribute('readonly')"
|
||||
>
|
||||
{% else %}
|
||||
<input
|
||||
@@ -73,6 +79,14 @@
|
||||
type="text"
|
||||
data-env-key="{{ field.key }}"
|
||||
value="{{ field.current or field.default or '' }}"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="off"
|
||||
spellcheck="false"
|
||||
data-lpignore="true"
|
||||
data-1p-ignore="true"
|
||||
data-bwignore="true"
|
||||
data-form-type="other"
|
||||
>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<script src="/static/instance_theme.js?v=50"></script>
|
||||
<script src="/static/autofill_guard.js?v=1"></script>
|
||||
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
||||
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
|
||||
<script src="/static/account_risk_badge.js?v=4"></script>
|
||||
@@ -2019,6 +2020,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
});
|
||||
{% endif %}
|
||||
</script>
|
||||
<script src="/static/instance_settings_prefs.js?v=14"></script>
|
||||
<script src="/static/instance_settings_prefs.js?v=15"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -8,14 +8,17 @@
|
||||
不足从 <code>{{ auto_transfer_from }}</code> 划入,超出划回 <code>{{ auto_transfer_from }}</code>;
|
||||
<strong>持仓中不划转</strong>并微信通知.
|
||||
</p>
|
||||
<form action="/manual_transfer" method="post" class="form-row gate-transfer-form settings-transfer-form">
|
||||
<input name="amount" type="number" min="0.01" step="0.01" placeholder="手动划转金额 U" required>
|
||||
<select name="from_account" aria-label="划出账户">
|
||||
<form action="/manual_transfer" method="post" class="form-row gate-transfer-form settings-transfer-form" autocomplete="off">
|
||||
<input type="text" name="username" autocomplete="username" tabindex="-1" aria-hidden="true"
|
||||
style="position:absolute;left:-9999px;width:1px;height:1px;opacity:0" value="">
|
||||
<input name="amount" id="manual-xfer-amount" type="number" min="0.01" step="0.01" placeholder="手动划转金额 U" required
|
||||
autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-bwignore="true" data-form-type="other" readonly>
|
||||
<select name="from_account" aria-label="划出账户" autocomplete="off">
|
||||
<option value="funding" {% if auto_transfer_from == 'funding' %}selected{% endif %}>from: funding</option>
|
||||
<option value="swap" {% if auto_transfer_from == 'swap' %}selected{% endif %}>from: swap</option>
|
||||
<option value="spot" {% if auto_transfer_from == 'spot' %}selected{% endif %}>from: spot</option>
|
||||
</select>
|
||||
<select name="to_account" aria-label="划入账户">
|
||||
<select name="to_account" aria-label="划入账户" autocomplete="off">
|
||||
<option value="swap" {% if auto_transfer_to == 'swap' %}selected{% endif %}>to: swap</option>
|
||||
<option value="funding" {% if auto_transfer_to == 'funding' %}selected{% endif %}>to: funding</option>
|
||||
<option value="spot" {% if auto_transfer_to == 'spot' %}selected{% endif %}>to: spot</option>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{# 系统设置 · 账户密码(外层 card 由 settings_panel 提供) #}
|
||||
<h2>账户密码修改</h2>
|
||||
<p class="settings-subcard-desc">修改网页登录账号密码,写入 <code>.env</code> 后需重启实例生效.</p>
|
||||
<div class="settings-password-form">
|
||||
<div class="settings-password-form password-settings" data-password-settings="1">
|
||||
<label>当前密码 <input type="password" id="pwd-old" autocomplete="current-password"></label>
|
||||
<label>新用户名(可选) <input type="text" id="pwd-new-username" autocomplete="username"></label>
|
||||
<label>新密码 <input type="password" id="pwd-new" autocomplete="new-password"></label>
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
<label><input type="checkbox" name="mood_issues" value="扛单">扛单</label>
|
||||
<label><input type="checkbox" name="mood_issues" value="重仓违规">重仓违规</label>
|
||||
</div>
|
||||
<textarea name="note" rows="2" placeholder="备注"></textarea>
|
||||
<textarea name="note" rows="2" placeholder="备注" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other"></textarea>
|
||||
<button type="submit" style="margin-top:8px">保存复盘记录</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -7,14 +7,17 @@
|
||||
划转:自动划转 {{ '开启' if auto_transfer_enabled else '关闭' }}(每天<strong>北京时间 {{ auto_transfer_bj_hour }}:00</strong>起该整点小时内尝试;账簿按 <strong>UTC 自然日</strong>去重;将 {{ auto_transfer_to }} 调整至 {{ transfer_amount_fmt|default(funds_fmt(auto_transfer_amount)) }}U:不足从 {{ auto_transfer_from }} 划入,超出划回 {{ auto_transfer_from }};<strong>持仓中不划转</strong>并微信通知)
|
||||
</div>
|
||||
</details>
|
||||
<form action="/manual_transfer" method="post" class="form-row gate-transfer-form">
|
||||
<input name="amount" type="number" min="0.01" step="0.01" placeholder="手动划转金额U" required>
|
||||
<select name="from_account">
|
||||
<form action="/manual_transfer" method="post" class="form-row gate-transfer-form" autocomplete="off">
|
||||
<input type="text" name="username" autocomplete="username" tabindex="-1" aria-hidden="true"
|
||||
style="position:absolute;left:-9999px;width:1px;height:1px;opacity:0" value="">
|
||||
<input name="amount" type="number" min="0.01" step="0.01" placeholder="手动划转金额U" required
|
||||
autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-bwignore="true" data-form-type="other" readonly>
|
||||
<select name="from_account" autocomplete="off">
|
||||
<option value="funding" {% if auto_transfer_from == 'funding' %}selected{% endif %}>from: funding</option>
|
||||
<option value="swap" {% if auto_transfer_from == 'swap' %}selected{% endif %}>from: swap</option>
|
||||
<option value="spot" {% if auto_transfer_from == 'spot' %}selected{% endif %}>from: spot</option>
|
||||
</select>
|
||||
<select name="to_account">
|
||||
<select name="to_account" autocomplete="off">
|
||||
<option value="swap" {% if auto_transfer_to == 'swap' %}selected{% endif %}>to: swap</option>
|
||||
<option value="funding" {% if auto_transfer_to == 'funding' %}selected{% endif %}>to: funding</option>
|
||||
<option value="spot" {% if auto_transfer_to == 'spot' %}selected{% endif %}>to: spot</option>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{# 复盘表单:首行按字段宽度比例;下单类型/开仓类型与离场触发同一行 #}
|
||||
{% macro journal_form_fields(entry_reason_options, order_type_options) -%}
|
||||
<div class="form-grid journal-form-row1">
|
||||
<input type="datetime-local" name="open_datetime" class="journal-field-datetime" required>
|
||||
<input type="datetime-local" name="close_datetime" class="journal-field-datetime" required>
|
||||
<input name="coin" class="journal-field-coin" placeholder="BTC" required>
|
||||
<input name="tf" class="journal-field-tf" placeholder="5m" required>
|
||||
<input name="pnl" class="journal-field-num" placeholder="盈亏(U)" required>
|
||||
<input name="expect_rr" class="journal-field-num" placeholder="预期RR">
|
||||
<input name="real_rr" class="journal-field-num" placeholder="实际RR">
|
||||
<input type="datetime-local" name="open_datetime" class="journal-field-datetime" required autocomplete="off">
|
||||
<input type="datetime-local" name="close_datetime" class="journal-field-datetime" required autocomplete="off">
|
||||
<input name="coin" class="journal-field-coin" placeholder="BTC" required autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other">
|
||||
<input name="tf" class="journal-field-tf" placeholder="5m" required autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other">
|
||||
<input name="pnl" class="journal-field-num" placeholder="盈亏(U)" required autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other">
|
||||
<input name="expect_rr" class="journal-field-num" placeholder="预期RR" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other">
|
||||
<input name="real_rr" class="journal-field-num" placeholder="实际RR" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other">
|
||||
</div>
|
||||
<div class="form-grid journal-form-row2">
|
||||
<select name="direction" id="journal-direction" class="journal-field-direction" required title="做多/做空">
|
||||
@@ -38,7 +38,7 @@
|
||||
<option value="止损">止损</option>
|
||||
<option value="其他">其他</option>
|
||||
</select>
|
||||
<input name="early_exit_note" id="early-exit-note" placeholder="离场补充(仅手工平仓必填)">
|
||||
<input name="early_exit_note" id="early-exit-note" placeholder="离场补充(仅手工平仓必填)" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other">
|
||||
<select name="post_breakeven_stare"><option value="否">保本后盯盘:否</option><option value="是">保本后盯盘:是</option></select>
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% else %}
|
||||
<input id="{{ id }}" name="{{ name }}" placeholder="{{ placeholder }}" {% if required %}required{% endif %} value="{{ value }}">
|
||||
<input id="{{ id }}" name="{{ name }}" placeholder="{{ placeholder }}" {% if required %}required{% endif %} value="{{ value }}" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" data-lpignore="true" data-1p-ignore="true" data-form-type="other">
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
|
||||
@@ -777,6 +777,17 @@ _ACCOUNT_RISK_BADGE_CSS = _REPO_STATIC / "account_risk_badge.css"
|
||||
_ACCOUNT_RISK_BADGE_JS = _REPO_STATIC / "account_risk_badge.js"
|
||||
_OPTIONS_EXPIRY_COUNTDOWN_JS = _REPO_STATIC / "options_expiry_countdown.js"
|
||||
_OPTIONS_POSITION_CARDS_JS = _REPO_STATIC / "options_position_cards.js"
|
||||
_AUTOFILL_GUARD_JS = _REPO_STATIC / "autofill_guard.js"
|
||||
|
||||
|
||||
@app.get("/assets/autofill_guard.js")
|
||||
def hub_autofill_guard_js():
|
||||
if not _AUTOFILL_GUARD_JS.is_file():
|
||||
raise HTTPException(status_code=404, detail="autofill_guard.js not found")
|
||||
return FileResponse(
|
||||
str(_AUTOFILL_GUARD_JS),
|
||||
media_type="application/javascript; charset=utf-8",
|
||||
)
|
||||
|
||||
|
||||
@app.get("/assets/account_risk_badge.css")
|
||||
|
||||
@@ -5009,12 +5009,12 @@
|
||||
<div class="settings-card-head">
|
||||
<label class="chk-label"><input type="checkbox" class="ex-enabled" ${ex.enabled ? "checked" : ""} ${ex.env_disabled ? "disabled" : ""}/> 启用</label>
|
||||
${envOff}
|
||||
<input class="ex-name" value="${esc(ex.name || "")}" placeholder="显示名称" />
|
||||
<input class="ex-name" value="${esc(ex.name || "")}" placeholder="显示名称" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
|
||||
</div>
|
||||
<div class="settings-grid">
|
||||
<div class="field"><label>Flask URL</label><input class="ex-flask" value="${esc(ex.flask_url || "")}" /></div>
|
||||
<div class="field"><label>Agent URL</label><input class="ex-agent" value="${esc(ex.agent_url || "")}" /></div>
|
||||
<div class="field field-wide"><label>复盘链接(可空)</label><input class="ex-review" value="${esc(ex.review_url || "")}" placeholder="留空则自动生成 /records" /></div>
|
||||
<div class="field"><label>Flask URL</label><input class="ex-flask" value="${esc(ex.flask_url || "")}" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other" /></div>
|
||||
<div class="field"><label>Agent URL</label><input class="ex-agent" value="${esc(ex.agent_url || "")}" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other" /></div>
|
||||
<div class="field field-wide"><label>复盘链接(可空)</label><input class="ex-review" value="${esc(ex.review_url || "")}" placeholder="留空则自动生成 /records" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other" /></div>
|
||||
</div>
|
||||
<div class="cap-chips">
|
||||
<label><input type="checkbox" class="cap-key" ${caps.includes("key") ? "checked" : ""}/> 监控关键位</label>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<script src="/assets/theme.js?v=20260604-hub-inst-theme"></script>
|
||||
<script src="/assets/autofill_guard.js?v=1"></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content" />
|
||||
<meta name="theme-color" content="#0b0e18" />
|
||||
<meta name="apple-mobile-web-app-title" content="中控" />
|
||||
@@ -113,15 +114,15 @@
|
||||
</label>
|
||||
<label class="plan-field">
|
||||
<span>目标位</span>
|
||||
<input id="plan-create-target" type="text" placeholder="如 68500" />
|
||||
<input id="plan-create-target" type="text" placeholder="如 68500" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
|
||||
</label>
|
||||
<label class="plan-field">
|
||||
<span>当前区间</span>
|
||||
<input id="plan-create-range" type="text" placeholder="如 67000-68000" />
|
||||
<input id="plan-create-range" type="text" placeholder="如 67000-68000" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
|
||||
</label>
|
||||
<label class="plan-field plan-field-full">
|
||||
<span>备注</span>
|
||||
<textarea id="plan-create-note" rows="2" placeholder="计划说明…"></textarea>
|
||||
<textarea id="plan-create-note" rows="2" placeholder="计划说明…" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other"></textarea>
|
||||
</label>
|
||||
</div>
|
||||
<button type="submit" class="primary plan-submit-btn">保存并进入进行中</button>
|
||||
@@ -1077,10 +1078,10 @@
|
||||
</div>
|
||||
<p class="settings-display-hint">修改中控网页登录账号密码,写入 <code>manual_trading_hub/.env</code> 后需重启中控生效.当前用户:<code id="hub-pwd-current-user">—</code></p>
|
||||
<div class="settings-grid hub-password-grid">
|
||||
<div class="field"><label>当前密码</label><input type="password" id="hub-pwd-old" autocomplete="current-password"></div>
|
||||
<div class="field"><label>新用户名(可选)</label><input type="text" id="hub-pwd-new-username" autocomplete="username"></div>
|
||||
<div class="field"><label>新密码</label><input type="password" id="hub-pwd-new" autocomplete="new-password"></div>
|
||||
<div class="field"><label>确认新密码</label><input type="password" id="hub-pwd-confirm" autocomplete="new-password"></div>
|
||||
<div class="field" data-password-settings="1"><label>当前密码</label><input type="password" id="hub-pwd-old" autocomplete="current-password"></div>
|
||||
<div class="field" data-password-settings="1"><label>新用户名(可选)</label><input type="text" id="hub-pwd-new-username" autocomplete="username"></div>
|
||||
<div class="field" data-password-settings="1"><label>新密码</label><input type="password" id="hub-pwd-new" autocomplete="new-password"></div>
|
||||
<div class="field" data-password-settings="1"><label>确认新密码</label><input type="password" id="hub-pwd-confirm" autocomplete="new-password"></div>
|
||||
</div>
|
||||
<div class="hub-settings-tab-actions">
|
||||
<button type="button" class="primary" id="hub-pwd-save-btn">保存密码</button>
|
||||
@@ -1378,7 +1379,7 @@
|
||||
<script src="https://unpkg.com/lightweight-charts@4.2.0/dist/lightweight-charts.standalone.production.js"></script>
|
||||
<script src="/assets/chart_draw.js?v=20260609-market-day-split"></script>
|
||||
<script src="/assets/chart.js?v=20260715-fs-landscape"></script>
|
||||
<script src="/assets/plan.js?v=20260614-plan-refresh"></script>
|
||||
<script src="/assets/plan.js?v=20260720-autofill"></script>
|
||||
<script src="/assets/calculator.js?v=20260715-calc-tabs"></script>
|
||||
<script src="/assets/trade_stats_calendar.js?v=3"></script>
|
||||
<script src="/assets/archive.js?v=20260717-archive-cal-chart"></script>
|
||||
@@ -1393,6 +1394,6 @@
|
||||
<script src="/assets/options_expiry_countdown.js?v=1"></script>
|
||||
<script src="/assets/options_position_cards.js?v=2"></script>
|
||||
<script src="/assets/backup.js?v=1"></script>
|
||||
<script src="/assets/app.js?v=20260717-quotes-feed"></script>
|
||||
<script src="/assets/app.js?v=20260720-autofill"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -481,7 +481,7 @@
|
||||
"</select></label>" +
|
||||
'<label class="plan-field"><span>币种</span><input name="symbol" type="text" value="' +
|
||||
esc(p.symbol) +
|
||||
'" required /></label>' +
|
||||
'" required autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other" /></label>' +
|
||||
'<label class="plan-field"><span>类型</span><select name="plan_type" required>' +
|
||||
opts(meta.plan_types, "plan_type", "value", "label") +
|
||||
"</select></label>" +
|
||||
@@ -496,10 +496,10 @@
|
||||
"</span></label>" +
|
||||
'<label class="plan-field"><span>目标位</span><input name="target_level" type="text" value="' +
|
||||
esc(p.target_level || "") +
|
||||
'" /></label>' +
|
||||
'" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other" /></label>' +
|
||||
'<label class="plan-field"><span>当前区间</span><input name="current_range" type="text" value="' +
|
||||
esc(p.current_range || "") +
|
||||
'" /></label>' +
|
||||
'" autocomplete="off" data-lpignore="true" data-1p-ignore="true" data-form-type="other" /></label>' +
|
||||
'<label class="plan-field plan-field-full"><span>入场方案</span><select name="entry_scheme" required>' +
|
||||
opts(meta.entry_schemes, "entry_scheme", "value", "label") +
|
||||
"</select></label>" +
|
||||
|
||||
Reference in New Issue
Block a user