Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 71ef310648 | |||
| e3f288083c | |||
| d44e93dd4f |
@@ -3,7 +3,7 @@ from fastapi import APIRouter, Depends, Form, Request
|
|||||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from app.database import get_db
|
from app.database import get_db
|
||||||
from app.models import Round, Position, Contract
|
from app.models import Round, Position, Contract, Product
|
||||||
|
|
||||||
router = APIRouter(prefix="/positions", tags=["positions"])
|
router = APIRouter(prefix="/positions", tags=["positions"])
|
||||||
|
|
||||||
@@ -18,6 +18,16 @@ def get_active_contracts(db: Session) -> list[str]:
|
|||||||
return [c[0] for c in contracts]
|
return [c[0] for c in contracts]
|
||||||
|
|
||||||
|
|
||||||
|
def get_product_contracts(db: Session) -> dict:
|
||||||
|
result: dict[str, list[str]] = {}
|
||||||
|
products = db.query(Product).order_by(Product.code).all()
|
||||||
|
for p in products:
|
||||||
|
codes = [c.code for c in p.contracts if c.is_active]
|
||||||
|
if codes:
|
||||||
|
result[p.code] = codes
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_class=HTMLResponse)
|
@router.get("/", response_class=HTMLResponse)
|
||||||
def positions_page(request: Request, db: Session = Depends(get_db)):
|
def positions_page(request: Request, db: Session = Depends(get_db)):
|
||||||
active_rounds = (
|
active_rounds = (
|
||||||
@@ -33,6 +43,7 @@ def positions_page(request: Request, db: Session = Depends(get_db)):
|
|||||||
request=request,
|
request=request,
|
||||||
active_nav="positions",
|
active_nav="positions",
|
||||||
contracts=get_active_contracts(db),
|
contracts=get_active_contracts(db),
|
||||||
|
product_contracts=get_product_contracts(db),
|
||||||
active_rounds=active_rounds,
|
active_rounds=active_rounds,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -20,6 +20,17 @@ def get_active_contracts(db: Session) -> list[str]:
|
|||||||
return [c[0] for c in contracts]
|
return [c[0] for c in contracts]
|
||||||
|
|
||||||
|
|
||||||
|
def get_product_contracts(db: Session) -> dict:
|
||||||
|
"""Return {product_code: [contract_codes]} for active contracts."""
|
||||||
|
result: dict[str, list[str]] = {}
|
||||||
|
products = db.query(Product).order_by(Product.code).all()
|
||||||
|
for p in products:
|
||||||
|
codes = [c.code for c in p.contracts if c.is_active]
|
||||||
|
if codes:
|
||||||
|
result[p.code] = codes
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def today_str() -> str:
|
def today_str() -> str:
|
||||||
return date.today().isoformat()
|
return date.today().isoformat()
|
||||||
|
|
||||||
@@ -41,6 +52,7 @@ def trades_page(request: Request, db: Session = Depends(get_db)):
|
|||||||
request=request,
|
request=request,
|
||||||
active_nav="trades",
|
active_nav="trades",
|
||||||
contracts=get_active_contracts(db),
|
contracts=get_active_contracts(db),
|
||||||
|
product_contracts=get_product_contracts(db),
|
||||||
directions=DIRECTIONS,
|
directions=DIRECTIONS,
|
||||||
open_trades=open_trades,
|
open_trades=open_trades,
|
||||||
closed_trades=closed_trades,
|
closed_trades=closed_trades,
|
||||||
|
|||||||
@@ -16,15 +16,21 @@
|
|||||||
<div class="form-card" style="margin-bottom:28px;">
|
<div class="form-card" style="margin-bottom:28px;">
|
||||||
<form method="post" action="/positions/round">
|
<form method="post" action="/positions/round">
|
||||||
<div style="display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap;">
|
<div style="display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap;">
|
||||||
<div class="form-group" style="margin-bottom:0;flex:1;min-width:140px;">
|
<div class="form-group" style="margin-bottom:0;flex:1;min-width:100px;">
|
||||||
<label>合约</label>
|
<label>品种</label>
|
||||||
<select name="contract_code" required>
|
<select id="productSelect" required onchange="filterContracts()">
|
||||||
<option value="">-- 选择合约 --</option>
|
<option value="">--</option>
|
||||||
{% for c in contracts %}
|
{% for pcode in product_contracts %}
|
||||||
<option value="{{ c }}">{{ c }}</option>
|
<option value="{{ pcode }}">{{ pcode }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group" style="margin-bottom:0;flex:1;min-width:120px;">
|
||||||
|
<label>合约</label>
|
||||||
|
<select name="contract_code" id="contractSelect" required disabled>
|
||||||
|
<option value="">-- 先选品种 --</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="form-group" style="margin-bottom:0;flex:1;min-width:100px;">
|
<div class="form-group" style="margin-bottom:0;flex:1;min-width:100px;">
|
||||||
<label>每日手数 N</label>
|
<label>每日手数 N</label>
|
||||||
<input type="number" name="daily_hands" value="1" min="1" max="10" required>
|
<input type="number" name="daily_hands" value="1" min="1" max="10" required>
|
||||||
@@ -161,4 +167,19 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var productContracts = {{ product_contracts | tojson }};
|
||||||
|
function filterContracts() {
|
||||||
|
var prod = document.getElementById('productSelect').value;
|
||||||
|
var sel = document.getElementById('contractSelect');
|
||||||
|
sel.innerHTML = '<option value="">-- 选择合约 --</option>';
|
||||||
|
sel.disabled = !prod;
|
||||||
|
if (prod && productContracts[prod]) {
|
||||||
|
productContracts[prod].forEach(function(c) {
|
||||||
|
var display = c.startsWith(prod) ? c.substring(prod.length) : c;
|
||||||
|
sel.innerHTML += '<option value="' + c + '">' + display + '</option>';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -34,13 +34,19 @@
|
|||||||
<div class="form-card" style="margin-bottom:28px;max-width:100%;">
|
<div class="form-card" style="margin-bottom:28px;max-width:100%;">
|
||||||
<form method="post" action="/trades/open">
|
<form method="post" action="/trades/open">
|
||||||
<div style="display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap;">
|
<div style="display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap;">
|
||||||
|
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:100px;">
|
||||||
|
<label>品种</label>
|
||||||
|
<select id="productSelect" required onchange="filterContracts()">
|
||||||
|
<option value="">--</option>
|
||||||
|
{% for pcode in product_contracts %}
|
||||||
|
<option value="{{ pcode }}">{{ pcode }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:120px;">
|
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:120px;">
|
||||||
<label>合约</label>
|
<label>合约</label>
|
||||||
<select name="contract_code" required>
|
<select name="contract_code" id="contractSelect" required disabled>
|
||||||
<option value="">--</option>
|
<option value="">-- 先选品种 --</option>
|
||||||
{% for c in contracts %}
|
|
||||||
<option value="{{ c }}">{{ c }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:70px;">
|
<div class="form-group" style="margin-bottom:0;flex:0 0 auto;min-width:70px;">
|
||||||
@@ -197,6 +203,19 @@
|
|||||||
|
|
||||||
{% if view != 'closed' %}
|
{% if view != 'closed' %}
|
||||||
<script>
|
<script>
|
||||||
|
var productContracts = {{ product_contracts | tojson }};
|
||||||
|
function filterContracts() {
|
||||||
|
var prod = document.getElementById('productSelect').value;
|
||||||
|
var sel = document.getElementById('contractSelect');
|
||||||
|
sel.innerHTML = '<option value="">-- 选择合约 --</option>';
|
||||||
|
sel.disabled = !prod;
|
||||||
|
if (prod && productContracts[prod]) {
|
||||||
|
productContracts[prod].forEach(function(c) {
|
||||||
|
var display = c.startsWith(prod) ? c.substring(prod.length) : c;
|
||||||
|
sel.innerHTML += '<option value="' + c + '">' + display + '</option>';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
function showCloseForm(tradeId) {
|
function showCloseForm(tradeId) {
|
||||||
document.getElementById('closeForm').action = '/trades/' + tradeId + '/close';
|
document.getElementById('closeForm').action = '/trades/' + tradeId + '/close';
|
||||||
document.getElementById('closeFormOverlay').style.display = 'block';
|
document.getElementById('closeFormOverlay').style.display = 'block';
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user