Initial commit
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
commit
71db82393a
@@ -0,0 +1,75 @@
|
||||
{# 第十一部分:实践落地行动指南(拆分为并行segment,动态编号) #}
|
||||
{% set ns = namespace(idx=0) %}
|
||||
{# 章节小节编号:中文用一二三..,英文用 I II III.. #}
|
||||
{% set ag_section_labels = ag_section_labels if ag_section_labels is defined else (cn_nums if cn_nums is defined else ['I.','II.','III.','IV.','V.','VI.','VII.','VIII.','IX.']) %}
|
||||
|
||||
<div class="section" id="action-guide">
|
||||
<h1>{{ t.p11_h1 }}</h1>
|
||||
|
||||
<p class="section-intro" style="color:#555; font-style:italic; margin-bottom:1.5em; border-left:4px solid #2563eb; padding-left:12px;">
|
||||
{{ t.p11_intro }}
|
||||
</p>
|
||||
|
||||
{# ===== 战略聚焦:最紧迫的三件事(从第十部分引用,再次强化) ===== #}
|
||||
{% if llm_sections.get('part10_top3_priorities') %}
|
||||
<div class="top3-box" style="background: linear-gradient(135deg, #fef2f2, #fee2e2); border: 2px solid #dc2626; border-radius: 12px; padding: 24px; margin: 0 0 24px 0;">
|
||||
<h2 style="color: #991b1b; margin: 0 0 12px 0; font-size: 18px;">{{ t.p11_focus_title }}</h2>
|
||||
<p style="color: #7f1d1d; font-size: 14px; margin: 0 0 16px 0;">{{ t.p11_focus_intro | safe }}</p>
|
||||
<div class="llm-analysis" style="color: #7f1d1d;">
|
||||
{{ llm_sections.get('part10_top3_priorities') | safe }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ===== 急需突破(水平1)——重点展开 ===== #}
|
||||
{% if llm_sections.get('part11_critical') %}
|
||||
<h2 id="action-critical">{{ ag_section_labels[ns.idx] }} {{ t.p11_critical }}</h2>
|
||||
{% set ns.idx = ns.idx + 1 %}
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get('part11_critical') | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ===== 重点攻关(水平2)——重点展开 ===== #}
|
||||
{% if llm_sections.get('part11_attention') %}
|
||||
<h2 id="action-attention">{{ ag_section_labels[ns.idx] }} {{ t.p11_attention }}</h2>
|
||||
{% set ns.idx = ns.idx + 1 %}
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get('part11_attention') | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ===== 如果水平1和2都没有,显示提示 ===== #}
|
||||
{% if not llm_sections.get('part11_critical') and not llm_sections.get('part11_attention') %}
|
||||
<p style="color:#059669; margin:1em 0;">{{ t.p11_no_weak }}</p>
|
||||
{% endif %}
|
||||
|
||||
{# ===== 稳步巩固(水平3)——精简概括 ===== #}
|
||||
{% if llm_sections.get('part11_maintain') %}
|
||||
<h2 id="action-maintain">{{ ag_section_labels[ns.idx] }} {{ t.p11_maintain }}</h2>
|
||||
{% set ns.idx = ns.idx + 1 %}
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get('part11_maintain') | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ===== 深化引领(水平4)——精简概括 ===== #}
|
||||
{% if llm_sections.get('part11_excel') %}
|
||||
<h2 id="action-excel">{{ ag_section_labels[ns.idx] }} {{ t.p11_excel }}</h2>
|
||||
{% set ns.idx = ns.idx + 1 %}
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get('part11_excel') | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ===== 学期行动时间表 ===== #}
|
||||
<h2 id="action-timeline">{{ ag_section_labels[ns.idx] }} {{ t.p11_timeline }}</h2>
|
||||
{% set ns.idx = ns.idx + 1 %}
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get('part11_timeline', '<p>' + t.p11_timeline_loading + '</p>') | safe }}
|
||||
</div>
|
||||
|
||||
<p class="section-note" style="color:#888; font-size:0.9em; margin-top:2em; border-top:1px solid #eee; padding-top:1em;">
|
||||
{{ t.p11_disclaimer | safe }}
|
||||
</p>
|
||||
</div>
|
||||
@@ -0,0 +1,40 @@
|
||||
{# 总结与建议 #}
|
||||
<div class="section" id="conclusion">
|
||||
<h1>{{ t.p10_h1 }}</h1>
|
||||
|
||||
{# ===== 最紧迫的三件事(置顶,让校长第一时间看到) ===== #}
|
||||
{% if llm_sections.get('part10_top3_priorities') %}
|
||||
<div class="top3-box" style="background: linear-gradient(135deg, #eff6ff, #dbeafe); border: 2px solid #3b82f6; border-radius: 12px; padding: 24px; margin: 0 0 24px 0;">
|
||||
<h2 style="color: #1e40af; margin: 0 0 16px 0; font-size: 20px;">{{ t.p10_h2_top3 }}</h2>
|
||||
<p style="color: #1e3a5f; font-size: 14px; margin: 0 0 16px 0; font-style: italic;">{{ t.top3_intro }}</p>
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get('part10_top3_priorities') | safe }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ===== 跨维度综合分析 ===== #}
|
||||
{% if llm_sections.get('part10_cross_dimension') %}
|
||||
<h2>{{ t.p10_h2_cross }}</h2>
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get('part10_cross_dimension') | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- D. 进步空间瀑布图 -->
|
||||
{% if waterfall_data and waterfall_data.improvements %}
|
||||
<h2>{{ t.p10_h2_improve }}</h2>
|
||||
<div class="chart-box">
|
||||
<div id="waterfall-chart" class="chart" style="height:400px"></div>
|
||||
<div class="chart-title">{{ t.p10_fig_waterfall }}</div>
|
||||
</div>
|
||||
<div class="chart-caption">
|
||||
{{ llm_sections.get('part10_caption_waterfall', '') | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h2>{{ t.p10_h2_review }}</h2>
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get('part10_conclusion', '<p>' + t.loading + '</p>') | safe }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
{# 封面 #}
|
||||
<div class="cover">
|
||||
<h1>{{ t.report_title }}</h1>
|
||||
<div class="subtitle">{{ t.report_subtitle }}</div>
|
||||
<div class="school-name">{{ school_display }}</div>
|
||||
<div class="subtitle">{{ district_display }} · {{ t.school_type(school_info.get('type', '')) }}</div>
|
||||
<div class="date">{{ generation_date }}</div>
|
||||
</div>
|
||||
@@ -0,0 +1,144 @@
|
||||
{# 单个维度详细分析(在 for 循环内 include) #}
|
||||
{# 需要外部传入: dim_name, dim_data, part_id #}
|
||||
{% set dim_display = t.dim(dim_name) %}
|
||||
{% set part_num = part_id | replace('part', '') %}
|
||||
|
||||
<div class="section" id="{{ part_id }}">
|
||||
<h1>{{ t.part(part_id) }}</h1>
|
||||
|
||||
<h2>{{ t.dim_section_overall }}</h2>
|
||||
|
||||
<div class="score-cards">
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.dim_score_label.format(name=dim_display) }}</div>
|
||||
<div class="value">{{ "%.1f"|format(dim_data.score) }}</div>
|
||||
<div class="diff {{ 'positive' if dim_data.diff_district > 0 else 'negative' }}">
|
||||
{{ "%+.1f"|format(dim_data.diff_district) }} {{ t.vs_district_avg }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.same_type_avg }}</div>
|
||||
<div class="value" style="font-size:24px">{{ "%.1f"|format(dim_data.same_type_avg) }}</div>
|
||||
</div>
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.rank_in_district }}</div>
|
||||
<div class="value">{{ dim_data.rank_in_district }}/{{ overall.total_schools }}</div>
|
||||
{% if overall.total_schools_in_city and dim_data.rank_in_city is defined %}
|
||||
<div class="diff" style="color: var(--gray-500); font-size: 12px;">
|
||||
{{ t.sd_city_rank_prefix }} {{ dim_data.rank_in_city }}/{{ overall.total_schools_in_city }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.performance }}</div>
|
||||
<div class="value" style="font-size:14px">
|
||||
{# 基于实际数据判断表现标签,而非聚类标签 #}
|
||||
{% set diff = dim_data.diff_district %}
|
||||
{% set rank = dim_data.rank_in_district %}
|
||||
{% set total = overall.total_schools %}
|
||||
{% set rank_pct = rank / total if total else 1 %}
|
||||
{% if diff > 3 and rank_pct <= 0.33 %}
|
||||
<span class="type-badge good">{{ t.perf_good }}</span>
|
||||
{% elif diff > 0 and rank_pct <= 0.5 %}
|
||||
<span class="type-badge good">{{ t.perf_above }}</span>
|
||||
{% elif diff >= -2 and rank_pct <= 0.67 %}
|
||||
<span class="type-badge neutral">{{ t.perf_neutral }}</span>
|
||||
{% elif diff < -3 or rank_pct > 0.8 %}
|
||||
<span class="type-badge weak">{{ t.perf_weak }}</span>
|
||||
{% else %}
|
||||
<span class="type-badge neutral">{{ t.perf_below }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 维度独立得分柱状图 + 子维度雷达/柱状图 -->
|
||||
<div class="chart-row">
|
||||
<div class="chart-box">
|
||||
<div id="dim-score-{{ part_id }}" class="chart"></div>
|
||||
<div class="chart-title">{{ t.dim_fig_score.format(n=part_num, name=dim_display) }}</div>
|
||||
</div>
|
||||
<div class="chart-box">
|
||||
<div id="sub-radar-{{ part_id }}" class="chart"></div>
|
||||
<div class="chart-title">{{ t.dim_fig_subradar.format(n=part_num, name=dim_display) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-caption">
|
||||
{{ llm_sections.get(part_id + '_caption_dim_score', '') | safe }}
|
||||
</div>
|
||||
|
||||
<!-- 子维度柱状图 + 水平分布堆叠图 -->
|
||||
<div class="chart-row">
|
||||
<div class="chart-box">
|
||||
<div id="chart-{{ part_id }}" class="chart"></div>
|
||||
<div class="chart-title">{{ t.dim_fig_subbar.format(n=part_num, name=dim_display) }}</div>
|
||||
</div>
|
||||
<div class="chart-box">
|
||||
<div id="level-{{ part_id }}" class="chart"></div>
|
||||
<div class="chart-title">{{ t.dim_fig_levels.format(n=part_num, name=dim_display) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-caption">
|
||||
{{ llm_sections.get(part_id + '_caption_sub_detail', '') | safe }}
|
||||
</div>
|
||||
|
||||
<!-- 聚类散点图(2D或3D) -->
|
||||
<div class="chart-box">
|
||||
<div id="scatter-{{ part_id }}" class="chart" style="height:450px"></div>
|
||||
<div class="chart-title">{{ t.dim_fig_scatter.format(n=part_num, name=dim_display) }}</div>
|
||||
</div>
|
||||
<div class="chart-caption">
|
||||
{{ llm_sections.get(part_id + '_caption_scatter', '') | safe }}
|
||||
</div>
|
||||
|
||||
<!-- 维度整体LLM分析 -->
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get(part_id + '_overall', '<p>' + t.loading + '</p>') | safe }}
|
||||
</div>
|
||||
|
||||
<!-- 水平对比表 -->
|
||||
<h3>{{ t.dim_section_subdims.format(name=dim_display) }} ({{ t.tbl }} {{ part_num }}-1)</h3>
|
||||
<table class="level-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ t.sub_dimension }}</th>
|
||||
<th>{{ school_display }}</th>
|
||||
<th>{{ t.score }}</th>
|
||||
<th>{{ t.district_avg }}</th>
|
||||
<th>{{ t.rank_in_district }}</th>
|
||||
{% if overall.total_schools_in_city %}<th>{{ t.rank_in_city }}</th>{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for sub_dim in framework[dim_name].sub_dimensions %}
|
||||
{% set sd = sub_dimensions.get(sub_dim, {}) %}
|
||||
{% if sd %}
|
||||
<tr>
|
||||
<td>{{ t.sub(sub_dim) }}</td>
|
||||
<td class="lv{{ sd.level }}">{{ t.level_label }} {{ sd.level }}</td>
|
||||
<td>{{ "%.1f"|format(sd.score) }}</td>
|
||||
<td>{{ "%.1f"|format(sd.district_avg) }}</td>
|
||||
<td>{{ sd.rank_in_district }}/{{ overall.total_schools }}</td>
|
||||
{% if overall.total_schools_in_city %}
|
||||
<td>{{ sd.rank_in_city if sd.rank_in_city is defined else '-' }}/{{ overall.total_schools_in_city }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- 各三级维度详细分析 -->
|
||||
{% for sub_dim in framework[dim_name].sub_dimensions %}
|
||||
{% set sd = sub_dimensions.get(sub_dim, {}) %}
|
||||
{% if sd %}
|
||||
{% set sub_index = loop.index %}
|
||||
{% include 'sections/sub_dimension.html' %}
|
||||
{% if not loop.last %}
|
||||
<hr class="section-divider">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -0,0 +1,106 @@
|
||||
{# 第一部分:测评背景与实施(固定内容,不需要LLM生成) #}
|
||||
<div class="section" id="part1">
|
||||
<h1>{{ t.part('part0') }}</h1>
|
||||
|
||||
<h2>{{ t.p0_h1_background }}</h2>
|
||||
|
||||
<p>{{ t.p0_para1 }}</p>
|
||||
|
||||
<p>{{ t.p0_para2 }}</p>
|
||||
|
||||
<h2>{{ t.p0_h1_framework }}</h2>
|
||||
|
||||
<p>{{ t.p0_framework_intro }}</p>
|
||||
|
||||
<table class="data-table">
|
||||
<caption style="text-align:center; font-weight:600; margin-bottom:10px; color:var(--gray-700);">{{ t.tbl_indicator_system }}</caption>
|
||||
<thead>
|
||||
<tr><th style="width:140px;">{{ t.th_secondary_dim }}</th><th style="width:170px;">{{ t.th_tertiary_dim }}</th><th>{{ t.th_indicator_interp }}</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan="3"><strong>{{ t.dim('课程领导力') }}</strong></td>
|
||||
<td>{{ t.sub('国家标准遵循') }}</td>
|
||||
<td rowspan="3" style="text-align:left;">{{ t.p0_interp_curriculum }}</td>
|
||||
</tr>
|
||||
<tr><td>{{ t.sub('课程结构建设') }}</td></tr>
|
||||
<tr><td>{{ t.sub('课程规范落实') }}</td></tr>
|
||||
<tr>
|
||||
<td rowspan="2"><strong>{{ t.dim('教学变革力') }}</strong></td>
|
||||
<td>{{ t.sub('教学方式变革') }}</td>
|
||||
<td rowspan="2" style="text-align:left;">{{ t.p0_interp_instruction }}</td>
|
||||
</tr>
|
||||
<tr><td>{{ t.sub('作业设计与管理变革') }}</td></tr>
|
||||
<tr>
|
||||
<td rowspan="2"><strong>{{ t.dim('学生发展指导力') }}</strong></td>
|
||||
<td>{{ t.sub('学科发展的个性化辅导') }}</td>
|
||||
<td rowspan="2" style="text-align:left;">{{ t.p0_interp_student }}</td>
|
||||
</tr>
|
||||
<tr><td>{{ t.sub('学生生涯发展指导') }}</td></tr>
|
||||
<tr>
|
||||
<td rowspan="3"><strong>{{ t.dim('教师发展支持力') }}</strong></td>
|
||||
<td>{{ t.sub('培训支持') }}</td>
|
||||
<td rowspan="3" style="text-align:left;">{{ t.p0_interp_teacher }}</td>
|
||||
</tr>
|
||||
<tr><td>{{ t.sub('教研支持') }}</td></tr>
|
||||
<tr><td>{{ t.sub('项目支持') }}</td></tr>
|
||||
<tr>
|
||||
<td rowspan="4"><strong>{{ t.dim('教育质量评估力') }}</strong></td>
|
||||
<td>{{ t.sub('科学评价观') }}</td>
|
||||
<td rowspan="4" style="text-align:left;">{{ t.p0_interp_quality }}</td>
|
||||
</tr>
|
||||
<tr><td>{{ t.sub('学业质量评估') }}</td></tr>
|
||||
<tr><td>{{ t.sub('综合素质评估') }}</td></tr>
|
||||
<tr><td>{{ t.sub('实践活动评估') }}</td></tr>
|
||||
<tr>
|
||||
<td rowspan="3"><strong>{{ t.dim('教育条件保障力') }}</strong></td>
|
||||
<td>{{ t.sub('区域推进') }}</td>
|
||||
<td rowspan="3" style="text-align:left;">{{ t.p0_interp_condition }}</td>
|
||||
</tr>
|
||||
<tr><td>{{ t.sub('环境支持') }}</td></tr>
|
||||
<tr><td>{{ t.sub('资源支持') }}</td></tr>
|
||||
<tr>
|
||||
<td rowspan="3"><strong>{{ t.dim('数字化赋能力') }}</strong></td>
|
||||
<td>{{ t.sub('教学方式创新') }}</td>
|
||||
<td rowspan="3" style="text-align:left;">{{ t.p0_interp_digital }}</td>
|
||||
</tr>
|
||||
<tr><td>{{ t.sub('评价精准化与个性化') }}</td></tr>
|
||||
<tr><td>{{ t.sub('课程迭代优化') }}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>{{ t.p0_h1_implement }}</h2>
|
||||
|
||||
<h3>{{ t.p0_h2_target }}</h3>
|
||||
<p>{{ t.p0_target_text.format(district=district_display, total=total_schools_in_district) }}</p>
|
||||
|
||||
<h3>{{ t.p0_h2_method }}</h3>
|
||||
<p>{{ t.p0_method_text }}</p>
|
||||
|
||||
<h3>{{ t.p0_h2_analysis }}</h3>
|
||||
<p>{{ t.p0_analysis_intro }}</p>
|
||||
<p>{{ t.p0_step1 | safe }}</p>
|
||||
<p>{{ t.p0_step2 | safe }}</p>
|
||||
<p>{{ t.p0_step3 | safe }}</p>
|
||||
<p>{{ t.p0_step4 | safe }}</p>
|
||||
<p>{{ t.p0_step5 | safe }}</p>
|
||||
|
||||
<h3>{{ t.p0_h2_levels }}</h3>
|
||||
<table class="data-table" style="font-size:13px;">
|
||||
<caption style="text-align:center; font-weight:600; margin-bottom:10px; color:var(--gray-700);">{{ t.tbl_level_definition }}</caption>
|
||||
<thead>
|
||||
<tr><th>{{ t.th_tertiary_dim }}</th><th>{{ t.level_4 }}</th><th>{{ t.level_3 }}</th><th>{{ t.level_2 }}</th><th>{{ t.level_1 }}</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for sub_dim_zh in level_descriptions_keys %}
|
||||
<tr>
|
||||
<td style="text-align:left;"><strong>{{ t.sub(sub_dim_zh) }}</strong></td>
|
||||
<td style="text-align:left; font-size:12px;">{{ t.level_desc(sub_dim_zh, 4) }}</td>
|
||||
<td style="text-align:left; font-size:12px;">{{ t.level_desc(sub_dim_zh, 3) }}</td>
|
||||
<td style="text-align:left; font-size:12px;">{{ t.level_desc(sub_dim_zh, 2) }}</td>
|
||||
<td style="text-align:left; font-size:12px;">{{ t.level_desc(sub_dim_zh, 1) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -0,0 +1,176 @@
|
||||
{# 第一部分:总体表现 #}
|
||||
<div class="section" id="part2">
|
||||
<h1>{{ t.part('part1') }}</h1>
|
||||
|
||||
<h2>{{ t.p1_h1_overall_status }}</h2>
|
||||
|
||||
<!-- 得分卡片 -->
|
||||
<div class="score-cards">
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.total_score }}</div>
|
||||
<div class="value">{{ "%.1f"|format(overall.score) }}</div>
|
||||
<div class="diff {{ 'positive' if overall.score > overall.district_avg else 'negative' }}">
|
||||
{{ "%+.1f"|format(overall.score - overall.district_avg) }} {{ t.vs_district_avg }} ({{ "%.1f"|format(overall.district_avg) }})
|
||||
</div>
|
||||
</div>
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.rank_in_district }}</div>
|
||||
<div class="value">{{ overall.rank_in_district }}/{{ overall.total_schools }}</div>
|
||||
</div>
|
||||
{% if overall.rank_in_city is defined and overall.total_schools_in_city %}
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.rank_in_city }}</div>
|
||||
<div class="value">{{ overall.rank_in_city }}/{{ overall.total_schools_in_city }}</div>
|
||||
{% set city_pct = (overall.rank_in_city / overall.total_schools_in_city * 100) | round(1) %}
|
||||
<div class="diff {{ 'positive' if city_pct <= 50 else 'negative' }}">
|
||||
{{ t.rank_in_top_pct.format(pct=city_pct) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.same_type_avg }}</div>
|
||||
<div class="value" style="font-size:24px">{{ "%.1f"|format(overall.same_type_avg) }}</div>
|
||||
<div class="diff {{ 'positive' if overall.score > overall.same_type_avg else 'negative' }}">
|
||||
{{ "%+.1f"|format(overall.score - overall.same_type_avg) }} {{ t.vs_same_type }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.cluster_type }}</div>
|
||||
<div class="value" style="font-size:16px">
|
||||
{% set cluster_raw = (overall.cluster or '') %}
|
||||
{% set is_good = ('较好' in cluster_raw) or ('High' in cluster_raw) or ('high' in cluster_raw) %}
|
||||
<span class="type-badge {{ 'good' if is_good else 'weak' }}">
|
||||
{{ t.cluster_label(cluster_raw) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- A. 学校画像卡 + 优势-短板象限图 -->
|
||||
<div class="chart-row">
|
||||
<div class="chart-box">
|
||||
<div id="profile-card-chart" class="chart" style="height:420px"></div>
|
||||
<div class="chart-title">{{ t.fig2_0a }}</div>
|
||||
</div>
|
||||
<div class="chart-box">
|
||||
<div id="quadrant-chart" class="chart" style="height:420px"></div>
|
||||
<div class="chart-title">{{ t.fig2_0b }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-caption">
|
||||
{{ llm_sections.get('part2_caption_profile', '') | safe }}
|
||||
</div>
|
||||
|
||||
<!-- 得分对比横向条形图 + 七维度雷达图 -->
|
||||
<div class="chart-row">
|
||||
<div class="chart-box">
|
||||
<div id="score-compare-chart" class="chart"></div>
|
||||
<div class="chart-title">{{ t.fig2_1 }}</div>
|
||||
</div>
|
||||
<div class="chart-box">
|
||||
<div id="radar-chart" class="chart"></div>
|
||||
<div class="chart-title">{{ t.fig2_2 }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-caption">
|
||||
{{ llm_sections.get('part2_caption_scores', '') | safe }}
|
||||
</div>
|
||||
|
||||
<!-- 聚类类型分布 + 两类学校折线对比 -->
|
||||
<div class="chart-row">
|
||||
<div class="chart-box">
|
||||
<div id="cluster-type-dist-chart" class="chart"></div>
|
||||
<div class="chart-title">{{ t.fig2_3 }}</div>
|
||||
</div>
|
||||
<div class="chart-box">
|
||||
<div id="cluster-line-chart" class="chart"></div>
|
||||
<div class="chart-title">{{ t.fig2_4 }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-caption">
|
||||
{{ llm_sections.get('part2_caption_cluster', '') | safe }}
|
||||
</div>
|
||||
|
||||
<!-- 聚类类型对比雷达图 + 区内学校排名条形图 -->
|
||||
<div class="chart-row">
|
||||
<div class="chart-box">
|
||||
<div id="cluster-radar-chart" class="chart"></div>
|
||||
<div class="chart-title">{{ t.fig2_5 }}</div>
|
||||
</div>
|
||||
<div class="chart-box">
|
||||
<div id="school-ranking-chart" class="chart"></div>
|
||||
<div class="chart-title">{{ t.fig2_6 }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-caption">
|
||||
{{ llm_sections.get('part2_caption_ranking', '') | safe }}
|
||||
</div>
|
||||
|
||||
<!-- 维度间相关性热力图 -->
|
||||
<div class="chart-box">
|
||||
<div id="correlation-chart" class="chart" style="height:450px"></div>
|
||||
<div class="chart-title">{{ t.fig2_7 }}</div>
|
||||
</div>
|
||||
<div class="chart-caption">
|
||||
{{ llm_sections.get('part2_caption_correlation', '') | safe }}
|
||||
</div>
|
||||
|
||||
<!-- LLM综合分析 -->
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get('part2_overview', '<p>' + t.loading + '</p>') | safe }}
|
||||
</div>
|
||||
|
||||
{# ===== 紧急预警框(仅在存在预警子维度时显示) ===== #}
|
||||
{% if llm_sections.get('part2_alert') %}
|
||||
<div class="alert-box" style="background: linear-gradient(135deg, #fef2f2, #fee2e2); border: 2px solid #ef4444; border-radius: 12px; padding: 20px 24px; margin: 24px 0;">
|
||||
<h3 style="color: #dc2626; margin: 0 0 12px 0; font-size: 18px;">{{ t.alert_title }}</h3>
|
||||
<div class="llm-analysis" style="color: #7f1d1d;">
|
||||
{{ llm_sections.get('part2_alert') | safe }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ===== 学校定位与实际表现差距分析(所有学校均显示) ===== #}
|
||||
{% if llm_sections.get('part2_positioning_gap') %}
|
||||
<div class="positioning-gap-box" style="background: linear-gradient(135deg, #fffbeb, #fef3c7); border: 2px solid #f59e0b; border-radius: 12px; padding: 20px 24px; margin: 24px 0;">
|
||||
<h3 style="color: #b45309; margin: 0 0 12px 0; font-size: 18px;">{{ t.positioning_gap_title }}</h3>
|
||||
<div class="llm-analysis" style="color: #78350f;">
|
||||
{{ llm_sections.get('part2_positioning_gap') | safe }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h2>{{ t.p1_h1_dim_status }}</h2>
|
||||
|
||||
<!-- 维度得分对比表 -->
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ t.dimension }}</th>
|
||||
<th>{{ school_display }}</th>
|
||||
<th>{{ t.district_avg }}</th>
|
||||
<th>{{ t.same_type_avg }}</th>
|
||||
<th>{{ t.diff_vs_district }}</th>
|
||||
<th>{{ t.rank_in_district }}</th>
|
||||
{% if overall.total_schools_in_city %}<th>{{ t.rank_in_city }}</th>{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for dim_name, dim_data in dimensions.items() %}
|
||||
<tr>
|
||||
<td><strong>{{ t.dim(dim_name) }}</strong></td>
|
||||
<td>{{ "%.2f"|format(dim_data.score) }}</td>
|
||||
<td>{{ "%.2f"|format(dim_data.district_avg) }}</td>
|
||||
<td>{{ "%.2f"|format(dim_data.same_type_avg) }}</td>
|
||||
<td style="color: {{ 'green' if dim_data.diff_district > 0 else 'red' }}">
|
||||
{{ "%+.2f"|format(dim_data.diff_district) }}
|
||||
</td>
|
||||
<td>{{ dim_data.rank_in_district }}/{{ overall.total_schools }}</td>
|
||||
{% if overall.total_schools_in_city %}
|
||||
<td>{{ dim_data.rank_in_city if dim_data.rank_in_city is defined else '-' }}/{{ overall.total_schools_in_city }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -0,0 +1,64 @@
|
||||
{# 单个子维度详情(含金字塔) #}
|
||||
{# 需要外部传入: sub_dim, sd, part_id, sub_index, school_display #}
|
||||
{# sub_index 从1开始,子维度在维度页面中的小节号从"二/II"开始("一/I"是"整体表现") #}
|
||||
{% set sub_section_label = sub_section_label_func(sub_index) if sub_section_label_func is defined else (cn_subnums[sub_index] if cn_subnums is defined else '') %}
|
||||
{% set sub_display = t.sub(sub_dim) %}
|
||||
|
||||
<h2 id="sub-{{ part_id }}-{{ sub_index }}">{{ sub_section_label }} {{ sub_display }}</h2>
|
||||
|
||||
<div class="score-cards" style="grid-template-columns: repeat(4, 1fr);">
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.sd_score }}</div>
|
||||
<div class="value" style="font-size:24px">{{ "%.1f"|format(sd.score) }}</div>
|
||||
<div class="diff {{ 'positive' if sd.diff_district > 0 else 'negative' }}">
|
||||
{{ "%+.1f"|format(sd.diff_district) }} {{ t.vs_district_avg }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.sd_district_avg }}</div>
|
||||
<div class="value" style="font-size:24px">{{ "%.1f"|format(sd.district_avg) }}</div>
|
||||
</div>
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.sd_level_grade }}</div>
|
||||
<div class="level-indicator level-{{ sd.level }}">{{ t.level_label }} {{ sd.level }}</div>
|
||||
</div>
|
||||
<div class="score-card">
|
||||
<div class="label">{{ t.sd_rank }}</div>
|
||||
<div class="value" style="font-size:24px">{{ sd.rank_in_district }}/{{ overall.total_schools }}</div>
|
||||
{% if overall.total_schools_in_city and sd.rank_in_city is defined %}
|
||||
<div class="diff" style="color: var(--gray-500); font-size: 12px;">
|
||||
{{ t.sd_city_rank_prefix }} {{ sd.rank_in_city }}/{{ overall.total_schools_in_city }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- C. 温度计条形图 -->
|
||||
<div class="chart-box" style="padding:10px 16px;">
|
||||
<div id="thermo-{{ part_id }}-{{ sub_index }}" class="chart" style="height:80px"></div>
|
||||
</div>
|
||||
|
||||
<!-- 金字塔水平指示器(含各水平学校数量) -->
|
||||
<div class="pyramid-container">
|
||||
{% for lv in [4, 3, 2, 1] %}
|
||||
{% set lv_count = sd.level_distribution.get('水平' ~ lv, 0) if sd.level_distribution else '' %}
|
||||
<div class="pyramid-row">
|
||||
<div class="pyramid-block lv{{ lv }} {{ 'active' if sd.level == lv else 'dimmed' }}">
|
||||
{{ t.level_label }} {{ lv }}{% if lv_count is not none and lv_count != '' %} · {{ lv_count }} {{ t.schools_unit }}{% endif %}
|
||||
</div>
|
||||
{% if sd.level == lv %}
|
||||
<span class="pyramid-label"><span class="arrow">◀</span>{{ school_display }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<p style="text-indent:0; margin:10px 0; color: var(--gray-500); font-size:14px;">
|
||||
<strong>{{ t.sd_level_meaning.format(lv=sd.level) }}:</strong>{{ t.level_desc(sub_dim, sd.level) or sd.level_description }}
|
||||
</p>
|
||||
|
||||
<!-- 三级维度LLM分析 -->
|
||||
{% set sub_key = part_id + '_sub' + sub_index|string + '_' + sub_dim %}
|
||||
<div class="llm-analysis">
|
||||
{{ llm_sections.get(sub_key, '<p>' + t.loading + '</p>') | safe }}
|
||||
</div>
|
||||
Reference in New Issue
Block a user