diff --git a/README.md b/README.md
index 55f7453..695d476 100644
--- a/README.md
+++ b/README.md
@@ -64,7 +64,6 @@ yarn dev
#### 练习题相关
- `GET /api/practice/questions` - 获取练习题目列表 (支持分页和类型过滤)
-- `GET /api/practice/questions/random` - 获取随机练习题目
- `GET /api/practice/questions/:id` - 获取指定练习题目
- `POST /api/practice/submit` - 提交练习答案 (简答题自动AI评分)
- `GET /api/practice/types` - 获取题型列表
@@ -224,7 +223,7 @@ yarn build
## 页面结构
- **登录页** (`/login`) - 用户登录和注册,支持密码可见性切换
-- **首页** (`/`) - 题目练习、随机题目、题目列表、筛选等功能
+- **首页** (`/`) - 题型选择、错题本、题目列表等功能
- **我的** (`/profile`) - 用户信息、退出登录
## 特性
@@ -238,7 +237,6 @@ yarn build
- 密码bcrypt加密存储
- 练习题管理系统(236道练习题,5种题型)
- 支持分页查询和题型筛选
-- 随机题目推送功能
- **AI智能评分系统** - 使用deepseek-v3对简答题进行智能评分和反馈
### 前端特性
diff --git a/main.go b/main.go
index d70fe97..024514d 100644
--- a/main.go
+++ b/main.go
@@ -43,22 +43,21 @@ func main() {
auth.PUT("/user/type", handlers.UpdateUserType) // 更新用户类型
// 练习题相关API(需要登录)
- auth.GET("/practice/questions", handlers.GetPracticeQuestions) // 获取练习题目列表
- auth.GET("/practice/questions/random", handlers.GetRandomPracticeQuestion) // 获取随机练习题目
- auth.GET("/practice/questions/:id", handlers.GetPracticeQuestionByID) // 获取指定练习题目
- auth.POST("/practice/explain", handlers.ExplainQuestion) // 生成题目解析(AI)
+ auth.GET("/practice/questions", handlers.GetPracticeQuestions) // 获取练习题目列表
+ auth.GET("/practice/questions/:id", handlers.GetPracticeQuestionByID) // 获取指定练习题目
+ auth.POST("/practice/explain", handlers.ExplainQuestion) // 生成题目解析(AI)
// 练习题提交(需要登录才能记录错题)
auth.POST("/practice/submit", handlers.SubmitPracticeAnswer) // 提交练习答案
auth.GET("/practice/statistics", handlers.GetStatistics) // 获取统计数据
// 错题本相关API
- auth.GET("/wrong-questions", handlers.GetWrongQuestions) // 获取错题列表
- auth.GET("/wrong-questions/stats", handlers.GetWrongQuestionStats) // 获取错题统计
- auth.GET("/wrong-questions/random", handlers.GetRandomWrongQuestion) // 获取随机错题
- auth.DELETE("/wrong-questions/:id", handlers.DeleteWrongQuestion) // 删除单个错题
+ auth.GET("/wrong-questions", handlers.GetWrongQuestions) // 获取错题列表
+ auth.GET("/wrong-questions/stats", handlers.GetWrongQuestionStats) // 获取错题统计
+ auth.GET("/wrong-questions/random", handlers.GetRandomWrongQuestion) // 获取随机错题
+ auth.DELETE("/wrong-questions/:id", handlers.DeleteWrongQuestion) // 删除单个错题
auth.PUT("/wrong-questions/:id/mastered", handlers.MarkWrongQuestionMastered) // 标记已掌握
- auth.DELETE("/wrong-questions", handlers.ClearWrongQuestions) // 清空错题本
+ auth.DELETE("/wrong-questions", handlers.ClearWrongQuestions) // 清空错题本
}
// 题库管理API(需要管理员权限)
diff --git a/web/index.html b/web/index.html
index d9aa1a2..bd72568 100644
--- a/web/index.html
+++ b/web/index.html
@@ -2,10 +2,12 @@
-
+
-
- AnKao
+
+
+
+ AnKao - 安全保密考试
diff --git a/web/public/icon.svg b/web/public/icon.svg
new file mode 100644
index 0000000..8a76dc3
--- /dev/null
+++ b/web/public/icon.svg
@@ -0,0 +1,117 @@
+
diff --git a/web/src/api/question.ts b/web/src/api/question.ts
index 532a58f..31a6fe8 100644
--- a/web/src/api/question.ts
+++ b/web/src/api/question.ts
@@ -6,11 +6,6 @@ export const getQuestions = (params?: { type?: string; search?: string }) => {
return request.get>('/practice/questions', { params })
}
-// 获取随机题目
-export const getRandomQuestion = () => {
- return request.get>('/practice/questions/random')
-}
-
// 获取指定题目
export const getQuestionById = (id: number) => {
return request.get>(`/practice/questions/${id}`)
diff --git a/web/src/pages/Home.module.less b/web/src/pages/Home.module.less
index 14279f7..f0fc068 100644
--- a/web/src/pages/Home.module.less
+++ b/web/src/pages/Home.module.less
@@ -15,6 +15,20 @@
flex: 1;
}
+ .logoArea {
+ display: flex;
+ align-items: flex-start;
+ gap: 16px;
+ }
+
+ .logo {
+ width: 64px;
+ height: 64px;
+ object-fit: contain;
+ flex-shrink: 0;
+ filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.08));
+ }
+
.title {
color: #1d1d1f !important;
margin-bottom: 4px !important;
@@ -183,6 +197,15 @@
margin-bottom: 12px;
}
+ .logoArea {
+ gap: 12px;
+ }
+
+ .logo {
+ width: 48px;
+ height: 48px;
+ }
+
.title {
font-size: 22px !important;
}
diff --git a/web/src/pages/Home.tsx b/web/src/pages/Home.tsx
index 6c28519..e3503cd 100644
--- a/web/src/pages/Home.tsx
+++ b/web/src/pages/Home.tsx
@@ -200,8 +200,13 @@ const Home: React.FC = () => {
{/* 头部 */}
-
AnKao 刷题
-
选择题型开始练习
+
+

+
+
{/* 用户信息 */}
{userInfo && (
@@ -300,24 +305,6 @@ const Home: React.FC = () => {
快速开始
-
- navigate('/question')}
- >
-
-
-
-
-
-
-
-
-
{
return saved !== null ? parseInt(saved, 10) : 2;
});
+ // 随机题目开关(默认关闭)
+ const [randomMode, setRandomMode] = useState(() => {
+ const saved = localStorage.getItem('randomModeEnabled');
+ return saved !== null ? saved === 'true' : false;
+ });
+
// 切换自动跳转开关
const toggleAutoNext = () => {
const newValue = !autoNext;
@@ -55,6 +61,13 @@ const QuestionPage: React.FC = () => {
localStorage.setItem('autoNextEnabled', String(newValue));
};
+ // 切换随机模式开关
+ const toggleRandomMode = () => {
+ const newValue = !randomMode;
+ setRandomMode(newValue);
+ localStorage.setItem('randomModeEnabled', String(newValue));
+ };
+
// 修改自动跳转延迟时间
const handleDelayChange = (value: number | null) => {
if (value !== null && value >= 1 && value <= 10) {
@@ -121,16 +134,11 @@ const QuestionPage: React.FC = () => {
return 0;
};
- // 加载随机题目
- const loadRandomQuestion = async () => {
+ // 加载随机错题
+ const loadRandomWrongQuestion = async () => {
setLoading(true);
try {
- // 检查是否是错题练习模式
- const mode = searchParams.get("mode");
- const res =
- mode === "wrong"
- ? await questionApi.getRandomWrongQuestion()
- : await questionApi.getRandomQuestion();
+ const res = await questionApi.getRandomWrongQuestion();
if (res.success && res.data) {
setCurrentQuestion(res.data);
@@ -258,16 +266,26 @@ const QuestionPage: React.FC = () => {
// 下一题
const handleNext = () => {
if (allQuestions.length > 0) {
- // 检查是否完成所有题目
- if (currentIndex + 1 >= allQuestions.length) {
- // 显示统计摘要
- setShowSummary(true);
- // 清除进度
- localStorage.removeItem(getStorageKey());
- return;
+ let nextIndex: number;
+
+ // 随机模式:从题库中随机选择一题
+ if (randomMode) {
+ // 生成一个不等于当前索引的随机索引
+ do {
+ nextIndex = Math.floor(Math.random() * allQuestions.length);
+ } while (nextIndex === currentIndex && allQuestions.length > 1);
+ } else {
+ // 顺序模式:检查是否完成所有题目
+ if (currentIndex + 1 >= allQuestions.length) {
+ // 显示统计摘要
+ setShowSummary(true);
+ // 清除进度
+ localStorage.removeItem(getStorageKey());
+ return;
+ }
+ nextIndex = currentIndex + 1;
}
- const nextIndex = currentIndex + 1;
setCurrentIndex(nextIndex);
setCurrentQuestion(allQuestions[nextIndex]);
setSelectedAnswer(
@@ -310,7 +328,7 @@ const QuestionPage: React.FC = () => {
// 错题练习模式
if (mode === "wrong") {
- loadRandomQuestion();
+ loadRandomWrongQuestion();
return;
}
@@ -462,6 +480,24 @@ const QuestionPage: React.FC = () => {
)}
+
+
+
+ 随机题目
+
+ 开启后点击下一题时随机跳转
+
+
+
+
+
+ {randomMode ? '已开启' : '已关闭'}
+
+
+
diff --git a/web/src/pages/QuestionList.tsx b/web/src/pages/QuestionList.tsx
index 28876bc..35239f0 100644
--- a/web/src/pages/QuestionList.tsx
+++ b/web/src/pages/QuestionList.tsx
@@ -277,7 +277,6 @@ const QuestionList: React.FC = () => {
{
- const typeConfig = questionTypeConfig[question.type]
return (