From cf63b75590a5ed12e7b8d55599e3c9c4204136e9 Mon Sep 17 00:00:00 2001 From: mlogclub Date: Tue, 28 Apr 2026 11:10:47 +0800 Subject: [PATCH] refactor: rename ExternalInfo to ExternalUser and update related functions for consistency Co-authored-by: Copilot --- internal/bootstrap/server.go | 8 +-- .../api/conversation_controller.go | 6 +- .../controllers/api/message_controller.go | 10 ++-- internal/middleware/chat_middleware.go | 6 +- internal/pkg/enums/external_identity.go | 10 ---- internal/pkg/irisx/context.go | 12 ++-- internal/pkg/openidentity/openidentity.go | 60 +++++++------------ .../conversation_participant_service.go | 4 +- .../conversation_read_state_service.go | 6 +- internal/services/conversation_service.go | 24 ++++---- internal/services/customer_service.go | 16 ++--- internal/services/message_service.go | 8 +-- internal/services/ws_realtime_types.go | 2 +- internal/services/ws_service.go | 6 +- .../services/wxwork_kf_inbound_service.go | 14 ++--- 15 files changed, 81 insertions(+), 111 deletions(-) diff --git a/internal/bootstrap/server.go b/internal/bootstrap/server.go index d87a0d5..7dbeaa4 100644 --- a/internal/bootstrap/server.go +++ b/internal/bootstrap/server.go @@ -28,9 +28,9 @@ func NewServer() (*iris.Application, error) { app := iris.New() corsHandler := cors.New(). AllowOrigin("*"). - AllowHeaders("Origin", "Content-Type", "Accept", "Authorization", "X-Requested-With", "X-Guest-Id", "X-Channel-Id", "X-External-Source", "X-External-Id", "X-External-Name"). + AllowHeaders("Origin", "Content-Type", "Accept", "Authorization", "X-Requested-With", "X-Guest-Id", "X-Channel-Id", "X-External-Id", "X-External-Name"). MaxAge(600). - ExposeHeaders("Content-Length", "Content-Type", "Authorization", "X-Guest-Id", "X-Channel-Id", "X-External-Source", "X-External-Id", "X-External-Name"). + ExposeHeaders("Content-Length", "Content-Type", "Authorization", "X-Guest-Id", "X-Channel-Id", "X-External-Id", "X-External-Name"). Handler() app.UseRouter(func(ctx iris.Context) { // WebSocket upgrade is validated by the upgrader's origin policy. @@ -95,8 +95,8 @@ func addRouter(app *iris.Application) { mvc.Configure(app.Party("/api"), func(m *mvc.Application) { m.Party("/auth").Handle(new(api.AuthController)) m.Party("/channel").Handle(new(api.ChannelController)) - m.Party("/conversation", middleware.ExternalInfoMiddleware).Handle(new(api.ConversationController)) - m.Party("/message", middleware.ExternalInfoMiddleware).Handle(new(api.MessageController)) + m.Party("/conversation", middleware.ExternalUserMiddleware).Handle(new(api.ConversationController)) + m.Party("/message", middleware.ExternalUserMiddleware).Handle(new(api.MessageController)) }) mvc.Configure(app.Party("/api/ws"), func(m *mvc.Application) { diff --git a/internal/controllers/api/conversation_controller.go b/internal/controllers/api/conversation_controller.go index 0bf8782..32161a7 100644 --- a/internal/controllers/api/conversation_controller.go +++ b/internal/controllers/api/conversation_controller.go @@ -20,7 +20,7 @@ func (c *ConversationController) GetBy(id int64) *web.JsonResult { if services.ChannelService.GetEnabledChannel(c.Ctx) == nil { return web.JsonErrorMsg("接入渠道未初始化") } - external := irisx.GetExternalInfo(c.Ctx) + external := irisx.GetExternalUser(c.Ctx) if external == nil { return web.JsonErrorMsg("外部身份未初始化") } @@ -45,7 +45,7 @@ func (c *ConversationController) PostCreate_or_match() *web.JsonResult { if channel == nil { return web.JsonErrorMsg("接入渠道未初始化") } - external := irisx.GetExternalInfo(c.Ctx) + external := irisx.GetExternalUser(c.Ctx) if external == nil { return web.JsonErrorMsg("外部身份未初始化") } @@ -61,7 +61,7 @@ func (c *ConversationController) PostClose() *web.JsonResult { if services.ChannelService.GetEnabledChannel(c.Ctx) == nil { return web.JsonErrorMsg("接入渠道未初始化") } - external := irisx.GetExternalInfo(c.Ctx) + external := irisx.GetExternalUser(c.Ctx) if external == nil { return web.JsonErrorMsg("外部身份未初始化") } diff --git a/internal/controllers/api/message_controller.go b/internal/controllers/api/message_controller.go index 33b0c8b..0c39512 100644 --- a/internal/controllers/api/message_controller.go +++ b/internal/controllers/api/message_controller.go @@ -23,7 +23,7 @@ func (c *MessageController) AnyList() *web.JsonResult { if services.ChannelService.GetEnabledChannel(c.Ctx) == nil { return web.JsonErrorMsg("接入渠道未初始化") } - external := irisx.GetExternalInfo(c.Ctx) + external := irisx.GetExternalUser(c.Ctx) if external == nil { return web.JsonErrorMsg("外部身份未初始化") } @@ -57,7 +57,7 @@ func (c *MessageController) PostSend() *web.JsonResult { if services.ChannelService.GetEnabledChannel(c.Ctx) == nil { return web.JsonErrorMsg("接入渠道未初始化") } - external := irisx.GetExternalInfo(c.Ctx) + external := irisx.GetExternalUser(c.Ctx) if external == nil { return web.JsonErrorMsg("外部身份未初始化") } @@ -78,7 +78,7 @@ func (c *MessageController) PostRead() *web.JsonResult { if services.ChannelService.GetEnabledChannel(c.Ctx) == nil { return web.JsonErrorMsg("接入渠道未初始化") } - external := irisx.GetExternalInfo(c.Ctx) + external := irisx.GetExternalUser(c.Ctx) if external == nil { return web.JsonErrorMsg("外部身份未初始化") } @@ -97,7 +97,7 @@ func (c *MessageController) PostUpload_image() *web.JsonResult { if services.ChannelService.GetEnabledChannel(c.Ctx) == nil { return web.JsonErrorMsg("接入渠道未初始化") } - external := irisx.GetExternalInfo(c.Ctx) + external := irisx.GetExternalUser(c.Ctx) if external == nil { return web.JsonErrorMsg("外部身份未初始化") } @@ -142,7 +142,7 @@ func (c *MessageController) PostUpload_attachment() *web.JsonResult { if services.ChannelService.GetEnabledChannel(c.Ctx) == nil { return web.JsonErrorMsg("接入渠道未初始化") } - external := irisx.GetExternalInfo(c.Ctx) + external := irisx.GetExternalUser(c.Ctx) if external == nil { return web.JsonErrorMsg("外部身份未初始化") } diff --git a/internal/middleware/chat_middleware.go b/internal/middleware/chat_middleware.go index 475ede6..7b63241 100644 --- a/internal/middleware/chat_middleware.go +++ b/internal/middleware/chat_middleware.go @@ -9,7 +9,7 @@ import ( "github.com/mlogclub/simple/web" ) -func ExternalInfoMiddleware(ctx iris.Context) { +func ExternalUserMiddleware(ctx iris.Context) { channel := services.ChannelService.GetEnabledChannel(ctx) if channel == nil { ctx.StopExecution() @@ -17,12 +17,12 @@ func ExternalInfoMiddleware(ctx iris.Context) { return } secret := services.ChannelService.GetUserTokenSecret(channel) - ext, err := openidentity.GetExternalInfo(ctx, secret) + ext, err := openidentity.GetExternalUser(ctx, secret) if err != nil { ctx.StopExecution() _ = ctx.JSON(web.JsonError(err)) return } - irisx.SetExternalInfo(ctx, ext) + irisx.SetExternalUser(ctx, ext) ctx.Next() } diff --git a/internal/pkg/enums/external_identity.go b/internal/pkg/enums/external_identity.go index 0e7b7d1..d9476fc 100644 --- a/internal/pkg/enums/external_identity.go +++ b/internal/pkg/enums/external_identity.go @@ -23,13 +23,3 @@ func GetExternalSourceLabel(v ExternalSource) string { } return string(v) } - -// IsAllowedOpenImExternalSource 开放 IM 入口允许的外部来源(闭集校验)。 -func IsAllowedOpenImExternalSource(s ExternalSource) bool { - switch s { - case ExternalSourceGuest, ExternalSourceUser: - return true - default: - return false - } -} diff --git a/internal/pkg/irisx/context.go b/internal/pkg/irisx/context.go index 536fcf2..2f0a4a5 100644 --- a/internal/pkg/irisx/context.go +++ b/internal/pkg/irisx/context.go @@ -9,16 +9,16 @@ import ( ) const ( - ctxKeyExternalInfo = "externalInfo" + ctxKeyExternalUser = "externalUser" ) -func SetExternalInfo(ctx iris.Context, ext *openidentity.ExternalInfo) { - ctx.Values().Set(ctxKeyExternalInfo, ext) +func SetExternalUser(ctx iris.Context, ext *openidentity.ExternalUser) { + ctx.Values().Set(ctxKeyExternalUser, ext) } -func GetExternalInfo(ctx iris.Context) *openidentity.ExternalInfo { - v := ctx.Values().Get(ctxKeyExternalInfo) - ext, _ := v.(*openidentity.ExternalInfo) +func GetExternalUser(ctx iris.Context) *openidentity.ExternalUser { + v := ctx.Values().Get(ctxKeyExternalUser) + ext, _ := v.(*openidentity.ExternalUser) return ext } diff --git a/internal/pkg/openidentity/openidentity.go b/internal/pkg/openidentity/openidentity.go index 085849f..460fcc1 100644 --- a/internal/pkg/openidentity/openidentity.go +++ b/internal/pkg/openidentity/openidentity.go @@ -1,4 +1,3 @@ -// Package openidentity 解析开放 IM 场景下的外部访客身份(HTTP Header / Query),与 JSON 请求体 DTO 解耦。 package openidentity import ( @@ -14,8 +13,8 @@ import ( "github.com/mlogclub/simple/web/params" ) -// ExternalInfo 外部访客身份(IM 客户),与站内 AuthPrincipal 区分。 -type ExternalInfo struct { +// ExternalUser 外部访客身份(IM 客户),与站内 AuthPrincipal 区分。 +type ExternalUser struct { ExternalSource enums.ExternalSource `json:"externalSource"` ExternalID string `json:"externalId"` ExternalName string `json:"externalName"` @@ -27,37 +26,19 @@ type UserTokenClaims struct { jwt.RegisteredClaims } -func GetExternalInfo(ctx iris.Context, secret string) (*ExternalInfo, error) { +func GetExternalUser(ctx iris.Context, secret string) (*ExternalUser, error) { if userToken := getUserToken(ctx); strs.IsNotBlank(userToken) { claims, err := verifyUserToken(userToken, secret) if err != nil { return nil, err } - return &ExternalInfo{ + return &ExternalUser{ ExternalSource: enums.ExternalSourceUser, ExternalID: claims.UserID, ExternalName: claims.Name, }, nil } - externalSource, err := getExternalSource(ctx) - if err != nil { - return nil, err - } - if !enums.IsAllowedOpenImExternalSource(externalSource) { - return nil, errorsx.InvalidParam("不支持的外部来源") - } - if externalSource == enums.ExternalSourceUser { - return nil, errorsx.Unauthorized("用户身份不能为空") - } - externalID, err := getExternalID(ctx) - if err != nil { - return nil, err - } - return &ExternalInfo{ - ExternalSource: externalSource, - ExternalID: externalID, - ExternalName: getExternalName(ctx), - }, nil + return getGuestUser(ctx) } func verifyUserToken(userToken, secret string) (*UserTokenClaims, error) { @@ -113,26 +94,24 @@ func getUserToken(ctx iris.Context) string { return strings.TrimSpace(userToken) } -func getExternalSource(ctx iris.Context) (enums.ExternalSource, error) { - externalSource := ctx.GetHeader("X-External-Source") - if strs.IsBlank(externalSource) { - externalSource, _ = params.Get(ctx, "externalSource") +func getGuestUser(ctx iris.Context) (*ExternalUser, error) { + externalID := getExternalID(ctx) + if strs.IsBlank(externalID) { + return nil, errorsx.Unauthorized("用户标识不能为空") } - if strs.IsBlank(externalSource) { - return "", errorsx.Unauthorized("用户来源不能为空") - } - return enums.ExternalSource(strings.TrimSpace(externalSource)), nil + return &ExternalUser{ + ExternalSource: enums.ExternalSourceGuest, + ExternalID: externalID, + ExternalName: getExternalName(ctx), + }, nil } -func getExternalID(ctx iris.Context) (string, error) { +func getExternalID(ctx iris.Context) string { externalID := ctx.GetHeader("X-External-Id") if strs.IsBlank(externalID) { externalID, _ = params.Get(ctx, "externalId") } - if strs.IsBlank(externalID) { - return "", errorsx.Unauthorized("用户标识不能为空") - } - return strings.TrimSpace(externalID), nil + return externalID } func getExternalName(ctx iris.Context) string { @@ -140,11 +119,12 @@ func getExternalName(ctx iris.Context) string { if strs.IsBlank(externalName) { externalName, _ = params.Get(ctx, "externalName") } - return decodeExternalDisplayName(externalName) + if strs.IsNotBlank(externalName) { + externalName, _ = url.QueryUnescape(externalName) + } + return externalName } -// decodeExternalDisplayName 将客户端对 X-External-Name / externalName 做的 encodeURIComponent 还原为 UTF-8。 -// 无百分号编码时 QueryUnescape 原样返回,解码失败则保留原串(兼容异常或旧客户端明文)。 func decodeExternalDisplayName(s string) string { s = strings.TrimSpace(s) if s == "" { diff --git a/internal/services/conversation_participant_service.go b/internal/services/conversation_participant_service.go index 36722bd..ee17e38 100644 --- a/internal/services/conversation_participant_service.go +++ b/internal/services/conversation_participant_service.go @@ -69,12 +69,12 @@ func (s *conversationParticipantService) Delete(id int64) { repositories.ConversationParticipantRepository.Delete(sqls.DB(), id) } -func (s *conversationParticipantService) CreateCustomerParticipant(ctx *sqls.TxContext, conversationID int64, externalInfo openidentity.ExternalInfo) error { +func (s *conversationParticipantService) CreateCustomerParticipant(ctx *sqls.TxContext, conversationID int64, externalUser openidentity.ExternalUser) error { return repositories.ConversationParticipantRepository.Create(ctx.Tx, &models.ConversationParticipant{ ConversationID: conversationID, ParticipantType: string(enums.IMParticipantTypeCustomer), ParticipantID: 0, - ExternalParticipantID: externalInfo.ExternalID, + ExternalParticipantID: externalUser.ExternalID, JoinedAt: new(time.Now()), Status: enums.StatusOk, AuditFields: utils.BuildAuditFields(nil), diff --git a/internal/services/conversation_read_state_service.go b/internal/services/conversation_read_state_service.go index dfb9f6d..8634c35 100644 --- a/internal/services/conversation_read_state_service.go +++ b/internal/services/conversation_read_state_service.go @@ -47,7 +47,7 @@ func agentReaderCursor(operator *dto.AuthPrincipal) (readerCursor, error) { }, nil } -func customerReaderCursor(external *openidentity.ExternalInfo) (readerCursor, error) { +func customerReaderCursor(external *openidentity.ExternalUser) (readerCursor, error) { if external == nil || strings.TrimSpace(external.ExternalID) == "" { return readerCursor{}, errorsx.Unauthorized("外部用户标识不能为空") } @@ -126,7 +126,7 @@ func (s *conversationReadStateService) GetByAgentReader(conversationID int64, op } // GetByCustomerReader 查询 IM 客户侧已读游标(按 ExternalID)。 -func (s *conversationReadStateService) GetByCustomerReader(conversationID int64, external *openidentity.ExternalInfo) *models.ConversationReadState { +func (s *conversationReadStateService) GetByCustomerReader(conversationID int64, external *openidentity.ExternalUser) *models.ConversationReadState { if external == nil || strings.TrimSpace(external.ExternalID) == "" { return nil } @@ -181,7 +181,7 @@ func (s *conversationReadStateService) MarkAgentRead(ctx *sqls.TxContext, conver } // MarkCustomerRead 在事务内更新/创建 IM 客户已读游标。 -func (s *conversationReadStateService) MarkCustomerRead(ctx *sqls.TxContext, conversation *models.Conversation, external *openidentity.ExternalInfo, message *models.Message, now time.Time) (*models.ConversationReadState, error) { +func (s *conversationReadStateService) MarkCustomerRead(ctx *sqls.TxContext, conversation *models.Conversation, external *openidentity.ExternalUser, message *models.Message, now time.Time) (*models.ConversationReadState, error) { c, err := customerReaderCursor(external) if err != nil { return nil, err diff --git a/internal/services/conversation_service.go b/internal/services/conversation_service.go index 54d5b82..995b5a3 100644 --- a/internal/services/conversation_service.go +++ b/internal/services/conversation_service.go @@ -100,7 +100,7 @@ func (s *conversationService) getLatestNotFinishedByCustomerID(db *gorm.DB, cust return repositories.ConversationRepository.FindOne(db, cnd) } -func (s *conversationService) Create(externalInfo openidentity.ExternalInfo, channelID, aiAgentID int64) (*models.Conversation, error) { +func (s *conversationService) Create(externalUser openidentity.ExternalUser, channelID, aiAgentID int64) (*models.Conversation, error) { aiAgent := AIAgentService.Get(aiAgentID) if aiAgent == nil || aiAgent.Status != enums.StatusOk { return nil, errorsx.InvalidParam("AI Agent not found") @@ -109,7 +109,7 @@ func (s *conversationService) Create(externalInfo openidentity.ExternalInfo, cha var conversation *models.Conversation created := false if err := sqls.WithTransaction(func(ctx *sqls.TxContext) error { - customerID, err := CustomerService.EnsureExternalCustomer(ctx.Tx, externalInfo) + customerID, err := CustomerService.EnsureExternalCustomer(ctx.Tx, externalUser) if err != nil { return err } @@ -146,7 +146,7 @@ func (s *conversationService) Create(externalInfo openidentity.ExternalInfo, cha if err := ctx.Tx.Create(conversation).Error; err != nil { return err } - if err := ConversationParticipantService.CreateCustomerParticipant(ctx, conversation.ID, externalInfo); err != nil { + if err := ConversationParticipantService.CreateCustomerParticipant(ctx, conversation.ID, externalUser); err != nil { return err } return ConversationEventLogService.CreateEvent(ctx, conversation.ID, enums.IMEventTypeCreate, enums.IMSenderTypeCustomer, 0, "用户创建会话", "") @@ -378,12 +378,12 @@ func (s *conversationService) CloseConversation(conversationID int64, closeReaso return s.closeConversation(conversationID, enums.IMSenderTypeAgent, closeReason, operator) } -func (s *conversationService) CloseCustomerConversation(conversationID int64, externalInfo openidentity.ExternalInfo) error { +func (s *conversationService) CloseCustomerConversation(conversationID int64, externalUser openidentity.ExternalUser) error { conversation := s.Get(conversationID) if conversation == nil { return errorsx.InvalidParam("会话不存在") } - if !s.IsCustomerConversationOwner(conversation, externalInfo) { + if !s.IsCustomerConversationOwner(conversation, externalUser) { return errorsx.Forbidden("无权访问该会话") } return s.closeConversation(conversationID, enums.IMSenderTypeCustomer, "", nil) @@ -477,7 +477,7 @@ func (s *conversationService) MarkAgentConversationReadToMessage(conversationID, } // MarkCustomerConversationReadToMessage IM 客户将会话已读推进到指定消息(需为会话归属外部身份)。 -func (s *conversationService) MarkCustomerConversationReadToMessage(conversationID, messageID int64, external *openidentity.ExternalInfo) error { +func (s *conversationService) MarkCustomerConversationReadToMessage(conversationID, messageID int64, external *openidentity.ExternalUser) error { if external == nil || strings.TrimSpace(external.ExternalID) == "" { return errorsx.Unauthorized("外部用户标识不能为空") } @@ -500,7 +500,7 @@ func (s *conversationService) MarkCustomerConversationReadToMessage(conversation return nil } -func displayExternalName(ext *openidentity.ExternalInfo) string { +func displayExternalName(ext *openidentity.ExternalUser) string { if ext == nil { return "" } @@ -541,7 +541,7 @@ func (a agentConversationReadActor) conversationUpdateAudit() (int64, string) { } type customerConversationReadActor struct { - external *openidentity.ExternalInfo + external *openidentity.ExternalUser } func (a customerConversationReadActor) isAgentSide() bool { return false } @@ -651,15 +651,15 @@ func (s *conversationService) countUnreadByState(ctx *sqls.TxContext, conversati return int(count), err } -func (s *conversationService) IsCustomerConversationOwner(conversation *models.Conversation, externalInfo openidentity.ExternalInfo) bool { +func (s *conversationService) IsCustomerConversationOwner(conversation *models.Conversation, externalUser openidentity.ExternalUser) bool { if conversation == nil { return false } - extID := strings.TrimSpace(externalInfo.ExternalID) - if extID == "" || strings.TrimSpace(string(externalInfo.ExternalSource)) == "" || conversation.CustomerID <= 0 { + extID := strings.TrimSpace(externalUser.ExternalID) + if extID == "" || strings.TrimSpace(string(externalUser.ExternalSource)) == "" || conversation.CustomerID <= 0 { return false } - identity := repositories.CustomerIdentityRepository.GetBy(sqls.DB(), externalInfo.ExternalSource, extID) + identity := repositories.CustomerIdentityRepository.GetBy(sqls.DB(), externalUser.ExternalSource, extID) if identity == nil { return false } diff --git a/internal/services/customer_service.go b/internal/services/customer_service.go index 9e4ec46..580a2b2 100644 --- a/internal/services/customer_service.go +++ b/internal/services/customer_service.go @@ -113,9 +113,9 @@ func (s *customerService) CountByCompanyIDs(companyIDs []int64) map[int64]int64 return repositories.CustomerRepository.CountByCompanyIDs(sqls.DB(), companyIDs, int(enums.StatusDeleted)) } -func (s *customerService) EnsureExternalCustomer(db *gorm.DB, externalInfo openidentity.ExternalInfo) (int64, error) { - externalSource := externalInfo.ExternalSource - externalID := strings.TrimSpace(externalInfo.ExternalID) +func (s *customerService) EnsureExternalCustomer(db *gorm.DB, externalUser openidentity.ExternalUser) (int64, error) { + externalSource := externalUser.ExternalSource + externalID := strings.TrimSpace(externalUser.ExternalID) if strings.TrimSpace(string(externalSource)) == "" || externalID == "" { return 0, errorsx.Unauthorized("外部用户标识不能为空") } @@ -129,7 +129,7 @@ func (s *customerService) EnsureExternalCustomer(db *gorm.DB, externalInfo openi } customer := &models.Customer{ - Name: buildExternalCustomerName(externalInfo), + Name: buildExternalCustomerName(externalUser), LastActiveAt: &now, Status: enums.StatusOk, AuditFields: utils.BuildAuditFields(nil), @@ -149,11 +149,11 @@ func (s *customerService) EnsureExternalCustomer(db *gorm.DB, externalInfo openi return customer.ID, nil } -func buildExternalCustomerName(externalInfo openidentity.ExternalInfo) string { - if strs.IsNotBlank(externalInfo.ExternalName) { - return externalInfo.ExternalName +func buildExternalCustomerName(externalUser openidentity.ExternalUser) string { + if strs.IsNotBlank(externalUser.ExternalName) { + return externalUser.ExternalName } - return "访客" + hashUUID(externalInfo.ExternalID) + return "访客" + hashUUID(externalUser.ExternalID) } func hashUUID(uuid string) string { diff --git a/internal/services/message_service.go b/internal/services/message_service.go index c31fe94..70d500d 100644 --- a/internal/services/message_service.go +++ b/internal/services/message_service.go @@ -127,7 +127,7 @@ func (s *messageService) GetConversationReadTarget(conversationID, messageID int return s.FindOne(sqls.NewCnd().Eq("conversation_id", conversationID).Desc("seq_no").Desc("id")), nil } -func (s *messageService) SendMessage(conversationID int64, senderType enums.IMSenderType, reqSenderID int64, clientMsgID string, messageType enums.IMMessageType, content, payload string, operator *dto.AuthPrincipal, external *openidentity.ExternalInfo) (*models.Message, error) { +func (s *messageService) SendMessage(conversationID int64, senderType enums.IMSenderType, reqSenderID int64, clientMsgID string, messageType enums.IMMessageType, content, payload string, operator *dto.AuthPrincipal, external *openidentity.ExternalUser) (*models.Message, error) { switch senderType { case enums.IMSenderTypeAgent: return s.sendMessage(conversationID, enums.IMSenderTypeAgent, reqSenderID, clientMsgID, messageType, content, payload, operator, nil) @@ -243,13 +243,13 @@ func (s *messageService) SendAIMessage(conversationID int64, aiAgentID int64, cl return s.sendMessage(conversationID, enums.IMSenderTypeAI, aiAgentID, clientMsgID, messageType, content, payload, operator, nil) } -func (s *messageService) SendCustomerMessage(conversationID int64, clientMsgID string, messageType enums.IMMessageType, content, payload string, external openidentity.ExternalInfo) (*models.Message, error) { +func (s *messageService) SendCustomerMessage(conversationID int64, clientMsgID string, messageType enums.IMMessageType, content, payload string, external openidentity.ExternalUser) (*models.Message, error) { ext := external return s.sendMessage(conversationID, enums.IMSenderTypeCustomer, 0, clientMsgID, messageType, content, payload, nil, &ext) } func (s *messageService) sendMessage(conversationID int64, senderType enums.IMSenderType, reqSenderID int64, clientMsgID string, - messageType enums.IMMessageType, content, payload string, operator *dto.AuthPrincipal, external *openidentity.ExternalInfo) (*models.Message, error) { + messageType enums.IMMessageType, content, payload string, operator *dto.AuthPrincipal, external *openidentity.ExternalUser) (*models.Message, error) { if senderType == enums.IMSenderTypeCustomer { if external == nil || strings.TrimSpace(external.ExternalID) == "" { @@ -493,7 +493,7 @@ func (s *messageService) normalizeMessageContent(conversationID int64, messageTy } } -func (s *messageService) ValidateConversationSender(conversationID int64, senderType enums.IMSenderType, operator *dto.AuthPrincipal, external *openidentity.ExternalInfo) (*models.Conversation, error) { +func (s *messageService) ValidateConversationSender(conversationID int64, senderType enums.IMSenderType, operator *dto.AuthPrincipal, external *openidentity.ExternalUser) (*models.Conversation, error) { conversation := ConversationService.Get(conversationID) if conversation == nil { return nil, errorsx.InvalidParam("会话不存在") diff --git a/internal/services/ws_realtime_types.go b/internal/services/ws_realtime_types.go index 9a74d5f..23ee588 100644 --- a/internal/services/ws_realtime_types.go +++ b/internal/services/ws_realtime_types.go @@ -229,7 +229,7 @@ type ClientSession struct { ID string Conn *websocket.Conn Principal *dto.AuthPrincipal - External *openidentity.ExternalInfo + External *openidentity.ExternalUser Role string TerminalType string Topics map[string]struct{} diff --git a/internal/services/ws_service.go b/internal/services/ws_service.go index 8b02dda..529d2cb 100644 --- a/internal/services/ws_service.go +++ b/internal/services/ws_service.go @@ -63,10 +63,10 @@ func (s *wsService) HandleOpenWS(ctx iris.Context) { var ( principal = AuthService.GetAuthPrincipal(ctx) - external *openidentity.ExternalInfo + external *openidentity.ExternalUser ) if principal == nil { - ext, err := openidentity.GetExternalInfoWithUserTokenSecret(ctx, ChannelService.GetUserTokenSecret(channel)) + ext, err := openidentity.GetExternalUser(ctx, ChannelService.GetUserTokenSecret(channel)) if err != nil { _ = ctx.StopWithJSON(iris.StatusUnauthorized, web.JsonError(err)) return @@ -80,7 +80,7 @@ func (s *wsService) HandleOpenWS(ctx iris.Context) { } } -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.ExternalUser, role string) error { conn, err := s.upgrader.Upgrade(ctx.ResponseWriter().Naive(), ctx.Request(), nil) if err != nil { return err diff --git a/internal/services/wxwork_kf_inbound_service.go b/internal/services/wxwork_kf_inbound_service.go index 9e36d72..d6f473e 100644 --- a/internal/services/wxwork_kf_inbound_service.go +++ b/internal/services/wxwork_kf_inbound_service.go @@ -119,7 +119,7 @@ func (s *wxWorkKFInboundService) handleTextMessage(item syncmsg.Message) error { enums.IMMessageTypeText, strings.TrimSpace(payload.Text.Content), "", - s.buildExternalInfo(payload.ExternalUserID), + s.buildExternalUser(payload.ExternalUserID), ) if err != nil { return err @@ -149,7 +149,7 @@ func (s *wxWorkKFInboundService) handleImageMessage(item syncmsg.Message) error enums.IMMessageTypeImage, content, canonicalPayload, - s.buildExternalInfo(payload.ExternalUserID), + s.buildExternalUser(payload.ExternalUserID), ) if err != nil { return err @@ -179,7 +179,7 @@ func (s *wxWorkKFInboundService) handleFileMessage(item syncmsg.Message) error { enums.IMMessageTypeAttachment, content, canonicalPayload, - s.buildExternalInfo(payload.ExternalUserID), + s.buildExternalUser(payload.ExternalUserID), ) if err != nil { return err @@ -203,7 +203,7 @@ func (s *wxWorkKFInboundService) handleUnsupportedMessage(item syncmsg.Message) enums.IMMessageTypeText, content, string(item.OriginData), - s.buildExternalInfo(base.ExternalUserID), + s.buildExternalUser(base.ExternalUserID), ) if err != nil { return err @@ -376,7 +376,7 @@ func (s *wxWorkKFInboundService) ensureConversation(base syncmsg.BaseMessage, pr return nil, err } - external := s.buildExternalInfo(externalID) + external := s.buildExternalUser(externalID) conversation, err := ConversationService.Create(external, channel.ID, channel.AIAgentID) if err != nil { return nil, err @@ -558,8 +558,8 @@ func (s *wxWorkKFInboundService) getChannelByOpenKfID(openKfID string) (*models. return channel, nil } -func (s *wxWorkKFInboundService) buildExternalInfo(externalUserID string) openidentity.ExternalInfo { - return openidentity.ExternalInfo{ +func (s *wxWorkKFInboundService) buildExternalUser(externalUserID string) openidentity.ExternalUser { + return openidentity.ExternalUser{ ExternalSource: enums.ExternalSourceWxWorkKF, ExternalID: strings.TrimSpace(externalUserID), ExternalName: strings.TrimSpace(externalUserID),