Skip to content

Commit da422f7

Browse files
committed
✨ feat: Enhance API endpoints and documentation
- Added new anonymous and authenticated test endpoints under /foo. - Updated authentication routes to remove deprecated comments and improve clarity. - Refactored health check endpoint to simplify routing. - Updated laboratory-related API routes to use /v1 prefix for versioning. - Improved workflow-related API documentation and added new endpoints for workflow management. - Integrated @tanstack/react-query for improved data fetching in the frontend. - Created new service files for environment, material, and workflow management in the frontend. - Added DTOs for Swagger documentation to improve API response clarity.
1 parent c17e323 commit da422f7

19 files changed

Lines changed: 7013 additions & 2641 deletions

File tree

service/docs/docs.go

Lines changed: 2720 additions & 1153 deletions
Large diffs are not rendered by default.

service/docs/swagger.json

Lines changed: 2720 additions & 1153 deletions
Large diffs are not rendered by default.

service/docs/swagger.yaml

Lines changed: 1233 additions & 250 deletions
Large diffs are not rendered by default.

service/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// @license.url http://www.gnu.org/licenses/agpl-3.0.en.html
1212

1313
// @host localhost:48197
14-
// @BasePath /api/v1
14+
// @BasePath /api
1515
// @schemes http
1616
// @securityDefinitions.apikey BearerAuth
1717
// @in header

service/pkg/core/workflow/model.go

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,18 @@ type TemplateHandleResp struct {
7272
// 节点详情响应
7373
type NodeTemplateDetailResp struct {
7474
UUID uuid.UUID `json:"uuid"`
75-
Name string `json:"name"` // 模板名称
76-
Class string `json:"class"` // 类名
77-
Type string `json:"type"` // 类型
78-
Icon string `json:"icon"` // 图标
79-
Schema datatypes.JSON `json:"schema"` // 数据模式
80-
Goal datatypes.JSON `json:"goal"` // 目标参数
81-
GoalDefault datatypes.JSON `json:"goal_default"` // 默认目标参数
82-
Feedback datatypes.JSON `json:"feedback"` // 反馈参数
83-
Result datatypes.JSON `json:"result"` // 结果参数
84-
LabName string `json:"lab_name"` // 实验室名称
85-
CreatedAt string `json:"created_at"` // 创建时间
86-
Handles []*NodeHandle `json:"handles"` // handle列表
75+
Name string `json:"name"` // 模板名称
76+
Class string `json:"class"` // 类名
77+
Type string `json:"type"` // 类型
78+
Icon string `json:"icon"` // 图标
79+
Schema datatypes.JSON `json:"schema" swaggertype:"object"` // 数据模式
80+
Goal datatypes.JSON `json:"goal" swaggertype:"object"` // 目标参数
81+
GoalDefault datatypes.JSON `json:"goal_default" swaggertype:"object"` // 默认目标参数
82+
Feedback datatypes.JSON `json:"feedback" swaggertype:"object"` // 反馈参数
83+
Result datatypes.JSON `json:"result" swaggertype:"object"` // 结果参数
84+
LabName string `json:"lab_name"` // 实验室名称
85+
CreatedAt string `json:"created_at"` // 创建时间
86+
Handles []*NodeHandle `json:"handles"` // handle列表
8787
Header string `json:"header"`
8888
Footer string `json:"footer"`
8989
}
@@ -151,9 +151,9 @@ type WSNode struct {
151151
Status string `json:"status"`
152152
Type model.WorkflowNodeType `json:"type"`
153153
Icon string `json:"icon"`
154-
Pose datatypes.JSONType[model.Pose] `json:"pose"`
155-
Param datatypes.JSON `json:"param"`
156-
Schema datatypes.JSON `json:"schema"`
154+
Pose datatypes.JSONType[model.Pose] `json:"pose" swaggertype:"object"`
155+
Param datatypes.JSON `json:"param" swaggertype:"object"`
156+
Schema datatypes.JSON `json:"schema" swaggertype:"object"`
157157
Handles []*WSNodeHandle `json:"handles"`
158158
Footer string `json:"footer"`
159159
DeviceName *string `json:"device_name,omitempty"`
@@ -181,7 +181,7 @@ type WSTemplate struct {
181181
DisplayName string `json:"display_name"`
182182
Header string `json:"header"`
183183
Footer *string `json:"footer"`
184-
Schema datatypes.JSON `json:"schema"`
184+
Schema datatypes.JSON `json:"schema" swaggertype:"object"`
185185
ExecuteScript string `json:"execute_script"`
186186
NodeType string `json:"node_type"`
187187
Icon string `json:"icon"`
@@ -207,8 +207,8 @@ type WSCreateNode struct {
207207
ParentUUID uuid.UUID `json:"parent_uuid"`
208208
Type model.WorkflowNodeType `json:"type"`
209209
Icon string `json:"icon"`
210-
Pose datatypes.JSONType[model.Pose] `json:"pose"`
211-
Param *datatypes.JSON `json:"param,omitempty"`
210+
Pose datatypes.JSONType[model.Pose] `json:"pose" swaggertype:"object"`
211+
Param *datatypes.JSON `json:"param,omitempty" swaggertype:"object"`
212212
Footer string `json:"footer"`
213213
Name string `json:"name"`
214214
}
@@ -219,8 +219,8 @@ type WSUpdateNode struct {
219219
Status *string `json:"status,omitempty"`
220220
Type *model.WorkflowNodeType `json:"type,omitempty"`
221221
Icon *string `json:"icon,omitempty"`
222-
Pose *datatypes.JSONType[model.Pose] `json:"pose,omitempty"`
223-
Param *datatypes.JSON `json:"param,omitempty"`
222+
Pose *datatypes.JSONType[model.Pose] `json:"pose,omitempty" swaggertype:"object"`
223+
Param *datatypes.JSON `json:"param,omitempty" swaggertype:"object"`
224224
Footer *string `json:"footer,omitempty"`
225225
Name *string `json:"name,omitempty"`
226226
Disabled *bool `json:"disabled,omitempty"`
@@ -353,8 +353,8 @@ type ExportNode struct {
353353
Name string `json:"name"`
354354
Type model.WorkflowNodeType `json:"type"`
355355
Icon string `json:"icon"`
356-
Pose datatypes.JSONType[model.Pose] `json:"pose"`
357-
Param datatypes.JSON `json:"param"`
356+
Pose datatypes.JSONType[model.Pose] `json:"pose" swaggertype:"object"`
357+
Param datatypes.JSON `json:"param" swaggertype:"object"`
358358
Footer string `json:"footer"`
359359
DeviceName *string `json:"device_name,omitempty"`
360360
Disabled bool `json:"disabled"`

service/pkg/web/router.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ func NewRouter(ctx context.Context, g *gin.Engine) {
2929
}
3030

3131
func installMiddleware(g *gin.Engine) {
32-
// TODO: trace 中间件
3332
g.ContextWithFallback = true
3433
server := config.Global().Server
3534
g.Use(cors.Default())
@@ -44,24 +43,29 @@ func InstallURL(ctx context.Context, g *gin.Engine) {
4443
api.GET("/health", views.Health)
4544
api.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
4645

47-
// 登录模块
46+
// Test
47+
{
48+
fooGroup := api.Group("/foo")
49+
fooGroup.GET("", foo.HandleTestAnomy)
50+
fooGroup.GET("/auth", auth.Auth(), foo.HandleTestAuth)
51+
}
52+
53+
// Auth
4854
{
4955
l := login.NewLogin()
5056
// 设置认证相关路由
5157
authGroup := api.Group("/auth")
52-
// 登录路由 - 使用改进版处理器
58+
// 登录路由
5359
authGroup.GET("/login", l.Login)
54-
// OAuth2 回调处理路由 - 使用改进版处理器
60+
// OAuth2 回调处理路由
5561
authGroup.GET("/callback/casdoor", l.Callback)
5662
// 刷新令牌路由
5763
authGroup.POST("/refresh", l.Refresh)
5864
}
5965

66+
// V1 API
6067
{
6168
v1 := api.Group("/v1")
62-
// 测试路由
63-
fooGroup := v1.Group("/foo")
64-
fooGroup.GET("/hello", auth.Auth(), foo.HandleHelloWorld)
6569
wsRouter := v1.Group("/ws", auth.Auth())
6670

6771
// 环境相关
@@ -141,7 +145,7 @@ func InstallURL(ctx context.Context, g *gin.Engine) {
141145
owner := workflowRouter.Group("owner")
142146
owner.PATCH("", workflowHandle.UpdateWorkflow) // 更新工作流 done
143147
owner.POST("", workflowHandle.Create) // 创建工作流 done
144-
owner.DELETE("/:uuid", workflowHandle.DelWrokflow) // 删除自己创建的工作流 done
148+
owner.DELETE("/:uuid", workflowHandle.DelWorkflow) // 删除自己创建的工作流 done
145149
owner.GET("/list", workflowHandle.GetWorkflowList) // 获取工作流列表 done
146150
owner.GET("/export", workflowHandle.Export) // 导出工作流
147151
owner.POST("/import", workflowHandle.Import) // 导入工作流

service/pkg/web/views/foo/foo.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,30 @@ import (
99
)
1010

1111
// HandleHelloWorld godoc
12-
// @Summary Hello World
12+
// @Summary Anonymous Test Endpoint
13+
// @Description A simple test endpoint that does not require authentication
14+
// @Tags Test
15+
// @Accept json
16+
// @Produce json
17+
// @Success 200 {object} map[string]interface{}
18+
// @Router /foo [get]
19+
func HandleTestAnomy(ctx *gin.Context) {
20+
ctx.JSON(http.StatusOK, gin.H{
21+
"message": "This is an anonymous test endpoint",
22+
})
23+
}
24+
25+
// HandleHelloWorld godoc
26+
// @Summary Authenticated Test Endpoint
1327
// @Description A simple hello world endpoint
14-
// @Tags foo
28+
// @Tags Test
1529
// @Accept json
1630
// @Produce json
1731
// @Success 200 {object} map[string]interface{}
18-
// @Router /api/v1/foo/hello [get]
19-
func HandleHelloWorld(ctx *gin.Context) {
32+
// @Router /foo/auth [get]
33+
func HandleTestAuth(ctx *gin.Context) {
2034
// 使用GetCurrentUser获取当前用户
2135
user := auth.GetCurrentUser(ctx)
22-
if user == nil {
23-
// 由于已经使用了RequireAuth中间件,这种情况正常不会发生
24-
ctx.JSON(http.StatusForbidden, gin.H{
25-
"error": "Forbidden: Not authenticated",
26-
})
27-
}
2836

2937
logger.Infof(ctx.Request.Context(), "User %v is authenticated", user)
3038

service/pkg/web/views/health.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import "github.com/gin-gonic/gin"
88
// @Accept json
99
// @Produce json
1010
// @Success 200 {object} map[string]interface{} "返回成功状态"
11-
// @Router /api/health [get]
11+
// @Router /health [get]
1212
func Health(g *gin.Context) {
1313
g.JSON(200, map[string]any{
1414
"success": "ok",

service/pkg/web/views/laboratory/laboratory.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func NewEnvironment() *EnvHandle {
2727
// @Param lab body environment.LaboratoryEnvReq true "实验室环境创建请求"
2828
// @Success 200 {object} common.Resp{data=environment.LaboratoryEnvResp} "创建成功"
2929
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
30-
// @Router /api/lab [post]
30+
// @Router /v1/lab [post]
3131
func (l *EnvHandle) CreateLabEnv(ctx *gin.Context) {
3232
req := &environment.LaboratoryEnvReq{}
3333
if err := ctx.ShouldBindJSON(req); err != nil {
@@ -54,7 +54,7 @@ func (l *EnvHandle) CreateLabEnv(ctx *gin.Context) {
5454
// @Param lab body environment.UpdateEnvReq true "实验室环境更新请求"
5555
// @Success 200 {object} common.Resp{data=environment.LaboratoryResp} "更新成功"
5656
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
57-
// @Router /api/lab [patch]
57+
// @Router /v1/lab [patch]
5858
func (l *EnvHandle) UpdateLabEnv(ctx *gin.Context) {
5959
req := &environment.UpdateEnvReq{}
6060
if err := ctx.ShouldBindJSON(req); err != nil {
@@ -81,7 +81,7 @@ func (l *EnvHandle) UpdateLabEnv(ctx *gin.Context) {
8181
// @Param lab body environment.DelLabReq true "删除实验室请求"
8282
// @Success 200 {object} common.Resp{} "删除成功"
8383
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
84-
// @Router /api/lab [delete]
84+
// @Router /v1/lab [delete]
8585
func (l *EnvHandle) DelLabEnv(ctx *gin.Context) {
8686
req := &environment.DelLabReq{}
8787
if err := ctx.ShouldBindJSON(req); err != nil {
@@ -102,7 +102,7 @@ func (l *EnvHandle) DelLabEnv(ctx *gin.Context) {
102102
// @Param page query common.PageReq false "分页参数"
103103
// @Success 200 {object} common.Resp{data=environment.LaboratoryListResp} "获取成功"
104104
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
105-
// @Router /api/lab/list [get]
105+
// @Router /v1/lab/list [get]
106106
func (l *EnvHandle) LabList(ctx *gin.Context) {
107107
req := &common.PageReq{}
108108
if err := ctx.ShouldBindQuery(req); err != nil {
@@ -130,7 +130,7 @@ func (l *EnvHandle) LabList(ctx *gin.Context) {
130130
// @Param with_member query bool false "是否包含成员列表"
131131
// @Success 200 {object} common.Resp{data=environment.LabInfoResp} "获取成功"
132132
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
133-
// @Router /api/lab/{lab_uuid} [get]
133+
// @Router /v1/lab/{lab_uuid} [get]
134134
func (l *EnvHandle) LabInfo(ctx *gin.Context) {
135135
req := &environment.LabInfoReq{}
136136
if err := ctx.ShouldBindUri(req); err != nil {
@@ -157,7 +157,7 @@ func (l *EnvHandle) LabInfo(ctx *gin.Context) {
157157
// @Param resource body environment.ResourceReq true "资源请求"
158158
// @Success 200 {object} common.Resp{} "创建成功"
159159
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
160-
// @Router /api/lab/resource [post]
160+
// @Router /v1/lab/resource [post]
161161
func (l *EnvHandle) CreateLabResource(ctx *gin.Context) {
162162
req := &environment.ResourceReq{}
163163
if err := ctx.ShouldBindJSON(req); err != nil {
@@ -185,7 +185,7 @@ func (l *EnvHandle) CreateLabResource(ctx *gin.Context) {
185185
// @Param page query common.PageReq false "分页参数"
186186
// @Success 200 {object} common.Resp{data=environment.LabMemberListResp} "获取成功"
187187
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
188-
// @Router /api/lab/member/{lab_uuid} [get]
188+
// @Router /v1/lab/member/{lab_uuid} [get]
189189
func (l *EnvHandle) GetLabMemeber(ctx *gin.Context) {
190190
req := &environment.LabMemberReq{}
191191
if err := ctx.ShouldBindUri(req); err != nil {
@@ -217,7 +217,7 @@ func (l *EnvHandle) GetLabMemeber(ctx *gin.Context) {
217217
// @Param member_uuid path string true "成员UUID"
218218
// @Success 200 {object} common.Resp{} "删除成功"
219219
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
220-
// @Router /api/lab/member/{lab_uuid}/{member_uuid} [delete]
220+
// @Router /v1/lab/member/{lab_uuid}/{member_uuid} [delete]
221221
func (l *EnvHandle) DelLabMember(ctx *gin.Context) {
222222
req := &environment.DelLabMemberReq{}
223223
if err := ctx.ShouldBindUri(req); err != nil {
@@ -243,7 +243,7 @@ func (l *EnvHandle) DelLabMember(ctx *gin.Context) {
243243
// @Param lab_uuid path string true "实验室UUID"
244244
// @Success 200 {object} common.Resp{data=environment.InviteResp} "创建成功"
245245
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
246-
// @Router /api/lab/invite/{lab_uuid} [post]
246+
// @Router /v1/lab/invite/{lab_uuid} [post]
247247
func (l *EnvHandle) CreateInvite(ctx *gin.Context) {
248248
req := &environment.InviteReq{}
249249
if err := ctx.ShouldBindUri(req); err != nil {
@@ -269,7 +269,7 @@ func (l *EnvHandle) CreateInvite(ctx *gin.Context) {
269269
// @Param uuid path string true "邀请链接UUID"
270270
// @Success 200 {object} common.Resp{} "接受成功"
271271
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
272-
// @Router /api/lab/invite/{uuid} [get]
272+
// @Router /v1/lab/invite/{uuid} [get]
273273
func (l EnvHandle) AcceptInvite(ctx *gin.Context) {
274274
req := &environment.AcceptInviteReq{}
275275
if err := ctx.ShouldBindUri(req); err != nil {
@@ -294,7 +294,7 @@ func (l EnvHandle) AcceptInvite(ctx *gin.Context) {
294294
// @Produce json
295295
// @Success 200 {object} common.Resp{data=model.UserData} "获取成功"
296296
// @Failure 200 {object} common.Resp{code=code.ErrCode} "请求参数错误"
297-
// @Router /api/lab/user [get]
297+
// @Router /v1/lab/user [get]
298298
func (l *EnvHandle) UserInfo(ctx *gin.Context) {
299299
resp, err := l.envService.UserInfo(ctx)
300300
common.Reply(ctx, err, resp)

service/pkg/web/views/login/login.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func NewLogin() *Login {
3838
// @Param frontend_callback_url query string false "前端回调地址"
3939
// @Success 302 {string} string "重定向到OAuth2授权页面"
4040
// @Header 302 {string} Location "重定向的授权URL地址"
41-
// @Router /api/auth/login [get]
41+
// @Router /auth/login [get]
4242
func (l *Login) Login(ctx *gin.Context) {
4343
req := &ls.LoginReq{}
4444
// 从查询参数获取前端回调地址(可选)
@@ -63,7 +63,7 @@ func (l *Login) Login(ctx *gin.Context) {
6363
// @Success 200 {object} common.Resp{data=ls.RefreshTokenResp} "刷新令牌成功 code=0"
6464
// @Failure 200 {object} common.Resp{code=code.ErrCode} "参数错误 code = 1011"
6565
// @Failure 200 {object} common.Resp{code=code.ErrCode} "刷新 token 失败 code = 1002"
66-
// @Router /api/auth/refresh [post]
66+
// @Router /auth/refresh [post]
6767
func (l *Login) Refresh(ctx *gin.Context) {
6868
// 从请求中获取刷新令牌
6969
req := &ls.RefreshTokenReq{}
@@ -91,7 +91,7 @@ func (l *Login) Refresh(ctx *gin.Context) {
9191
// @Param state query string true "防CSRF攻击的状态码"
9292
// @Success 302 {string} string "重定向到前端"
9393
// @Failure 302 {string} string "重定向到前端错误页面"
94-
// @Router /api/auth/callback/casdoor [get]
94+
// @Router /auth/callback/casdoor [get]
9595
func (l *Login) Callback(ctx *gin.Context) {
9696
req := &ls.CallbackReq{}
9797
if err := ctx.ShouldBindQuery(req); err != nil {

0 commit comments

Comments
 (0)