feat条件单页支持资金与交易户双向划转,并修正账户名被挤占。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-13 14:36:52 +08:00
parent 1c3ea77db8
commit b81b999090
4 changed files with 90 additions and 34 deletions
+51 -21
View File
@@ -251,7 +251,7 @@
if (fundEl) fundEl.textContent = "资金 " + fmtTradingU(fundingUsdt); if (fundEl) fundEl.textContent = "资金 " + fmtTradingU(fundingUsdt);
} }
function transferFundingToTrading(instanceId) { function transferInternal(instanceId, direction) {
const id = String(instanceId || ""); const id = String(instanceId || "");
const it = candidatesById[id]; const it = candidatesById[id];
if (!it) return; if (!it) return;
@@ -263,31 +263,39 @@
window.alert(it.transfer_block_msg || "当前不可划转"); window.alert(it.transfer_block_msg || "当前不可划转");
return; return;
} }
const fund = Number(it.funding_usdt); const toTrading = direction !== "to_funding";
const fromAcct = toTrading ? "funding" : "trading";
const toAcct = toTrading ? "trading" : "funding";
const srcBal = Number(toTrading ? it.funding_usdt : it.trading_usdt);
const defAmt = const defAmt =
!Number.isNaN(fund) && fund > 0 ? String(Math.round(fund * 10000) / 10000) : ""; !Number.isNaN(srcBal) && srcBal > 0
const raw = window.prompt("资金户 → 交易户(USDT)。本页划转,条件单表单不会丢失。", defAmt); ? String(Math.round(srcBal * 10000) / 10000)
: "";
const label = toTrading ? "资金户 → 交易户" : "交易户 → 资金户";
const raw = window.prompt(label + "(USDT)。本页划转,条件单表单不会丢失。", defAmt);
if (raw == null) return; if (raw == null) return;
const amount = Number(String(raw).trim()); const amount = Number(String(raw).trim());
if (!(amount > 0)) { if (!(amount > 0)) {
window.alert("请输入大于 0 的数量"); window.alert("请输入大于 0 的数量");
return; return;
} }
const btn = document.querySelector( const btns = document.querySelectorAll(
'.cond-inst-xfer[data-inst-id="' + id.replace(/"/g, "") + '"]' '.cond-inst-xfer[data-inst-id="' + id.replace(/"/g, "") + '"]'
); );
if (btn) { const labels = [];
btns.forEach(function (btn) {
labels.push(btn.textContent);
btn.disabled = true; btn.disabled = true;
btn.textContent = "划转中…"; btn.textContent = "划转中…";
} });
fetch("/api/instances/" + encodeURIComponent(id) + "/transfer", { fetch("/api/instances/" + encodeURIComponent(id) + "/transfer", {
method: "POST", method: "POST",
credentials: "same-origin", credentials: "same-origin",
headers: { "Content-Type": "application/json", Accept: "application/json" }, headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify({ body: JSON.stringify({
amount: amount, amount: amount,
from: "funding", from: fromAcct,
to: "trading", to: toAcct,
ccy: "USDT", ccy: "USDT",
}), }),
}) })
@@ -307,10 +315,14 @@
if (st) { if (st) {
st.textContent = st.textContent =
(it.name || id) + (it.name || id) +
" 已划入交易 " + " " +
label +
" " +
fmtTradingU(amount) + fmtTradingU(amount) +
"(交易 " + "(交易 " +
fmtTradingU(d.trading_usdt) + fmtTradingU(d.trading_usdt) +
" / 资金 " +
fmtTradingU(d.funding_usdt) +
")"; ")";
} }
}) })
@@ -318,10 +330,11 @@
window.alert("划转请求失败"); window.alert("划转请求失败");
}) })
.finally(function () { .finally(function () {
if (btn) { const blocked = !!(it.transfer_blocked || !it.online);
btn.disabled = !!(it.transfer_blocked || !it.online); btns.forEach(function (btn, i) {
btn.textContent = "划入交易"; btn.disabled = blocked;
} btn.textContent = labels[i] || btn.getAttribute("data-label") || "划转";
});
}); });
} }
@@ -341,16 +354,18 @@
const xferBlocked = !!(it.transfer_blocked || !it.online); const xferBlocked = !!(it.transfer_blocked || !it.online);
const xferTitle = xferBlocked const xferTitle = xferBlocked
? it.transfer_block_msg || (!it.online ? "离线" : "不可划转") ? it.transfer_block_msg || (!it.online ? "离线" : "不可划转")
: "资金户→交易户,本页完成不丢表单"; : "本页双向划转,表单不丢";
const dis = xferBlocked ? " disabled" : "";
return ( return (
'<div class="cond-inst-row' + '<div class="cond-inst-row' +
(disabled ? " is-off" : "") + (disabled ? " is-off" : "") +
'" data-inst-id="' + '" data-inst-id="' +
escapeHtml(id) + escapeHtml(id) +
'">' + '">' +
'<label class="cond-inst' + '<div class="cond-inst' +
(disabled ? " is-off" : "") + (disabled ? " is-off" : "") +
'" title="' + '">' +
'<label class="cond-inst-head" title="' +
escapeHtml(tip) + escapeHtml(tip) +
'">' + '">' +
'<input type="checkbox" name="cf-inst" value="' + '<input type="checkbox" name="cf-inst" value="' +
@@ -365,23 +380,35 @@
'<span class="cond-inst-tag">' + '<span class="cond-inst-tag">' +
escapeHtml(tip) + escapeHtml(tip) +
"</span>" + "</span>" +
"</label>" +
'<div class="cond-inst-body">' +
'<span class="cond-inst-funds cond-inst-funds--trading" title="交易账户可用">交易 ' + '<span class="cond-inst-funds cond-inst-funds--trading" title="交易账户可用">交易 ' +
escapeHtml(fmtTradingU(it.trading_usdt)) + escapeHtml(fmtTradingU(it.trading_usdt)) +
"</span>" + "</span>" +
'<span class="cond-inst-funds cond-inst-funds--funding muted" title="资金账户可用">资金 ' + '<span class="cond-inst-funds cond-inst-funds--funding muted" title="资金账户可用">资金 ' +
escapeHtml(fmtTradingU(it.funding_usdt)) + escapeHtml(fmtTradingU(it.funding_usdt)) +
"</span>" + "</span>" +
"</label>" + '<span class="cond-inst-actions">' +
'<button type="button" class="btn btn-sm cond-inst-xfer" data-inst-id="' + '<button type="button" class="btn btn-sm cond-inst-xfer" data-inst-id="' +
escapeHtml(id) + escapeHtml(id) +
'" title="' + '" data-dir="to_trading" data-label="划入交易" title="' +
escapeHtml(xferTitle) + escapeHtml(xferTitle) +
'"' + '"' +
(xferBlocked ? " disabled" : "") + dis +
">划入交易</button>" + ">划入交易</button>" +
'<button type="button" class="btn btn-secondary btn-sm cond-inst-xfer" data-inst-id="' +
escapeHtml(id) +
'" data-dir="to_funding" data-label="划入资金" title="' +
escapeHtml(xferTitle) +
'"' +
dis +
">划入资金</button>" +
'<button type="button" class="btn btn-secondary btn-sm cond-inst-open" data-inst-id="' + '<button type="button" class="btn btn-secondary btn-sm cond-inst-open" data-inst-id="' +
escapeHtml(id) + escapeHtml(id) +
'" title="新标签打开实例">打开</button>' + '" title="新标签打开实例">打开</button>' +
"</span>" +
"</div>" +
"</div>" +
"</div>" "</div>"
); );
} }
@@ -443,7 +470,10 @@
btn.addEventListener("click", function (ev) { btn.addEventListener("click", function (ev) {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
transferFundingToTrading(btn.getAttribute("data-inst-id") || ""); transferInternal(
btn.getAttribute("data-inst-id") || "",
btn.getAttribute("data-dir") || "to_trading"
);
}); });
}); });
box.querySelectorAll(".cond-inst-open").forEach(function (btn) { box.querySelectorAll(".cond-inst-open").forEach(function (btn) {
+36 -10
View File
@@ -1524,31 +1524,51 @@ input.readonly {
.cond-inst-group-label { margin-bottom: 8px; } .cond-inst-group-label { margin-bottom: 8px; }
.cond-inst-grid { .cond-inst-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 10px; gap: 10px;
} }
.cond-inst-row { .cond-inst-row {
display: flex; display: block;
align-items: stretch; min-width: 0;
gap: 8px;
} }
.cond-inst-row.is-off { opacity: 0.5; } .cond-inst-row.is-off { opacity: 0.5; }
.cond-inst { .cond-inst {
display: flex; display: flex;
align-items: center; flex-direction: column;
justify-content: space-between; align-items: stretch;
gap: 8px; gap: 8px;
flex: 1;
min-width: 0; min-width: 0;
padding: 10px 12px; padding: 10px 12px;
border-radius: 10px; border-radius: 10px;
border: 1px solid var(--line); border: 1px solid var(--line);
background: rgba(8, 16, 30, 0.72); background: rgba(8, 16, 30, 0.72);
}
.cond-inst input { width: auto; margin: 0; flex-shrink: 0; }
.cond-inst-head {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
cursor: pointer; cursor: pointer;
} }
.cond-inst input { width: auto; margin: 0; } .cond-inst.is-off .cond-inst-head { cursor: not-allowed; }
.cond-inst-name { flex: 1; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .cond-inst-name {
flex: 1;
font-weight: 600;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cond-inst-tag { color: var(--muted); font-size: 0.75rem; flex-shrink: 0; } .cond-inst-tag { color: var(--muted); font-size: 0.75rem; flex-shrink: 0; }
.cond-inst-body {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px 10px;
padding-left: 24px;
min-width: 0;
}
.cond-inst-funds { .cond-inst-funds {
color: var(--accent-2, #38bdf8); color: var(--accent-2, #38bdf8);
font-size: 0.78rem; font-size: 0.78rem;
@@ -1560,10 +1580,16 @@ input.readonly {
color: var(--muted); color: var(--muted);
font-weight: 500; font-weight: 500;
} }
.cond-inst-actions {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 6px;
margin-left: auto;
}
.cond-inst-xfer, .cond-inst-xfer,
.cond-inst-open { .cond-inst-open {
flex-shrink: 0; flex-shrink: 0;
align-self: center;
white-space: nowrap; white-space: nowrap;
} }
.cond-inst.is-off { cursor: not-allowed; } .cond-inst.is-off { cursor: not-allowed; }
+1 -1
View File
@@ -11,7 +11,7 @@
<link rel="icon" href="{{ url_for('static', filename='icons/favicon.ico') }}?v=2" sizes="any"> <link rel="icon" href="{{ url_for('static', filename='icons/favicon.ico') }}?v=2" sizes="any">
<link rel="apple-touch-icon" href="{{ url_for('static', filename='icons/apple-touch-icon.png') }}?v=2"> <link rel="apple-touch-icon" href="{{ url_for('static', filename='icons/apple-touch-icon.png') }}?v=2">
<link rel="manifest" href="/manifest.webmanifest"> <link rel="manifest" href="/manifest.webmanifest">
<link rel="stylesheet" href="{{ url_for('static', filename='hub.css') }}?v=48"> <link rel="stylesheet" href="{{ url_for('static', filename='hub.css') }}?v=50">
<script> <script>
(function () { (function () {
try { try {
+2 -2
View File
@@ -68,7 +68,7 @@
<div class="cond-section"> <div class="cond-section">
<div class="cond-section-title">客户端</div> <div class="cond-section-title">客户端</div>
<p class="muted" style="margin:0 0 8px;font-size:.76rem">展示交易/资金余额;「划入交易」在本页完成(资金→交易),表单不丢。「打开」仅备用进实例。</p> <p class="muted" style="margin:0 0 8px;font-size:.76rem">展示交易/资金余额;「划入交易 / 划入资金」本页双向划转,表单不丢。「打开」仅备用进实例。</p>
<div id="cf-instances"></div> <div id="cf-instances"></div>
</div> </div>
@@ -95,6 +95,6 @@
</div> </div>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script src="{{ url_for('static', filename='cond_orders.js') }}?v=9"></script> <script src="{{ url_for('static', filename='cond_orders.js') }}?v=11"></script>
<script>HubCondOrders.boot();</script> <script>HubCondOrders.boot();</script>
{% endblock %} {% endblock %}