AnCao/CLAUDE.md
yanlongqi ea051e9380 添加AI评分系统和题目列表功能
新增功能:
1. AI智能评分系统
   - 集成OpenAI兼容API进行简答题评分
   - 提供分数、评语和改进建议
   - 支持自定义AI服务配置(BaseURL、APIKey、Model)

2. 题目列表页面
   - 展示所有题目和答案
   - Tab标签页形式的题型筛选(选择题、多选题、判断题、填空题、简答题)
   - 关键词搜索功能(支持题目内容和编号搜索)
   - 填空题特殊渲染:****显示为下划线
   - 判断题不显示选项,界面更简洁

3. UI优化
   - 答题结果组件重构,支持AI评分显示
   - 首页新增"题目列表"快速入口
   - 响应式设计,适配移动端和PC端

技术改进:
- 添加AI评分服务层(internal/services/ai_grading.go)
- 扩展题目模型支持AI评分结果
- 更新配置管理支持AI服务配置
- 添加AI评分测试脚本和文档

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 13:36:30 +08:00

370 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CLAUDE.md
本文件为 Claude Code (claude.ai/code) 在此代码仓库中工作时提供指导。
## 重要开发规范
### 文档同步更新规则
**关键规则**: 当实现新功能、修改现有功能或更改项目配置时,**必须同步更新相关文档**。
- **README.md 更新时机**:
- 添加新的核心功能或特性
- 修改项目安装、配置或运行方式
- 更改技术栈或主要依赖
- 添加新的 API 端点或修改现有端点
- 更新项目架构或目录结构
- **CLAUDE.md 更新时机**:
- 添加新的开发规范或最佳实践
- 修改项目配置(如代理、构建工具等)
- 更改目录结构或文件组织方式
- 引入新的工具或技术
- 更新常用命令或开发流程
- **更新原则**:
- 代码修改和文档更新应在同一次提交中完成
- 文档要清晰、准确,反映当前代码状态
- 使用 markdown 链接引用具体文件位置
- 及时移除过时的说明和示例
## 项目概述
AnKao 是一个使用 **Gin 框架**构建的 Go Web 应用程序。该项目遵循整洁架构模式,具有清晰的关注点分离,并设计为支持数据库集成。
## 架构
### 请求流程
1. HTTP 请求到达运行在 8080 端口的 Gin 服务器
2. 请求通过 Gin 的默认中间件(Logger、Recovery)和自定义中间件
3. Gin 路由器匹配路由并将请求定向到相应的处理器
4. 处理器(位于 `internal/handlers/`)使用 `*gin.Context` 处理请求并返回 JSON 响应
### 中间件模式
Gin 中的中间件使用 `gin.HandlerFunc` 模式:
```go
func MiddlewareName() gin.HandlerFunc {
return func(c *gin.Context) {
// 预处理
c.Next()
// 后处理
}
}
```
中间件在 [main.go:15](main.go#L15) 中使用 `r.Use()` 注册。
### 模块结构
- **main.go** - 应用程序入口点,服务器配置和路由设置
- **internal/handlers/** - HTTP 请求处理器,全部使用 `*gin.Context` 并返回 JSON 响应
- [user.go](internal/handlers/user.go) - 用户登录注册相关
- [practice_handler.go](internal/handlers/practice_handler.go) - 练习题相关
- [handlers.go](internal/handlers/handlers.go) - 通用处理器(健康检查等)
- **internal/middleware/** - Gin 中间件链(当前:自定义日志记录器、CORS)
- **internal/models/** - 数据模型
- [user.go](internal/models/user.go) - 用户模型
- [practice_question.go](internal/models/practice_question.go) - 练习题模型
- **internal/services/** - 业务服务
- [ai_grading.go](internal/services/ai_grading.go) - AI评分服务
- **internal/database/** - 数据库连接和初始化
- **pkg/config/** - 配置管理(数据库配置、AI配置等)
- **scripts/** - 工具脚本
- [import_questions.go](scripts/import_questions.go) - 题目数据导入脚本
## 常用命令
### 开发
```bash
# 运行服务器
go run main.go
# 安装/更新依赖
go mod tidy
# 格式化代码
go fmt ./...
# 检查代码常见问题
go vet ./...
# 导入练习题数据(首次运行需要)
go run scripts/import_questions.go
```
### 构建
```bash
# 构建二进制文件到 bin/server
go build -o bin/server.exe main.go
# 运行构建的二进制文件 (Windows)
.\bin\server.exe
# 运行构建的二进制文件 (Unix)
./bin/server
```
### 测试
```bash
# 运行所有测试
go test ./...
# 运行带覆盖率的测试
go test -cover ./...
# 运行特定包的测试
go test ./internal/handlers/
# 运行详细输出的测试
go test -v ./...
```
## 关键实现细节
- **框架**: 使用 Gin v1.11.0
- **ORM**: 使用 GORM v1.31.1
- **数据库**: PostgreSQL (配置在 [pkg/config/config.go](pkg/config/config.go))
- **AI服务**: 使用 go-openai SDK v1.41.2,配置在 [pkg/config/config.go](pkg/config/config.go)
- **服务器端口**: :8080 (在 [main.go:42](main.go#L42) 中配置)
- **处理器签名**: 所有处理器使用 `func(c *gin.Context)` 模式
- **JSON 响应**: 使用 `c.JSON()` 方法配合 `gin.H{}` 或结构体
- **导入路径**: 使用模块名 `ankao` (在 go.mod 中定义)
- **路由注册**: 路由在 [main.go](main.go) 中使用 `r.GET()``r.POST()` 等注册
- **中间件**: 使用 `r.Use()` 全局应用或通过路由分组应用到特定路由
- **密码加密**: 使用 bcrypt 加密存储用户密码
- **AI评分**: 简答题使用AI智能评分提供分数、评语和改进建议
## 添加新功能
### 添加新处理器
1.`internal/handlers/` 中创建处理器函数,签名为 `func(c *gin.Context)`
2. 使用 `c.JSON()` 返回响应
3. 在 [main.go](main.go) 中注册路由(例如:`r.GET("/path", handlers.YourHandler)`)
### 添加中间件
1.`internal/middleware/` 中创建返回 `gin.HandlerFunc` 的中间件
2. 使用 `r.Use(middleware.YourMiddleware())` 全局应用或应用到路由组
### 数据库集成
项目已集成 PostgreSQL 数据库:
- **配置**: 数据库配置在 [pkg/config/config.go](pkg/config/config.go)
- **初始化**: 数据库初始化在 [internal/database/database.go](internal/database/database.go)
- **模型定义**: 在 `internal/models/` 中添加 GORM 模型
- **迁移**: 使用 `DB.AutoMigrate()` 自动迁移表结构
- **使用方式**: 通过 `database.GetDB()` 获取数据库实例
### 添加新的数据模型
1.`internal/models/` 中创建模型文件
2. 定义结构体,使用 GORM 标签
3. 在 [internal/database/database.go](internal/database/database.go) 的 `InitDB()` 中添加 `AutoMigrate`
4. 在处理器中使用 `database.GetDB()` 进行数据库操作
### 导入数据到数据库
**示例**: 练习题数据导入
1. **准备JSON数据文件**: 如 [practice_question_pool.json](practice_question_pool.json)
2. **创建数据模型**: 在 `internal/models/` 中定义数据结构
3. **创建导入脚本**: 在 `scripts/` 目录创建导入脚本,如 [import_questions.go](scripts/import_questions.go)
4. **解析JSON并插入**:
```go
// 读取JSON文件
data, _ := os.ReadFile("data.json")
// 解析JSON
var items []YourStruct
json.Unmarshal(data, &items)
// 插入数据库
db := database.GetDB()
for _, item := range items {
db.Create(&item)
}
```
5. **运行导入脚本**: `go run scripts/import_questions.go`
**注意事项**:
- JSON中复杂数据(如数组、对象)需要序列化为字符串存储
- 使用唯一索引防止重复导入
- 大批量导入建议使用事务提高性能
## AI评分系统
项目集成了AI智能评分功能专门用于对简答题进行评分和反馈。
### AI评分配置
AI服务配置位于 [pkg/config/config.go](pkg/config/config.go)
```go
type AIConfig struct {
BaseURL string // AI API地址
APIKey string // API密钥
Model string // 使用的模型名称
}
```
**配置方式**
1. **默认配置**: 直接在代码中设置默认值
2. **环境变量**: 通过环境变量覆盖默认配置
```bash
export AI_BASE_URL="https://ai.yuchat.top"
export AI_API_KEY="你的API密钥"
export AI_MODEL="deepseek-v3"
```
### AI评分服务
AI评分服务实现位于 [internal/services/ai_grading.go](internal/services/ai_grading.go)
**主要功能**
- `NewAIGradingService()` - 创建AI评分服务实例
- `GradeShortAnswer(question, standardAnswer, userAnswer)` - 对简答题进行AI评分
**返回结果**
```go
type AIGradingResult struct {
Score float64 // 得分 (0-100)
IsCorrect bool // 是否正确 (Score >= 60 视为正确)
Feedback string // 评语
Suggestion string // 改进建议
}
```
### 集成方式
在 [practice_handler.go](internal/handlers/practice_handler.go) 的 `SubmitPracticeAnswer` 函数中:
```go
// 对简答题使用AI评分
if question.Type == "short-answer" {
aiService := services.NewAIGradingService()
aiResult, err := aiService.GradeShortAnswer(
question.Question,
standardAnswerStr,
userAnswerStr,
)
// 使用AI评分结果
correct = aiResult.IsCorrect
aiGrading = &models.AIGrading{
Score: aiResult.Score,
Feedback: aiResult.Feedback,
Suggestion: aiResult.Suggestion,
}
}
```
### API响应格式
简答题提交后,响应中会包含 `ai_grading` 字段:
```json
{
"success": true,
"data": {
"correct": true,
"user_answer": "用户的答案",
"correct_answer": "标准答案",
"ai_grading": {
"score": 85,
"feedback": "答案基本正确,要点全面",
"suggestion": "可以补充一些具体的例子"
}
}
}
```
### 注意事项
- AI评分仅对 `short-answer` 类型的题目生效
- 其他题型(填空题、判断题、选择题)仍使用传统的精确匹配方式
- AI评分失败时不影响主流程会记录日志并使用传统评分方式
- 评分采用温度参数 0.3,确保评分结果稳定可靠
### 自定义AI评分提示词
如需调整评分标准,修改 [ai_grading.go](internal/services/ai_grading.go) 中的 `prompt` 变量:
```go
prompt := fmt.Sprintf(`你是一位专业的阅卷老师,请对以下简答题进行评分。
题目:%s
标准答案:%s
学生答案:%s
请按照以下要求进行评分:
1. 给出一个0-100的分数
2. 判断答案是否正确60分及以上为正确
3. 给出简短的评语不超过50字
4. 如果答案不完善给出改进建议不超过50字
...
`, question, standardAnswer, userAnswer)
```
## 前端开发规范
### 包管理和开发
**重要**: 前端项目使用 **yarn** 作为包管理工具。
- **包管理器**: 使用 `yarn` 而非 `npm`
- **常用命令**:
```bash
# 安装依赖
yarn install
# 启动开发服务器 (运行在 http://localhost:3000)
yarn dev
# 构建生产版本
yarn build
# 添加依赖
yarn add <package-name>
# 添加开发依赖
yarn add -D <package-name>
```
### API 代理配置
- **开发环境**: Vite 已配置代理,前端请求 `/api/*` 会被代理到后端 `http://localhost:8080`
- **配置位置**: [web/vite.config.ts](web/vite.config.ts)
- **使用方式**: 前端代码中使用相对路径调用API,例如 `fetch('/api/login')`
- **后端服务器**: 确保后端服务运行在 `http://localhost:8080`
### UI 组件使用原则
**重要**: 在开发前端页面时,必须优先使用 UI 框架的组件。
- **优先使用 Ant Design 组件**: 项目使用 **antd (Ant Design)** 作为 UI 框架,开发时应优先查找并使用框架提供的组件
- **常用组件示例**:
- 表单输入: 使用 `Input` 组件,而非原生 `<input>`
- 按钮: 使用 `Button` 组件,而非原生 `<button>`
- 表单: 使用 `Form` 和 `Form.Item` 组件
- 提示信息: 使用 `message` 组件,而非自定义提示框
- 对话框: 使用 `Modal` 组件
- 列表: 使用 `List` 组件
- 布局: 使用 `Row`、`Col`、`Layout` 等布局组件
- 图标: 使用 `@ant-design/icons` 包中的图标
- **仅在必要时自定义**: 只有当 antd 没有提供对应组件时,才使用自定义组件
- **样式处理**: 使用 CSS Modules (`.module.less`) 编写组件样式,避免全局样式污染
- **主题定制**: 在 [web/vite.config.ts](web/vite.config.ts) 中通过 `modifyVars` 定制 antd 主题
### 前端项目结构
- **web/src/pages/** - 页面组件
- **web/src/components/** - 可复用组件
- **web/src/pages/*.module.less** - 页面样式文件 (CSS Modules)
- **web/vite.config.ts** - Vite 配置文件(包含代理配置和 antd 主题定制)
### 响应式设计
**重要**: 应用采用响应式设计,同时适配移动端和PC端。
- **响应式断点**:
- 移动端: `max-width: 768px`
- 平板: `769px ~ 1024px`
- PC端: `min-width: 1025px`
- **布局适配**: 使用 antd 的 Grid 系统 (`Row`、`Col`) 实现响应式布局
- **移动端优化**:
- 底部导航栏仅在移动端显示
- 触摸区域大小适中(最小 44x44px)
- 禁止双指缩放
- **PC端优化**:
- 内容居中,最大宽度限制
- 隐藏移动端特有的底部导航栏
- 更大的字体和间距