feat: add reporting workflow and optimize dashboard loading
This commit is contained in:
56
backend/scripts/daily_report.py
Normal file
56
backend/scripts/daily_report.py
Normal file
@ -0,0 +1,56 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from _bootstrap import add_src_to_path
|
||||
|
||||
add_src_to_path()
|
||||
|
||||
from lhbfx.config import load_config
|
||||
from lhbfx.mailer import send_email
|
||||
from lhbfx.pdf_export import generate_daily_report_pdf
|
||||
from lhbfx.reporting import (
|
||||
build_daily_report,
|
||||
build_email_body,
|
||||
default_report_output_path,
|
||||
get_latest_trade_date,
|
||||
)
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Generate and optionally send lhbfx daily report")
|
||||
parser.add_argument("--trade-date", help="Trade date in YYYY-MM-DD format")
|
||||
parser.add_argument("--send", action="store_true", help="Send email after generating report")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = parse_args()
|
||||
config = load_config()
|
||||
trade_date = args.trade_date or get_latest_trade_date(config)
|
||||
if not trade_date:
|
||||
raise RuntimeError("No trade date available in database")
|
||||
|
||||
report = build_daily_report(config=config, trade_date=trade_date)
|
||||
pdf_path = default_report_output_path(trade_date)
|
||||
generate_daily_report_pdf(report, pdf_path)
|
||||
body_text = build_email_body(report)
|
||||
|
||||
print(f"Generated PDF: {pdf_path}")
|
||||
|
||||
if args.send:
|
||||
if config.mail is None:
|
||||
raise RuntimeError("Mail config is missing")
|
||||
subject = f"lhbfx 盘后日报 - {trade_date}"
|
||||
send_email(
|
||||
mail_config=config.mail,
|
||||
subject=subject,
|
||||
body_text=body_text,
|
||||
attachments=[pdf_path],
|
||||
)
|
||||
print(f"Email sent to: {', '.join(config.mail.recipients)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -59,6 +59,15 @@ def apply_incremental_alters(config: AppConfig) -> None:
|
||||
cursor.execute(
|
||||
"ALTER TABLE lhb_detail_seats ADD UNIQUE KEY uniq_lhb_detail_record (trade_date, stock_code, rid, table_title, seat_name)"
|
||||
)
|
||||
if not _index_exists(cursor, schema_name, "lhb_detail_seats", "idx_lhb_detail_trader_stock_date"):
|
||||
cursor.execute(
|
||||
"ALTER TABLE lhb_detail_seats ADD KEY idx_lhb_detail_trader_stock_date (matched_trader_name, stock_code, trade_date)"
|
||||
)
|
||||
|
||||
if not _index_exists(cursor, schema_name, "warning_events", "idx_warning_events_trader_type_date_code"):
|
||||
cursor.execute(
|
||||
"ALTER TABLE warning_events ADD KEY idx_warning_events_trader_type_date_code (trader_name, warning_type, trade_date, stock_code)"
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
||||
Reference in New Issue
Block a user