refactor: update WebSocket API routes for improved clarity and structure
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
|||||||
"cs-agent/internal/controllers/third"
|
"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/services"
|
||||||
|
|
||||||
"github.com/kataras/iris/v12"
|
"github.com/kataras/iris/v12"
|
||||||
"github.com/kataras/iris/v12/middleware/cors"
|
"github.com/kataras/iris/v12/middleware/cors"
|
||||||
@@ -91,13 +92,17 @@ func addRouter(app *iris.Application) {
|
|||||||
mcpHandler.ServeHTTP(w, r)
|
mcpHandler.ServeHTTP(w, r)
|
||||||
})))
|
})))
|
||||||
|
|
||||||
app.Get("/api/dashboard/ws", middleware.AuthMiddleware, middleware.DashboardWsMiddleware)
|
mvc.Configure(app.Party("/api/ws"), func(m *mvc.Application) {
|
||||||
app.Get("/api/open/im/ws", middleware.OpenImWsMiddleware)
|
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) {
|
mvc.Configure(app.Party("/api"), func(m *mvc.Application) {
|
||||||
m.Party("/auth").Handle(new(api.AuthController))
|
m.Party("/auth").Handle(new(api.AuthController))
|
||||||
m.Party("/channel").Handle(new(api.ChannelController))
|
m.Party("/channel").Handle(new(api.ChannelController))
|
||||||
|
|
||||||
|
// m.Router.Get("/ws", middleware.OpenImWsMiddleware)
|
||||||
|
|
||||||
m.Party("/conversation", middleware.ExternalInfoMiddleware).Handle(new(api.ConversationController))
|
m.Party("/conversation", middleware.ExternalInfoMiddleware).Handle(new(api.ConversationController))
|
||||||
m.Party("/message", middleware.ExternalInfoMiddleware).Handle(new(api.MessageController))
|
m.Party("/message", middleware.ExternalInfoMiddleware).Handle(new(api.MessageController))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"cs-agent/internal/models"
|
"cs-agent/internal/models"
|
||||||
"cs-agent/internal/pkg/dto"
|
"cs-agent/internal/pkg/dto"
|
||||||
"cs-agent/internal/pkg/enums"
|
"cs-agent/internal/pkg/enums"
|
||||||
|
"cs-agent/internal/pkg/errorsx"
|
||||||
"cs-agent/internal/pkg/openidentity"
|
"cs-agent/internal/pkg/openidentity"
|
||||||
"cs-agent/internal/pkg/utils"
|
"cs-agent/internal/pkg/utils"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -17,6 +18,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/kataras/iris/v12"
|
"github.com/kataras/iris/v12"
|
||||||
|
"github.com/mlogclub/simple/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
var WsService = newWsService()
|
var WsService = newWsService()
|
||||||
@@ -38,14 +40,43 @@ func newWsService() *wsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpgradeUserConnection 开放 IM 用户侧 WebSocket。
|
func (s *wsService) HandleDashboardWS(ctx iris.Context) {
|
||||||
// principal 非空时表示站内用户;否则应传入 external(IM 访客)。二者勿混用为同一业务身份。
|
principal := AuthService.GetAuthPrincipal(ctx)
|
||||||
func (s *wsService) UpgradeUserConnection(ctx iris.Context, principal *dto.AuthPrincipal, external *openidentity.ExternalInfo) error {
|
if principal == nil {
|
||||||
return s.upgradeConnection(ctx, principal, external, realtimeRoleUser)
|
_ = 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 {
|
func (s *wsService) HandleOpenWS(ctx iris.Context) {
|
||||||
return s.upgradeConnection(ctx, principal, nil, realtimeRoleAdmin)
|
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 {
|
func (s *wsService) upgradeConnection(ctx iris.Context, principal *dto.AuthPrincipal, external *openidentity.ExternalInfo, role string) error {
|
||||||
|
|||||||
@@ -542,7 +542,7 @@ export function createAdminWebSocketUrl() {
|
|||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
accessToken: session.accessToken,
|
accessToken: session.accessToken,
|
||||||
})
|
})
|
||||||
return `${baseUrl}/api/dashboard/ws?${params.toString()}`
|
return `${baseUrl}/api/ws/dashboard?${params.toString()}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchChannels(
|
export function fetchChannels(
|
||||||
|
|||||||
@@ -32,6 +32,6 @@ export function createImRealtimeConnection() {
|
|||||||
? `&externalName=${encodeURIComponent(externalName)}`
|
? `&externalName=${encodeURIComponent(externalName)}`
|
||||||
: ""
|
: ""
|
||||||
return new WebSocket(
|
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}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user