feat: 增加自动回复开关

This commit is contained in:
徐俊杰 2025-08-21 14:16:51 +08:00
parent c135849195
commit 07326e3af8
5 changed files with 114 additions and 32 deletions

View File

@ -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)

View File

@ -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
}

View File

@ -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"`
}

View File

@ -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)
}

View File

@ -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)
}
}
}