GoTrain 项目开发指南
1 make code table=users 2 cd ./goapi/data/code/internal/dbentity 3 copy entity ,dao至beapi dbdao dbentity 4 ai生成uiTableRequest 对于公共代码可以开发 apiservice apifacade domainfacade 5 ai生成TableController 6 编写swag 7 测试 8 make doc生成文档 9 make dev安装
GoTrain项目开发指南摘要:本项目采用分层架构设计,包含API核心模块和Web控制器模块。开发流程包括:1)使用makecode命令生成实体代码;2)迁移代码至正式目录;3)生成UI请求对象;4)创建Controller;5)编写Swagger文档;6)单元测试;7)生成API文档;8)安装运行。项目遵循标准化规范,提供代码生成模板和依赖注入机制,支持分页查询、排序、导出等通用功能。通过分层设计(DAO层、API服务层、控制器层)实现业务逻辑解耦,提高开发效率和代码可维护性。
项目架构概述
本项目采用分层架构设计,遵循 Clean Architecture 原则,整体结构如下:
plainText
├── beapi/ # API 核心模块 │ ├── data/code/internal/dbentity/ # 代码生成临时目录 │ ├── db/ # 数据访问层 │ │ ├── dbdao/ # DAO 层(数据访问对象) │ │ ├── dbentity/ # 数据库实体 │ │ ├── apiservice/ # API 服务层 │ │ └── apiface/ # API 接口定义 │ ├── trainframe/ # 业务框架 │ │ ├── service/ # 业务服务层 │ │ └── repository/ # 数据仓库层 │ └── webframe/ # Web 框架基础设施 └── beweb/ # Web 控制器模块 └── webctl/ # REST API 控制器开发流程指南
1. 代码生成:根据数据库表生成实体代码
命令执行:
bash
make code table=users作用:根据数据库表结构自动生成实体类和基础 DAO 代码,输出到beapi/data/code/internal/dbentity/目录。
生成文件示例:
users.go- 实体类定义(包含字段映射、表名、主键等)users_dao.go- DAO 数据访问对象users_init.go- 依赖注入初始化文件
实体类结构示例:
go
type Users struct { basedto.BaseEntity Id int64 `json:"id,string" gorm:"primaryKey"` Name string `json:"name" gorm:"column:name"` Phone string `json:"phone" gorm:"column:phone"` CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` } func (u *Users) TableName() string { return "users" } func (u *Users) PkeyName() string { return "id" }2. 代码迁移:复制生成的代码到正式目录
命令执行:
bash
cd ./beapi/data/code/internal/dbentity手动复制操作:
| 源文件 | 目标目录 | 说明 |
|---|---|---|
users.go | beapi/db/dbentity/userentity/ | 实体类 |
users_dao.go | beapi/db/dbdao/userdao/ | DAO 层 |
users_init.go | beapi/db/dbentity/userentity/ | 初始化文件 |
users_dao_init.go | beapi/db/dbdao/userdao/ | DAO 初始化文件 |
3. 生成 UI 请求对象:ai生成uiTableRequest
设计原则:
- 请求对象用于接收前端查询参数
- 继承基础分页查询结构
- 支持关键字搜索、字段过滤、排序等
示例结构:
go
type UiUsersRequest struct { basedto.BaseEntity Name string `json:"name"` // 用户姓名 Phone string `json:"phone"` // 手机号 UserType int32 `json:"userType"` // 用户类型 PageNum int `json:"pageNum"` // 页码 PageSize int `json:"pageSize"` // 每页数量 OrderBy string `json:"orderBy"` // 排序字段 SortBy string `json:"sortBy"` // 排序方向(asc/desc) }创建位置:beweb/uipage/uitrain/ui_users_request.go
4. 生成 Controller:ai生成TableController
Controller 设计规范:
go
type UsersController struct { userService serviceuser.UserService ctlbase.BaseController basedto.BaseEntitySingle } func DefaultUsersController() webfacade.Controller { return &UsersController{ userService: serviceuser.FindBeanuserService(), } } // RegisterRoute 注册路由 func (c *UsersController) RegisterRoute(api *gin.RouterGroup) { api.GET("/users", c.List) api.GET("/users/:id", c.Get) api.POST("/users", c.Create) api.PUT("/users/:id", c.Update) api.DELETE("/users/:id", c.Delete) }创建位置:beweb/webctl/ctluser/users_controller.go
5. 编写 Swagger 文档注释
Swagger 注解规范:
go
// @Summary 获取用户列表 // @Description 根据条件分页查询用户列表 // @Produce json // @Tags 用户管理 // @Security JWT // @Param name query string false "用户姓名" // @Param phone query string false "手机号" // @Param pageNum query int false "页码" default(1) // @Param pageSize query int false "每页数量" default(20) // @Success 200 {object} common.Response{data=common.PaginationResult{list=[]entityuser.Users}} // @Router /api/v1/users [get] func (c *UsersController) List(ctx *gin.Context) { // ... }Swagger 注解说明:
| 注解 | 说明 | 示例 |
|---|---|---|
@Summary | 接口摘要 | 获取用户列表 |
@Description | 接口描述 | 详细说明 |
@Produce | 响应格式 | json |
@Tags | 分组标签 | 用户管理 |
@Security | 安全认证 | JWT |
@Param | 请求参数 | name query string |
@Success | 成功响应 | 200 {object} Response |
@Router | 路由路径 | /api/v1/users [get] |
6. 测试
单元测试规范:
go
func TestUsersController_List(t *testing.T) { ctrl := DefaultUsersController() req := &apimodel.QueryUserRequest{ ObjectId: "test", } result := ctrl.userService.QueryUsers(req) assert.NotNil(t, result) assert.True(t, result.Success) }测试命令:
bash
go test -v ./beweb/webctl/ctluser/... -run TestUsersController7. 生成 API 文档
命令执行:
bash
make doc作用:使用 Swaggo 生成 OpenAPI 文档
生成产物:
trainplat/server/docs/docs.go- Swagger 文档定义- 访问地址:
http://localhost:8080/swagger/index.html
8. 开发环境安装
命令执行:
bash
make dev作用:
- 安装所有依赖包
- 编译项目
- 启动开发服务器
启动命令:
bash
go run trainplat/server/main.go服务访问:
- API 地址:
http://localhost:8080/api/v1/ - Swagger 文档:
http://localhost:8080/swagger/index.html
公共代码开发建议
apiservice - API 服务层
用于封装复杂业务逻辑,作为 Controller 和 Repository 之间的桥梁。
go
type UserApiService struct { basedto.BaseEntitySingle userRepository reposuser.UserRepository } func (s *UserApiService) GetUserInfo(userId int64) (*userentity.Users, error) { // 组合多个 Repository 操作 user, err := s.userRepository.FindById(userId) if err != nil { return nil, err } // 添加额外业务逻辑 return user, nil }apifacade - API 门面层
提供统一的 API 入口,聚合多个服务。
go
type ApiFacade struct { userService serviceuser.UserService creditService servicecredit.CreditService planService serviceplan.PlanService } func (f *ApiFacade) CreateUser(ctx context.Context, user *entityuser.User) (*entityuser.User, error) { // 事务处理 // 调用多个服务 return user, nil }domainfacade - 领域门面层
封装领域业务规则,供多个模块复用。
go
type DomainFacade struct { basedto.BaseEntitySingle } func (f *DomainFacade) ValidateUserRole(user *entityuser.User, role string) bool { // 领域规则验证 return strings.Contains(user.RelRole, role) }文件命名规范
| 类型 | 命名规则 | 示例 |
|---|---|---|
| 实体类 | 首字母大写单数 | Users,Student |
| DAO | 实体名 + Dao | UsersDao |
| Service | 实体名 + Service | UserService |
| Controller | 实体名 + Controller | UsersController |
| 请求DTO | Ui + 实体名 + Request | UiUsersRequest |
| 响应DTO | 实体名 + Result | UsersResult |
依赖注入规范
所有服务需提供初始化函数:
go
// 用户服务初始化 func init() { godi.RegisterBean("UserService", NewUserService) } func FindBeanUserService() *UserService { return godi.FindBean[*UserService]("UserService") }代码提交规范
bash
# 提交格式 git commit -m "feat: 添加用户查询接口" git commit -m "fix: 修复用户创建失败问题" git commit -m "docs: 更新API文档" git commit -m "refactor: 重构用户服务"总结
本项目采用标准化的代码生成和开发流程,核心步骤为:
- 代码生成→
make code table=xxx - 代码迁移→ 复制到正式目录
- 生成请求对象→
UiXXXRequest - 生成控制器→
XXXController - 编写文档→ Swagger 注解
- 测试验证→ 单元测试
- 生成文档→
make doc - 部署运行→
make dev
通过遵循以上规范,可以高效、规范地完成业务功能开发。
根据查看的代码结构,我需要创建一个继承uiframe.UiSimpleRequest的UiUsersRequest。
go
package uiframe import ( "gitea.super-study.com/ys-study/gotrain/beapi/db/dbentity/userentity" ) // UiUsersRequest 用户列表查询请求 // 继承 UiSimpleRequest,支持通用的分页、排序、搜索功能 type UiUsersRequest struct { *UiSimpleRequest[int64, *userentity.Users] } // NewUiUsersRequest 创建用户查询请求实例 func NewUiUsersRequest() *UiUsersRequest { return &UiUsersRequest{ UiSimpleRequest: NewUiSimpleRequest[int64, *userentity.Users](), } } // BuildQuery 构建查询条件 func (self *UiUsersRequest) BuildQuery() *UiUsersRequest { self.UiSimpleRequest.BuildRequest() return self } // List 执行查询并返回结果 func (self *UiUsersRequest) List() *PageResult[*userentity.Users] { return self.UiSimpleRequest.List() }说明:
| 方法 | 功能说明 |
|---|---|
NewUiUsersRequest() | 创建查询请求实例,自动初始化 DAO 和参数 |
BuildQuery() | 构建查询条件(分页、排序等) |
List() | 执行查询,返回分页结果 |
继承自UiSimpleRequest | 支持排序、分页、搜索、导出等通用功能 |
使用示例:
go
// 创建查询请求 req := NewUiUsersRequest() // 设置查询条件 req.DbEq("user_type", 20) // 查询学员 req.DbLike("name", "张") // 姓名包含"张" req.OrderByDesc("created_at") // 执行查询 result := req.List() // 导出Excel req.ExportDefault(ctx)继承的通用功能:
- 分页查询(PageSize, PageCurrent)
- 排序支持(OrderBys)
- 关键字搜索(Keyword)
- Excel/PDF/HTML 导出
- 数据权限过滤(DataScopeFilter)
请将此代码保存到beapi/gotool/dbframe/uiframe/ui_users_request.go文件中。