feat: integrate swagger documentation and gin cors middleware
This commit is contained in:
6
Makefile
6
Makefile
@@ -59,6 +59,12 @@ deps:
|
||||
@echo "安装依赖..."
|
||||
@go mod tidy
|
||||
|
||||
# 生成 Swagger 文档
|
||||
swagger:
|
||||
@echo "生成 Swagger 文档..."
|
||||
@swag init -g main.go
|
||||
@echo "Swagger 文档已生成在 docs/ 目录"
|
||||
|
||||
# 初始化数据库
|
||||
init-db:
|
||||
@echo "初始化数据库..."
|
||||
|
||||
31
README.md
31
README.md
@@ -12,6 +12,8 @@
|
||||
- **认证**: 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 文件加载)
|
||||
@@ -188,6 +190,35 @@ curl -X POST http://localhost:3000/api/auth/login \
|
||||
|
||||
## API 文档
|
||||
|
||||
项目使用 Swagger 生成交互式 API 文档。
|
||||
|
||||
启动服务器后,访问以下地址查看完整的 API 文档:
|
||||
|
||||
```
|
||||
http://localhost:3000/swagger/index.html
|
||||
```
|
||||
|
||||
### Swagger 文档功能
|
||||
|
||||
- **交互式测试**: 直接在浏览器中测试 API 端点
|
||||
- **请求/响应示例**: 查看每个接口的请求参数和响应格式
|
||||
- **认证支持**: 支持 Bearer Token 认证,可以输入 JWT 令牌进行测试
|
||||
- **按分组浏览**: API 按功能模块分组(认证、序列号管理、企业管理等)
|
||||
|
||||
### 重新生成 Swagger 文档
|
||||
|
||||
如果修改了代码中的 API 注解,需要重新生成 Swagger 文档:
|
||||
|
||||
```bash
|
||||
# 确保已安装 swag 工具
|
||||
go install github.com/swaggo/swag/cmd/swag@latest
|
||||
|
||||
# 生成文档
|
||||
swag init -g main.go
|
||||
|
||||
# 文档将生成在 docs/ 目录下
|
||||
```
|
||||
|
||||
### 认证路由
|
||||
|
||||
| 方法 | 路径 | 描述 | 需要认证 |
|
||||
|
||||
@@ -28,9 +28,9 @@ func NewAuthController() *AuthController {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param loginData body models.LoginDTO true "登录数据"
|
||||
// @Success 200 {object} gin.H{message: string, accessToken: string, user: models.UserDTO}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.LoginResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Router /auth/login [post]
|
||||
func (c *AuthController) Login(ctx *gin.Context) {
|
||||
var loginData models.LoginDTO
|
||||
@@ -78,8 +78,8 @@ func (c *AuthController) Login(ctx *gin.Context) {
|
||||
// @Tags 认证
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} models.UserDTO
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.DataResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Router /auth/profile [get]
|
||||
func (c *AuthController) GetProfile(ctx *gin.Context) {
|
||||
userModel, ok := GetCurrentUser(ctx)
|
||||
@@ -106,9 +106,9 @@ func (c *AuthController) GetProfile(ctx *gin.Context) {
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param passwordData body models.ChangePasswordDTO true "密码修改数据"
|
||||
// @Success 200 {object} gin.H{message: string}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.BaseResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Router /auth/change-password [post]
|
||||
func (c *AuthController) ChangePassword(ctx *gin.Context) {
|
||||
userModel, ok := GetCurrentUser(ctx)
|
||||
@@ -138,9 +138,9 @@ func (c *AuthController) ChangePassword(ctx *gin.Context) {
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param profileData body models.UpdateProfileDTO true "用户信息更新数据"
|
||||
// @Success 200 {object} models.UserDTO
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.DataResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Router /auth/profile [put]
|
||||
func (c *AuthController) UpdateProfile(ctx *gin.Context) {
|
||||
userModel, ok := GetCurrentUser(ctx)
|
||||
|
||||
@@ -30,9 +30,9 @@ func NewCompaniesController() *CompaniesController {
|
||||
// @Param page query int false "页码"
|
||||
// @Param limit query int false "每页数量"
|
||||
// @Param search query string false "搜索关键词"
|
||||
// @Success 200 {object} gin.H{message: string, data: []models.Company, pagination: gin.H{page: int, limit: int, total: int, totalPages: int}}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.PaginationResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /companies [get]
|
||||
func (c *CompaniesController) FindAll(ctx *gin.Context) {
|
||||
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
||||
@@ -66,12 +66,12 @@ func (c *CompaniesController) FindAll(ctx *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param companyData body gin.H{companyName: string} true "企业数据"
|
||||
// @Success 201 {object} gin.H{message: string, company: models.Company}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Failure 409 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Param companyData body models.CompanyDataRequest true "企业数据"
|
||||
// @Success 201 {object} models.CompanyResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 409 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /companies [post]
|
||||
func (c *CompaniesController) Create(ctx *gin.Context) {
|
||||
var companyData struct {
|
||||
@@ -113,13 +113,13 @@ func (c *CompaniesController) Create(ctx *gin.Context) {
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param companyName path string true "企业名称"
|
||||
// @Param companyData body gin.H{companyName?: string, isActive?: bool} true "企业数据"
|
||||
// @Success 200 {object} gin.H{message: string, company: models.Company}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Failure 404 {object} gin.H{message: string}
|
||||
// @Failure 409 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Param companyData body models.CompanyUpdateRequest true "企业数据"
|
||||
// @Success 200 {object} models.CompanyResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 409 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /companies/{companyName} [put]
|
||||
func (c *CompaniesController) Update(ctx *gin.Context) {
|
||||
companyName := ctx.Param("companyName")
|
||||
@@ -167,11 +167,11 @@ func (c *CompaniesController) Update(ctx *gin.Context) {
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param companyName path string true "企业名称"
|
||||
// @Success 200 {object} gin.H{message: string}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Failure 404 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.BaseResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /companies/{companyName} [delete]
|
||||
func (c *CompaniesController) Delete(ctx *gin.Context) {
|
||||
companyName := ctx.Param("companyName")
|
||||
|
||||
@@ -30,10 +30,10 @@ func NewSerialsController() *SerialsController {
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param generateData body models.GenerateSerialDTO true "生成数据"
|
||||
// @Success 200 {object} gin.H{message: string, serials: []models.Serial}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.DataResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /serials/generate [post]
|
||||
func (c *SerialsController) Generate(ctx *gin.Context) {
|
||||
userModel, ok := GetCurrentUser(ctx)
|
||||
@@ -70,10 +70,10 @@ func (c *SerialsController) Generate(ctx *gin.Context) {
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param generateData body models.GenerateWithPrefixDTO true "生成数据"
|
||||
// @Success 200 {object} gin.H{message: string, serials: []models.Serial}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.DataResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /serials/generate-with-prefix [post]
|
||||
func (c *SerialsController) GenerateWithPrefix(ctx *gin.Context) {
|
||||
userModel, ok := GetCurrentUser(ctx)
|
||||
@@ -112,11 +112,11 @@ func (c *SerialsController) GenerateWithPrefix(ctx *gin.Context) {
|
||||
// @Security BearerAuth
|
||||
// @Param serialNumber path string true "序列号"
|
||||
// @Param qrCodeData body models.QRCodeDTO false "二维码数据"
|
||||
// @Success 200 {object} gin.H{message: string, qrCodeData: string, queryUrl: string}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Failure 404 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.QRCodeResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /serials/{serialNumber}/qrcode [post]
|
||||
func (c *SerialsController) GenerateQRCode(ctx *gin.Context) {
|
||||
serialNumber := ctx.Param("serialNumber")
|
||||
@@ -154,10 +154,10 @@ func (c *SerialsController) GenerateQRCode(ctx *gin.Context) {
|
||||
// @Tags 序列号查询
|
||||
// @Produce json
|
||||
// @Param serialNumber path string true "序列号"
|
||||
// @Success 200 {object} gin.H{message: string, serial: models.Serial}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 404 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.DataResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /serials/{serialNumber}/query [get]
|
||||
func (c *SerialsController) Query(ctx *gin.Context) {
|
||||
serialNumber := ctx.Param("serialNumber")
|
||||
@@ -180,11 +180,11 @@ func (c *SerialsController) Query(ctx *gin.Context) {
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param page query int false "页码"
|
||||
// @Param limit query int false "每页数量"
|
||||
// @Param limit query int false " "每页数量"
|
||||
// @Param search query string false "搜索关键词"
|
||||
// @Success 200 {object} gin.H{message: string, data: []models.Serial, pagination: gin.H{page: int, limit: int, total: int, totalPages: int}}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.PaginationResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /serials [get]
|
||||
func (c *SerialsController) FindAll(ctx *gin.Context) {
|
||||
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
||||
@@ -217,11 +217,11 @@ func (c *SerialsController) FindAll(ctx *gin.Context) {
|
||||
// @Security BearerAuth
|
||||
// @Param serialNumber path string true "序列号"
|
||||
// @Param updateData body models.UpdateSerialDTO true "更新数据"
|
||||
// @Success 200 {object} gin.H{message: string, serial: models.Serial}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Failure 404 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.DataResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /serials/{serialNumber} [put]
|
||||
func (c *SerialsController) Update(ctx *gin.Context) {
|
||||
serialNumber := ctx.Param("serialNumber")
|
||||
@@ -249,11 +249,11 @@ func (c *SerialsController) Update(ctx *gin.Context) {
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param serialNumber path string true "序列号"
|
||||
// @Success 200 {object} gin.H{message: string}
|
||||
// @Failure 400 {object} gin.H{message: string}
|
||||
// @Failure 401 {object} gin.H{message: string}
|
||||
// @Failure 404 {object} gin.H{message: string}
|
||||
// @Failure 500 {object} gin.H{message: string}
|
||||
// @Success 200 {object} models.BaseResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Router /serials/{serialNumber}/revoke [post]
|
||||
func (c *SerialsController) Revoke(ctx *gin.Context) {
|
||||
serialNumber := ctx.Param("serialNumber")
|
||||
|
||||
1173
docs/docs.go
Normal file
1173
docs/docs.go
Normal file
File diff suppressed because it is too large
Load Diff
1149
docs/swagger.json
Normal file
1149
docs/swagger.json
Normal file
File diff suppressed because it is too large
Load Diff
742
docs/swagger.yaml
Normal file
742
docs/swagger.yaml
Normal file
@@ -0,0 +1,742 @@
|
||||
basePath: /api
|
||||
definitions:
|
||||
models.BaseResponse:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
type: object
|
||||
models.ChangePasswordDTO:
|
||||
properties:
|
||||
currentPassword:
|
||||
type: string
|
||||
newPassword:
|
||||
minLength: 6
|
||||
type: string
|
||||
required:
|
||||
- currentPassword
|
||||
- newPassword
|
||||
type: object
|
||||
models.Company:
|
||||
properties:
|
||||
companyName:
|
||||
type: string
|
||||
createdAt:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
isActive:
|
||||
type: boolean
|
||||
updatedAt:
|
||||
type: string
|
||||
type: object
|
||||
models.CompanyDataRequest:
|
||||
properties:
|
||||
companyName:
|
||||
type: string
|
||||
required:
|
||||
- companyName
|
||||
type: object
|
||||
models.CompanyResponse:
|
||||
properties:
|
||||
company:
|
||||
$ref: '#/definitions/models.Company'
|
||||
message:
|
||||
type: string
|
||||
type: object
|
||||
models.CompanyUpdateRequest:
|
||||
properties:
|
||||
companyName:
|
||||
type: string
|
||||
isActive:
|
||||
type: boolean
|
||||
type: object
|
||||
models.DataResponse:
|
||||
properties:
|
||||
data: {}
|
||||
message:
|
||||
type: string
|
||||
type: object
|
||||
models.ErrorResponse:
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
type: object
|
||||
models.GenerateSerialDTO:
|
||||
properties:
|
||||
companyName:
|
||||
type: string
|
||||
quantity:
|
||||
maximum: 1000
|
||||
minimum: 1
|
||||
type: integer
|
||||
validDays:
|
||||
maximum: 3650
|
||||
minimum: 1
|
||||
type: integer
|
||||
required:
|
||||
- companyName
|
||||
type: object
|
||||
models.GenerateWithPrefixDTO:
|
||||
properties:
|
||||
companyName:
|
||||
type: string
|
||||
quantity:
|
||||
maximum: 1000
|
||||
minimum: 1
|
||||
type: integer
|
||||
serialPrefix:
|
||||
type: string
|
||||
validDays:
|
||||
maximum: 3650
|
||||
minimum: 1
|
||||
type: integer
|
||||
required:
|
||||
- companyName
|
||||
type: object
|
||||
models.LoginDTO:
|
||||
properties:
|
||||
password:
|
||||
minLength: 6
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
- password
|
||||
- username
|
||||
type: object
|
||||
models.LoginResponse:
|
||||
properties:
|
||||
accessToken:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
user:
|
||||
$ref: '#/definitions/models.UserDTO'
|
||||
type: object
|
||||
models.Pagination:
|
||||
properties:
|
||||
limit:
|
||||
type: integer
|
||||
page:
|
||||
type: integer
|
||||
total:
|
||||
type: integer
|
||||
totalPages:
|
||||
type: integer
|
||||
type: object
|
||||
models.PaginationResponse:
|
||||
properties:
|
||||
data: {}
|
||||
message:
|
||||
type: string
|
||||
pagination:
|
||||
$ref: '#/definitions/models.Pagination'
|
||||
type: object
|
||||
models.QRCodeDTO:
|
||||
properties:
|
||||
baseUrl:
|
||||
type: string
|
||||
type: object
|
||||
models.QRCodeResponse:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
qrCodeData:
|
||||
type: string
|
||||
queryUrl:
|
||||
type: string
|
||||
type: object
|
||||
models.UpdateProfileDTO:
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- email
|
||||
- name
|
||||
type: object
|
||||
models.UpdateSerialDTO:
|
||||
properties:
|
||||
companyName:
|
||||
type: string
|
||||
isActive:
|
||||
type: boolean
|
||||
validUntil:
|
||||
type: string
|
||||
type: object
|
||||
models.UserDTO:
|
||||
properties:
|
||||
createdAt:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
role:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
type: object
|
||||
host: localhost:8080
|
||||
info:
|
||||
contact:
|
||||
email: support@swagger.io
|
||||
name: API Support
|
||||
url: http://www.swagger.io/support
|
||||
description: 防伪溯源系统 API 文档
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
termsOfService: http://swagger.io/terms/
|
||||
title: Trace System API
|
||||
version: "1.0"
|
||||
paths:
|
||||
/auth/change-password:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 修改当前登录用户的密码
|
||||
parameters:
|
||||
- description: 密码修改数据
|
||||
in: body
|
||||
name: passwordData
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.ChangePasswordDTO'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.BaseResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 修改密码
|
||||
tags:
|
||||
- 认证
|
||||
/auth/login:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 验证用户身份并返回 JWT 令牌
|
||||
parameters:
|
||||
- description: 登录数据
|
||||
in: body
|
||||
name: loginData
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.LoginDTO'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.LoginResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
summary: 用户登录
|
||||
tags:
|
||||
- 认证
|
||||
/auth/profile:
|
||||
get:
|
||||
description: 获取当前登录用户的个人信息
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.DataResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 获取用户信息
|
||||
tags:
|
||||
- 认证
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 更新当前登录用户的个人信息
|
||||
parameters:
|
||||
- description: 用户信息更新数据
|
||||
in: body
|
||||
name: profileData
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.UpdateProfileDTO'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.DataResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 更新用户信息
|
||||
tags:
|
||||
- 认证
|
||||
/companies:
|
||||
get:
|
||||
description: 获取企业列表,支持分页和搜索
|
||||
parameters:
|
||||
- description: 页码
|
||||
in: query
|
||||
name: page
|
||||
type: integer
|
||||
- description: 每页数量
|
||||
in: query
|
||||
name: limit
|
||||
type: integer
|
||||
- description: 搜索关键词
|
||||
in: query
|
||||
name: search
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.PaginationResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 获取企业列表
|
||||
tags:
|
||||
- 企业管理
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 创建新的企业
|
||||
parameters:
|
||||
- description: 企业数据
|
||||
in: body
|
||||
name: companyData
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.CompanyDataRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"201":
|
||||
description: Created
|
||||
schema:
|
||||
$ref: '#/definitions/models.CompanyResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"409":
|
||||
description: Conflict
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 创建企业
|
||||
tags:
|
||||
- 企业管理
|
||||
/companies/{companyName}:
|
||||
delete:
|
||||
description: 删除企业
|
||||
parameters:
|
||||
- description: 企业名称
|
||||
in: path
|
||||
name: companyName
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.BaseResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 删除企业
|
||||
tags:
|
||||
- 企业管理
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 更新企业信息
|
||||
parameters:
|
||||
- description: 企业名称
|
||||
in: path
|
||||
name: companyName
|
||||
required: true
|
||||
type: string
|
||||
- description: 企业数据
|
||||
in: body
|
||||
name: companyData
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.CompanyUpdateRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.CompanyResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"409":
|
||||
description: Conflict
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 更新企业信息
|
||||
tags:
|
||||
- 企业管理
|
||||
/serials:
|
||||
get:
|
||||
description: 获取序列号列表,支持分页和搜索
|
||||
parameters:
|
||||
- description: 页码
|
||||
in: query
|
||||
name: page
|
||||
type: integer
|
||||
- description: ' '
|
||||
in: query
|
||||
name: limit
|
||||
type: integer
|
||||
- description: 搜索关键词
|
||||
in: query
|
||||
name: search
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.PaginationResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 获取序列号列表
|
||||
tags:
|
||||
- 序列号管理
|
||||
/serials/{serialNumber}:
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 更新指定序列号的信息
|
||||
parameters:
|
||||
- description: 序列号
|
||||
in: path
|
||||
name: serialNumber
|
||||
required: true
|
||||
type: string
|
||||
- description: 更新数据
|
||||
in: body
|
||||
name: updateData
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.UpdateSerialDTO'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.DataResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 更新序列号信息
|
||||
tags:
|
||||
- 序列号管理
|
||||
/serials/{serialNumber}/qrcode:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 为指定序列号生成查询二维码
|
||||
parameters:
|
||||
- description: 序列号
|
||||
in: path
|
||||
name: serialNumber
|
||||
required: true
|
||||
type: string
|
||||
- description: 二维码数据
|
||||
in: body
|
||||
name: qrCodeData
|
||||
schema:
|
||||
$ref: '#/definitions/models.QRCodeDTO'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.QRCodeResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 生成二维码
|
||||
tags:
|
||||
- 序列号管理
|
||||
/serials/{serialNumber}/query:
|
||||
get:
|
||||
description: 查询指定序列号的详细信息
|
||||
parameters:
|
||||
- description: 序列号
|
||||
in: path
|
||||
name: serialNumber
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.DataResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
summary: 查询序列号信息
|
||||
tags:
|
||||
- 序列号查询
|
||||
/serials/{serialNumber}/revoke:
|
||||
post:
|
||||
description: 吊销指定序列号
|
||||
parameters:
|
||||
- description: 序列号
|
||||
in: path
|
||||
name: serialNumber
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.BaseResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 吊销序列号
|
||||
tags:
|
||||
- 序列号管理
|
||||
/serials/generate:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 生成指定数量的序列号
|
||||
parameters:
|
||||
- description: 生成数据
|
||||
in: body
|
||||
name: generateData
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.GenerateSerialDTO'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.DataResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 生成序列号
|
||||
tags:
|
||||
- 序列号管理
|
||||
/serials/generate-with-prefix:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 生成带有指定前缀的序列号
|
||||
parameters:
|
||||
- description: 生成数据
|
||||
in: body
|
||||
name: generateData
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.GenerateWithPrefixDTO'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.DataResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 带前缀生成序列号
|
||||
tags:
|
||||
- 序列号管理
|
||||
securityDefinitions:
|
||||
BearerAuth:
|
||||
description: Bearer token 认证
|
||||
in: header
|
||||
name: Authorization
|
||||
type: apiKey
|
||||
swagger: "2.0"
|
||||
46
go.mod
46
go.mod
@@ -3,6 +3,7 @@ module git.beifan.cn/trace-system/backend-go
|
||||
go 1.26
|
||||
|
||||
require (
|
||||
github.com/gin-contrib/cors v1.7.6
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1
|
||||
github.com/google/uuid v1.6.0
|
||||
@@ -10,6 +11,9 @@ require (
|
||||
github.com/mattn/go-sqlite3 v1.14.22
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/swaggo/files v1.0.1
|
||||
github.com/swaggo/gin-swagger v1.6.1
|
||||
github.com/swaggo/swag v1.16.6
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.5
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.3.0
|
||||
go.uber.org/zap v1.27.1
|
||||
@@ -20,35 +24,47 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||
github.com/bytedance/sonic/loader v0.5.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/fogleman/gg v1.3.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.30.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/goccy/go-yaml v1.18.0 // indirect
|
||||
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.54.0 // indirect
|
||||
github.com/quic-go/qpack v0.6.0 // indirect
|
||||
github.com/quic-go/quic-go v0.59.0 // indirect
|
||||
github.com/yeqown/reedsolomon v1.0.0 // indirect
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/image v0.10.0 // indirect
|
||||
golang.org/x/mod v0.32.0 // indirect
|
||||
golang.org/x/mod v0.33.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/tools v0.41.0 // indirect
|
||||
golang.org/x/tools v0.42.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.14.0 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/bytedance/gopkg v0.1.3 // indirect
|
||||
github.com/bytedance/sonic v1.15.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.22.4 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.4 // indirect
|
||||
github.com/go-openapi/spec v0.22.3 // indirect
|
||||
github.com/go-openapi/swag/conv v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/jsonname v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/loading v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/stringutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/typeutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v5 v5.6.0 // indirect
|
||||
@@ -69,12 +85,12 @@ require (
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/arch v0.20.0 // indirect
|
||||
golang.org/x/net v0.49.0 // indirect
|
||||
golang.org/x/arch v0.24.0 // indirect
|
||||
golang.org/x/net v0.50.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
google.golang.org/protobuf v1.36.9 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
110
go.sum
110
go.sum
@@ -1,7 +1,11 @@
|
||||
github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=
|
||||
github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=
|
||||
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
|
||||
github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
|
||||
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
|
||||
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
|
||||
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
|
||||
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
|
||||
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -14,26 +18,57 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/gin-contrib/cors v1.7.6 h1:3gQ8GMzs1Ylpf70y8bMw4fVpycXIeX1ZemuSQIsnQQY=
|
||||
github.com/gin-contrib/cors v1.7.6/go.mod h1:Ulcl+xN4jel9t1Ry8vqph23a60FwH9xVLd+3ykmTjOk=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
|
||||
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
|
||||
github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=
|
||||
github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=
|
||||
github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
|
||||
github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
|
||||
github.com/go-openapi/spec v0.22.3 h1:qRSmj6Smz2rEBxMnLRBMeBWxbbOvuOoElvSvObIgwQc=
|
||||
github.com/go-openapi/spec v0.22.3/go.mod h1:iIImLODL2loCh3Vnox8TY2YWYJZjMAKYyLH2Mu8lOZs=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=
|
||||
github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
|
||||
github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
|
||||
github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
|
||||
github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo=
|
||||
github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM=
|
||||
github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
|
||||
github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=
|
||||
github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=
|
||||
github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
|
||||
github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=
|
||||
github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
|
||||
github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4=
|
||||
github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg=
|
||||
github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=
|
||||
github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
|
||||
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
|
||||
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
||||
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
@@ -83,12 +118,12 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
|
||||
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
|
||||
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
@@ -104,19 +139,27 @@ github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjb
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||
github.com/swaggo/gin-swagger v1.6.1 h1:Ri06G4gc9N4t4k8hekMigJ9zKTFSlqj/9paAQCQs7cY=
|
||||
github.com/swaggo/gin-swagger v1.6.1/go.mod h1:LQ+hJStHakCWRiK/YNYtJOu4mR2FP+pxLnILT/qNiTw=
|
||||
github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI=
|
||||
github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
||||
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
|
||||
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.5 h1:HCOe2bSjkhZyYoyyNaXNzh4DJZll6inVJQQw+8228Zk=
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.5/go.mod h1:uHpt9CM0V1HeXLz+Wg5MN50/sI/fQhfkZlOM+cOTHxw=
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.3.0 h1:chdyhEfRtUPgQtuPeaWVGQ/TQx4rE1PqeoW3U+53t34=
|
||||
@@ -126,16 +169,16 @@ github.com/yeqown/reedsolomon v1.0.0/go.mod h1:P76zpcn2TCuL0ul1Fso373qHRc69LKwAw
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
|
||||
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y=
|
||||
golang.org/x/arch v0.24.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
@@ -144,14 +187,15 @@ golang.org/x/image v0.10.0 h1:gXjUUtwtx5yOE0VKWq1CH4IJAClq4UGgUA3i+rpON9M=
|
||||
golang.org/x/image v0.10.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
|
||||
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
|
||||
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -180,11 +224,11 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
||||
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
|
||||
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
49
main.go
49
main.go
@@ -1,11 +1,34 @@
|
||||
package main
|
||||
|
||||
// @title Trace System API
|
||||
// @version 1.0
|
||||
// @description 防伪溯源系统 API 文档
|
||||
// @termsOfService http://swagger.io/terms/
|
||||
|
||||
// @contact.name API Support
|
||||
// @contact.url http://www.swagger.io/support
|
||||
// @contact.email support@swagger.io
|
||||
|
||||
// @license.name Apache 2.0
|
||||
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
// @host localhost:8080
|
||||
// @BasePath /api
|
||||
// @securityDefinitions.apikey BearerAuth
|
||||
// @in header
|
||||
// @name Authorization
|
||||
// @description Bearer token 认证
|
||||
|
||||
import (
|
||||
"git.beifan.cn/trace-system/backend-go/config"
|
||||
"git.beifan.cn/trace-system/backend-go/database"
|
||||
_ "git.beifan.cn/trace-system/backend-go/docs"
|
||||
"git.beifan.cn/trace-system/backend-go/logger"
|
||||
"git.beifan.cn/trace-system/backend-go/routes"
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -45,18 +68,14 @@ func main() {
|
||||
r.Use(gin.Recovery())
|
||||
|
||||
// 启用 CORS
|
||||
r.Use(func(c *gin.Context) {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
|
||||
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.AbortWithStatus(204)
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
})
|
||||
r.Use(cors.New(cors.Config{
|
||||
AllowOrigins: []string{"*"},
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||
AllowHeaders: []string{"Origin", "Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization", "accept", "origin", "Cache-Control", "X-Requested-With"},
|
||||
ExposeHeaders: []string{"Content-Length"},
|
||||
AllowCredentials: true,
|
||||
MaxAge: 12 * 3600,
|
||||
}))
|
||||
|
||||
// 配置路由
|
||||
routes.SetupRoutes(r)
|
||||
@@ -65,10 +84,14 @@ func main() {
|
||||
api := r.Group("/api")
|
||||
routes.SetupAPIRoutes(api)
|
||||
|
||||
// Swagger 文档路由
|
||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
|
||||
// 启动服务器
|
||||
port := cfg.Server.Port
|
||||
logger.Info("服务器运行在 http://localhost:" + port)
|
||||
logger.Info("API 文档: http://localhost:" + port + "/api/health")
|
||||
logger.Info("Swagger 文档: http://localhost:" + port + "/swagger/index.html")
|
||||
logger.Info("健康检查: http://localhost:" + port + "/api/health")
|
||||
logger.Info("环境: " + cfg.Server.Environment)
|
||||
|
||||
if err := r.Run(":" + port); err != nil {
|
||||
|
||||
@@ -22,13 +22,13 @@ type User struct {
|
||||
|
||||
// Company 模型
|
||||
type Company struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CompanyName string `gorm:"uniqueIndex;size:255"`
|
||||
IsActive bool `gorm:"default:true"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||
Serials []Serial `gorm:"foreignKey:CompanyName;references:CompanyName"`
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
CompanyName string `gorm:"uniqueIndex;size:255" json:"companyName"`
|
||||
IsActive bool `gorm:"default:true" json:"isActive"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
Serials []Serial `gorm:"foreignKey:CompanyName;references:CompanyName" json:"-"`
|
||||
}
|
||||
|
||||
// Serial 模型
|
||||
@@ -100,3 +100,66 @@ type UpdateSerialDTO struct {
|
||||
type QRCodeDTO struct {
|
||||
BaseUrl string `json:"baseUrl,omitempty"`
|
||||
}
|
||||
|
||||
// LoginResponse 登录响应
|
||||
type LoginResponse struct {
|
||||
Message string `json:"message"`
|
||||
AccessToken string `json:"accessToken"`
|
||||
User UserDTO `json:"user"`
|
||||
}
|
||||
|
||||
// BaseResponse 基础响应
|
||||
type BaseResponse struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// ErrorResponse 错误响应
|
||||
type ErrorResponse struct {
|
||||
Message string `json:"message"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// DataResponse 数据响应
|
||||
type DataResponse struct {
|
||||
Message string `json:"message"`
|
||||
Data any `json:"data"`
|
||||
}
|
||||
|
||||
// PaginationResponse 分页响应
|
||||
type PaginationResponse struct {
|
||||
Message string `json:"message"`
|
||||
Data any `json:"data"`
|
||||
Pagination Pagination `json:"pagination"`
|
||||
}
|
||||
|
||||
// Pagination 分页信息
|
||||
type Pagination struct {
|
||||
Page int `json:"page"`
|
||||
Limit int `json:"limit"`
|
||||
Total int64 `json:"total"`
|
||||
TotalPages int `json:"totalPages"`
|
||||
}
|
||||
|
||||
// QRCodeResponse 二维码响应
|
||||
type QRCodeResponse struct {
|
||||
Message string `json:"message"`
|
||||
QRCodeData string `json:"qrCodeData"`
|
||||
QueryURL string `json:"queryUrl"`
|
||||
}
|
||||
|
||||
// CompanyResponse 企业响应
|
||||
type CompanyResponse struct {
|
||||
Message string `json:"message"`
|
||||
Company Company `json:"company"`
|
||||
}
|
||||
|
||||
// CompanyDataRequest 企业数据请求
|
||||
type CompanyDataRequest struct {
|
||||
CompanyName string `json:"companyName" validate:"required"`
|
||||
}
|
||||
|
||||
// CompanyUpdateRequest 企业更新请求
|
||||
type CompanyUpdateRequest struct {
|
||||
CompanyName string `json:"companyName"`
|
||||
IsActive *bool `json:"isActive"`
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user