Files
piano-plan/app/templates/plan_detail.html
T

158 lines
5.7 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}方案详情 - 钢琴练习方案系统{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h4><i class="bi bi-file-text"></i> 方案详情</h4>
<div>
<button onclick="goBack()" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left"></i> 返回
</button>
</div>
</div>
<div id="planContent" class="card">
<div class="card-body">
<div class="text-center text-muted py-5">
<i class="bi bi-hourglass fs-4"></i>
<p class="mt-2">加载中...</p>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
var currentPlanId = null;
async function loadPlan() {
currentPlanId = window.location.pathname.split('/').pop();
try {
const resp = await fetch(`/api/plans/${currentPlanId}`);
const data = await resp.json();
window.currentStudentId = data.student_id;
let html = `
<div class="mb-3">
<strong>学员:</strong>${data.student_name} &nbsp;&nbsp;
<strong>练习时间:</strong>${data.content.practice_time} &nbsp;&nbsp;
<strong>生成时间:</strong>${data.created_at} &nbsp;&nbsp;
<strong>模板:</strong>${data.template_name || '无'}
<div class="mt-2">
<a href="/student/${data.student_id}" class="btn btn-sm btn-outline-primary">
<i class="bi bi-person"></i> 查看学员
</a>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="typicalToggle" ${data.is_typical ? 'checked' : ''} onchange="toggleTypical(${currentPlanId}, this.checked)">
<label class="form-check-label" for="typicalToggle">典型方案</label>
</div>
<a href="/plan/${currentPlanId}/edit" class="btn btn-sm btn-warning" onclick="markFromEdit()">
<i class="bi bi-edit"></i> 编辑
</a>
<div class="form-check form-check-inline">
<select id="reportTemplateSelect" class="form-select form-select-sm" style="width: auto;" onchange="updateDownloadLinks()">
</select>
</div>
<button onclick="downloadPDFWithTemplate()" class="btn btn-sm btn-primary">
<i class="bi bi-download"></i> 下载PDF
</button>
<button onclick="downloadMDWithTemplate()" class="btn btn-sm btn-outline-primary">
<i class="bi bi-file-markdown"></i> 下载MD
</button>
</div>
</div>
<hr>
<h6>问题诊断</h6>
<div class="mb-3">
`;
data.content.problems.forEach(p => {
html += `<span class="problem-tag severity-${p.severity}">${p.name}${p.severity}</span> `;
});
html += `</div>`;
if (data.content.ai_report) {
const aiReportHtml = marked.parse(data.content.ai_report);
html += `
<h6>AI个性化练习报告</h6>
<div class="mb-3 p-3 bg-light rounded">${aiReportHtml}</div>
`;
} else if (data.content.ai_report_error) {
html += `
<h6>AI报告</h6>
<div class="mb-3 p-3 bg-warning rounded">AI生成失败: ${data.content.ai_report_error}</div>
`;
}
document.getElementById('planContent').innerHTML = html;
loadTemplates();
} catch (e) {
document.getElementById('planContent').innerHTML = `
<div class="card-body text-center text-danger py-5">
<i class="bi bi-exclamation-triangle fs-4"></i>
<p class="mt-2">加载失败: ${e.message}</p>
</div>
`;
}
}
function updateDownloadLinks() {
// No longer needed - buttons now use downloadPDFWithTemplate/downloadMDWithTemplate directly
}
function downloadPDFWithTemplate() {
const templateId = document.getElementById('reportTemplateSelect')?.value;
const suffix = templateId ? `?template_id=${templateId}` : '';
window.open(`/api/plans/${currentPlanId}/pdf${suffix}`, '_blank');
}
function downloadMDWithTemplate() {
const templateId = document.getElementById('reportTemplateSelect')?.value;
const suffix = templateId ? `?template_id=${templateId}` : '';
window.open(`/api/plans/${currentPlanId}/md${suffix}`, '_blank');
}
async function loadTemplates() {
try {
const resp = await fetch('/templates/templates?type=report');
if (resp.ok) {
const templates = await resp.json();
const select = document.getElementById('reportTemplateSelect');
select.innerHTML = templates.map(t => `<option value="${t.id}">${t.name}</option>`).join('');
}
} catch (e) {
console.error('加载模板失败:', e);
}
}
// 设为典型
async function toggleTypical(planId, isTypical) {
try {
await fetch(`/api/plans/${planId}/typical`, {method: 'POST'});
} catch (e) {
alert('设置失败: ' + e.message);
}
}
// 返回按钮处理:如果是编辑页返回的,跳过编辑页
function goBack() {
if (sessionStorage.getItem('fromEdit') === 'true') {
sessionStorage.removeItem('fromEdit');
history.go(-2); // 跳过编辑页
} else {
history.back();
}
}
// 标记来源为编辑页(编辑页点击"返回详情"前设置)
function markFromEdit() {
sessionStorage.setItem('fromEdit', 'true');
}
window.currentStudentId = null;
loadPlan();
</script>
{% endblock %}