97 lines
3.7 KiB
Python
97 lines
3.7 KiB
Python
"""统计报表:以课时核对表 Excel 快照为主数据源"""
|
|
from datetime import date
|
|
|
|
from flask import render_template, request
|
|
from models import Student
|
|
from utils import login_required, permission_required
|
|
from keshi_display import list_period_stats
|
|
from keshi_stats import (
|
|
resolve_report_period,
|
|
period_overview,
|
|
year_overview,
|
|
cumulative_finance,
|
|
course_stats_for_period,
|
|
refund_breakdown,
|
|
monthly_trend_from_snapshots,
|
|
class_activity_for_period,
|
|
)
|
|
|
|
|
|
def register_routes(app):
|
|
|
|
@app.route('/statistics', endpoint='statistics')
|
|
@login_required
|
|
@permission_required('statistics_view')
|
|
def statistics():
|
|
year_arg = request.args.get('year', type=int)
|
|
month_arg = request.args.get('month', type=int)
|
|
period_arg = request.args.get('period', '').strip()
|
|
if period_arg and '-' in period_arg:
|
|
y_s, m_s = period_arg.split('-', 1)
|
|
try:
|
|
year_arg, month_arg = int(y_s), int(m_s)
|
|
except ValueError:
|
|
pass
|
|
year, month = resolve_report_period(year_arg, month_arg)
|
|
period_stats_list = list_period_stats()
|
|
available_periods = sorted(
|
|
period_stats_list,
|
|
key=lambda p: (p['year'], p['month']),
|
|
)
|
|
month_ov = period_overview(year, month)
|
|
year_ov = year_overview(year)
|
|
finance = cumulative_finance()
|
|
course_stats = course_stats_for_period(year, month)
|
|
refund_rows = refund_breakdown(year, month)
|
|
class_activity = class_activity_for_period(year, month)
|
|
monthly_trend = monthly_trend_from_snapshots()
|
|
|
|
active_students = Student.query.filter_by(status=1).count()
|
|
|
|
return render_template(
|
|
'statistics.html',
|
|
year=year,
|
|
month=month,
|
|
period_label=f'{year}-{month:02d}',
|
|
period_stats_list=period_stats_list,
|
|
available_periods=available_periods,
|
|
data_source='excel',
|
|
month_recharge=month_ov['recharge'],
|
|
month_consumption=month_ov['consumed_hours'],
|
|
month_consumed_amount=month_ov['consumed_amount'],
|
|
month_refund=month_ov['refund'],
|
|
month_new_signups=month_ov['new_signups'],
|
|
month_end_balance=month_ov['end_balance'],
|
|
month_accounts=month_ov['active_accounts'],
|
|
year_recharge=year_ov['recharge'],
|
|
year_consumption=year_ov['consumed_hours'],
|
|
year_refund=year_ov['refund'],
|
|
year_new_signups=year_ov['new_signups'],
|
|
course_stats=course_stats,
|
|
refund_rows=refund_rows,
|
|
class_activity=class_activity,
|
|
total_recharge=finance['total_recharge'],
|
|
total_refund=finance['total_refund'],
|
|
net_income=finance['net_income'],
|
|
total_consumed_amount=finance['total_consumed_amount'],
|
|
monthly_trend=monthly_trend,
|
|
active_students=active_students,
|
|
)
|
|
|
|
@app.route('/statistics/export', endpoint='statistics_export')
|
|
@login_required
|
|
@permission_required('statistics_export')
|
|
def statistics_export():
|
|
from utils import export_statistics_snapshot_data
|
|
year_arg = request.args.get('year', type=int)
|
|
month_arg = request.args.get('month', type=int)
|
|
period_arg = request.args.get('period', '').strip()
|
|
if period_arg and '-' in period_arg:
|
|
y_s, m_s = period_arg.split('-', 1)
|
|
try:
|
|
year_arg, month_arg = int(y_s), int(m_s)
|
|
except ValueError:
|
|
pass
|
|
year, month = resolve_report_period(year_arg, month_arg)
|
|
return export_statistics_snapshot_data(year, month)
|