加速月份總表特殊趨勢載入
All checks were successful
CD Pipeline / deploy (push) Successful in 55s

This commit is contained in:
OoO
2026-05-13 10:12:01 +08:00
parent 0bc6f18732
commit 0359e8154a
3 changed files with 89 additions and 2 deletions

View File

@@ -53,6 +53,37 @@ sys_log = SystemLogger("MonthlyRoutes").get_logger()
monthly_bp = Blueprint('monthly', __name__)
def _split_csv_param(value):
if not value:
return []
return [item.strip() for item in value.split(',') if item.strip()]
def _apply_monthly_filters(query, *, year=None, month=None, division=None, pm_name=None,
brand_name=None, vendor_name=None, area_name=None,
trade_type=None, ignore_year=False):
if year and not ignore_year:
query = query.filter(MonthlySummaryAnalysis.year == year)
if month:
query = query.filter(MonthlySummaryAnalysis.month == month)
if division:
query = query.filter(MonthlySummaryAnalysis.division == division)
if pm_name:
query = query.filter(MonthlySummaryAnalysis.pm_name == pm_name)
if brand_name:
query = query.filter(MonthlySummaryAnalysis.brand_name == brand_name)
if vendor_name:
query = query.filter(MonthlySummaryAnalysis.vendor_name == vendor_name)
area_values = _split_csv_param(area_name)
if len(area_values) > 1:
query = query.filter(MonthlySummaryAnalysis.area_name.in_(area_values))
elif len(area_values) == 1:
query = query.filter(MonthlySummaryAnalysis.area_name == area_values[0])
if trade_type:
query = query.filter(MonthlySummaryAnalysis.trade_type == trade_type)
return query
# ==========================================
# 頁面路由
# ==========================================
@@ -71,6 +102,57 @@ def monthly_summary_analysis_page():
# API 路由
# ==========================================
@monthly_bp.route('/api/monthly_summary_trend')
@login_required
def get_monthly_summary_trend():
"""API: 取得月份總表輕量趨勢資料。"""
year = request.args.get('year', type=int)
month = request.args.get('month', type=int)
division = request.args.get('division')
pm_name = request.args.get('pm_name')
brand_name = request.args.get('brand_name')
vendor_name = request.args.get('vendor')
area_name = request.args.get('area_name')
trade_type = request.args.get('trade_type')
db = DatabaseManager()
session = db.get_session()
try:
trend_query = session.query(
MonthlySummaryAnalysis.year,
MonthlySummaryAnalysis.month,
func.sum(MonthlySummaryAnalysis.sales_amt_curr).label('sales')
).group_by(
MonthlySummaryAnalysis.year, MonthlySummaryAnalysis.month
).order_by(MonthlySummaryAnalysis.year, MonthlySummaryAnalysis.month)
trend_query = _apply_monthly_filters(
trend_query,
year=year,
month=month,
division=division,
pm_name=pm_name,
brand_name=brand_name,
vendor_name=vendor_name,
area_name=area_name,
trade_type=trade_type,
)
trend_results = trend_query.all()
return jsonify({
'status': 'success',
'trend': [
{'date': f"{r.year}/{r.month}", 'sales': int(r.sales or 0)}
for r in trend_results
],
})
except Exception as e:
sys_log.error(f"取得月份總表趨勢資料失敗: {e}")
return jsonify({'status': 'error', 'message': str(e)}), 500
finally:
session.close()
@monthly_bp.route('/api/monthly_summary_data')
@login_required
def get_monthly_summary_data():

View File

@@ -231,6 +231,7 @@ def test_ai_recommend_uses_v2_shell_and_runtime_category_data():
def test_monthly_summary_analysis_uses_v2_shell_and_real_monthly_api():
template = (ROOT / "templates/monthly_summary_analysis.html").read_text(encoding="utf-8")
route_source = (ROOT / "routes/monthly_routes.py").read_text(encoding="utf-8")
script = (ROOT / "web/static/js/page-monthly-summary.js").read_text(encoding="utf-8")
assert "{% extends 'ewoooc_base.html' %}" in template
assert "{% block ewooo_content %}" in template
@@ -241,6 +242,9 @@ def test_monthly_summary_analysis_uses_v2_shell_and_real_monthly_api():
assert "monthly-analysis-hero" in template
assert "monthly-analysis-page" in template
assert "/api/monthly_summary_data" in template
assert "/api/monthly_summary_trend" in route_source
assert "/api/monthly_summary_trend" in script
assert "area_name=${encodeURIComponent(area)}&limit=1" not in script
assert "monthly_summary_analysis" in route_source
assert "active_page='monthly'" in route_source
assert "MonthlySummaryAnalysis" in route_source

View File

@@ -79,9 +79,10 @@
['私密保養,嬰幼洗沐', privacyInfantChart, 'privacyInfantChartTableBody']
];
pairs.forEach(([area, chart, tbody]) => {
fetch(`/api/monthly_summary_data?area_name=${encodeURIComponent(area)}&limit=1`)
fetch(`/api/monthly_summary_trend?area_name=${encodeURIComponent(area)}`)
.then(r => r.json())
.then(d => { if (d.status === 'success') renderExcelChart(chart, tbody, d.trend); });
.then(d => { if (d.status === 'success') renderExcelChart(chart, tbody, d.trend); })
.catch(err => console.error('monthly special trend failed', err));
});
}