- 后端功能: * 新增练习题数据模型和数据库表结构 * 实现题目列表、随机题目、提交答案等API接口 * 支持5种题型:单选、多选、判断、填空、简答 * 判断题自动生成"对/错"选项 * 前后端类型映射(single/multiple/judge/fill/short) - 前端功能: * 新增首页,展示5种题型选择卡片和统计信息 * 完善答题页面,支持所有题型的渲染和答题 * 填空题特殊渲染:将****替换为横线输入框 * 实现题目列表、筛选、随机练习等功能 * 优化底部导航,添加首页、答题、我的三个标签 - 工具脚本: * 新增题目数据导入脚本 * 支持从JSON文件批量导入题库 - 文档更新: * 更新CLAUDE.md和README.md,记录新增功能 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
8.0 KiB
8.0 KiB
CLAUDE.md
本文件为 Claude Code (claude.ai/code) 在此代码仓库中工作时提供指导。
重要开发规范
文档同步更新规则
关键规则: 当实现新功能、修改现有功能或更改项目配置时,必须同步更新相关文档。
-
README.md 更新时机:
- 添加新的核心功能或特性
- 修改项目安装、配置或运行方式
- 更改技术栈或主要依赖
- 添加新的 API 端点或修改现有端点
- 更新项目架构或目录结构
-
CLAUDE.md 更新时机:
- 添加新的开发规范或最佳实践
- 修改项目配置(如代理、构建工具等)
- 更改目录结构或文件组织方式
- 引入新的工具或技术
- 更新常用命令或开发流程
-
更新原则:
- 代码修改和文档更新应在同一次提交中完成
- 文档要清晰、准确,反映当前代码状态
- 使用 markdown 链接引用具体文件位置
- 及时移除过时的说明和示例
项目概述
AnKao 是一个使用 Gin 框架构建的 Go Web 应用程序。该项目遵循整洁架构模式,具有清晰的关注点分离,并设计为支持数据库集成。
架构
请求流程
- HTTP 请求到达运行在 8080 端口的 Gin 服务器
- 请求通过 Gin 的默认中间件(Logger、Recovery)和自定义中间件
- Gin 路由器匹配路由并将请求定向到相应的处理器
- 处理器(位于
internal/handlers/)使用*gin.Context处理请求并返回 JSON 响应
中间件模式
Gin 中的中间件使用 gin.HandlerFunc 模式:
func MiddlewareName() gin.HandlerFunc {
return func(c *gin.Context) {
// 预处理
c.Next()
// 后处理
}
}
中间件在 main.go:15 中使用 r.Use() 注册。
模块结构
- main.go - 应用程序入口点,服务器配置和路由设置
- internal/handlers/ - HTTP 请求处理器,全部使用
*gin.Context并返回 JSON 响应- user.go - 用户登录注册相关
- practice_handler.go - 练习题相关
- handlers.go - 通用处理器(健康检查等)
- internal/middleware/ - Gin 中间件链(当前:自定义日志记录器、CORS)
- internal/models/ - 数据模型
- user.go - 用户模型
- practice_question.go - 练习题模型
- internal/database/ - 数据库连接和初始化
- pkg/config/ - 配置管理(数据库配置等)
- scripts/ - 工具脚本
- import_questions.go - 题目数据导入脚本
常用命令
开发
# 运行服务器
go run main.go
# 安装/更新依赖
go mod tidy
# 格式化代码
go fmt ./...
# 检查代码常见问题
go vet ./...
# 导入练习题数据(首次运行需要)
go run scripts/import_questions.go
构建
# 构建二进制文件到 bin/server
go build -o bin/server.exe main.go
# 运行构建的二进制文件 (Windows)
.\bin\server.exe
# 运行构建的二进制文件 (Unix)
./bin/server
测试
# 运行所有测试
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)
- 服务器端口: :8080 (在 main.go:42 中配置)
- 处理器签名: 所有处理器使用
func(c *gin.Context)模式 - JSON 响应: 使用
c.JSON()方法配合gin.H{}或结构体 - 导入路径: 使用模块名
ankao(在 go.mod 中定义) - 路由注册: 路由在 main.go 中使用
r.GET()、r.POST()等注册 - 中间件: 使用
r.Use()全局应用或通过路由分组应用到特定路由 - 密码加密: 使用 bcrypt 加密存储用户密码
添加新功能
添加新处理器
- 在
internal/handlers/中创建处理器函数,签名为func(c *gin.Context) - 使用
c.JSON()返回响应 - 在 main.go 中注册路由(例如:
r.GET("/path", handlers.YourHandler))
添加中间件
- 在
internal/middleware/中创建返回gin.HandlerFunc的中间件 - 使用
r.Use(middleware.YourMiddleware())全局应用或应用到路由组
数据库集成
项目已集成 PostgreSQL 数据库:
- 配置: 数据库配置在 pkg/config/config.go
- 初始化: 数据库初始化在 internal/database/database.go
- 模型定义: 在
internal/models/中添加 GORM 模型 - 迁移: 使用
DB.AutoMigrate()自动迁移表结构 - 使用方式: 通过
database.GetDB()获取数据库实例
添加新的数据模型
- 在
internal/models/中创建模型文件 - 定义结构体,使用 GORM 标签
- 在 internal/database/database.go 的
InitDB()中添加AutoMigrate - 在处理器中使用
database.GetDB()进行数据库操作
导入数据到数据库
示例: 练习题数据导入
- 准备JSON数据文件: 如 practice_question_pool.json
- 创建数据模型: 在
internal/models/中定义数据结构 - 创建导入脚本: 在
scripts/目录创建导入脚本,如 import_questions.go - 解析JSON并插入:
// 读取JSON文件 data, _ := os.ReadFile("data.json") // 解析JSON var items []YourStruct json.Unmarshal(data, &items) // 插入数据库 db := database.GetDB() for _, item := range items { db.Create(&item) } - 运行导入脚本:
go run scripts/import_questions.go
注意事项:
- JSON中复杂数据(如数组、对象)需要序列化为字符串存储
- 使用唯一索引防止重复导入
- 大批量导入建议使用事务提高性能
前端开发规范
包管理和开发
重要: 前端项目使用 yarn 作为包管理工具。
- 包管理器: 使用
yarn而非npm - 常用命令:
# 安装依赖 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
- 使用方式: 前端代码中使用相对路径调用API,例如
fetch('/api/login') - 后端服务器: 确保后端服务运行在
http://localhost:8080
UI 组件使用原则
重要: 在开发前端页面时,必须优先使用 UI 框架的组件。
- 优先使用 antd-mobile 组件: 项目使用 antd-mobile 作为 UI 框架,开发时应优先查找并使用框架提供的组件
- 常用组件示例:
- 表单输入: 使用
Input组件,而非原生<input> - 按钮: 使用
Button组件,而非原生<button> - 表单: 使用
Form和Form.Item组件 - 提示信息: 使用
Toast组件,而非自定义提示框 - 对话框: 使用
Dialog组件 - 列表: 使用
List组件
- 表单输入: 使用
- 仅在必要时自定义: 只有当 antd-mobile 没有提供对应组件时,才使用自定义组件
- 样式处理: 使用 CSS Modules (
.module.less) 编写组件样式,避免全局样式污染
前端项目结构
- web/src/pages/ - 页面组件
- web/src/components/ - 可复用组件
- web/src/pages/*.module.less - 页面样式文件 (CSS Modules)
- web/vite.config.ts - Vite 配置文件(包含代理配置)
移动端适配
- 禁止缩放: 应用已配置防止移动端双指缩放
- 响应式设计: 优先考虑移动端布局和交互
- 触摸优化: 使用合适的触摸区域大小(最小 44x44px)