HEL-155: 按第三轮效果图改造管理端首页
替换借贷轧差为待审核统计卡;公司往来合计/明细合成主从模块(折叠明细); 新增柱状图与折线图位;接入 /api/admin/dashboard 真实归集与审核队列数据。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Cursor
multica-agent
parent
ece3e53472
commit
77fc625ded
@@ -11,7 +11,7 @@ from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
from bank_importer import (
|
||||
auth, importing, ledger_events, manual_records, master_data, matching,
|
||||
auth, dashboard, importing, ledger_events, manual_records, master_data, matching,
|
||||
multipart, personal_transit, positions, settings, subjects,
|
||||
)
|
||||
from bank_importer.db import connect, migrate, utc_now
|
||||
@@ -95,6 +95,13 @@ class AppHandler(SimpleHTTPRequestHandler):
|
||||
if path == "/api/admin/match-exceptions":
|
||||
self._handle_admin_match_exceptions(query)
|
||||
return
|
||||
if path == "/api/admin/dashboard":
|
||||
self._handle_admin_dashboard(query)
|
||||
return
|
||||
company_dash = re.fullmatch(r"/api/admin/dashboard/companies/(\d+)", path)
|
||||
if company_dash:
|
||||
self._handle_admin_dashboard_company(int(company_dash.group(1)), query)
|
||||
return
|
||||
if path == "/api/admin/personal-transit-mappings":
|
||||
self._handle_admin_personal_mappings(query)
|
||||
return
|
||||
@@ -1866,6 +1873,49 @@ class AppHandler(SimpleHTTPRequestHandler):
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
def _handle_admin_dashboard(self, query: dict[str, list[str]]) -> None:
|
||||
connection = connect(DB_PATH)
|
||||
try:
|
||||
user = self._require_admin(connection)
|
||||
if user is None:
|
||||
return
|
||||
from_date = (query.get("from") or ["2026-01-01"])[0] or "2026-01-01"
|
||||
cutoff = (query.get("cutoff") or [None])[0] or None
|
||||
try:
|
||||
payload = dashboard.build_dashboard(
|
||||
connection, from_date=from_date, cutoff=cutoff
|
||||
)
|
||||
except ValueError as exc:
|
||||
self._send_json(400, {"status": "error", "message": str(exc)})
|
||||
return
|
||||
self._send_json(200, {"status": "ok", **payload})
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
def _handle_admin_dashboard_company(
|
||||
self, company_id: int, query: dict[str, list[str]]
|
||||
) -> None:
|
||||
connection = connect(DB_PATH)
|
||||
try:
|
||||
user = self._require_admin(connection)
|
||||
if user is None:
|
||||
return
|
||||
from_date = (query.get("from") or ["2026-01-01"])[0] or "2026-01-01"
|
||||
cutoff = (query.get("cutoff") or [dashboard.today_shanghai()])[0]
|
||||
try:
|
||||
payload = dashboard.company_peer_groups(
|
||||
connection, company_id, from_date=from_date, cutoff=cutoff
|
||||
)
|
||||
except KeyError:
|
||||
self._send_json(404, {"status": "error", "message": "公司不存在。"})
|
||||
return
|
||||
except ValueError as exc:
|
||||
self._send_json(400, {"status": "error", "message": str(exc)})
|
||||
return
|
||||
self._send_json(200, {"status": "ok", **payload})
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
def _handle_admin_reconcile(self) -> None:
|
||||
connection = connect(DB_PATH)
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user