Compare commits
2 Commits
91840ca2ca
...
5e9d9f00e8
| Author | SHA1 | Date | |
|---|---|---|---|
| 5e9d9f00e8 | |||
| e155682b5f |
@@ -24,11 +24,33 @@ def get_active_contracts(db: Session) -> list[str]:
|
|||||||
|
|
||||||
@router.get("/", response_class=HTMLResponse)
|
@router.get("/", response_class=HTMLResponse)
|
||||||
def contract_index(request: Request, db: Session = Depends(get_db)):
|
def contract_index(request: Request, db: Session = Depends(get_db)):
|
||||||
active_contracts = get_active_contracts(db)
|
from app.models import Product
|
||||||
|
|
||||||
|
# Build product → contracts mapping, ordered by product code
|
||||||
|
products = (
|
||||||
|
db.query(Product)
|
||||||
|
.order_by(Product.code)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
|
product_groups = []
|
||||||
|
all_codes = []
|
||||||
|
for prod in products:
|
||||||
|
codes = [
|
||||||
|
c.code for c in prod.contracts if c.is_active
|
||||||
|
]
|
||||||
|
if codes:
|
||||||
|
product_groups.append({
|
||||||
|
"code": prod.code,
|
||||||
|
"name": prod.name,
|
||||||
|
"exchange": prod.exchange,
|
||||||
|
"contracts": codes,
|
||||||
|
})
|
||||||
|
all_codes.extend(codes)
|
||||||
|
|
||||||
latest = (
|
latest = (
|
||||||
db.query(DailyBar)
|
db.query(DailyBar)
|
||||||
.filter(DailyBar.contract.in_(active_contracts))
|
.filter(DailyBar.contract.in_(all_codes))
|
||||||
.order_by(DailyBar.date.desc())
|
.order_by(DailyBar.date.desc())
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
@@ -42,7 +64,7 @@ def contract_index(request: Request, db: Session = Depends(get_db)):
|
|||||||
template.render(
|
template.render(
|
||||||
request=request,
|
request=request,
|
||||||
active_nav="contracts",
|
active_nav="contracts",
|
||||||
contracts=active_contracts,
|
product_groups=product_groups,
|
||||||
contract_bars=contract_bars,
|
contract_bars=contract_bars,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,12 +5,20 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="section-title">合约列表</div>
|
{% for pg in product_groups %}
|
||||||
|
<div style="margin-bottom:24px;border:1px solid var(--border);border-radius:10px;overflow:hidden;">
|
||||||
<div class="table-wrap">
|
<div class="product-header"
|
||||||
<table>
|
style="display:flex;align-items:center;gap:12px;padding:12px 18px;background:var(--th-bg);cursor:pointer;user-select:none;"
|
||||||
|
onclick="toggleProduct(this)">
|
||||||
|
<span class="collapse-arrow" style="font-size:0.75rem;transition:transform .2s;display:inline-block;transform:rotate(0deg);">▼</span>
|
||||||
|
<strong style="font-size:0.92rem;">{{ pg.code }} · {{ pg.name }}</strong>
|
||||||
|
<span style="font-size:0.78rem;color:var(--sub);">{{ pg.exchange }}</span>
|
||||||
|
<span style="font-size:0.78rem;color:var(--sub);margin-left:8px;">{{ pg.contracts|length }} 合约</span>
|
||||||
|
</div>
|
||||||
|
<div class="product-body">
|
||||||
|
<table>
|
||||||
<tr><th>合约</th><th>日期</th><th>开盘</th><th>收盘</th><th>最高</th><th>最低</th><th>振幅</th><th>操作</th></tr>
|
<tr><th>合约</th><th>日期</th><th>开盘</th><th>收盘</th><th>最高</th><th>最低</th><th>振幅</th><th>操作</th></tr>
|
||||||
{% for c in contracts %}
|
{% for c in pg.contracts %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{{ c }}</strong></td>
|
<td><strong>{{ c }}</strong></td>
|
||||||
{% if c in contract_bars %}
|
{% if c in contract_bars %}
|
||||||
@@ -32,6 +40,22 @@
|
|||||||
<td><a href="/contracts/{{ c }}" style="color:var(--accent);text-decoration:none;">详情 →</a></td>
|
<td><a href="/contracts/{{ c }}" style="color:var(--accent);text-decoration:none;">详情 →</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function toggleProduct(header) {
|
||||||
|
var body = header.nextElementSibling;
|
||||||
|
var arrow = header.querySelector('.collapse-arrow');
|
||||||
|
if (body.style.display === 'none') {
|
||||||
|
body.style.display = 'block';
|
||||||
|
arrow.style.transform = 'rotate(0deg)';
|
||||||
|
} else {
|
||||||
|
body.style.display = 'none';
|
||||||
|
arrow.style.transform = 'rotate(-90deg)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user