feat: v1.4.0 - 典型方案采纳、推荐方案列表、审计字段、导航优化

- 添加典型方案采纳功能 (POST /api/plans/<id>/adopt)
- 添加推荐方案列表 (GET /api/students/<id>/recommended-plans)
- PracticePlan 新增 created_by/updated_by/updated_at 审计字段
- 方案编辑/详情页导航优化 (bfcache 处理、pageshow 事件)
- 方案列表支持删除功能
- 学员列表'暂无方案/问题'样式统一
- 更新文档:问题文件已废弃(迁移到数据库)
- 更新部署脚本和验证清单
This commit is contained in:
hmo
2026-04-27 02:01:22 +08:00
parent 6abdd49c04
commit e50a9207b4
20 changed files with 873 additions and 88 deletions
+39 -8
View File
@@ -28,16 +28,40 @@ var currentPlanId = null;
async function loadPlan() {
currentPlanId = window.location.pathname.split('/').pop();
// 清除编辑页标记(从编辑页返回后不要再跳回去)
sessionStorage.removeItem('fromEdit');
// 记录来源页面
const referrer = document.referrer;
if (referrer.includes('/student/')) {
sessionStorage.setItem('plan_detail_referrer', 'student');
} else if (referrer.includes('/plans')) {
sessionStorage.setItem('plan_detail_referrer', 'plans');
} else {
sessionStorage.setItem('plan_detail_referrer', 'unknown');
}
// 如果是从编辑页返回(plan_detail_reload被设置),强制刷新
const needsReload = sessionStorage.getItem('plan_detail_reload') === 'true';
if (needsReload) {
sessionStorage.removeItem('plan_detail_reload');
}
try {
const resp = await fetch(`/api/plans/${currentPlanId}`);
const data = await resp.json();
window.currentStudentId = data.student_id;
let editInfo = '';
if (data.updated_at) {
const editor = data.updated_by_name ? ` by ${data.updated_by_name}` : '';
editInfo = `<span class="text-muted">(于${data.updated_at}${editor}编辑)</span>`;
}
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.created_at} ${editInfo} &nbsp;&nbsp;
<strong>模板:</strong>${data.template_name || '无'}
<div class="mt-2">
<a href="/student/${data.student_id}" class="btn btn-sm btn-outline-primary">
@@ -131,21 +155,28 @@ async function loadTemplates() {
async function toggleTypical(planId, isTypical) {
try {
await fetch(`/api/plans/${planId}/typical`, {method: 'POST'});
// 标记需要刷新方案列表
sessionStorage.setItem('plans_needs_refresh', 'true');
} catch (e) {
alert('设置失败: ' + e.message);
}
}
// 返回按钮处理:如果是编辑页返回的,跳过编辑页
// 返回按钮处理
function goBack() {
if (sessionStorage.getItem('fromEdit') === 'true') {
sessionStorage.removeItem('fromEdit');
history.go(-2); // 跳过编辑页
} else {
history.back();
}
// 标记需要刷新推荐方案列表
sessionStorage.setItem('needs_refresh_recommended', 'true');
history.back();
}
// 处理 bfcache - 页面从缓存恢复时需要重新加载以获取最新数据
window.addEventListener('pageshow', function(event) {
if (event.persisted) {
// 页面从 bfcache 恢复,需要重新加载
loadPlan();
}
});
// 标记来源为编辑页(编辑页点击"返回详情"前设置)
function markFromEdit() {
sessionStorage.setItem('fromEdit', 'true');