189 lines
9.1 KiB
HTML
189 lines
9.1 KiB
HTML
{% extends 'ewoooc_base.html' %}
|
||
{% block title %}營運成長報表 - EwoooC{% endblock %}
|
||
|
||
{% block extra_css %}
|
||
<link rel="stylesheet" href="{{ url_for('static', filename='css/page-growth.css') }}">
|
||
<link rel="stylesheet" href="{{ url_for('static', filename='css/page-growth-bem.css') }}">
|
||
{% endblock %}
|
||
|
||
{% macro ga_chart_snapshot(labels, values, mode='currency') %}
|
||
<div class="ga-chart-snapshot">
|
||
{% for label in labels %}
|
||
{% set val = values[loop.index0]|default(0) %}
|
||
<span class="ga-chart-snapshot__item">
|
||
<b>{{ label }}</b>
|
||
<strong>
|
||
{% if mode == 'pct' %}{{ "{:+.1f}%".format(val) }}
|
||
{% else %}${{ "{:,.0f}".format(val) }}{% endif %}
|
||
</strong>
|
||
</span>
|
||
{% endfor %}
|
||
</div>
|
||
{% endmacro %}
|
||
|
||
{% block ewooo_content %}
|
||
<div class="growth-analysis-page" data-page-group="analytics">
|
||
{% include 'components/_analysis_report_tabs.html' %}
|
||
|
||
{# ── Page head ──────────────────────────────────── #}
|
||
<header class="ga-page-head">
|
||
<div class="ga-page-head__title">
|
||
<i class="fas fa-rocket ga-page-head__icon"></i>
|
||
<div>
|
||
<h1 class="ga-page-head__h1">營運成長策略報表</h1>
|
||
<p class="ga-page-head__brief">用月趨勢評估成長缺口、價差壓力與毛利品質。</p>
|
||
</div>
|
||
</div>
|
||
<span class="ga-page-head__meta">
|
||
數據更新至 <strong>{{ chart_data.labels[-1] if chart_data.labels else '-' }}</strong>
|
||
</span>
|
||
</header>
|
||
|
||
{% if is_empty_state|default(false) %}
|
||
<section class="ga-empty-state">
|
||
<i class="fas fa-chart-line" aria-hidden="true"></i>
|
||
<h2>尚未匯入可分析的業績資料</h2>
|
||
<p>{{ empty_message|default('先匯入月度業績資料,再評估成長、AOV 與毛利缺口。') }}</p>
|
||
</section>
|
||
{% endif %}
|
||
|
||
{# ── KPI Row (3 cards) ──────────────────────────── #}
|
||
<section class="ga-kpi-row">
|
||
<article class="ga-kpi ga-kpi--revenue">
|
||
<div class="ga-kpi__label">YTD 本年度累計業績 ({{ kpi.current_year }})</div>
|
||
<div class="ga-kpi__value">${{ "{:,.0f}".format(kpi.ytd_revenue) }}</div>
|
||
<div class="ga-kpi__delta">
|
||
<span class="ga-kpi__chip">YoY Growth</span>
|
||
<span class="ga-kpi__yoy {{ 'is-up' if kpi.ytd_growth >= 0 else 'is-down' }}">
|
||
<i class="fas fa-{{ 'arrow-up' if kpi.ytd_growth >= 0 else 'arrow-down' }}"></i>
|
||
{{ "{:+.1f}%".format(kpi.ytd_growth) }}
|
||
</span>
|
||
<span class="ga-kpi__hint">vs 去年同期</span>
|
||
</div>
|
||
<i class="fas fa-chart-line ga-kpi__icon-bg"></i>
|
||
</article>
|
||
|
||
<article class="ga-kpi ga-kpi--aov">
|
||
<div class="ga-kpi__label">最新月平均單價</div>
|
||
<div class="ga-kpi__value">${{ "{:,.0f}".format(kpi.recent_aov) }}</div>
|
||
<div class="ga-kpi__hint">月結銷售額 ÷ 銷量</div>
|
||
<i class="fas fa-shopping-cart ga-kpi__icon-bg"></i>
|
||
</article>
|
||
|
||
<article class="ga-kpi ga-kpi--orders">
|
||
<div class="ga-kpi__label">總銷量</div>
|
||
<div class="ga-kpi__value">{{ "{:,.0f}".format(kpi.total_orders) }}</div>
|
||
<div class="ga-kpi__hint">全時期累計件數</div>
|
||
<i class="fas fa-receipt ga-kpi__icon-bg"></i>
|
||
</article>
|
||
</section>
|
||
|
||
{# ── Charts Row 1 ──────────────────────────────── #}
|
||
<section class="ga-chart-row ga-chart-row--8-4">
|
||
<article class="ga-chart-card">
|
||
<header class="ga-chart-card__head">
|
||
<span class="ga-chart-card__title"><i class="fas fa-chart-bar"></i> 月營收與年增率 (Revenue & YoY)</span>
|
||
</header>
|
||
<div class="ga-chart-card__body ga-chart-card__body--lg has-html-chart">
|
||
<canvas id="revenueChart"></canvas>
|
||
{{ ga_chart_snapshot(chart_data.labels, chart_data.revenue, 'currency') }}
|
||
</div>
|
||
</article>
|
||
|
||
<article class="ga-chart-card">
|
||
<header class="ga-chart-card__head">
|
||
<span class="ga-chart-card__title"><i class="fas fa-percentage"></i> 月增率分析 (MoM)</span>
|
||
</header>
|
||
<div class="ga-chart-card__body ga-chart-card__body--lg has-html-chart">
|
||
<canvas id="momChart"></canvas>
|
||
{{ ga_chart_snapshot(chart_data.labels, chart_data.mom, 'pct') }}
|
||
</div>
|
||
</article>
|
||
</section>
|
||
|
||
{# ── Charts Row 2 ──────────────────────────────── #}
|
||
<section class="ga-chart-row ga-chart-row--6-6">
|
||
<article class="ga-chart-card">
|
||
<header class="ga-chart-card__head">
|
||
<span class="ga-chart-card__title"><i class="fas fa-wallet"></i> 平均單價趨勢</span>
|
||
</header>
|
||
<div class="ga-chart-card__body ga-chart-card__body--md has-html-chart">
|
||
<canvas id="aovChart"></canvas>
|
||
{{ ga_chart_snapshot(chart_data.labels, chart_data.aov, 'currency') }}
|
||
</div>
|
||
</article>
|
||
|
||
<article class="ga-chart-card">
|
||
<header class="ga-chart-card__head">
|
||
<span class="ga-chart-card__title"><i class="fas fa-hand-holding-usd"></i> 獲利能力分析 (Gross Margin %)</span>
|
||
</header>
|
||
<div class="ga-chart-card__body ga-chart-card__body--md has-html-chart">
|
||
<canvas id="marginChart"></canvas>
|
||
{{ ga_chart_snapshot(chart_data.labels, chart_data.margin_rate, 'pct') }}
|
||
</div>
|
||
</article>
|
||
</section>
|
||
|
||
<section class="ga-chart-row ga-chart-row--8-4">
|
||
<article class="ga-chart-card">
|
||
<header class="ga-chart-card__head">
|
||
<span class="ga-chart-card__title"><i class="fas fa-scale-balanced"></i> PChome 價格壓力趨勢</span>
|
||
</header>
|
||
<div class="ga-chart-card__body ga-chart-card__body--md has-html-chart">
|
||
<canvas id="competitorPressureChart"></canvas>
|
||
{{ ga_chart_snapshot(chart_data.labels, chart_data.competitor_gap_pct, 'pct') }}
|
||
</div>
|
||
</article>
|
||
|
||
<article class="ga-chart-card">
|
||
<header class="ga-chart-card__head">
|
||
<span class="ga-chart-card__title"><i class="fas fa-bullseye"></i> 比價資料品質</span>
|
||
</header>
|
||
<div class="ga-chart-card__body ga-chart-card__body--md">
|
||
{% set coverage = chart_data.competitor_coverage | default({}) %}
|
||
<div class="ga-competitor-quality">
|
||
<span>高信心門檻</span>
|
||
<strong class="momo-mono">{{ coverage.match_score_floor | default(0.76) }}</strong>
|
||
<span>決策支援覆蓋率</span>
|
||
<strong class="momo-mono">{{ coverage.decision_support_rate | default(coverage.decision_ready_rate | default(0)) }}%</strong>
|
||
<span>精準可告警覆蓋</span>
|
||
<strong class="momo-mono">{{ coverage.decision_ready_rate | default(0) }}%</strong>
|
||
<span>身份配對</span>
|
||
<strong class="momo-mono">{{ coverage.valid_matches | default(0) | number_format }}</strong>
|
||
<span>身份覆蓋率</span>
|
||
<strong class="momo-mono">{{ coverage.match_rate | default(0) }}%</strong>
|
||
<span>價格新鮮</span>
|
||
<strong class="momo-mono">{{ coverage.fresh_matches | default(0) | number_format }}</strong>
|
||
<span>新鮮率</span>
|
||
<strong class="momo-mono">{{ coverage.fresh_match_rate | default(0) }}%</strong>
|
||
<span>價格過期</span>
|
||
<strong class="momo-mono">{{ coverage.stale_matches | default(0) | number_format }}</strong>
|
||
<span>未知新鮮度</span>
|
||
<strong class="momo-mono">{{ coverage.unknown_freshness_matches | default(0) | number_format }}</strong>
|
||
<span>未形成有效身份配對</span>
|
||
<strong class="momo-mono">{{ coverage.pending | default(0) | number_format }}</strong>
|
||
<span>需單位價覆核</span>
|
||
<strong class="momo-mono">{{ coverage.unit_comparable_count | default(0) | number_format }}</strong>
|
||
<span>型錄/任選可比</span>
|
||
<strong class="momo-mono">{{ coverage.catalog_comparable_count | default(0) | number_format }}</strong>
|
||
<span>重算待人工覆核</span>
|
||
<strong class="momo-mono">{{ coverage.rescore_accepted_count | default(0) | number_format }}</strong>
|
||
<span>人工採用</span>
|
||
<strong class="momo-mono">{{ coverage.manual_accept_count | default(0) | number_format }}</strong>
|
||
<span>人工否決</span>
|
||
<strong class="momo-mono">{{ coverage.manual_reject_count | default(0) | number_format }}</strong>
|
||
<span>人工單位價</span>
|
||
<strong class="momo-mono">{{ coverage.manual_unit_price_count | default(0) | number_format }}</strong>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
</section>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block extra_js %}
|
||
<template id="chart-data">{{ chart_data | tojson }}</template>
|
||
<script src="{{ url_for('static', filename='js/analysis-chart-theme.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='js/page-growth.js') }}"></script>
|
||
{% endblock %}
|