Files
backend-go/README.md

325 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 浙江贝凡溯源管理平台 - 后端服务 (Go 版本)
这是一个使用 Go 语言开发的溯源管理平台后端服务,提供序列号生成、查询、管理等功能。
## 技术栈
- **Web 框架**: Gin (高性能 HTTP 框架)
- **ORM**: GORM (Go 对象关系映射)
- **数据库**:
- SQLite (默认,适用于开发和轻量级部署)
- PostgreSQL (生产环境推荐)
- **认证**: JWT (JSON Web Token) - golang-jwt/jwt/v5
- **密码加密**: bcrypt (golang.org/x/crypto)
- **二维码生成**: yeqown/go-qrcode/v2
- **配置管理**:
- Viper (环境变量和配置文件)
- gotenv (.env 文件加载)
- **日志**: Zap (高性能结构化日志)
- **验证**: go-playground/validator
- **测试**: Testify (测试框架)
- **工具**: UUID (github.com/google/uuid)
## 项目结构
```
backend-go/
├── config/ # 配置管理
│ └── config.go # 配置加载和解析(支持 .env 文件和环境变量)
├── controllers/ # 控制器层,处理 HTTP 请求
│ ├── auth_controller.go # 认证相关接口
│ ├── companies_controller.go # 企业管理接口
│ ├── helper.go # 控制器通用辅助函数
│ └── serials_controller.go # 序列号管理接口
├── database/ # 数据库连接和操作
│ └── database.go # 数据库初始化、连接池配置
├── logger/ # 日志管理
│ └── logger.go # 结构化日志(使用 Zap
├── middleware/ # 中间件层
│ └── auth.go # JWT 认证和权限检查
├── models/ # 数据模型和 DTO
│ └── models.go # User、Company、Serial 等模型定义
├── routes/ # 路由配置
│ └── routes.go # API 路由注册
├── services/ # 业务逻辑层
│ ├── auth_service.go # 认证业务逻辑
│ ├── companies_service.go # 企业管理业务逻辑
│ ├── serials_service.go # 序列号业务逻辑
│ └── services_test.go # 服务层单元测试
├── tests/ # 集成测试
│ └── main_test.go # 端到端测试
├── data/ # 数据目录 (SQLite 数据库存储)
├── main.go # 应用程序入口
├── go.mod # Go 模块依赖
├── go.sum # Go 模块校验和
├── Makefile # 构建和开发任务
├── .env.example # 环境变量示例
├── .env # 环境变量配置(需手动创建)
├── .golangci.yml # 代码检查配置
└── .gitignore # Git 忽略文件
```
## 快速开始
### 1. 安装依赖
```bash
cd backend-go
go mod download
# 或使用 Makefile
make deps
```
### 2. 配置环境变量
复制 `.env.example` 文件为 `.env` 并根据需要修改:
```bash
cp .env.example .env
```
**重要**: 生产环境请务必修改 `JWT_SECRET` 环境变量!
### 3. 使用 Makefile推荐
```bash
# 启动开发服务器
make run
# 编译项目
make build
# 运行测试
make test
# 生成测试覆盖率报告
make test-coverage
# 代码质量检查
make quality
# 清理构建文件
make clean
```
### 4. 手动启动
```bash
go run main.go
```
服务器将在 http://localhost:3000 上运行。
### 5. 配置管理
项目采用 **YAML 结构化管理 + 环境变量动态覆盖** 的方案:
#### 配置文件优先级(从高到低)
1. **环境变量** (最高优先级) - 格式:`APP_配置项`
2. **.env 文件** - 本地开发环境配置
3. **config.yaml** - 默认配置文件
4. **内置默认值** (最低优先级)
#### 环境变量命名规则
所有环境变量使用 `APP_` 前缀,多级配置使用 `_` 连接:
```bash
# 示例
APP_SERVER_PORT=8080 # 覆盖 server.port
APP_DATABASE_DRIVER=postgres # 覆盖 database.driver
APP_DATABASE_POSTGRES_HOST=db.com # 覆盖 database.postgres.host
APP_JWT_SECRET=my-secret-key # 覆盖 jwt.secret
```
#### 常用配置项
| 环境变量 | 对应配置项 | 说明 | 默认值 |
|---------|-----------|------|--------|
| `APP_SERVER_PORT` | server.port | 服务器端口 | 3000 |
| `APP_SERVER_ENVIRONMENT` | server.environment | 运行环境 | development |
| `APP_DATABASE_DRIVER` | database.driver | 数据库驱动 | sqlite |
| `APP_DATABASE_SQLITE_PATH` | database.sqlite.path | SQLite 路径 | ./data/database.sqlite |
| `APP_DATABASE_POSTGRES_HOST` | database.postgres.host | PostgreSQL 主机 | localhost |
| `APP_DATABASE_POSTGRES_PORT` | database.postgres.port | PostgreSQL 端口 | 5432 |
| `APP_DATABASE_POSTGRES_USER` | database.postgres.user | PostgreSQL 用户名 | trace |
| `APP_DATABASE_POSTGRES_PASSWORD` | database.postgres.password | PostgreSQL 密码 | trace123 |
| `APP_DATABASE_POSTGRES_DBNAME` | database.postgres.dbname | PostgreSQL 数据库名 | trace |
| `APP_JWT_SECRET` | jwt.secret | JWT 签名密钥 | your-secret-key... |
| `APP_JWT_EXPIRE` | jwt.expire | JWT 过期时间(秒) | 7200 |
#### 快速配置示例
**开发环境(.env**:
```bash
# 使用 SQLite
DATABASE_DRIVER=sqlite
DATABASE_PATH=./data/dev.sqlite
```
**生产环境(环境变量)**:
```bash
# 使用 PostgreSQL
export APP_SERVER_PORT=8080
export APP_SERVER_ENVIRONMENT=production
export APP_DATABASE_DRIVER=postgres
export APP_DATABASE_POSTGRES_HOST=prod-db.example.com
export APP_DATABASE_POSTGRES_PASSWORD=secure-password
export APP_JWT_SECRET=your-production-secret-key
```
### 6. 测试 API
**健康检查**:
```bash
curl -X GET http://localhost:3000/api/health
```
**用户登录**:
```bash
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"password123"}'
```
## API 文档
### 认证路由
| 方法 | 路径 | 描述 | 需要认证 |
| ---- | --------------------------- | ----------------------- | -------- |
| POST | `/api/auth/login` | 用户登录,返回 JWT 令牌 | 否 |
| GET | `/api/auth/profile` | 获取当前用户信息 | 是 |
| PUT | `/api/auth/profile` | 更新用户信息 | 是 |
| POST | `/api/auth/change-password` | 修改密码 | 是 |
### 序列号管理
| 方法 | 路径 | 描述 | 需要认证 | 角色 |
| ---- | ----------------------------------- | ---------------- | -------- | ------ |
| POST | `/api/serials/generate` | 生成序列号 | 是 | 管理员 |
| POST | `/api/serials/generate-with-prefix` | 带前缀生成序列号 | 是 | 管理员 |
| POST | `/api/serials/:serialNumber/qrcode` | 生成序列号二维码 | 是 | 任何 |
| GET | `/api/serials/:serialNumber/query` | 查询序列号信息 | 否 | 任何 |
| GET | `/api/serials` | 获取序列号列表 | 是 | 任何 |
| PUT | `/api/serials/:serialNumber` | 更新序列号信息 | 是 | 管理员 |
| POST | `/api/serials/:serialNumber/revoke` | 吊销序列号 | 是 | 管理员 |
### 企业管理
| 方法 | 路径 | 描述 | 需要认证 | 角色 |
| ------ | ----------------------------- | ------------ | -------- | ------ |
| GET | `/api/companies` | 获取企业列表 | 是 | 任何 |
| POST | `/api/companies` | 创建新企业 | 是 | 管理员 |
| PUT | `/api/companies/:companyName` | 更新企业信息 | 是 | 管理员 |
| DELETE | `/api/companies/:companyName` | 删除企业 | 是 | 管理员 |
## 测试
### 运行所有测试
```bash
# 运行所有测试
go test -v ./...
# 仅运行服务层单元测试
cd services && go test -v -cover
# 仅运行集成测试
go test -v ./tests/...
```
### 生成测试覆盖率报告
```bash
# 生成覆盖率报告
go test -v ./services/... -coverprofile=coverage.out
go tool cover -html=coverage.out
```
### 当前测试覆盖
- **services/**: 包含 AuthService 和 SerialsService 的完整单元测试
- 用户认证测试(登录、获取用户信息、修改密码、更新资料)
- 序列号管理测试(生成、查询、更新、吊销、分页列表)
- **tests/**: 集成测试(健康检查、登录流程)
## 代码检查
使用 golangci-lint 进行代码检查:
```bash
golangci-lint run ./...
```
## 部署
### 编译为二进制文件
```bash
# Linux/Mac
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o trace-backend
# Windows
go build -o trace-backend.exe main.go
# macOS
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o trace-backend
```
### 运行
```bash
./trace-backend
```
## 数据库迁移
### SQLite 到 PostgreSQL 的迁移
修改 `.env` 文件中的数据库配置:
```bash
# 将数据库驱动改为 postgres
DATABASE_DRIVER=postgres
# PostgreSQL 配置
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=trace
POSTGRES_PASSWORD=trace123
POSTGRES_DB=trace
POSTGRES_SSLMODE=disable
```
然后重新启动应用即可:
```bash
./trace-backend
```
**注意**: 切换数据库后,原有 SQLite 中的数据不会自动迁移到 PostgreSQL。需要使用数据库迁移工具如 pgloader手动迁移数据。
## 贡献指南
1. 克隆项目
2. 创建新功能分支
3. 提交更改
4. 推送到远程仓库
5. 创建 Pull Request
### 代码风格要求
- 使用 gofmt 自动格式化代码
- 遵循 Go 官方编码规范
- 使用 golangci-lint 进行代码检查
- 保持代码简洁和高效
## 许可证
MIT License