feat: restructure API routing and remove ginx package
- Added new routing functions for API and dashboard endpoints in controller_routes.go. - Replaced previous ginx.HandleController calls with explicit route registrations. - Removed the ginx package as it is no longer needed for handling controllers. - Improved organization and readability of route definitions.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -10,12 +10,8 @@ import (
|
|||||||
|
|
||||||
"cs-agent/internal/ai/mcps"
|
"cs-agent/internal/ai/mcps"
|
||||||
_ "cs-agent/internal/ai/runtime"
|
_ "cs-agent/internal/ai/runtime"
|
||||||
"cs-agent/internal/controllers/api"
|
|
||||||
"cs-agent/internal/controllers/dashboard"
|
|
||||||
"cs-agent/internal/controllers/third"
|
|
||||||
"cs-agent/internal/middleware"
|
"cs-agent/internal/middleware"
|
||||||
"cs-agent/internal/pkg/config"
|
"cs-agent/internal/pkg/config"
|
||||||
"cs-agent/internal/pkg/ginx"
|
|
||||||
"cs-agent/internal/services"
|
"cs-agent/internal/services"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -94,11 +90,11 @@ func addRouter(app *gin.Engine) {
|
|||||||
app.Any("/api/mcp", gin.WrapH(mcps.NewHTTPHandler()))
|
app.Any("/api/mcp", gin.WrapH(mcps.NewHTTPHandler()))
|
||||||
|
|
||||||
apiGroup := app.Group("/api")
|
apiGroup := app.Group("/api")
|
||||||
ginx.HandleController(apiGroup, "/auth", new(api.AuthController))
|
registerApiAuthRoutes(apiGroup.Group("/auth"))
|
||||||
ginx.HandleController(apiGroup, "/channel", new(api.ChannelController))
|
registerApiChannelRoutes(apiGroup.Group("/channel"))
|
||||||
ginx.HandleController(apiGroup, "/customer", new(api.CustomerController))
|
registerApiCustomerRoutes(apiGroup.Group("/customer"))
|
||||||
ginx.HandleController(apiGroup, "/conversation", new(api.ConversationController), middleware.ExternalUserMiddleware)
|
registerApiConversationRoutes(apiGroup.Group("/conversation", middleware.ExternalUserMiddleware))
|
||||||
ginx.HandleController(apiGroup, "/message", new(api.MessageController), middleware.ExternalUserMiddleware)
|
registerApiMessageRoutes(apiGroup.Group("/message", middleware.ExternalUserMiddleware))
|
||||||
|
|
||||||
wsGroup := app.Group("/api/ws")
|
wsGroup := app.Group("/api/ws")
|
||||||
wsGroup.GET("/dashboard", middleware.AuthMiddleware, services.WsService.HandleDashboardWS)
|
wsGroup.GET("/dashboard", middleware.AuthMiddleware, services.WsService.HandleDashboardWS)
|
||||||
@@ -106,37 +102,37 @@ func addRouter(app *gin.Engine) {
|
|||||||
wsGroup.GET("/open", services.WsService.HandleOpenWS)
|
wsGroup.GET("/open", services.WsService.HandleOpenWS)
|
||||||
|
|
||||||
dashboardGroup := app.Group("/api/dashboard", middleware.AuthMiddleware)
|
dashboardGroup := app.Group("/api/dashboard", middleware.AuthMiddleware)
|
||||||
ginx.HandleController(dashboardGroup, "/dashboard", new(dashboard.DashboardController))
|
registerDashboardDashboardRoutes(dashboardGroup.Group("/dashboard"))
|
||||||
ginx.HandleController(dashboardGroup, "/user", new(dashboard.UserController))
|
registerDashboardUserRoutes(dashboardGroup.Group("/user"))
|
||||||
ginx.HandleController(dashboardGroup, "/company", new(dashboard.CompanyController))
|
registerDashboardCompanyRoutes(dashboardGroup.Group("/company"))
|
||||||
ginx.HandleController(dashboardGroup, "/customer", new(dashboard.CustomerController))
|
registerDashboardCustomerRoutes(dashboardGroup.Group("/customer"))
|
||||||
ginx.HandleController(dashboardGroup, "/customer-contact", new(dashboard.CustomerContactController))
|
registerDashboardCustomerContactRoutes(dashboardGroup.Group("/customer-contact"))
|
||||||
ginx.HandleController(dashboardGroup, "/role", new(dashboard.RoleController))
|
registerDashboardRoleRoutes(dashboardGroup.Group("/role"))
|
||||||
ginx.HandleController(dashboardGroup, "/permission", new(dashboard.PermissionController))
|
registerDashboardPermissionRoutes(dashboardGroup.Group("/permission"))
|
||||||
ginx.HandleController(dashboardGroup, "/session", new(dashboard.SessionController))
|
registerDashboardSessionRoutes(dashboardGroup.Group("/session"))
|
||||||
ginx.HandleController(dashboardGroup, "/tag", new(dashboard.TagController))
|
registerDashboardTagRoutes(dashboardGroup.Group("/tag"))
|
||||||
ginx.HandleController(dashboardGroup, "/conversation", new(dashboard.ConversationController))
|
registerDashboardConversationRoutes(dashboardGroup.Group("/conversation"))
|
||||||
ginx.HandleController(dashboardGroup, "/ticket", new(dashboard.TicketController))
|
registerDashboardTicketRoutes(dashboardGroup.Group("/ticket"))
|
||||||
ginx.HandleController(dashboardGroup, "/notification", new(dashboard.NotificationController))
|
registerDashboardNotificationRoutes(dashboardGroup.Group("/notification"))
|
||||||
ginx.HandleController(dashboardGroup, "/quick-reply", new(dashboard.QuickReplyController))
|
registerDashboardQuickReplyRoutes(dashboardGroup.Group("/quick-reply"))
|
||||||
ginx.HandleController(dashboardGroup, "/channel", new(dashboard.ChannelController))
|
registerDashboardChannelRoutes(dashboardGroup.Group("/channel"))
|
||||||
ginx.HandleController(dashboardGroup, "/agent", new(dashboard.AgentController))
|
registerDashboardAgentRoutes(dashboardGroup.Group("/agent"))
|
||||||
ginx.HandleController(dashboardGroup, "/agent-team", new(dashboard.AgentTeamController))
|
registerDashboardAgentTeamRoutes(dashboardGroup.Group("/agent-team"))
|
||||||
ginx.HandleController(dashboardGroup, "/agent-team-schedule", new(dashboard.AgentTeamScheduleController))
|
registerDashboardAgentTeamScheduleRoutes(dashboardGroup.Group("/agent-team-schedule"))
|
||||||
ginx.HandleController(dashboardGroup, "/ai-agent", new(dashboard.AIAgentController))
|
registerDashboardAIAgentRoutes(dashboardGroup.Group("/ai-agent"))
|
||||||
ginx.HandleController(dashboardGroup, "/ai-config", new(dashboard.AIConfigController))
|
registerDashboardAIConfigRoutes(dashboardGroup.Group("/ai-config"))
|
||||||
ginx.HandleController(dashboardGroup, "/asset", new(dashboard.AssetController))
|
registerDashboardAssetRoutes(dashboardGroup.Group("/asset"))
|
||||||
ginx.HandleController(dashboardGroup, "/knowledge-base", new(dashboard.KnowledgeBaseController))
|
registerDashboardKnowledgeBaseRoutes(dashboardGroup.Group("/knowledge-base"))
|
||||||
ginx.HandleController(dashboardGroup, "/knowledge-document", new(dashboard.KnowledgeDocumentController))
|
registerDashboardKnowledgeDocumentRoutes(dashboardGroup.Group("/knowledge-document"))
|
||||||
ginx.HandleController(dashboardGroup, "/knowledge-faq", new(dashboard.KnowledgeFAQController))
|
registerDashboardKnowledgeFAQRoutes(dashboardGroup.Group("/knowledge-faq"))
|
||||||
ginx.HandleController(dashboardGroup, "/knowledge-retrieve", new(dashboard.KnowledgeRetrieveController))
|
registerDashboardKnowledgeRetrieveRoutes(dashboardGroup.Group("/knowledge-retrieve"))
|
||||||
ginx.HandleController(dashboardGroup, "/knowledge-retrieve-log", new(dashboard.KnowledgeRetrieveLogController))
|
registerDashboardKnowledgeRetrieveLogRoutes(dashboardGroup.Group("/knowledge-retrieve-log"))
|
||||||
ginx.HandleController(dashboardGroup, "/agent-run-log", new(dashboard.AgentRunLogController))
|
registerDashboardAgentRunLogRoutes(dashboardGroup.Group("/agent-run-log"))
|
||||||
ginx.HandleController(dashboardGroup, "/skill-definition", new(dashboard.SkillDefinitionController))
|
registerDashboardSkillDefinitionRoutes(dashboardGroup.Group("/skill-definition"))
|
||||||
ginx.HandleController(dashboardGroup, "/mcp", new(dashboard.MCPController))
|
registerDashboardMCPRoutes(dashboardGroup.Group("/mcp"))
|
||||||
|
|
||||||
thirdGroup := app.Group("/api/third")
|
thirdGroup := app.Group("/api/third")
|
||||||
ginx.HandleController(thirdGroup, "/wechat", new(third.WechatController))
|
registerThirdWechatRoutes(thirdGroup.Group("/wechat"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerDashboardStatic(app *gin.Engine, root string) {
|
func registerDashboardStatic(app *gin.Engine, root string) {
|
||||||
|
|||||||
@@ -1,137 +0,0 @@
|
|||||||
package ginx
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/mlogclub/simple/web"
|
|
||||||
)
|
|
||||||
|
|
||||||
var jsonResultType = reflect.TypeOf((*web.JsonResult)(nil))
|
|
||||||
|
|
||||||
func HandleController(group *gin.RouterGroup, relativePath string, prototype any, handlers ...gin.HandlerFunc) {
|
|
||||||
router := group.Group(relativePath, handlers...)
|
|
||||||
t := reflect.TypeOf(prototype)
|
|
||||||
if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
|
|
||||||
panic("ginx.HandleController requires a pointer to a controller struct")
|
|
||||||
}
|
|
||||||
for i := 0; i < t.NumMethod(); i++ {
|
|
||||||
method := t.Method(i)
|
|
||||||
httpMethods, path, ok := parseAction(method)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
handler := buildHandler(t, method)
|
|
||||||
for _, httpMethod := range httpMethods {
|
|
||||||
router.Handle(httpMethod, path, handler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseAction(method reflect.Method) ([]string, string, bool) {
|
|
||||||
prefixes := []struct {
|
|
||||||
name string
|
|
||||||
methods []string
|
|
||||||
}{
|
|
||||||
{"Any", []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodPatch, http.MethodOptions}},
|
|
||||||
{"Get", []string{http.MethodGet}},
|
|
||||||
{"Post", []string{http.MethodPost}},
|
|
||||||
{"Put", []string{http.MethodPut}},
|
|
||||||
{"Delete", []string{http.MethodDelete}},
|
|
||||||
}
|
|
||||||
for _, prefix := range prefixes {
|
|
||||||
if !strings.HasPrefix(method.Name, prefix.name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
suffix := strings.TrimPrefix(method.Name, prefix.name)
|
|
||||||
return prefix.methods, actionPath(suffix, method.Type.NumIn()-1), true
|
|
||||||
}
|
|
||||||
return nil, "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
func actionPath(suffix string, argCount int) string {
|
|
||||||
if suffix == "" {
|
|
||||||
return "/"
|
|
||||||
}
|
|
||||||
if suffix == "By" && argCount == 1 {
|
|
||||||
return "/:id"
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(suffix, "By") && argCount == 1 {
|
|
||||||
base := strings.TrimSuffix(suffix, "By")
|
|
||||||
return "/" + actionSegmentPath(base) + "/:id"
|
|
||||||
}
|
|
||||||
return "/" + actionSegmentPath(suffix)
|
|
||||||
}
|
|
||||||
|
|
||||||
func actionSegmentPath(s string) string {
|
|
||||||
if s == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
parts := strings.Split(s, "_")
|
|
||||||
for i, part := range parts {
|
|
||||||
parts[i] = camelToPath(part)
|
|
||||||
}
|
|
||||||
return strings.Join(parts, "_")
|
|
||||||
}
|
|
||||||
|
|
||||||
func camelToPath(s string) string {
|
|
||||||
var b strings.Builder
|
|
||||||
for i, r := range s {
|
|
||||||
if unicode.IsUpper(r) {
|
|
||||||
if i > 0 {
|
|
||||||
b.WriteByte('/')
|
|
||||||
}
|
|
||||||
r = unicode.ToLower(r)
|
|
||||||
}
|
|
||||||
b.WriteRune(r)
|
|
||||||
}
|
|
||||||
return b.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildHandler(controllerType reflect.Type, method reflect.Method) gin.HandlerFunc {
|
|
||||||
return func(ctx *gin.Context) {
|
|
||||||
controller := reflect.New(controllerType.Elem())
|
|
||||||
if field := controller.Elem().FieldByName("Ctx"); field.IsValid() && field.CanSet() {
|
|
||||||
field.Set(reflect.ValueOf(ctx))
|
|
||||||
}
|
|
||||||
|
|
||||||
args := []reflect.Value{controller}
|
|
||||||
for i := 1; i < method.Type.NumIn(); i++ {
|
|
||||||
argType := method.Type.In(i)
|
|
||||||
raw := ctx.Param("id")
|
|
||||||
value, ok := convertPathArg(raw, argType)
|
|
||||||
if !ok {
|
|
||||||
ctx.JSON(http.StatusBadRequest, web.JsonErrorMsg("路径参数错误"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
args = append(args, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
results := method.Func.Call(args)
|
|
||||||
if len(results) == 0 || results[0].IsNil() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if result, ok := results[0].Interface().(*web.JsonResult); ok {
|
|
||||||
ctx.JSON(http.StatusOK, result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertPathArg(raw string, t reflect.Type) (reflect.Value, bool) {
|
|
||||||
switch t.Kind() {
|
|
||||||
case reflect.Int64:
|
|
||||||
v, err := strconv.ParseInt(raw, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return reflect.Value{}, false
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(v), true
|
|
||||||
case reflect.String:
|
|
||||||
return reflect.ValueOf(raw), true
|
|
||||||
default:
|
|
||||||
return reflect.Zero(t), false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user