本文说明在 CloudQue API 中新增或维护功能时应遵循的本地开发流程。项目已有清晰的 Controller、Service、Repository、DTO、Entity 分层,新增能力优先复用现有模块模式。
go mod tidy
Copy-Item configs/config.yaml.example configs/config.yaml修改 configs/config.yaml 后启动:
go run cmd/server/main.go常用检查:
go test ./...
go fmt ./...
go vet ./...也可以使用:
make run
make test
make fmt
make vet在 internal/model/entity 下创建实体,只表达数据库字段和表关系。
package entity
// Example 示例实体
type Example struct {
BaseEntity
Name string `gorm:"type:varchar(100);not null" json:"name"`
}
// TableName 返回表名
func (Example) TableName() string {
return "examples"
}新增实体后,在 internal/app/app.go 的 initDatabase 中加入 AutoMigrate。
请求结构放在 internal/model/dto/request,响应结构放在 internal/model/dto/response。Controller 使用 DTO 绑定参数,避免直接暴露 Entity。
package request
// CreateExampleRequest 创建示例请求
type CreateExampleRequest struct {
Name string `json:"name" binding:"required"`
}接口文件命名为 xxx_interface.go,实现文件命名为 xxx_repository.go。
type ExampleRepository interface {
FindByID(id int) (*entity.Example, error)
Create(example *entity.Example) error
}Repository 只处理数据访问,不写 HTTP、权限、日志和业务编排逻辑。
Service 负责业务规则、事务、跨 Repository 编排和远程能力调用。
type ExampleService interface {
Create(req *request.CreateExampleRequest) error
GetByID(id int) (*entity.Example, error)
}如果能力需要远程服务器,优先复用 AuthService、ExecService、FileService、TerminalService 或 ssh.SessionManager 的现有逻辑。
Controller 放在 internal/api/v1/<module>,常见结构是 controller.go 和 routes.go。
func (ctrl *Controller) RegisterRoutes(r *gin.RouterGroup) {
group := r.Group("/example")
group.Use(middleware.Auth())
group.Use(middleware.RequirePermission(ctrl.authService))
group.Use(middleware.CaptureRawBody())
group.Use(middleware.GlobalLogManager.UserOperationLogs())
{
group.POST("", middleware.WithOperation("创建示例"), ctrl.Create)
}
}Controller 只做参数绑定、上下文读取、调用 Service 和返回响应。
在 internal/app/app.go 的 initDependencies 中创建 Repository 和 Service,再传入 api.NewRouter。在 internal/api/router.go 中添加 Controller 字段、构造参数和路由注册。
- 登录、登出、刷新 Token、验证码、密码重置位于
internal/api/v1/auth - 权限判断集中在
AuthService和RequirePermission中间件 - SSH 会话依赖用户登录凭证和远程服务器配置
- 普通用户接口位于
/api/v1/user - 管理员用户维护位于
/api/v1/admin - 用户注册、密码修改、管理员创建用户会涉及远程服务器用户或 SSH 凭证逻辑,修改前要核对
user_service.go和auth_service.go
- API 权限:
/api/v1/permissionManage/API - 菜单:
/api/v1/permissionManage/menus - 角色:
/api/v1/permissionManage/roles - 权限数据同时影响接口访问和前端菜单展示,修改时要同步检查角色权限聚合逻辑
- 任务接口位于
/api/v1/job - 队列接口位于
/api/v1/queue - 调度器位于
internal/service/scheduler_service.go - 任务执行依赖
ExecService和 SSH 会话 - GPU 占用和释放由
GpuService和调度器协作完成
- 文件接口位于
/api/v1/files和/api/v1/directories - 终端接口位于
/api/v1/terminal/ws - 两者都依赖远程 SSH/SFTP,修改时优先保持路径解析、root 模式和用户目录隔离逻辑稳定
- 系统实时信息位于
/api/v1/system - 首页概览位于
/api/v1/home - WebSocket 推送由对应 Service 和
pkg/websocket连接池管理
- 用户操作日志通过中间件捕获
- 管理员关机重启日志有独立接口
- 新增需要记录的写操作时,路由上添加
middleware.WithOperation("中文操作名")
统一使用 pkg/response 返回 JSON:
response.Success(c, data)
response.BizError(c, err)
response.BadRequest(c, "参数错误")业务错误使用 pkg/errors 中的错误码。新增错误码时同时补充错误消息。
业务日志使用 pkg/logger:
logger.Info("任务提交成功", zap.Int("job_id", jobID))
logger.Warn("任务取消失败", zap.Error(err))日志文本保持简洁中文描述。不要在日志中输出密码、Token、私钥、验证码等敏感信息。
configs/config.yaml.example只保留示例值configs/config.yaml保存本地真实配置,不应提交真实敏感信息- 新增配置项时同步更新
pkg/config/config.go、configs/config.yaml.example和 README 配置说明
新增、删除或调整接口时,同步更新:
README.md的模块概览docs/API.md的接口清单docs/ARCHITECTURE.md的模块说明- 相关协议文档,如
docs/terminal_ws_spec.md
go fmt ./...
go test ./...
go vet ./...如果只改文档,至少检查 Markdown 文件可读、链接存在、接口路径与路由文件一致。