diff --git a/ft-app/app/routers/admin.py b/ft-app/app/routers/admin.py index 9f5c305..38ca7ff 100644 --- a/ft-app/app/routers/admin.py +++ b/ft-app/app/routers/admin.py @@ -2,7 +2,7 @@ from fastapi import APIRouter, Depends, Form, Request from fastapi.responses import HTMLResponse, RedirectResponse from sqlalchemy.orm import Session from app.database import get_db -from app.models import Product, Contract +from app.models import Product, Contract, DailyBar from app.collector import sync_active_contracts, sync_one_contract router = APIRouter(prefix="/admin", tags=["admin"]) @@ -22,23 +22,35 @@ def admin_page(request: Request, db: Session = Depends(get_db)): .order_by(Contract.code) .all() ) + contract_list = [] + for c in contracts: + bar_count = ( + db.query(DailyBar) + .filter(DailyBar.contract == c.code) + .count() + ) + contract_list.append({ + "id": c.id, "code": c.code, "name": c.name, + "is_active": c.is_active, "bar_count": bar_count, + }) + product_data.append({ "id": p.id, "code": p.code, "name": p.name, "exchange": p.exchange, - "contracts": [ - {"id": c.id, "code": c.code, "name": c.name, "is_active": c.is_active} - for c in contracts - ], + "contracts": contract_list, }) + total_contracts = sum(len(pd["contracts"]) for pd in product_data) + template = request.app.state.templates.get_template("admin.html") return HTMLResponse( template.render( request=request, active_nav="admin", products=product_data, + total_contracts=total_contracts, exchanges=EXCHANGES, ) ) @@ -57,7 +69,7 @@ def create_product( p = Product(code=code.upper(), name=name, exchange=exchange) db.add(p) db.commit() - return RedirectResponse("/admin/", status_code=303) + return RedirectResponse("/admin/?tab=product", status_code=303) @router.post("/contract") @@ -78,7 +90,7 @@ def create_contract( ) db.add(c) db.commit() - return RedirectResponse("/admin/", status_code=303) + return RedirectResponse("/admin/?tab=contract", status_code=303) @router.post("/contract/{contract_id}/toggle") @@ -87,7 +99,7 @@ def toggle_contract(contract_id: int, db: Session = Depends(get_db)): if c: c.is_active = not c.is_active db.commit() - return RedirectResponse("/admin/", status_code=303) + return RedirectResponse("/admin/?tab=contract", status_code=303) @router.post("/contract/{contract_id}/delete") @@ -96,7 +108,7 @@ def delete_contract(contract_id: int, db: Session = Depends(get_db)): if c: db.delete(c) db.commit() - return RedirectResponse("/admin/", status_code=303) + return RedirectResponse("/admin/?tab=contract", status_code=303) @router.post("/product/{product_id}/delete") @@ -105,7 +117,7 @@ def delete_product(product_id: int, db: Session = Depends(get_db)): if p: db.delete(p) db.commit() - return RedirectResponse("/admin/", status_code=303) + return RedirectResponse("/admin/?tab=product", status_code=303) @router.post("/sync") @@ -113,10 +125,21 @@ def sync_all(request: Request): results = sync_active_contracts() total = sum(results.values()) print(f"[sync] Synced {total} bars across {len(results)} contracts: {results}") - return RedirectResponse("/admin/?synced=" + str(total), status_code=303) + return RedirectResponse(f"/admin/?tab=sync&synced={total}", status_code=303) @router.post("/sync/{contract_code}") def sync_single(contract_code: str): count = sync_one_contract(contract_code.upper()) - return RedirectResponse(f"/admin/?synced={count}", status_code=303) + return RedirectResponse(f"/admin/?tab=sync&synced={count}", status_code=303) + + +@router.post("/sync/product/{product_id}") +def sync_product(product_id: int, request: Request, db: Session = Depends(get_db)): + contracts = db.query(Contract).filter( + Contract.product_id == product_id, Contract.is_active == True + ).all() + total = 0 + for c in contracts: + total += sync_one_contract(c.code) + return RedirectResponse(f"/admin/?tab=sync&synced={total}", status_code=303) diff --git a/ft-app/app/templates/admin.html b/ft-app/app/templates/admin.html index ba16f67..7d903a3 100644 --- a/ft-app/app/templates/admin.html +++ b/ft-app/app/templates/admin.html @@ -29,7 +29,8 @@ {# ═══════════════════ Tab: 数据同步 ═══════════════════ #}
| 合约 | 品种 | 状态 | 操作 |
|---|---|---|---|
| {{ c.code }} | -{{ p.name }} | -{% if c.is_active %}启用{% else %}停用{% endif %} | -- 查看 - - | -