refactor: update WebSocket API routes for improved clarity and structure

This commit is contained in:
mlogclub
2026-04-25 10:50:23 +08:00
parent 270bb83fdb
commit 2c884c13cf
5 changed files with 46 additions and 60 deletions
+7 -2
View File
@@ -13,6 +13,7 @@ import (
"cs-agent/internal/controllers/third"
"cs-agent/internal/middleware"
"cs-agent/internal/pkg/config"
"cs-agent/internal/services"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/cors"
@@ -91,13 +92,17 @@ func addRouter(app *iris.Application) {
mcpHandler.ServeHTTP(w, r)
})))
app.Get("/api/dashboard/ws", middleware.AuthMiddleware, middleware.DashboardWsMiddleware)
app.Get("/api/open/im/ws", middleware.OpenImWsMiddleware)
mvc.Configure(app.Party("/api/ws"), func(m *mvc.Application) {
m.Router.Get("/dashboard", middleware.AuthMiddleware, services.WsService.HandleDashboardWS)
m.Router.Get("/open", services.WsService.HandleOpenWS)
})
mvc.Configure(app.Party("/api"), func(m *mvc.Application) {
m.Party("/auth").Handle(new(api.AuthController))
m.Party("/channel").Handle(new(api.ChannelController))
// m.Router.Get("/ws", middleware.OpenImWsMiddleware)
m.Party("/conversation", middleware.ExternalInfoMiddleware).Handle(new(api.ConversationController))
m.Party("/message", middleware.ExternalInfoMiddleware).Handle(new(api.MessageController))
})
-50
View File
@@ -1,50 +0,0 @@
package middleware
import (
"cs-agent/internal/pkg/openidentity"
"cs-agent/internal/services"
"log/slog"
"github.com/kataras/iris/v12"
"github.com/mlogclub/simple/web"
)
func DashboardWsMiddleware(ctx iris.Context) {
principal := services.AuthService.GetAuthPrincipal(ctx)
if principal == nil {
if _, err := services.AuthService.Authenticate(ctx); err != nil {
_ = ctx.StopWithJSON(iris.StatusUnauthorized, web.JsonError(err))
return
}
principal = services.AuthService.GetAuthPrincipal(ctx)
}
if err := services.WsService.UpgradeAdminConnection(ctx, principal); err != nil {
slog.Error("upgrade admin websocket failed", "error", err, "path", ctx.Path())
ctx.StopExecution()
return
}
}
func OpenImWsMiddleware(ctx iris.Context) {
channel := services.ChannelService.GetEnabledChannel(ctx)
if channel == nil {
_ = ctx.StopWithJSON(iris.StatusBadRequest, web.JsonErrorMsg("接入渠道不存在或已停用"))
return
}
principal := services.AuthService.GetAuthPrincipal(ctx)
var external *openidentity.ExternalInfo
if principal == nil {
ext, err := openidentity.GetExternalInfo(ctx)
if err != nil {
_ = ctx.StopWithJSON(iris.StatusUnauthorized, web.JsonError(err))
return
}
external = ext
}
if err := services.WsService.UpgradeUserConnection(ctx, principal, external); err != nil {
slog.Error("upgrade open im websocket failed", "error", err, "path", ctx.Path(), "channelId", channel.ChannelID, "channel_id", channel.ID)
ctx.StopExecution()
return
}
}
+37 -6
View File
@@ -4,6 +4,7 @@ import (
"cs-agent/internal/models"
"cs-agent/internal/pkg/dto"
"cs-agent/internal/pkg/enums"
"cs-agent/internal/pkg/errorsx"
"cs-agent/internal/pkg/openidentity"
"cs-agent/internal/pkg/utils"
"encoding/json"
@@ -17,6 +18,7 @@ import (
"github.com/gorilla/websocket"
"github.com/kataras/iris/v12"
"github.com/mlogclub/simple/web"
)
var WsService = newWsService()
@@ -38,14 +40,43 @@ func newWsService() *wsService {
}
}
// UpgradeUserConnection 开放 IM 用户侧 WebSocket。
// principal 非空时表示站内用户;否则应传入 external(IM 访客)。二者勿混用为同一业务身份。
func (s *wsService) UpgradeUserConnection(ctx iris.Context, principal *dto.AuthPrincipal, external *openidentity.ExternalInfo) error {
return s.upgradeConnection(ctx, principal, external, realtimeRoleUser)
func (s *wsService) HandleDashboardWS(ctx iris.Context) {
principal := AuthService.GetAuthPrincipal(ctx)
if principal == nil {
_ = ctx.StopWithJSON(iris.StatusUnauthorized, web.JsonError(errorsx.Unauthorized("未登录或登录已过期")))
return
}
if err := s.upgradeConnection(ctx, principal, nil, realtimeRoleAdmin); err != nil {
slog.Error("upgrade admin websocket failed", "error", err, "path", ctx.Path())
ctx.StopExecution()
return
}
}
func (s *wsService) UpgradeAdminConnection(ctx iris.Context, principal *dto.AuthPrincipal) error {
return s.upgradeConnection(ctx, principal, nil, realtimeRoleAdmin)
func (s *wsService) HandleOpenWS(ctx iris.Context) {
channel := ChannelService.GetEnabledChannel(ctx)
if channel == nil {
_ = ctx.StopWithJSON(iris.StatusBadRequest, web.JsonErrorMsg("接入渠道不存在或已停用"))
return
}
var (
principal = AuthService.GetAuthPrincipal(ctx)
external *openidentity.ExternalInfo
)
if principal == nil {
ext, err := openidentity.GetExternalInfo(ctx)
if err != nil {
_ = ctx.StopWithJSON(iris.StatusUnauthorized, web.JsonError(err))
return
}
external = ext
}
if err := s.upgradeConnection(ctx, principal, external, realtimeRoleUser); err != nil {
slog.Error("upgrade open im websocket failed", "error", err, "path", ctx.Path(), "channelId", channel.ChannelID, "channel_id", channel.ID)
ctx.StopExecution()
return
}
}
func (s *wsService) upgradeConnection(ctx iris.Context, principal *dto.AuthPrincipal, external *openidentity.ExternalInfo, role string) error {
+1 -1
View File
@@ -542,7 +542,7 @@ export function createAdminWebSocketUrl() {
const params = new URLSearchParams({
accessToken: session.accessToken,
})
return `${baseUrl}/api/dashboard/ws?${params.toString()}`
return `${baseUrl}/api/ws/dashboard?${params.toString()}`
}
export function fetchChannels(
+1 -1
View File
@@ -32,6 +32,6 @@ export function createImRealtimeConnection() {
? `&externalName=${encodeURIComponent(externalName)}`
: ""
return new WebSocket(
`${baseUrl}/api/open/im/ws?externalId=${externalId}&externalSource=${externalSource}&channelId=${channelId}${nameQuery}`
`${baseUrl}/api/ws/open?externalId=${externalId}&externalSource=${externalSource}&channelId=${channelId}${nameQuery}`
)
}