修正 AI 复盘解读:按日期顺序、得分率与科目专属建议。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -37,26 +37,57 @@ def _subject_display_name(score: SubjectScore) -> str:
|
||||
return score.subject.name if score.subject else f"科目{score.subject_id}"
|
||||
|
||||
|
||||
def _build_review_records_text(exams: list[ExamRecord], subject_name: str) -> str:
|
||||
lines: list[str] = []
|
||||
for exam in sorted(exams, key=lambda item: item.exam_date, reverse=True):
|
||||
def _build_review_insight_context(exams: list[ExamRecord], subject_name: str) -> str:
|
||||
entries: list[tuple[ExamRecord, SubjectScore, list[ReviewStatusEnum]]] = []
|
||||
status_counts = {status: 0 for status in ReviewStatusEnum}
|
||||
|
||||
for exam in exams:
|
||||
for score in exam.scores:
|
||||
if _subject_display_name(score) != subject_name:
|
||||
continue
|
||||
statuses = _parse_review_statuses(score.review_statuses_json)
|
||||
if not statuses:
|
||||
continue
|
||||
type_label = _EXAM_TYPE_LABELS.get(exam.exam_type.value, exam.exam_type.value)
|
||||
status_text = "、".join(_REVIEW_STATUS_LABELS.get(s, s.value) for s in statuses)
|
||||
ratio = float(score.ratio) * 100
|
||||
line = (
|
||||
f"- {exam.exam_date} {type_label} "
|
||||
f"得分{float(score.obtained_score):g}/{float(score.total_score):g}({ratio:.1f}%) "
|
||||
f"状态:{status_text}"
|
||||
)
|
||||
if exam.title:
|
||||
line += f" 备注:{exam.title}"
|
||||
lines.append(line)
|
||||
entries.append((exam, score, statuses))
|
||||
for status in statuses:
|
||||
status_counts[status] += 1
|
||||
|
||||
if not entries:
|
||||
return ""
|
||||
|
||||
entries.sort(key=lambda item: (item[0].exam_date, item[0].created_at))
|
||||
total = len(entries)
|
||||
|
||||
summary_parts = [
|
||||
f"{_REVIEW_STATUS_LABELS[s]}{status_counts[s]}次"
|
||||
for s in ReviewStatusEnum
|
||||
if status_counts[s] > 0
|
||||
]
|
||||
lines = [
|
||||
f"科目:{subject_name}",
|
||||
f"共 {total} 次有复盘记录的考试",
|
||||
f"状态统计:{'、'.join(summary_parts)}",
|
||||
"",
|
||||
"【按考试日期从早到晚,请严格按此顺序解读,不得颠倒】",
|
||||
]
|
||||
|
||||
for index, (exam, score, statuses) in enumerate(entries, start=1):
|
||||
type_label = _EXAM_TYPE_LABELS.get(exam.exam_type.value, exam.exam_type.value)
|
||||
status_text = "、".join(_REVIEW_STATUS_LABELS.get(s, s.value) for s in statuses)
|
||||
obtained = float(score.obtained_score)
|
||||
total_score = float(score.total_score)
|
||||
ratio = float(score.ratio) * 100
|
||||
lost = total_score - obtained
|
||||
when = "(最近一次)" if index == total else ""
|
||||
line = (
|
||||
f"第{index}次{when} | 日期 {exam.exam_date} | {type_label} | "
|
||||
f"得分 {obtained:g}/{total_score:g}(得分率 {ratio:.1f}%,失分 {lost:g} 分)| "
|
||||
f"复盘状态:{status_text}"
|
||||
)
|
||||
if exam.title:
|
||||
line += f" | 备注:{exam.title}"
|
||||
lines.append(line)
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@@ -298,7 +329,7 @@ async def review_insight(
|
||||
.all()
|
||||
)
|
||||
subject_name = data.subject_name.strip()
|
||||
records = _build_review_records_text(exams, subject_name)
|
||||
records = _build_review_insight_context(exams, subject_name)
|
||||
if not records:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
|
||||
Reference in New Issue
Block a user