diff --git a/gofaster/backend/cmd/server/logs/app.log b/gofaster/backend/cmd/server/logs/app.log index c9faf9e..5479d07 100644 --- a/gofaster/backend/cmd/server/logs/app.log +++ b/gofaster/backend/cmd/server/logs/app.log @@ -5,3 +5,6 @@ {"level":"FATAL","ts":"2025-08-02T23:03:55.914+0800","caller":"server/main.go:30","msg":"Failed to connect database","error":"failed to connect to `user=postgres database=gofaster`: [::1]:5432 (localhost): failed SASL auth: \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd: \ufffdû\ufffd \"postgres\" Password \ufffd\ufffd֤ʧ\ufffd\ufffd (SQLSTATE 28P01)","stacktrace":"main.main\n\tD:/aigc/manta/gofaster/backend/cmd/server/main.go:30\nruntime.main\n\tD:/Program Files/Go/src/runtime/proc.go:283"} {"level":"FATAL","ts":"2025-08-02T23:08:42.789+0800","caller":"server/main.go:30","msg":"Failed to connect database","error":"failed to connect to `user=postgres database=gofaster`: [::1]:5432 (localhost): server error: \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd: \ufffd\ufffd\ufffdݿ\ufffd \"gofaster\" \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd (SQLSTATE 3D000)","stacktrace":"main.main\n\tD:/aigc/manta/gofaster/backend/cmd/server/main.go:30\nruntime.main\n\tD:/Program Files/Go/src/runtime/proc.go:283"} {"level":"FATAL","ts":"2025-08-02T23:09:53.030+0800","caller":"server/main.go:35","msg":"Failed to migrate database","error":"invalid field found for struct gofaster/internal/model.WorkflowInstance's field Tasks: define a valid foreign key for relations or implement the Valuer/Scanner interface","stacktrace":"main.main\n\tD:/aigc/manta/gofaster/backend/cmd/server/main.go:35\nruntime.main\n\tD:/Program Files/Go/src/runtime/proc.go:283"} +{"level":"FATAL","ts":"2025-08-03T08:39:08.032+0800","caller":"server/main.go:35","msg":"Failed to migrate database","error":"invalid field found for struct gofaster/internal/model.WorkflowInstance's field Tasks: define a valid foreign key for relations or implement the Valuer/Scanner interface","stacktrace":"main.main\n\tD:/aigc/manta/gofaster/backend/cmd/server/main.go:35\nruntime.main\n\tD:/Program Files/Go/src/runtime/proc.go:283"} +{"level":"FATAL","ts":"2025-08-03T08:41:47.676+0800","caller":"server/main.go:35","msg":"Failed to migrate database","error":"invalid field found for struct gofaster/internal/model.WorkflowInstance's field Tasks: define a valid foreign key for relations or implement the Valuer/Scanner interface","stacktrace":"main.main\n\tD:/aigc/manta/gofaster/backend/cmd/server/main.go:35\nruntime.main\n\tD:/Program Files/Go/src/runtime/proc.go:283"} +{"level":"INFO","ts":"2025-08-03T09:05:17.773+0800","caller":"server/main.go:69","msg":"Starting server","port":"8080"} diff --git a/gofaster/backend/cmd/server/main.go b/gofaster/backend/cmd/server/main.go index fa250b1..cfc99f0 100644 --- a/gofaster/backend/cmd/server/main.go +++ b/gofaster/backend/cmd/server/main.go @@ -1,3 +1,18 @@ +// @title GoFaster API +// @version 1.0 +// @description GoFaster项目API文档 +// @termsOfService http://swagger.io/terms/ + +// @contact.name API支持 +// @contact.url http://www.gofaster.com/support +// @contact.email support@gofaster.com + +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host localhost:8080 +// @BasePath /api +// @schemes http package main import ( @@ -12,8 +27,13 @@ import ( "gofaster/routes" // 添加routes导入 "github.com/gin-gonic/gin" + ginSwagger "github.com/swaggo/gin-swagger" "go.uber.org/zap" "gorm.io/gorm" + + _ "gofaster/docs" // 确保这个路径是你的项目文档路径 + + swaggerFiles "github.com/swaggo/files" ) func main() { @@ -58,6 +78,9 @@ func main() { api := app.Group("/api") routes.RegisterUserRoutes(api, userCtrl) + // 添加Swagger路由 + app.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) + // 认证路由 authApi := api.Group("") authApi.Use(middleware.AuthMiddleware(cfg.JWT.Secret)) diff --git a/gofaster/backend/docs/docs.go b/gofaster/backend/docs/docs.go new file mode 100644 index 0000000..c19f617 --- /dev/null +++ b/gofaster/backend/docs/docs.go @@ -0,0 +1,371 @@ +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API支持", + "url": "http://www.gofaster.com/support", + "email": "support@gofaster.com" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/users": { + "get": { + "description": "获取分页用户列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "获取用户列表", + "parameters": [ + { + "type": "integer", + "default": 1, + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "每页数量", + "name": "pageSize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "用户列表", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "服务器内部错误", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/users/{id}": { + "get": { + "description": "根据ID获取用户详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "获取用户详情", + "parameters": [ + { + "type": "integer", + "description": "用户ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "用户信息", + "schema": { + "$ref": "#/definitions/model.User" + } + }, + "400": { + "description": "无效的用户ID", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "用户不存在", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "服务器内部错误", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "put": { + "description": "根据ID更新用户信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "更新用户信息", + "parameters": [ + { + "type": "integer", + "description": "用户ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "用户信息", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.User" + } + } + ], + "responses": { + "200": { + "description": "更新后的用户信息", + "schema": { + "$ref": "#/definitions/model.User" + } + }, + "400": { + "description": "无效的用户ID或请求参数", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "用户不存在", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "服务器内部错误", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "根据ID删除用户", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "删除用户", + "parameters": [ + { + "type": "integer", + "description": "用户ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "删除成功" + }, + "400": { + "description": "无效的用户ID", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "用户不存在", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "服务器内部错误", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + }, + "definitions": { + "model.Permission": { + "type": "object", + "properties": { + "action": { + "description": "create, read, update, delete等", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "resource": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "model.Role": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/model.Permission" + } + }, + "updated_at": { + "type": "string" + } + } + }, + "model.User": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "email": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "phone": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/model.Role" + } + }, + "status": { + "description": "1-正常 2-禁用", + "type": "integer" + }, + "updated_at": { + "type": "string" + }, + "username": { + "type": "string" + } + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1.0", + Host: "localhost:8080", + BasePath: "/api", + Schemes: []string{"http"}, + Title: "GoFaster API", + Description: "GoFaster项目API文档", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/gofaster/backend/docs/swagger.json b/gofaster/backend/docs/swagger.json new file mode 100644 index 0000000..3e663a5 --- /dev/null +++ b/gofaster/backend/docs/swagger.json @@ -0,0 +1,350 @@ +{ + "schemes": [ + "http" + ], + "swagger": "2.0", + "info": { + "description": "GoFaster项目API文档", + "title": "GoFaster API", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API支持", + "url": "http://www.gofaster.com/support", + "email": "support@gofaster.com" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "1.0" + }, + "host": "localhost:8080", + "basePath": "/api", + "paths": { + "/users": { + "get": { + "description": "获取分页用户列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "获取用户列表", + "parameters": [ + { + "type": "integer", + "default": 1, + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "每页数量", + "name": "pageSize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "用户列表", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "服务器内部错误", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/users/{id}": { + "get": { + "description": "根据ID获取用户详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "获取用户详情", + "parameters": [ + { + "type": "integer", + "description": "用户ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "用户信息", + "schema": { + "$ref": "#/definitions/model.User" + } + }, + "400": { + "description": "无效的用户ID", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "用户不存在", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "服务器内部错误", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "put": { + "description": "根据ID更新用户信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "更新用户信息", + "parameters": [ + { + "type": "integer", + "description": "用户ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "用户信息", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.User" + } + } + ], + "responses": { + "200": { + "description": "更新后的用户信息", + "schema": { + "$ref": "#/definitions/model.User" + } + }, + "400": { + "description": "无效的用户ID或请求参数", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "用户不存在", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "服务器内部错误", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "根据ID删除用户", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "删除用户", + "parameters": [ + { + "type": "integer", + "description": "用户ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "删除成功" + }, + "400": { + "description": "无效的用户ID", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "用户不存在", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "服务器内部错误", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + }, + "definitions": { + "model.Permission": { + "type": "object", + "properties": { + "action": { + "description": "create, read, update, delete等", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "resource": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "model.Role": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/model.Permission" + } + }, + "updated_at": { + "type": "string" + } + } + }, + "model.User": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "email": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "phone": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/model.Role" + } + }, + "status": { + "description": "1-正常 2-禁用", + "type": "integer" + }, + "updated_at": { + "type": "string" + }, + "username": { + "type": "string" + } + } + } + } +} \ No newline at end of file diff --git a/gofaster/backend/docs/swagger.yaml b/gofaster/backend/docs/swagger.yaml new file mode 100644 index 0000000..ed4ab78 --- /dev/null +++ b/gofaster/backend/docs/swagger.yaml @@ -0,0 +1,234 @@ +basePath: /api +definitions: + model.Permission: + properties: + action: + description: create, read, update, delete等 + type: string + created_at: + type: string + description: + type: string + id: + type: integer + name: + type: string + resource: + type: string + updated_at: + type: string + type: object + model.Role: + properties: + created_at: + type: string + description: + type: string + id: + type: integer + name: + type: string + permissions: + items: + $ref: '#/definitions/model.Permission' + type: array + updated_at: + type: string + type: object + model.User: + properties: + created_at: + type: string + email: + type: string + id: + type: integer + phone: + type: string + roles: + items: + $ref: '#/definitions/model.Role' + type: array + status: + description: 1-正常 2-禁用 + type: integer + updated_at: + type: string + username: + type: string + type: object +host: localhost:8080 +info: + contact: + email: support@gofaster.com + name: API支持 + url: http://www.gofaster.com/support + description: GoFaster项目API文档 + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + termsOfService: http://swagger.io/terms/ + title: GoFaster API + version: "1.0" +paths: + /users: + get: + consumes: + - application/json + description: 获取分页用户列表 + parameters: + - default: 1 + description: 页码 + in: query + name: page + type: integer + - default: 10 + description: 每页数量 + in: query + name: pageSize + type: integer + produces: + - application/json + responses: + "200": + description: 用户列表 + schema: + additionalProperties: true + type: object + "400": + description: 请求参数错误 + schema: + additionalProperties: + type: string + type: object + "500": + description: 服务器内部错误 + schema: + additionalProperties: + type: string + type: object + summary: 获取用户列表 + tags: + - 用户管理 + /users/{id}: + delete: + consumes: + - application/json + description: 根据ID删除用户 + parameters: + - description: 用户ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "204": + description: 删除成功 + "400": + description: 无效的用户ID + schema: + additionalProperties: + type: string + type: object + "404": + description: 用户不存在 + schema: + additionalProperties: + type: string + type: object + "500": + description: 服务器内部错误 + schema: + additionalProperties: + type: string + type: object + summary: 删除用户 + tags: + - 用户管理 + get: + consumes: + - application/json + description: 根据ID获取用户详情 + parameters: + - description: 用户ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 用户信息 + schema: + $ref: '#/definitions/model.User' + "400": + description: 无效的用户ID + schema: + additionalProperties: + type: string + type: object + "404": + description: 用户不存在 + schema: + additionalProperties: + type: string + type: object + "500": + description: 服务器内部错误 + schema: + additionalProperties: + type: string + type: object + summary: 获取用户详情 + tags: + - 用户管理 + put: + consumes: + - application/json + description: 根据ID更新用户信息 + parameters: + - description: 用户ID + in: path + name: id + required: true + type: integer + - description: 用户信息 + in: body + name: user + required: true + schema: + $ref: '#/definitions/model.User' + produces: + - application/json + responses: + "200": + description: 更新后的用户信息 + schema: + $ref: '#/definitions/model.User' + "400": + description: 无效的用户ID或请求参数 + schema: + additionalProperties: + type: string + type: object + "404": + description: 用户不存在 + schema: + additionalProperties: + type: string + type: object + "500": + description: 服务器内部错误 + schema: + additionalProperties: + type: string + type: object + summary: 更新用户信息 + tags: + - 用户管理 +schemes: +- http +swagger: "2.0" diff --git a/gofaster/backend/go.mod b/gofaster/backend/go.mod index a0afc49..4d82b2b 100644 --- a/gofaster/backend/go.mod +++ b/gofaster/backend/go.mod @@ -5,8 +5,16 @@ go 1.24.3 require github.com/spf13/viper v1.20.1 require ( + github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/swaggo/files v1.0.1 // indirect + github.com/urfave/cli/v2 v2.27.7 // indirect + github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) require ( @@ -56,7 +64,7 @@ require ( github.com/spf13/pflag v1.0.6 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/swaggo/gin-swagger v1.6.0 // indirect - github.com/swaggo/swag v1.16.5 // indirect + github.com/swaggo/swag v1.16.6 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect diff --git a/gofaster/backend/go.sum b/gofaster/backend/go.sum index f474584..4e826c9 100644 --- a/gofaster/backend/go.sum +++ b/gofaster/backend/go.sum @@ -21,6 +21,8 @@ github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLI github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= @@ -94,8 +96,12 @@ github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/redis/go-redis/v9 v9.11.0 h1:E3S08Gl/nJNn5vkxd2i78wZxWAPNZgUNTp8WIJUAiIs= github.com/redis/go-redis/v9 v9.11.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= @@ -116,36 +122,73 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 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.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo= github.com/swaggo/swag v1.16.5 h1:nMf2fEV1TetMTJb4XzD0Lz7jFfKJmJKGTygEey8NSxM= github.com/swaggo/swag v1.16.5/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg= +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/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU= +github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4= +github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAzt5X7s6266i6cSVkkFPS0TuXWbIg= +github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.19.0 h1:LmbDQUodHThXE+htjrnmVD73M//D9GTH6wFZjyDkjyU= golang.org/x/arch v0.19.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +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.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= +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.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +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.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= @@ -163,3 +206,5 @@ gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4= gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/gofaster/backend/internal/controller/user_controller.go b/gofaster/backend/internal/controller/user_controller.go index 43011ff..bf0da30 100644 --- a/gofaster/backend/internal/controller/user_controller.go +++ b/gofaster/backend/internal/controller/user_controller.go @@ -11,14 +11,17 @@ import ( "gorm.io/gorm" ) +// UserController 用户控制器 type UserController struct { userService *service.UserService } +// NewUserController 创建用户控制器实例 func NewUserController(userService *service.UserService) *UserController { return &UserController{userService: userService} } +// RegisterRoutes 注册用户路由 func (c *UserController) RegisterRoutes(r *gin.RouterGroup) { r.GET("/users", c.ListUsers) r.POST("/users", c.CreateUser) @@ -27,6 +30,18 @@ func (c *UserController) RegisterRoutes(r *gin.RouterGroup) { r.DELETE("/users/:id", c.DeleteUser) } +// ListUsers godoc +// @Summary 获取用户列表 +// @Description 获取分页用户列表 +// @Tags 用户管理 +// @Accept json +// @Produce json +// @Param page query int false "页码" default(1) +// @Param pageSize query int false "每页数量" default(10) +// @Success 200 {object} map[string]interface{} "用户列表" +// @Failure 400 {object} map[string]string "请求参数错误" +// @Failure 500 {object} map[string]string "服务器内部错误" +// @Router /users [get] func (c *UserController) ListUsers(ctx *gin.Context) { // 获取分页参数,默认值 page=1, pageSize=10 pageStr := ctx.DefaultQuery("page", "1") @@ -60,6 +75,18 @@ func (c *UserController) ListUsers(ctx *gin.Context) { }) } +// CreateUser godoc +// @Summary 创建用户 +// @Description 创建新用户 +// @Tags 用户管理 +// @Accept json +// @Produce json +// @Param user body model.User true "用户信息" +// @Success 201 {object} model.User "创建的用户信息" +// @Failure 400 {object} map[string]string "请求参数错误" +// @Failure 500 {object} map[string]string "服务器内部错误" +// @Router /users [post] + func (c *UserController) CreateUser(ctx *gin.Context) { var user model.User if err := ctx.ShouldBindJSON(&user); err != nil { @@ -75,6 +102,18 @@ func (c *UserController) CreateUser(ctx *gin.Context) { ctx.JSON(http.StatusCreated, user) } +// GetUser godoc +// @Summary 获取用户详情 +// @Description 根据ID获取用户详情 +// @Tags 用户管理 +// @Accept json +// @Produce json +// @Param id path int true "用户ID" +// @Success 200 {object} model.User "用户信息" +// @Failure 400 {object} map[string]string "无效的用户ID" +// @Failure 404 {object} map[string]string "用户不存在" +// @Failure 500 {object} map[string]string "服务器内部错误" +// @Router /users/{id} [get] func (c *UserController) GetUser(ctx *gin.Context) { idStr := ctx.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) @@ -96,6 +135,19 @@ func (c *UserController) GetUser(ctx *gin.Context) { ctx.JSON(http.StatusOK, user) } +// UpdateUser godoc +// @Summary 更新用户信息 +// @Description 根据ID更新用户信息 +// @Tags 用户管理 +// @Accept json +// @Produce json +// @Param id path int true "用户ID" +// @Param user body model.User true "用户信息" +// @Success 200 {object} model.User "更新后的用户信息" +// @Failure 400 {object} map[string]string "无效的用户ID或请求参数" +// @Failure 404 {object} map[string]string "用户不存在" +// @Failure 500 {object} map[string]string "服务器内部错误" +// @Router /users/{id} [put] func (c *UserController) UpdateUser(ctx *gin.Context) { idStr := ctx.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) @@ -125,6 +177,18 @@ func (c *UserController) UpdateUser(ctx *gin.Context) { ctx.JSON(http.StatusOK, user) } +// DeleteUser godoc +// @Summary 删除用户 +// @Description 根据ID删除用户 +// @Tags 用户管理 +// @Accept json +// @Produce json +// @Param id path int true "用户ID" +// @Success 204 "删除成功" +// @Failure 400 {object} map[string]string "无效的用户ID" +// @Failure 404 {object} map[string]string "用户不存在" +// @Failure 500 {object} map[string]string "服务器内部错误" +// @Router /users/{id} [delete] func (c *UserController) DeleteUser(ctx *gin.Context) { idStr := ctx.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) diff --git a/gofaster/backend/internal/model/workflow.go b/gofaster/backend/internal/model/workflow.go index f20066b..71751b6 100644 --- a/gofaster/backend/internal/model/workflow.go +++ b/gofaster/backend/internal/model/workflow.go @@ -6,18 +6,20 @@ type Workflow struct { BaseModel Name string `json:"name"` Description string `json:"description"` - Status int `json:"status"` // 1-启用 2-禁用 - Nodes []WorkflowNode `json:"nodes"` + Status int `json:"status"` // 1-启用 2-禁用 + Nodes []WorkflowNode `json:"nodes" gorm:"foreignKey:WorkflowID"` // 添加外键定义 } type WorkflowNode struct { BaseModel - WorkflowID uint `json:"workflow_id"` + WorkflowID uint `json:"workflow_id" gorm:"index"` // 添加索引 Name string `json:"name"` Type string `json:"type"` // start, end, task, approval等 Handler string `json:"handler"` // 处理函数 NextNodes string `json:"next_nodes"` // 逗号分隔的下个节点ID Position int `json:"position"` + // 可选:添加回Workflow的引用 + Workflow Workflow `json:"-" gorm:"foreignKey:WorkflowID"` } type WorkflowInstance struct { @@ -25,13 +27,13 @@ type WorkflowInstance struct { WorkflowID uint `json:"workflow_id"` Status string `json:"status"` // running, completed, canceled CurrentNodeID uint `json:"current_node_id"` - Data string `json:"data" gorm:"type:text"` // JSON格式的业务数据 - Tasks []WorkflowTask `json:"tasks"` + Data string `json:"data" gorm:"type:text"` // JSON格式的业务数据 + Tasks []WorkflowTask `json:"tasks" gorm:"foreignKey:InstanceID"` // 添加外键定义 } type WorkflowTask struct { BaseModel - InstanceID uint `json:"instance_id"` + InstanceID uint `json:"instance_id" gorm:"index"` // 添加索引 NodeID uint `json:"node_id"` Status string `json:"status"` // pending, processing, completed, canceled Result string `json:"result" gorm:"type:text"` // JSON格式的处理结果 @@ -39,4 +41,6 @@ type WorkflowTask struct { Assignee uint `json:"assignee"` // 处理人 StartTime time.Time `json:"start_time"` EndTime time.Time `json:"end_time"` + // 可选:添加回WorkflowInstance的引用 + Instance WorkflowInstance `json:"-" gorm:"foreignKey:InstanceID"` }