# Copyright (c) 2025-2026 马建军. All rights reserved. """HTTP routes for fees module.""" from __future__ import annotations from datetime import date, datetime from flask import ( Response, flash, jsonify, redirect, render_template, request, send_file, session, stream_with_context, url_for, ) def register(deps) -> None: app = deps.app login_required = deps.login_required require_nav = deps.require_nav get_db = deps.get_db get_setting = deps.get_setting set_setting = deps.set_setting fetch_price = deps.fetch_price send_wechat_msg = deps.send_wechat_msg touch_stats_cache = deps.touch_stats_cache get_stats_data = deps.get_stats_data build_market_quote_payload = deps.build_market_quote_payload today_str = deps.today_str expire_old_plans = deps.expire_old_plans TZ = deps.tz DB_PATH = deps.db_path UPLOAD_DIR = deps.upload_dir OPEN_TYPES = deps.open_types EXIT_TRIGGERS = deps.exit_triggers BEHAVIOR_TAGS = deps.behavior_tags KLINE_PERIODS = deps.kline_periods KLINE_CUTOFFS = deps.kline_cutoffs calc_holding_duration = deps.calc_holding_duration holding_to_minutes = deps.holding_to_minutes classify_close_result = deps.classify_close_result calc_rr_ratio = deps.calc_rr_ratio calc_theoretical_pnl = deps.calc_theoretical_pnl parse_review_date_filter = deps.parse_review_date_filter _trading_mode = deps.trading_mode _ua_is_phone = deps.ua_is_phone _static_asset_v = deps.static_asset_v from modules.fees.fee_specs import count_fee_rates_by_source, list_fee_rates_for_ui @app.route("/fees", methods=["GET", "POST"]) @login_required @require_nav("fees") def fees(): from modules.core.trading_context import get_trading_mode from modules.ctp.ctp_fee_worker import ( schedule_ctp_fee_sync, get_fee_last_sync, fees_synced_today, fee_sync_in_progress, ) from modules.ctp.vnpy_bridge import ctp_status mode = get_trading_mode(get_setting) if request.method == "POST": action = request.form.get("action") if action == "sync_ctp": force = request.form.get("force") == "1" _, msg = schedule_ctp_fee_sync( mode, get_setting=get_setting, set_setting=set_setting, force=force, ) flash(msg) return redirect(url_for("fees")) rates = list_fee_rates_for_ui() fee_counts = count_fee_rates_by_source() ctp_st = ctp_status(mode) return render_template( "fees.html", rates=rates, fee_counts=fee_counts, fee_last_sync=get_fee_last_sync(get_setting), fee_synced_today=fees_synced_today(get_setting), fee_sync_running=fee_sync_in_progress(), ctp_connected=bool(ctp_st.get("connected")), )