From 07326e3af8aeffc1c6965014a8137e734428daf9 Mon Sep 17 00:00:00 2001 From: jjxu <428192774@qq.com> Date: Thu, 21 Aug 2025 14:16:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=9B=9E=E5=A4=8D=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/router/router.go | 2 + pkg/service/asChat/chatCache/cache.go | 36 ++++++++++++++ pkg/service/asChat/dto/dto.go | 5 ++ pkg/service/asChat/handler.go | 33 +++++++++++++ pkg/service/asChat/robot/robot.go | 70 +++++++++++++++------------ 5 files changed, 114 insertions(+), 32 deletions(-) diff --git a/pkg/router/router.go b/pkg/router/router.go index 9602cfe..e1a21e5 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -135,6 +135,8 @@ func NewRouter() *gin.Engine { v1.POST("aschat/autoReplyRuler/update", asChat.Handler.UpdateChatAutoReplyRuler) v1.POST("aschat/autoReplyRuler/detail", asChat.Handler.GetChatAutoReplyRulerDetail) v1.POST("aschat/autoReplyRuler/query", asChat.Handler.GetChatAutoReplyRulerList) + v1.POST("aschat/autoReplyRuler/userSwitch/get", asChat.ChatHandlerIns.UserSwitchAutoReplyStatus) //获取自动回复开关状态 + v1.POST("aschat/autoReplyRuler/userSwitch/set", asChat.ChatHandlerIns.SetSwitchAutoReplyStatus) //设置自动回复开关状态 v1.POST("/test/user/log/erp", asChat.Handler.ErpLoginDemo) v1.POST("/test/user/log/fiee", asChat.Handler.FieeLoginDemo) diff --git a/pkg/service/asChat/chatCache/cache.go b/pkg/service/asChat/chatCache/cache.go index 74c30fb..981540d 100644 --- a/pkg/service/asChat/chatCache/cache.go +++ b/pkg/service/asChat/chatCache/cache.go @@ -17,6 +17,7 @@ import ( "github.com/goccy/go-json" "go.uber.org/zap" "log" + "strconv" "strings" "sync" "time" @@ -25,6 +26,7 @@ import ( const CacheChatRecordKey = "fiee:chatRecord" const CacheSessionKey = "fiee:chatSession" const CacheNewMsgStatKey = "fiee:newMsgStat" +const CacheAutoReplySwitchKey = "fiee:AutoReplySwitch" var chatCacheLocker sync.RWMutex @@ -248,3 +250,37 @@ func (cr ChatCache) coverOwnerNewMessageStat(ctx context.Context, ownerId int64, err = cache.RedisClient.Set(cr.GetNewMsgStatCacheKey(ownerId), value, 0).Err() return } + +// -----------------------------------用户自动回复开关 +// erp获取最新的消息统计 +func (cr ChatCache) GetCacheAutoReplySwitchKey(userId int64) string { + return fmt.Sprintf("%s:%d", CacheAutoReplySwitchKey, userId) +} + +func (cr ChatCache) SetAutoReplySwitch(ctx context.Context, ownerId int64, enableAutoReply bool) { + //chatCacheLocker.RLock() + //defer chatCacheLocker.RUnlock() + err := cache.RedisClient.Set(cr.GetCacheAutoReplySwitchKey(ownerId), enableAutoReply, 0).Err() + if err != nil { + log.Print("保存用户会话失败", zap.Error(err)) + } + return +} + +func (cr ChatCache) GetAutoReplySwitch(ctx context.Context, ownerId int64) (enableAutoReply bool) { + //chatCacheLocker.RLock() + //defer chatCacheLocker.RUnlock() + val, err := cache.RedisClient.Get(cr.GetCacheAutoReplySwitchKey(ownerId)).Bytes() + if err != nil { + log.Print("获取自动回复开关查询失败", zap.Error(err), zap.Int64("ownerId", ownerId)) + return true + } + // 解析缓存值为布尔值 + boolVal, err := strconv.ParseBool(string(val)) + if err != nil { + log.Print("解析自动回复开关值失败", zap.Error(err), zap.String("value", string(val)), zap.Int64("ownerId", ownerId)) + return true // 解析失败时也返回默认值true + } + + return boolVal +} diff --git a/pkg/service/asChat/dto/dto.go b/pkg/service/asChat/dto/dto.go index 3f7daf3..4b63b35 100644 --- a/pkg/service/asChat/dto/dto.go +++ b/pkg/service/asChat/dto/dto.go @@ -35,6 +35,7 @@ type NewMessageRequest struct { SessionId string `json:"sessionId"` Message AtUserId int64 `json:"atUserId"` //指定发送给sessionId中的某一个用户 + //EnableAutoReply bool `json:"-"` } // 服务端接收到消息后,使用websocket发送给userId关联的客户端,通知客户端有新消息,然后调用接口获取消息 @@ -218,3 +219,7 @@ type UserDetailResp struct { Phone string `json:"phone"` GroupPhoto string `json:"groupPhoto"` } + +type UserSwitchAutoReplyReq struct { + EnableAutoReply bool `json:"enableAutoReply"` +} diff --git a/pkg/service/asChat/handler.go b/pkg/service/asChat/handler.go index 6f39634..497d49b 100644 --- a/pkg/service/asChat/handler.go +++ b/pkg/service/asChat/handler.go @@ -612,3 +612,36 @@ func (cr ChatHandler) UserDetail(c *gin.Context) { service.Success(c, detail) } + +func (a *ChatHandler) UserSwitchAutoReplyStatus(c *gin.Context) { + chatUser, code := jwt.ParseToChatUser(c) + if code != 0 { + service.ErrWithCode(c, code) + return + } + var req dto.UserSwitchAutoReplyReq + if err := c.ShouldBindJSON(&req); err != nil { + service.Error(c, err) + return + } + enable := a.cache.GetAutoReplySwitch(c, chatUser.ID) + var resp = map[string]any{ + "enableAutoReply": enable, + } + service.Success(c, resp) +} + +func (a *ChatHandler) SetSwitchAutoReplyStatus(c *gin.Context) { + chatUser, code := jwt.ParseToChatUser(c) + if code != 0 { + service.ErrWithCode(c, code) + return + } + var req dto.UserSwitchAutoReplyReq + if err := c.ShouldBindJSON(&req); err != nil { + service.Error(c, err) + return + } + a.cache.SetAutoReplySwitch(c, chatUser.ID, req.EnableAutoReply) + service.Success(c) +} diff --git a/pkg/service/asChat/robot/robot.go b/pkg/service/asChat/robot/robot.go index d27785b..5cf82bc 100644 --- a/pkg/service/asChat/robot/robot.go +++ b/pkg/service/asChat/robot/robot.go @@ -165,29 +165,17 @@ func (r *Robot) Run() { fmt.Printf("robot listen event:%#v\n", event) r.mu.Lock() //加入聊天室规则 - hasHit := false - for _, rule := range r.joinSessionRules { - hit := rule.Hit(event, r.Info) - fmt.Printf("规则【%s】校验结果:%v\n", rule.GetTitle(), hit) - if hit { - hasHit = true - if rule.RunTime().IsZero() { - err := rule.Run(r.cache) - if err != nil { - log.Printf("robot 执行任务失败:%v\n", err) - } - } else { - r.RegisterDelayTask(rule) - } - } + enableAutoReply := false + if event.Client != nil { + enableAutoReply = new(chatCache.ChatCache).GetAutoReplySwitch(context.Background(), event.Client.UserId) } - if !hasHit { - for _, rule := range r.keywordsRules { + if enableAutoReply { + hasHit := false + for _, rule := range r.joinSessionRules { hit := rule.Hit(event, r.Info) fmt.Printf("规则【%s】校验结果:%v\n", rule.GetTitle(), hit) if hit { hasHit = true - fmt.Println("命中规则:", rule.GetTitle()) if rule.RunTime().IsZero() { err := rule.Run(r.cache) if err != nil { @@ -198,21 +186,39 @@ func (r *Robot) Run() { } } } - } - if !hasHit { - for _, rule := range r.noReplyAfterRules { - hit := rule.Hit(event, r.Info) - fmt.Printf("规则【%s】校验结果:%v\n", rule.GetTitle(), hit) - if hit { - hasHit = true - fmt.Println("命中规则:", rule.GetTitle()) - if rule.RunTime().IsZero() { - err := rule.Run(r.cache) - if err != nil { - log.Printf("robot 执行任务失败:%v\n", err) + if !hasHit { + for _, rule := range r.keywordsRules { + hit := rule.Hit(event, r.Info) + fmt.Printf("规则【%s】校验结果:%v\n", rule.GetTitle(), hit) + if hit { + hasHit = true + fmt.Println("命中规则:", rule.GetTitle()) + if rule.RunTime().IsZero() { + err := rule.Run(r.cache) + if err != nil { + log.Printf("robot 执行任务失败:%v\n", err) + } + } else { + r.RegisterDelayTask(rule) + } + } + } + } + if !hasHit { + for _, rule := range r.noReplyAfterRules { + hit := rule.Hit(event, r.Info) + fmt.Printf("规则【%s】校验结果:%v\n", rule.GetTitle(), hit) + if hit { + hasHit = true + fmt.Println("命中规则:", rule.GetTitle()) + if rule.RunTime().IsZero() { + err := rule.Run(r.cache) + if err != nil { + log.Printf("robot 执行任务失败:%v\n", err) + } + } else { + r.RegisterDelayTask(rule) } - } else { - r.RegisterDelayTask(rule) } } }