From b30647d81b7aa0388e0d6bd22799757cd8ecba18 Mon Sep 17 00:00:00 2001 From: yanlongqi Date: Fri, 7 Nov 2025 22:45:44 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=A2=98=E7=9B=AE=E7=BB=83?= =?UTF-8?q?=E4=B9=A0=E6=A8=A1=E5=BC=8F=EF=BC=8C=E4=BC=98=E5=8C=96=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要变更: - 移除独立的随机题目 API 和快速开始卡片 - 添加应用图标 (icon.svg) 和品牌标识 - 优化首页布局,添加 logo 和"安全保密考试题库"标语 - 将随机模式改为答题页面内的可选开关(默认关闭) - 改进错题练习逻辑,单独处理随机错题功能 - 同步更新 README.md 文档 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- README.md | 4 +- main.go | 17 +++-- web/index.html | 8 ++- web/public/icon.svg | 117 +++++++++++++++++++++++++++++++++ web/src/api/question.ts | 5 -- web/src/pages/Home.module.less | 23 +++++++ web/src/pages/Home.tsx | 27 ++------ web/src/pages/Question.tsx | 70 +++++++++++++++----- web/src/pages/QuestionList.tsx | 1 - 9 files changed, 214 insertions(+), 58 deletions(-) create mode 100644 web/public/icon.svg 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 刷题 - 选择题型开始练习 +
+ AnKao Logo +
+ 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 (