持仓页面品种tab增加全平按钮,支持按品种批量平仓
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -152,6 +152,29 @@ def edit_trade(
|
|||||||
return RedirectResponse("/trades/", status_code=303)
|
return RedirectResponse("/trades/", status_code=303)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/bulk-close")
|
||||||
|
def bulk_close(
|
||||||
|
request: Request,
|
||||||
|
product_code: str = Form(...),
|
||||||
|
close_date: str = Form(...),
|
||||||
|
close_price: float = Form(...),
|
||||||
|
close_fee: float = Form(0.0),
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
):
|
||||||
|
trades = (
|
||||||
|
db.query(Trade)
|
||||||
|
.filter(Trade.product_code == product_code.upper(), Trade.status == "open")
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
for t in trades:
|
||||||
|
t.close_date = date.fromisoformat(close_date)
|
||||||
|
t.close_price = close_price
|
||||||
|
t.close_fee = close_fee
|
||||||
|
t.status = "closed"
|
||||||
|
db.commit()
|
||||||
|
return RedirectResponse("/trades/", status_code=303)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/{trade_id}/delete")
|
@router.post("/{trade_id}/delete")
|
||||||
def delete_trade(trade_id: int, db: Session = Depends(get_db)):
|
def delete_trade(trade_id: int, db: Session = Depends(get_db)):
|
||||||
t = db.query(Trade).filter(Trade.id == trade_id).first()
|
t = db.query(Trade).filter(Trade.id == trade_id).first()
|
||||||
|
|||||||
@@ -138,6 +138,14 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if product_tab != '全部' and open_trades %}
|
||||||
|
<div style="margin-bottom:24px;">
|
||||||
|
<button class="btn" style="background:var(--danger);color:#fff;font-size:0.88rem;padding:8px 24px;" onclick="showBulkClose('{{ product_tab }}')">
|
||||||
|
全平 {{ product_tab }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div style="text-align:center;padding:40px;color:var(--sub);">暂无持仓</div>
|
<div style="text-align:center;padding:40px;color:var(--sub);">暂无持仓</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -166,6 +174,31 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{# ── 全平弹窗 ── #}
|
||||||
|
<div id="bulkCloseOverlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:99;" onclick="hideBulkClose()"></div>
|
||||||
|
<div id="bulkCloseBox" style="display:none;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:24px;z-index:100;width:360px;max-width:90vw;">
|
||||||
|
<h3 style="margin-bottom:16px;">全平 <span id="bulkCloseLabel"></span></h3>
|
||||||
|
<form method="post" id="bulkCloseForm" action="/trades/bulk-close">
|
||||||
|
<input type="hidden" name="product_code" id="bulkCloseProduct">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>平仓日期</label>
|
||||||
|
<input type="date" name="close_date" value="{{ today }}" required style="font-size:0.85rem;">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>平仓价格</label>
|
||||||
|
<input type="number" step="any" name="close_price" required style="font-size:0.9rem;">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>手续费</label>
|
||||||
|
<input type="number" step="any" name="close_fee" value="0" style="font-size:0.9rem;">
|
||||||
|
</div>
|
||||||
|
<div style="display:flex;gap:10px;justify-content:flex-end;">
|
||||||
|
<button type="button" class="btn" style="background:var(--th-bg);color:var(--fg);" onclick="hideBulkClose()">取消</button>
|
||||||
|
<button type="submit" class="btn" style="background:var(--danger);color:#fff;">确认全平</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="tab-panel active">
|
<div class="tab-panel active">
|
||||||
@@ -302,6 +335,16 @@ function hideCloseForm() {
|
|||||||
document.getElementById('closeFormOverlay').style.display = 'none';
|
document.getElementById('closeFormOverlay').style.display = 'none';
|
||||||
document.getElementById('closeFormBox').style.display = 'none';
|
document.getElementById('closeFormBox').style.display = 'none';
|
||||||
}
|
}
|
||||||
|
function showBulkClose(productCode) {
|
||||||
|
document.getElementById('bulkCloseLabel').textContent = productCode;
|
||||||
|
document.getElementById('bulkCloseProduct').value = productCode;
|
||||||
|
document.getElementById('bulkCloseOverlay').style.display = 'block';
|
||||||
|
document.getElementById('bulkCloseBox').style.display = 'block';
|
||||||
|
}
|
||||||
|
function hideBulkClose() {
|
||||||
|
document.getElementById('bulkCloseOverlay').style.display = 'none';
|
||||||
|
document.getElementById('bulkCloseBox').style.display = 'none';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user