Sin descripción
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

session_routes.go 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package routes
  2. import (
  3. "context"
  4. "git.x2erp.com/qdy/go-base/authbase"
  5. "git.x2erp.com/qdy/go-base/ctx"
  6. "git.x2erp.com/qdy/go-base/logger"
  7. "git.x2erp.com/qdy/go-base/model/response"
  8. "git.x2erp.com/qdy/go-base/webx/router"
  9. "git.x2erp.com/qdy/go-svc-code/internal/opencode"
  10. "git.x2erp.com/qdy/go-svc-code/internal/service/menu"
  11. )
  12. // SessionCreateRequest 创建会话请求
  13. type SessionCreateRequest struct {
  14. Title string `json:"title" binding:"required"`
  15. MenuItemID string `json:"menu_item_id" binding:"required"` // 菜单项ID,必填
  16. }
  17. // SessionResponse 会话响应
  18. type SessionResponse struct {
  19. ID string `json:"id"`
  20. Title string `json:"title"`
  21. Port int `json:"port"`
  22. BaseURL string `json:"baseURL"`
  23. }
  24. // RegisterSessionRoutes 注册会话管理路由
  25. func RegisterSessionRoutes(ws *router.RouterService, client opencode.OpenCodeClient, mappingService *menu.MappingService) {
  26. // 创建会话(需要Token认证)
  27. ws.POST("/api/session/create",
  28. func(req *SessionCreateRequest, ctx context.Context, reqCtx *ctx.RequestContext) (*response.QueryResult[SessionResponse], error) {
  29. session, err := client.CreateSession(ctx, req.Title)
  30. if err != nil {
  31. return &response.QueryResult[SessionResponse]{
  32. Success: false,
  33. Message: err.Error(),
  34. }, nil
  35. }
  36. // 从认证信息中获取用户ID和租户ID
  37. // TokenAuth中间件已经在reqCtx中设置了UserID和TenantID
  38. userID := reqCtx.UserID
  39. tenantID := reqCtx.TenantID
  40. // 如果无法获取,使用占位符(实际生产环境应该确保认证信息正确设置)
  41. if userID == "" {
  42. userID = "unknown_user"
  43. logger.Warn("无法从请求上下文获取用户ID,使用默认值", "session_id", session.ID)
  44. }
  45. if tenantID == "" {
  46. tenantID = "default"
  47. }
  48. if tenantID == "" {
  49. tenantID = "default"
  50. }
  51. // 保存会话-菜单映射
  52. if err := mappingService.CreateMapping(ctx, session.ID, req.MenuItemID, userID, tenantID); err != nil {
  53. logger.Warn("创建会话-菜单映射失败", "session_id", session.ID, "menu_item_id", req.MenuItemID, "error", err)
  54. // 注意:映射创建失败不影响会话创建,但会记录警告
  55. }
  56. return &response.QueryResult[SessionResponse]{
  57. Success: true,
  58. Data: SessionResponse{
  59. ID: session.ID,
  60. Title: session.Title,
  61. Port: client.GetPort(),
  62. BaseURL: client.GetBaseURL(),
  63. },
  64. }, nil
  65. },
  66. ).Use(authbase.TokenAuth).Desc("创建新的 opencode 会话").Register()
  67. // 获取会话列表(需要Token认证)
  68. ws.GET("/api/session/list",
  69. func(ctx context.Context, reqCtx *ctx.RequestContext) (*response.QueryResult[[]opencode.Session], error) {
  70. sessions, err := client.ListSessions(ctx)
  71. if err != nil {
  72. return &response.QueryResult[[]opencode.Session]{
  73. Success: false,
  74. Message: err.Error(),
  75. }, nil
  76. }
  77. return &response.QueryResult[[]opencode.Session]{
  78. Success: true,
  79. Data: sessions,
  80. }, nil
  81. },
  82. ).Use(authbase.TokenAuth).Desc("获取 opencode 会话列表").Register()
  83. // 获取会话的菜单项ID(需要Token认证)
  84. ws.GET("/api/session/menu",
  85. func(sessionID string, ctx context.Context, reqCtx *ctx.RequestContext) (*response.QueryResult[string], error) {
  86. if sessionID == "" {
  87. return &response.QueryResult[string]{
  88. Success: false,
  89. Message: "参数 session_id 不能为空",
  90. }, nil
  91. }
  92. // 获取会话的菜单项ID
  93. menuItemID, err := mappingService.GetMenuItemBySessionID(ctx, sessionID)
  94. if err != nil {
  95. logger.Error("获取会话菜单项失败", "session_id", sessionID, "error", err)
  96. return &response.QueryResult[string]{
  97. Success: false,
  98. Message: "获取会话菜单项失败: " + err.Error(),
  99. }, nil
  100. }
  101. return &response.QueryResult[string]{
  102. Success: true,
  103. Data: menuItemID,
  104. }, nil
  105. },
  106. ).Use(authbase.TokenAuth).Desc("获取会话的菜单项ID").Register()
  107. // 获取单个会话(暂不实现,因为 opencode API 可能不支持)
  108. // ws.GET("/api/session/get",
  109. // func(ctx context.Context, reqCtx *ctx.RequestContext) (*response.QueryResult[opencode.Session], error) {
  110. // sessionID := reqCtx.GetQuery("id")
  111. // if sessionID == "" {
  112. // return &response.QueryResult[opencode.Session]{
  113. // Success: false,
  114. // Message: "参数 id 不能为空",
  115. // }, nil
  116. // }
  117. // session, err := client.GetSession(ctx, sessionID)
  118. // if err != nil {
  119. // return &response.QueryResult[opencode.Session]{
  120. // Success: false,
  121. // Message: err.Error(),
  122. // }, nil
  123. // }
  124. //
  125. // return &response.QueryResult[opencode.Session]{
  126. // Success: true,
  127. // Data: *session,
  128. // }, nil
  129. // },
  130. // ).Desc("获取 opencode 会话详情").Register()
  131. }