- UI框架:从 antd-mobile 迁移到 Ant Design,支持更好的跨平台体验 - 响应式设计:实现移动端、平板、PC端全方位适配 - 移动端:保留底部导航栏,优化触摸交互 - PC端:隐藏底部导航,采用居中布局 - 样式重构:所有组件样式迁移到 CSS Modules(.module.less) - 功能优化: - 练习题答题改进:始终返回正确答案便于用户学习 - 添加题目编号字段(question_id) - 修复判断题选项:由 A/B 改为 true/false - 组件优化: - TabBarLayout 重构,支持响应式显示/隐藏 - 所有页面组件采用 Ant Design 组件替换原 antd-mobile 组件 - 统一使用 @ant-design/icons 图标库 - 文档同步:更新 CLAUDE.md 中 UI 组件使用规范和响应式设计说明 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
253 lines
8.5 KiB
Markdown
253 lines
8.5 KiB
Markdown
# 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/database/** - 数据库连接和初始化
|
|
- **pkg/config/** - 配置管理(数据库配置等)
|
|
- **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))
|
|
- **服务器端口**: :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 加密存储用户密码
|
|
|
|
## 添加新功能
|
|
|
|
### 添加新处理器
|
|
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中复杂数据(如数组、对象)需要序列化为字符串存储
|
|
- 使用唯一索引防止重复导入
|
|
- 大批量导入建议使用事务提高性能
|
|
|
|
## 前端开发规范
|
|
|
|
### 包管理和开发
|
|
**重要**: 前端项目使用 **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端优化**:
|
|
- 内容居中,最大宽度限制
|
|
- 隐藏移动端特有的底部导航栏
|
|
- 更大的字体和间距
|
|
|