Skip to content

Commit a0fe9e4

Browse files
author
CodeJudge
committed
feat: 题目列表显示已通过/已尝试状态
1 parent 07aeb6c commit a0fe9e4

3 files changed

Lines changed: 31 additions & 3 deletions

File tree

backend/src/controllers/problemController.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,26 @@ function listProblems(req, res) {
2626
params.push(Number(limit), (Number(page) - 1) * Number(limit));
2727

2828
const problems = queryAll(sql, params);
29+
30+
// Attach user status
31+
if (req.user) {
32+
const ids = problems.map(p => p.id);
33+
if (ids.length > 0) {
34+
const rows = queryAll(
35+
`SELECT problem_id, status FROM submissions WHERE user_id = ? AND problem_id IN (${ids.map(() => '?').join(',')}) GROUP BY problem_id`,
36+
[req.user.id, ...ids]
37+
);
38+
const statusMap = {};
39+
rows.forEach(r => { statusMap[r.problem_id] = r.status; });
40+
problems.forEach(p => {
41+
const s = statusMap[p.id];
42+
if (s === 'accepted') p.user_status = 'accepted';
43+
else if (s) p.user_status = 'attempted';
44+
else p.user_status = null;
45+
});
46+
}
47+
}
48+
2949
res.json({ problems, total, page: Number(page), totalPages: Math.ceil(total / Number(limit)) });
3050
}
3151

frontend/src/components/ProblemCard.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Link } from 'react-router-dom';
2-
import { Code2, ListChecks, PenLine, CheckCircle2, Star } from 'lucide-react';
2+
import { Code2, ListChecks, PenLine, CheckCircle2, Star, AlertCircle } from 'lucide-react';
33
import { useBookmarks } from '../context/BookmarkContext';
44
import type { Problem } from '../types';
55

@@ -41,20 +41,27 @@ export default function ProblemCard({ problem }: { problem: Problem }) {
4141
const ratio = problem.submission_count > 0
4242
? Math.round((problem.accepted_count / problem.submission_count) * 100)
4343
: 0;
44+
const userStatus = problem.user_status || (problem.user_passed ? 'accepted' : null);
4445

4546
return (
4647
<Link
4748
to={`/problems/${problem.id}`}
48-
className={`card flex flex-col gap-4 hover:border-primary-500/50 hover:-translate-y-0.5 hover:shadow-lg hover:shadow-primary-500/5 transition-all duration-200 group${problem.user_passed ? ' border-l-emerald-500' : ''}`}
49+
className={`card flex flex-col gap-4 hover:border-primary-500/50 hover:-translate-y-0.5 hover:shadow-lg hover:shadow-primary-500/5 transition-all duration-150 group${userStatus === 'accepted' ? ' border-l-emerald-500' : userStatus === 'attempted' ? ' border-l-yellow-500' : ''}`}
4950
>
5051
<div className="flex items-start justify-between gap-3">
5152
<div className="flex items-center gap-2.5 min-w-0">
52-
{problem.user_passed && (
53+
{userStatus === 'accepted' && (
5354
<span className="inline-flex items-center gap-1 px-2 py-0.5 bg-emerald-500/15 text-emerald-400 text-xs rounded-full border border-emerald-500/30 flex-shrink-0">
5455
<CheckCircle2 className="w-3.5 h-3.5" />
5556
已通过
5657
</span>
5758
)}
59+
{userStatus === 'attempted' && (
60+
<span className="inline-flex items-center gap-1 px-2 py-0.5 bg-yellow-500/15 text-yellow-400 text-xs rounded-full border border-yellow-500/30 flex-shrink-0">
61+
<AlertCircle className="w-3.5 h-3.5" />
62+
已尝试
63+
</span>
64+
)}
5865
<h3 className="text-lg font-semibold text-white truncate group-hover:text-primary-400 transition-colors">
5966
{problem.title}
6067
</h3>

frontend/src/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export interface Problem {
2020
accepted_count: number;
2121
submission_count: number;
2222
user_passed?: boolean;
23+
user_status?: 'accepted' | 'attempted' | null;
2324
created_at: string;
2425
}
2526

0 commit comments

Comments
 (0)