2026-06-05 18:00:14 +08:00
2026-02-12 14:31:30 +08:00
2026-06-02 17:21:07 +08:00
2026-02-12 19:24:21 +08:00
2026-02-12 14:31:30 +08:00
2026-06-02 17:18:49 +08:00
2026-06-02 17:18:49 +08:00
2026-05-28 10:05:59 +08:00

浙江贝凡溯源赋码平台 - 后端服务 (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
  • API 文档: Swagger/OpenAPI (swaggo/swag)
  • CORS: gin-contrib/cors (跨域资源共享)
  • 配置管理:
    • Viper (环境变量和配置文件)
    • gotenv (.env 文件加载)
  • 日志: Zap (高性能结构化日志)
  • 验证: go-playground/validator
  • 测试: Testify (测试框架)
  • 工具: UUID (github.com/google/uuid)

项目结构

backend-go/
├── config/                  # 配置管理
│   └── config.go            # 配置加载和解析(支持 .env 文件和环境变量)
├── controllers/             # 控制器层,处理 HTTP 请求
│   ├── aftersales_controller.go # 售后工单接口
│   ├── auth_controller.go   # 认证相关接口
│   ├── dashboard_controller.go  # 控制台统计接口
│   ├── employees_controller.go  # 员工赋码接口
│   ├── helper.go            # 控制器通用辅助函数
│   ├── product_traces_controller.go # 产品溯源接口
│   ├── project_orders_controller.go # 项目工单接口
│   └── users_controller.go      # 员工主档管理接口(仅管理员)
├── database/                # 数据库连接和操作
│   └── database.go          # 数据库初始化、连接池配置
├── docs/                    # Swagger API 文档(自动生成)
│   ├── docs.go              # Swagger 文档定义
│   ├── swagger.json         # Swagger JSON 格式文档
│   └── swagger.yaml         # Swagger YAML 格式文档
├── logger/                  # 日志管理
│   └── logger.go            # 结构化日志(使用 Zap
├── middleware/              # 中间件层
│   └── auth.go              # JWT 认证、管理员/技术员权限检查
├── models/                  # 数据模型和 DTO
│   └── models.go            # User、Company、EmployeeSerial、ProductTrace、AftersalesOrder、ProjectOrder 等模型定义
├── routes/                  # 路由配置
│   └── routes.go            # API 路由注册
├── services/                # 业务逻辑层
│   ├── aftersales_service.go # 售后工单业务逻辑
│   ├── auth_service.go      # 认证业务逻辑
│   ├── dashboard_service.go # 控制台统计业务逻辑
│   ├── employees_service.go # 员工赋码业务逻辑
│   ├── product_traces_service.go # 产品溯源业务逻辑
│   ├── project_orders_service.go # 项目工单业务逻辑
│   ├── aftersales_service_test.go # 售后工单单元测试
│   ├── services_test.go     # 认证/员工赋码单元测试
│   ├── users_service.go     # 员工主档/后台账号业务逻辑
│   └── users_service_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. 安装依赖

cd backend-go
go mod download

# 或使用 Makefile
make deps

2. 配置环境变量

复制 .env.example 文件为 .env 并根据需要修改:

cp .env.example .env

重要: 生产环境请务必修改 JWT_SECRET 环境变量!

3. 使用 Makefile(推荐)

# 启动开发服务器
make run

# 编译项目
make build

# 运行测试
make test

# 生成测试覆盖率报告
make test-coverage

# 代码质量检查
make quality

# 清理构建文件
make clean

4. 手动启动

go run main.go

服务器将在 http://localhost:3000 上运行。

5. 配置管理

项目采用 YAML 结构化管理 + 环境变量动态覆盖 的方案:

配置文件优先级(从高到低)

  1. 环境变量 (最高优先级) - 格式:APP_配置项
  2. .env 文件 - 本地开发环境配置
  3. config.yaml - 默认配置文件
  4. 内置默认值 (最低优先级)

环境变量命名规则

所有环境变量使用 APP_ 前缀,多级配置使用 _ 连接:

# 示例
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:

# 使用 SQLite
APP_DATABASE_DRIVER=sqlite
APP_DATABASE_SQLITE_PATH=./data/dev.sqlite

生产环境(环境变量):

# 使用 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

健康检查:

curl -X GET http://localhost:3000/api/health

用户登录:

curl -X POST http://localhost:3000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"Beifan@2026"}'

首次启动且用户表为空时,系统会自动创建默认管理员账号(请在生产环境立即修改密码):

  • username: admin
  • password: Beifan@2026

API 文档

项目使用 Swagger 生成交互式 API 文档。

启动服务器后,访问以下地址查看完整的 API 文档:

http://localhost:3000/swagger/index.html

Swagger 文档功能

  • 交互式测试: 直接在浏览器中测试 API 端点
  • 请求/响应示例: 查看每个接口的请求参数和响应格式
  • 认证支持: 支持 Bearer Token 认证,可以输入 JWT 令牌进行测试
  • 按分组浏览: API 按功能模块分组(认证、控制台、权限下发、产品溯源、项目工单、售后工单等)

重新生成 Swagger 文档

如果修改了代码中的 API 注解,需要重新生成 Swagger 文档:

# 生成文档
make swagger

# 或直接执行
go run github.com/swaggo/swag/cmd/swag@v1.16.6 init -g main.go

# 文档将生成在 docs/ 目录下

认证路由

方法 路径 描述 需要认证
POST /api/auth/login 用户登录,返回 JWT 令牌
POST /api/auth/logout 用户登出
GET /api/auth/profile 获取当前用户信息
PUT /api/auth/profile 更新用户信息
POST /api/auth/change-password 修改密码

错误提示已做用户友好化,例如登录失败统一返回:用户名或密码不正确

控制台

方法 路径 描述 需要认证 角色
GET /api/dashboard/stats 获取工单统计和最近售后工单 管理员

权限下发(员工赋码)

方法 路径 描述 需要认证 角色
POST /api/employee-serials/generate 生成员工权限码 管理员
GET /api/employee-serials 获取员工权限码列表 管理员
GET /api/employee-serials/:serialNumber/query 查询员工权限码信息 任何
POST /api/employee-serials/:serialNumber/qrcode 生成员工二维码 管理员
PATCH /api/employee-serials/:serialNumber 更新员工权限码信息 管理员
PUT /api/employee-serials/:serialNumber 更新员工权限码信息 管理员
POST /api/employee-serials/:serialNumber/revoke 吊销员工权限码 管理员

员工权限码特点:

  • 无有效期限制
  • 创建员工主档时会自动生成 1 个员工码,并通过 employeeId 绑定员工
  • 包含岗位(position)和员工姓名(employeeName)信息
  • 序列号格式: EMP26xxxxxx(EMP + 年份后两位 + 6位随机字符)

产品溯源

方法 路径 描述 需要认证 角色
GET /api/product-traces/:serialNumber/query 公开查询产品溯源信息 任何
POST /api/product-traces 创建产品溯源 管理员
GET /api/product-traces 产品溯源列表 管理员
GET /api/product-traces/:serialNumber 产品溯源详情 管理员
PATCH /api/product-traces/:serialNumber 更新产品溯源 管理员
POST /api/product-traces/:serialNumber/qrcode 生成产品二维码 管理员
POST /api/product-traces/:serialNumber/wechat-qrcode 上传公众号二维码 管理员
POST /api/product-traces/:serialNumber/revoke 停用产品溯源 管理员
DELETE /api/product-traces/:serialNumber 删除产品溯源 管理员

产品溯源字段顺序: 企业名称、地址、电话、设备信息、质保期、出厂日期、产品序列号、官网链接(可选)、公众号二维码(可选)。

项目工单

方法 路径 描述 需要认证 角色
GET /api/project-orders/:serialNumber/query 公开查询项目工单 任何
POST /api/project-orders/:serialNumber/site-images 上传现场图片 任何
POST /api/project-orders/:serialNumber/complete 工程师提交完成 任何
POST /api/project-orders 创建项目工单 管理员/技术员
GET /api/project-orders 项目工单列表 管理员/技术员
GET /api/project-orders/:serialNumber 项目工单详情 管理员/技术员
PATCH /api/project-orders/:serialNumber 更新项目工单 管理员/技术员
POST /api/project-orders/:serialNumber/qrcode 生成项目工单二维码 管理员/技术员
POST /api/project-orders/:serialNumber/submit 后台提交项目完成 管理员/技术员
POST /api/project-orders/:serialNumber/reassign 工单分配 管理员
POST /api/project-orders/:serialNumber/force-close 强制完成 管理员
DELETE /api/project-orders/:serialNumber 删除项目工单 管理员

项目工单特点:

  • 用于现场勘查、现场实施等项目任务
  • 工单号格式: zjbf-xm-YYMMDDNN
  • 现场图片最多 18 张
  • 仅需要工程师签名,无客户签字环节
  • 完成状态使用 已完成

售后工单

方法 路径 描述 需要认证 角色
GET /api/aftersales/:serialNumber/query 公开查询工单(脱敏) 任何
POST /api/aftersales/:serialNumber/confirm 客户授权/未授权确认 任何
POST /api/aftersales 创建售后工单 管理员/技术员
GET /api/aftersales 工单列表(支持筛选) 管理员/技术员
GET /api/aftersales/:serialNumber 工单详情 管理员/技术员
PATCH /api/aftersales/:serialNumber 更新工单(仅负责人或管理员) 管理员/技术员
POST /api/aftersales/:serialNumber/qrcode 生成工单二维码 管理员/技术员
POST /api/aftersales/:serialNumber/submit 提交客户确认 管理员/技术员
POST /api/aftersales/:serialNumber/reassign 工单分配(重新分配技术员) 管理员
POST /api/aftersales/:serialNumber/force-close 强制关闭工单 管理员
DELETE /api/aftersales/:serialNumber 删除工单 管理员

售后工单特点:

  • 服务类型枚举:software(软件故障)、hardware(硬件故障)、maintenance(售后维保)
  • 工单号格式: zjbf-sh-YYMMDDNN(年份后 2 位 + 月份 2 位 + 日期 2 位 + 当天序号至少 2 位,例:zjbf-sh-26052801
  • 序号按天重置,软删除工单不释放编号(避免回收造成混淆)
  • 工单里的企业名称是售后客户信息,只保存在工单中
  • 二维码扫码后客户在网页签名(canvas)后点「已授权」确认;选择「未授权」需填写退回原因
  • 签名以 PNG dataURL 形式持久化到工单(signature 字段),管理员详情页可查看留底
  • 签名校验:必须为 data:image/png;base64,data:image/jpeg;base64, 前缀,解码后 200B500KB
  • 客户确认接口每分钟同一工单最多 5 次请求
  • 工单状态机: createdpending_confirmationclosed / rejected,被退回后可重新提交
  • 公开查询不返回手机号(脱敏)

权限下发(仅管理员)

方法 路径 描述 需要认证 角色
GET /api/users/assignable 可分配用户列表(用于售后) 管理员/技术员
POST /api/employees 创建员工并自动生成员工码 管理员
GET /api/employees 员工列表(分页+筛选) 管理员
PATCH /api/employees/:id 更新员工姓名/电话/工号/岗位/角色 管理员
POST /api/employees/:id/reset-password 重置后台账号密码 管理员
DELETE /api/employees/:id 删除员工 管理员

员工角色:

  • admin:管理员,拥有全部后台权限,包括权限下发、产品溯源、工单分配、强制关闭和删除工单
  • technician:技术员,仅拥有工单模块权限,可创建/处理工单,可使用 assignable 查询可分配同事
  • employee:员工,无后台登录权限,不需要密码,仅用于员工主档和员工码查询

保护规则:

  • 不能删除自己;不能将自己的 admin 角色降级;不能删除最后一个 admin
  • 创建 admin / technician 必须设置初始密码,密码 bcrypt 加密存储
  • 创建 employee 不要求密码,且不能登录后台

测试

运行所有测试

# 运行所有测试
go test -v ./...

# 仅运行服务层单元测试
cd services && go test -v -cover

# 仅运行集成测试
go test -v ./tests/...

生成测试覆盖率报告

# 生成覆盖率报告
go test -v ./services/... -coverprofile=coverage.out
go tool cover -html=coverage.out

当前测试覆盖

  • services/: 包含 AuthService、EmployeeSerialsService、AftersalesService、ProjectOrdersService、ProductTracesService 和 UsersService 的单元测试
    • 用户认证测试(登录、获取用户信息、修改密码、更新资料)
    • 员工赋码测试(生成、查询、更新、吊销、二维码生成)
    • 售后工单测试(YYMMDDNN 序号生成、状态机、客户确认手机号校验、强制关闭)
    • 项目工单测试(创建、完成、现场图片、工程师签名)
    • 产品溯源测试(创建、查询、二维码、公众号二维码)
    • 权限下发测试(创建员工自动生成员工码、重复工号、自降级保护、最后管理员保护、密码重置)
  • tests/: 集成测试(健康检查、登录流程)

代码检查

使用 golangci-lint 进行代码检查:

golangci-lint run ./...

部署

编译为二进制文件

# 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

运行

./trace-backend

数据库迁移

SQLite 到 PostgreSQL 的迁移

修改 .env 文件中的数据库配置:

# 将数据库驱动改为 postgres
DATABASE_DRIVER=postgres

# PostgreSQL 配置
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=trace
POSTGRES_PASSWORD=trace123
POSTGRES_DB=trace
POSTGRES_SSLMODE=disable

然后重新启动应用即可:

./trace-backend

注意: 切换数据库后,原有 SQLite 中的数据不会自动迁移到 PostgreSQL。需要使用数据库迁移工具(如 pgloader)手动迁移数据。

贡献指南

  1. 克隆项目
  2. 创建新功能分支
  3. 提交更改
  4. 推送到远程仓库
  5. 创建 Pull Request

代码风格要求

  • 使用 gofmt 自动格式化代码
  • 遵循 Go 官方编码规范
  • 使用 golangci-lint 进行代码检查
  • 保持代码简洁和高效

许可证

MIT License

S
Description
No description provided
Readme 754 KiB
Languages
Go 99.2%
Makefile 0.8%