开发指南

添加新实体

以添加 Position(职位)为例,需要添加以下文件:

1. 模型

创建 models/position.go

package models

type Position struct {
    ID   uint   `gorm:"primaryKey" json:"id"`
    Name string `gorm:"not null" json:"name"`
}

2. Repository

创建 repository/position_repo.go

package repository

import (
    "pms-backend/models"
    "gorm.io/gorm"
)

type PositionRepository interface {
    Create(pos *models.Position) error
    GetAll() ([]models.Position, error)
    ExistsByID(id uint) (bool, error)
}

type positionRepository struct {
    db *gorm.DB
}

func NewPositionRepository(db *gorm.DB) PositionRepository {
    return &positionRepository{db: db}
}

// 实现接口方法...

创建 repository/position_repo_test.go,用测试 PostgreSQL 数据库测试。

3. Service

创建 service/position_service.go

package service

import (
    "pms-backend/models"
    "pms-backend/repository"
)

type PositionService interface {
    Create(name string) (*models.Position, error)
    GetAll() ([]models.Position, error)
}

type positionService struct {
    posRepo repository.PositionRepository
}

func NewPositionService(posRepo repository.PositionRepository) PositionService {
    return &positionService{posRepo: posRepo}
}

// 实现接口方法...

创建 service/position_service_test.go,用 mock repo 测试。

4. Handler

创建 handler/position_handler.go

package handler

import (
    "pms-backend/service"
    "github.com/gin-gonic/gin"
)

type PositionHandler struct {
    service service.PositionService
}

func NewPositionHandler(s service.PositionService) *PositionHandler {
    return &PositionHandler{service: s}
}

// 实现 handler 方法...

创建 handler/position_handler_test.go,用 mock service 测试。

5. 注册路由

修改 handler/router.go,在 SetupRouter 中添加:

positions := r.Group("/positions")
{
    positions.POST("", posHandler.Create)
    positions.GET("", posHandler.GetAll)
}

6. 组装依赖

修改 main.go,添加:

posRepo := repository.NewPositionRepository(db)
posSvc := service.NewPositionService(posRepo)
posHandler := handler.NewPositionHandler(posSvc)

7. 数据库迁移

修改 config/db.go,在 NewDB 的 AutoMigrate 中添加 &models.Position{}

命名约定

  • 接口:大写开头,如 EmployeeRepositoryEmployeeService
  • 实现:小写开头 struct,如 employeeRepositoryemployeeService
  • 构造函数:NewXxx,如 NewEmployeeRepository
  • 文件名:按实体名,如 employee_repo.goemployee_service.go
  • 测试文件:与实现文件对应,如 employee_repo_test.go

错误处理

  • 业务错误定义在 service/errors.go,用 sentinel error
  • Service 层返回 error,Handler 用 errors.Is 判断后返回对应 HTTP 状态码
  • Repository 层直接返回 GORM 错误,不包装

构建文档

# 安装 mdbook
cargo install mdbook

# 构建
cd docs && mdbook build

# 本地预览
cd docs && mdbook serve