feat条件单页支持资金与交易户双向划转,并修正账户名被挤占。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+51
-21
@@ -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
@@ -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
@@ -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 {
|
||||||
|
|||||||
@@ -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 %}
|
||||||
|
|||||||
Reference in New Issue
Block a user