Compare commits

..

No commits in common. "1d62e9591078fead0d57ead4b4322a899b06877a" and "f9921d2ba0d25a2f67b0d57b6079bb744f307e20" have entirely different histories.

15 changed files with 122 additions and 271 deletions

View File

@ -45,7 +45,7 @@ const (
MsgType_ImageMsgType MsgType = 2 //图片 MsgType_ImageMsgType MsgType = 2 //图片
MsgType_AudioMsgType MsgType = 3 //音频 MsgType_AudioMsgType MsgType = 3 //音频
MsgType_VideoMsgType MsgType = 4 //视频 MsgType_VideoMsgType MsgType = 4 //视频
MsgType_CardType MsgType = 5 //卡片 MsgType_FileType MsgType = 5 //文件
) )
// Enum value maps for MsgType. // Enum value maps for MsgType.
@ -56,7 +56,7 @@ var (
2: "ImageMsgType", 2: "ImageMsgType",
3: "AudioMsgType", 3: "AudioMsgType",
4: "VideoMsgType", 4: "VideoMsgType",
5: "CardType", 5: "FileType",
} }
MsgType_value = map[string]int32{ MsgType_value = map[string]int32{
"UnknownMsgType": 0, "UnknownMsgType": 0,
@ -64,7 +64,7 @@ var (
"ImageMsgType": 2, "ImageMsgType": 2,
"AudioMsgType": 3, "AudioMsgType": 3,
"VideoMsgType": 4, "VideoMsgType": 4,
"CardType": 5, "FileType": 5,
} }
) )
@ -11421,7 +11421,7 @@ var file_accountFiee_proto_rawDesc = []byte{
0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x73, 0x67, 0x54, 0x79, 0x70,
0x65, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x4d, 0x73, 0x67, 0x54, 0x65, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x4d, 0x73, 0x67, 0x54,
0x79, 0x70, 0x65, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x73, 0x79, 0x70, 0x65, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x73,
0x67, 0x54, 0x79, 0x70, 0x65, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x61, 0x72, 0x64, 0x54, 0x67, 0x54, 0x79, 0x70, 0x65, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x54,
0x79, 0x70, 0x65, 0x10, 0x05, 0x32, 0xeb, 0x2b, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x79, 0x70, 0x65, 0x10, 0x05, 0x32, 0xeb, 0x2b, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x46, 0x69, 0x65, 0x65, 0x12, 0x3c, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x19, 0x74, 0x46, 0x69, 0x65, 0x65, 0x12, 0x3c, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x19,
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x69, 0x65, 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x69, 0x65, 0x65, 0x2e, 0x4c, 0x6f, 0x67,

View File

@ -869,7 +869,7 @@ enum MsgType{
ImageMsgType = 2 ;// ImageMsgType = 2 ;//
AudioMsgType = 3 ;// AudioMsgType = 3 ;//
VideoMsgType = 4 ;// VideoMsgType = 4 ;//
CardType = 5 ;// FileType = 5 ;//
} }
message ChatRecordData{ message ChatRecordData{
int64 ID=1; int64 ID=1;

View File

@ -1,5 +1,5 @@
[system] [system]
Domain = "app" Domain = "fiee"
AppMode = "debug" AppMode = "debug"
HttpPort = ":8085" HttpPort = ":8085"
Host = "http://127.0.0.1:8085" Host = "http://127.0.0.1:8085"
@ -14,12 +14,12 @@ BosBaseDir = "fonchain-main"
BosHttp = "https://" BosHttp = "https://"
BosDomain = "cdns.fontree.cn" BosDomain = "cdns.fontree.cn"
[oss] [oss]
AccessKeyId = "LTAI5tHfjSmWXHqfWgaL7Uo5" AccessKeyId = "LTAI5tLz1fSK53FQAEC9uNSb"
AccessKeySecret = "kOPctFZ3DHsbdSSym1fLyDK39hkzPI" AccessKeySecret = "oGB9chrQzQzITXR2IGv37Ji5WxZh4j"
Endpoint = "oss-cn-hangzhou-internal.aliyuncs.com" Endpoint = "oss-cn-hangzhou.aliyuncs.com"
BucketName = "erp-k8s-store" BucketName = "fontree-test"
BaseDir = "fiee" BaseDir = "fonchain-main"
CdnHost = "https://e-cdn.fontree.cn" CdnHost = "https://cdn-test.szjixun.cn"
[redis] [redis]
RedisDB = "2" RedisDB = "2"
RedisAddr = "127.0.0.1:6379" RedisAddr = "127.0.0.1:6379"

View File

@ -27,7 +27,7 @@ Password = "Gy.123456"
[oss] [oss]
AccessKeyId = "LTAI5tHfjSmWXHqfWgaL7Uo5" AccessKeyId = "LTAI5tHfjSmWXHqfWgaL7Uo5"
AccessKeySecret = "kOPctFZ3DHsbdSSym1fLyDK39hkzPI" AccessKeySecret = "kOPctFZ3DHsbdSSym1fLyDK39hkzPI"
Endpoint = "oss-cn-hangzhou-internal.aliyuncs.com" Endpoint = "oss-cn-hangzhou.aliyuncs.com"
BucketName = "erp-k8s-store" BucketName = "erp-k8s-store"
BaseDir = "fiee" BaseDir = "fiee"
CdnHost = "https://e-cdn.fontree.cn" CdnHost = "https://e-cdn.fontree.cn"

View File

@ -12,13 +12,7 @@ BucketName = "dci-file-new"
BosUrl = ".bj.bcebos.com" BosUrl = ".bj.bcebos.com"
BosBaseDir = "fonchain-main" BosBaseDir = "fonchain-main"
BosHttp = "https://" BosHttp = "https://"
[oss]
AccessKeyId = "LTAI5tHfjSmWXHqfWgaL7Uo5"
AccessKeySecret = "kOPctFZ3DHsbdSSym1fLyDK39hkzPI"
Endpoint = "oss-cn-hangzhou-internal.aliyuncs.com"
BucketName = "erp-k8s-store"
BaseDir = "fiee"
CdnHost = "https://e-cdn.fontree.cn"
[redis] [redis]
RedisDB = "2" RedisDB = "2"
RedisAddr = "redis:6379" RedisAddr = "redis:6379"

View File

@ -136,11 +136,11 @@ func (o *ChatRoom) Run() {
} }
} }
} }
o.clientsRwLocker.Unlock()
//再把自己的客户端加入会话 //再把自己的客户端加入会话
o.Session[newClient.SessionId] = append(o.Session[newClient.SessionId], newClient) o.Session[newClient.SessionId] = append(o.Session[newClient.SessionId], newClient)
} }
o.pushEvent(EventUserJoin, EventProgressAfter, nil, newClient) o.pushEvent(EventUserJoin, EventProgressAfter, nil, newClient)
o.clientsRwLocker.Unlock()
//注销事件 //注销事件
case client := <-o.UnRegister: case client := <-o.UnRegister:
o.pushEvent(EventUserLeave, EventProgressBefore, nil, client) o.pushEvent(EventUserLeave, EventProgressBefore, nil, client)
@ -190,10 +190,10 @@ func (o *ChatRoom) Register(c *Client) (sessionId string) {
// sessionId 会话id // sessionId 会话id
// msgType 消息类型 // msgType 消息类型
// message: 消息内容 // message: 消息内容
func (o *ChatRoom) SendSessionMessage(sender *accountFiee.ChatUserData, sessionId string, msgType WsType, message any) (userIdInSession []int64, err error) { func (o *ChatRoom) SendSessionMessage(chatUser *accountFiee.ChatUserData, sessionId string, msgType WsType, message any) (userIdInSession []int64, err error) {
fmt.Println("ChatRoom.SendSessionMessage ------------------1") fmt.Println("ChatRoom.SendSessionMessage ------------------1")
//o.clientsRwLocker.Lock() o.clientsRwLocker.Lock()
//defer o.clientsRwLocker.Unlock() defer o.clientsRwLocker.Unlock()
var msg = WsSessionInfo{ var msg = WsSessionInfo{
Type: msgType, Type: msgType,
Content: message, Content: message,
@ -204,7 +204,7 @@ func (o *ChatRoom) SendSessionMessage(sender *accountFiee.ChatUserData, sessionI
err = fmt.Errorf("该会话不存在或已失效") err = fmt.Errorf("该会话不存在或已失效")
return return
} }
fmt.Println("ChatRoom.SendSessionMessage ------------------3") fmt.Println("ChatRoom.SendSessionMessage - 1")
usableClients := []*Client{} usableClients := []*Client{}
fmt.Printf("sessionId:[%s],客户端数量%d\n", sessionId, len(o.Session[sessionId])) fmt.Printf("sessionId:[%s],客户端数量%d\n", sessionId, len(o.Session[sessionId]))
for i, client := range o.Session[sessionId] { for i, client := range o.Session[sessionId] {
@ -212,13 +212,13 @@ func (o *ChatRoom) SendSessionMessage(sender *accountFiee.ChatUserData, sessionI
_, exist := o.clients[client.UserId][client.ClientId] _, exist := o.clients[client.UserId][client.ClientId]
if exist { if exist {
usableClients = append(usableClients, o.Session[sessionId][i]) usableClients = append(usableClients, o.Session[sessionId][i])
go o.pushEvent(EventChatMessage, EventProgressBefore, sender, o.Session[sessionId][i], message) o.pushEvent(EventChatMessage, EventProgressBefore, chatUser, o.Session[sessionId][i], message)
} }
} }
fmt.Printf("client:%+v\n", client) fmt.Printf("client:%+v\n", client)
if client != nil && (client.UserId != sender.ID || sender.Role == 3) { if client != nil && client.UserId != chatUser.ID {
client.Send <- msgBytes client.Send <- msgBytes
go o.pushEvent(EventChatMessage, EventProgressAfter, sender, o.Session[sessionId][i], message) o.pushEvent(EventChatMessage, EventProgressAfter, chatUser, o.Session[sessionId][i], message)
userIdInSession = append(userIdInSession, client.UserId) userIdInSession = append(userIdInSession, client.UserId)
} }
//client.Send <- msgBytes //client.Send <- msgBytes
@ -230,6 +230,8 @@ func (o *ChatRoom) SendSessionMessage(sender *accountFiee.ChatUserData, sessionI
} }
func (o *ChatRoom) GetUserIdInSession(sessionId string, withoutUserId ...int64) (userIds []int64) { func (o *ChatRoom) GetUserIdInSession(sessionId string, withoutUserId ...int64) (userIds []int64) {
fmt.Printf("sessionId:%s withoutUserId:%d\n", sessionId, withoutUserId) fmt.Printf("sessionId:%s withoutUserId:%d\n", sessionId, withoutUserId)
//o.clientsRwLocker.RLock()
//defer o.clientsRwLocker.RUnlock()
fmt.Println("GetUserIdInSession 1") fmt.Println("GetUserIdInSession 1")
if o.Session[sessionId] != nil { if o.Session[sessionId] != nil {
fmt.Printf("GetUserIdInSession 2,o.Session[sessionId]:%+v", o.Session[sessionId]) fmt.Printf("GetUserIdInSession 2,o.Session[sessionId]:%+v", o.Session[sessionId])
@ -343,8 +345,8 @@ func (o *ChatRoom) UnRegisterEventListener(listenerChan *EventListener) {
// pushEvent 推送聊天室事件 // pushEvent 推送聊天室事件
func (o *ChatRoom) pushEvent(eventType EventType, progress EventProgress, chatUser *accountFiee.ChatUserData, client *Client, data ...any) { func (o *ChatRoom) pushEvent(eventType EventType, progress EventProgress, chatUser *accountFiee.ChatUserData, client *Client, data ...any) {
//o.EventRwLocker.Lock() o.EventRwLocker.Lock()
//defer o.EventRwLocker.Unlock() defer o.EventRwLocker.Unlock()
for _, listener := range o.eventBus { for _, listener := range o.eventBus {
hit := false hit := false
for _, need := range listener.ListenEvents { for _, need := range listener.ListenEvents {
@ -356,20 +358,13 @@ func (o *ChatRoom) pushEvent(eventType EventType, progress EventProgress, chatUs
if hit == false { if hit == false {
continue continue
} }
msg := ""
if data != nil {
msg = fmt.Sprintf("%v", data[0])
}
listener.Chan <- ListenEventData{ listener.Chan <- ListenEventData{
ListenEvent: ListenEvent{ ListenEvent: ListenEvent{
EventType: eventType, EventType: eventType,
ProgressType: progress, ProgressType: progress,
}, },
ChatUser: chatUser,
Client: client, Client: client,
Msg: msg,
Data: data, Data: data,
} }
fmt.Printf("chatRooom 推送事件给%s eventType:%v progress:%v", listener.Name, eventType, progress)
} }
} }

View File

@ -6,8 +6,6 @@
// ------------------------------------------- // -------------------------------------------
package ws package ws
import "fonchain-fiee/api/accountFiee"
// websocket 消息类型 // websocket 消息类型
type WsType int type WsType int
@ -45,8 +43,6 @@ type ListenEvent struct {
type ListenEventData struct { type ListenEventData struct {
ListenEvent ListenEvent
Client *Client Client *Client
ChatUser *accountFiee.ChatUserData
Msg string
Data any Data any
} }
type ListenEventChan chan ListenEventData type ListenEventChan chan ListenEventData

View File

@ -80,7 +80,6 @@ func AuthorizationVerify(sourceData []byte) (userInfo *accountFiee.ChatUserData,
if err != nil || fontreeJwtInfo.IsOffline { if err != nil || fontreeJwtInfo.IsOffline {
check = false check = false
} else { } else {
check = true
fmt.Printf("fontreeJwtInfo is %#v\n", fontreeJwtInfo) fmt.Printf("fontreeJwtInfo is %#v\n", fontreeJwtInfo)
accountInfo.Origin = e.ErpDomain accountInfo.Origin = e.ErpDomain
accountInfo.OriginId = int64(fontreeJwtInfo.ID) accountInfo.OriginId = int64(fontreeJwtInfo.ID)
@ -148,7 +147,6 @@ func HandleMessage(sourceData []byte, cli *Client) {
switch msg.Type { switch msg.Type {
default: default:
cli.Send <- WsErrorUnknownMessageType(msg.From) cli.Send <- WsErrorUnknownMessageType(msg.From)
//fmt.Printf("不支持的ws业务消息%#v\n", msg)
case TestType: case TestType:
var newMsg = WsInfo{ var newMsg = WsInfo{
Type: TestType, Type: TestType,

View File

@ -55,37 +55,19 @@ type MessageListType struct {
ID int64 `json:"ID"` ID int64 `json:"ID"`
CreatedAt string `json:"createdAt"` CreatedAt string `json:"createdAt"`
UserId int64 `json:"userId"` UserId int64 `json:"userId"`
Role int32 `json:"role,omitempty"`
Name string `json:"name"` Name string `json:"name"`
Message Message `json:"message"` Message Message `json:"message"`
} }
func (m *MessageListType) BuildMessage(data *accountFiee.ChatRecordData, role int32) { func (m *MessageListType) BuildMessage(data *accountFiee.ChatRecordData) {
m.ID = data.ID m.ID = data.ID
m.CreatedAt = data.CreatedAt m.CreatedAt = data.CreatedAt
m.UserId = data.UserId m.UserId = data.UserId
m.Name = data.Name m.Name = data.Name
m.Role = role
switch data.MsgType { switch data.MsgType {
default:
m.Message.MsgType = data.MsgType
m.Message.Text = data.Content
m.Message.LocalStamp = data.LocalStamp
if data.Medias != nil {
for _, media := range data.Medias {
m.Message.Media = append(m.Message.Media, MessageMedia{
MediaId: media.ID,
MediaSize: media.Size,
Ext: media.Ext,
Url: media.Url,
ConvText: media.ConvText,
Duration: media.Duration,
})
}
}
case accountFiee.MsgType_TextMsgType: case accountFiee.MsgType_TextMsgType:
m.Message = Message{ m.Message = Message{
MsgType: data.MsgType, MsgType: accountFiee.MsgType_TextMsgType,
Text: data.Content, Text: data.Content,
Media: []MessageMedia{}, Media: []MessageMedia{},
LocalStamp: data.LocalStamp, LocalStamp: data.LocalStamp,

View File

@ -42,14 +42,9 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
var ChatHandlerIns = NewChatHandler() var ChatHandlerIns = ChatHandler{
func NewChatHandler() ChatHandler {
c := ChatHandler{
cache: chatCache.ChatCache{NewMessageStatExpireAfter: 10 * time.Minute}, cache: chatCache.ChatCache{NewMessageStatExpireAfter: 10 * time.Minute},
} robot: robot.NewRobot(),
c.robot = robot.NewRobot(&c.cache)
return c
} }
type ChatHandler struct { type ChatHandler struct {
@ -322,7 +317,7 @@ func (cr ChatHandler) MessageList(c *gin.Context) {
} }
returnDataIdList = append(returnDataIdList, message.ID) returnDataIdList = append(returnDataIdList, message.ID)
var msg = &dto.MessageListType{} var msg = &dto.MessageListType{}
msg.BuildMessage(message, 0) msg.BuildMessage(message)
resp = append(resp, msg) resp = append(resp, msg)
} }
} else { } else {
@ -354,7 +349,7 @@ func (cr ChatHandler) MessageList(c *gin.Context) {
total++ total++
returnDataIdList = append(returnDataIdList, message.ID) returnDataIdList = append(returnDataIdList, message.ID)
var msg = &dto.MessageListType{} var msg = &dto.MessageListType{}
msg.BuildMessage(message, 0) msg.BuildMessage(message)
resp = append(resp, msg) resp = append(resp, msg)
} }
} }
@ -434,7 +429,7 @@ func (cr ChatHandler) Upload(c *gin.Context) {
defer tmp.Close() defer tmp.Close()
fileBuffer := bytes.NewBuffer(fileContent) fileBuffer := bytes.NewBuffer(fileContent)
var bosUrl string var bosUrl string
bosUrl, err = upload.UploadWithBuffer(fileBuffer, fmt.Sprintf("%d/%v%v", chatUser.ID, filename, fileExt)) bosUrl, err = upload.UploadWithBuffer(fileBuffer, fmt.Sprintf("fiee/%d/%v%v", chatUser.ID, filename, fileExt))
if err != nil { if err != nil {
service.Error(c, err) service.Error(c, err)
return return

View File

@ -75,7 +75,7 @@ func NewMessage(ctx context.Context, cache *chatCache.ChatCache, chatUser *accou
fmt.Println("NewMessage 6") fmt.Println("NewMessage 6")
//发送websocket消息提醒通知 //发送websocket消息提醒通知
var notice = dto.MessageListType{} var notice = dto.MessageListType{}
notice.BuildMessage(resp.Data, chatUser.Role) notice.BuildMessage(resp.Data)
fmt.Printf("ws消息提醒:%+v\n", notice) fmt.Printf("ws消息提醒:%+v\n", notice)
_, err = consts.ChatRoom.SendSessionMessage(chatUser, request.SessionId, ws.NewChatMsgType, notice) _, err = consts.ChatRoom.SendSessionMessage(chatUser, request.SessionId, ws.NewChatMsgType, notice)
if err != nil { if err != nil {

View File

@ -11,22 +11,20 @@ import (
"fonchain-fiee/api/accountFiee" "fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/common/ws" "fonchain-fiee/pkg/common/ws"
"fonchain-fiee/pkg/service" "fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/asChat/chatCache" "fonchain-fiee/pkg/service/asChat/consts"
"fonchain-fiee/pkg/service/asChat/dto" "fonchain-fiee/pkg/service/asChat/dto"
"fonchain-fiee/pkg/service/asChat/logic"
"strings" "strings"
"time" "time"
) )
// 回复规则
type Reply struct { type Reply struct {
Response string Response string
Rules []IRule Rules []IRule
} }
func (r *Reply) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) { func (r *Reply) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, msg *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
for _, rule := range r.Rules { for _, rule := range r.Rules {
hit, task = rule.Hit(event, robotInfo) hit, runTime, logic = rule.Hit(eventType, chatUser, wsClient, msg, robotInfo)
if hit { if hit {
return return
} }
@ -34,9 +32,12 @@ func (r *Reply) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserDat
return return
} }
// 规则接口
type IRule interface { type IRule interface {
Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, msg *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error)
}
func NewReplyWhenHitKeywords(keywords []string) IRule {
return &ReplyWhenHitKeywords{Keywords: keywords}
} }
// KeywordsRuleChecker 关键字回复 // KeywordsRuleChecker 关键字回复
@ -44,80 +45,44 @@ type ReplyWhenHitKeywords struct {
Keywords []string `json:"keywords"` Keywords []string `json:"keywords"`
} }
func NewReplyWhenHitKeywords(keywords []string) IRule { func (k ReplyWhenHitKeywords) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, record *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
return &ReplyWhenHitKeywords{Keywords: keywords} if record == nil {
}
func (k ReplyWhenHitKeywords) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) {
if event.EventType != ws.EventChatMessage || event.Msg == "" || event.Client == nil || event.ChatUser == nil {
return return
} }
for _, v := range k.Keywords { for _, v := range k.Keywords {
if strings.Contains(event.Msg, v) { if strings.Contains(record.Content, v) {
hit = true hit = true
break break
} }
} }
task = RobotTask{ logic = func(msg string) error {
ChatUser: event.ChatUser, var notice = dto.MessageListType{}
Run: func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error { notice.BuildMessage(record)
return logic.NewMessage(context.Background(), cache, Sender, dto.NewMessageRequest{ _, err := consts.ChatRoom.SendSessionMessage(robotInfo, record.SessionId, ws.NewChatMsgType, notice)
Waiter: true, return err
SessionId: event.Client.SessionId,
Message: dto.Message{
MsgType: 1,
Text: msg,
LocalStamp: time.Now().Unix(),
},
})
},
} }
//logicFunc = func(content string, cache *chatCache.ChatCache, chatUser *accountFiee.ChatUserData) error {
// //var notice = dto.MessageListType{}
// //newRecord := &accountFiee.ChatRecordData{
// // SessionId: wsClient.SessionId,
// // UserId: wsClient.UserId,
// // Name: chatUser.NickName,
// // Avatar: robotInfo.Avatar,
// // MsgType: 1,
// // Content: content,
// //}
// //notice.BuildMessage(newRecord)
// //_, err := consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
// //return err
// err := logic.NewMessage(context.Background(), cache, chatUser, dto.NewMessageRequest{
// Waiter: true,
// SessionId: wsClient.SessionId,
// Message: dto.Message{
// MsgType: 1,
// Text: msg,
// LocalStamp: time.Now().Unix(),
// },
// })
// return err
//}
return return
} }
// 用户打开聊天会话直接发送 // 用户打开聊天会话直接发送
type ReplyWhenUserJoinSession struct {
}
func NewReplyWhenUserJoinSession() IRule { func NewReplyWhenUserJoinSession() IRule {
return &ReplyWhenUserJoinSession{} return &ReplyWhenUserJoinSession{}
} }
func (k ReplyWhenUserJoinSession) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) { type ReplyWhenUserJoinSession struct {
if event.EventType != ws.EventUserJoin { }
func (k ReplyWhenUserJoinSession) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, record *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
if eventType != ws.EventUserJoin {
return return
} }
if event.Client == nil { if wsClient == nil {
return return
} }
ctx := context.Background() ctx := context.Background()
queryRes, err := service.AccountFieeProvider.GetChatRecordList(ctx, &accountFiee.GetChatRecordListRequest{ queryRes, err := service.AccountFieeProvider.GetChatRecordList(ctx, &accountFiee.GetChatRecordListRequest{
Query: &accountFiee.ChatRecordData{ Query: &accountFiee.ChatRecordData{
SessionId: event.Client.SessionId, SessionId: wsClient.SessionId,
}, },
Page: 1, Page: 1,
PageSize: 1, PageSize: 1,
@ -137,115 +102,41 @@ func (k ReplyWhenUserJoinSession) Hit(event ws.ListenEventData, robotInfo *accou
} }
} }
hit = true hit = true
if event.ChatUser == nil { logic = func(msg string) error {
event.ChatUser, err = service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: event.Client.UserId}) var notice = dto.MessageListType{}
if err != nil { newRecord := &accountFiee.ChatRecordData{
return SessionId: wsClient.SessionId,
} UserId: wsClient.UserId,
} Name: wsClient.SessionId,
task = RobotTask{ Avatar: robotInfo.Avatar,
ChatUser: event.ChatUser,
Run: func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
return logic.NewMessage(ctx, cache, Sender, dto.NewMessageRequest{
Waiter: true,
SessionId: event.Client.SessionId,
Message: dto.Message{
MsgType: 1, MsgType: 1,
Text: msg, Content: msg,
LocalStamp: time.Now().Unix(), }
}, notice.BuildMessage(newRecord)
}) _, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
}, return err
} }
//logicFunc = func(msg string, cache *chatCache.ChatCache, chatUser *accountFiee.ChatUserData) error {
// //var notice = dto.MessageListType{}
// //newRecord := &accountFiee.ChatRecordData{
// // SessionId: wsClient.SessionId,
// // UserId: wsClient.UserId,
// // Name: wsClient.SessionId,
// // Avatar: robotInfo.Avatar,
// // MsgType: 1,
// // Content: msg,
// //}
// //notice.BuildMessage(newRecord)
// //_, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
// err = logic.NewMessage(ctx, cache, chatUser, dto.NewMessageRequest{
// Waiter: true,
// SessionId: wsClient.SessionId,
// Message: dto.Message{
// MsgType: 1,
// Text: msg,
// LocalStamp: time.Now().Unix(),
// },
// })
// return err
//}
return return
} }
// 客服指定时间不回复则自动回复 // 客服
type ReplyWhenWaiterNoAction struct {
DelaySecond time.Duration
}
func NewReplyWhenWaiterNoAction(delaySecond time.Duration) *ReplyWhenWaiterNoAction { func NewReplyWhenWaiterNoAction(delaySecond time.Duration) *ReplyWhenWaiterNoAction {
return &ReplyWhenWaiterNoAction{ return &ReplyWhenWaiterNoAction{
DelaySecond: delaySecond, DelaySecond: delaySecond,
} }
} }
func (k *ReplyWhenWaiterNoAction) Hit(event ws.ListenEventData, chatUser *accountFiee.ChatUserData) (hit bool, task RobotTask) { type ReplyWhenWaiterNoAction struct {
if event.Client == nil || event.EventType != ws.EventChatMessage { DelaySecond time.Duration
return
}
task = RobotTask{
RunTime: time.Now().Add(k.DelaySecond * time.Second),
Run: func(content string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
//如果客服已经回复则不发送消息
chatRecordListRes, err := service.AccountFieeProvider.GetChatRecordList(context.Background(), &accountFiee.GetChatRecordListRequest{
Query: &accountFiee.ChatRecordData{
SessionId: event.Client.SessionId,
},
Page: 1,
PageSize: 1,
Order: "created_at desc",
})
if err != nil || chatRecordListRes.Total == 0 {
return err
}
checkUserId := chatRecordListRes.List[0].UserId
checkChatUser, err := service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: checkUserId})
if err != nil || checkChatUser.Role != 1 {
return err
} }
//var notice = dto.MessageListType{} func (k *ReplyWhenWaiterNoAction) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, record *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
//newRecord := &accountFiee.ChatRecordData{ runTime = time.Now().Add(k.DelaySecond * time.Second)
// SessionId: wsClient.SessionId, logic = func(msg string) error {
// UserId: wsClient.UserId, var notice = dto.MessageListType{}
// Name: chatUser.NickName, notice.BuildMessage(record)
// Avatar: robotInfo.Avatar, _, err := consts.ChatRoom.SendSessionMessage(robotInfo, record.SessionId, ws.NewChatMsgType, notice)
// MsgType: 1,
// Content: content,
//}
//notice.BuildMessage(newRecord)
//_, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
//return err
err = logic.NewMessage(context.Background(), cache, chatUser, dto.NewMessageRequest{
Waiter: true,
SessionId: event.Client.SessionId,
Message: dto.Message{
MsgType: 1,
Text: event.Msg,
LocalStamp: time.Now().Unix(),
},
})
return err return err
},
Response: "",
ChatUser: event.ChatUser,
} }
return return

View File

@ -12,7 +12,6 @@ import (
"fonchain-fiee/api/accountFiee" "fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/common/ws" "fonchain-fiee/pkg/common/ws"
"fonchain-fiee/pkg/service" "fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/asChat/chatCache"
"fonchain-fiee/pkg/service/asChat/consts" "fonchain-fiee/pkg/service/asChat/consts"
"fonchain-fiee/pkg/service/asChat/dto" "fonchain-fiee/pkg/service/asChat/dto"
"log" "log"
@ -20,7 +19,7 @@ import (
"time" "time"
) )
func NewRobot(cache *chatCache.ChatCache) *Robot { func NewRobot() *Robot {
ctx := context.Background() ctx := context.Background()
robotQuery, err := service.AccountFieeProvider.GetChatUserList(ctx, &accountFiee.GetChatUserListRequest{ robotQuery, err := service.AccountFieeProvider.GetChatUserList(ctx, &accountFiee.GetChatUserListRequest{
Query: &accountFiee.ChatUserData{Role: 3}, Query: &accountFiee.ChatUserData{Role: 3},
@ -50,11 +49,10 @@ func NewRobot(cache *chatCache.ChatCache) *Robot {
Name: "robot1", Name: "robot1",
ListenEvents: []ws.ListenEvent{ //只监听消息推送事件 ListenEvents: []ws.ListenEvent{ //只监听消息推送事件
{ws.EventUserJoin, ws.EventProgressAfter}, {ws.EventUserJoin, ws.EventProgressAfter},
{ws.EventChatMessage, ws.EventProgressBefore}, {ws.EventChatMessage, ws.EventProgressAfter},
}, },
Chan: make(ws.ListenEventChan), Chan: make(ws.ListenEventChan),
}, },
cache: cache,
} }
ruleListRes, err := service.AccountFieeProvider.GetChatAutoReplyRulerList(ctx, &accountFiee.GetChatAutoReplyRulerListRequest{ ruleListRes, err := service.AccountFieeProvider.GetChatAutoReplyRulerList(ctx, &accountFiee.GetChatAutoReplyRulerListRequest{
Query: &accountFiee.ChatAutoReplyRulerData{Status: 1}, Query: &accountFiee.ChatAutoReplyRulerData{Status: 1},
@ -89,7 +87,6 @@ type Robot struct {
isRunning bool //运行状态 isRunning bool //运行状态
mu sync.Mutex mu sync.Mutex
*ws.EventListener *ws.EventListener
cache *chatCache.ChatCache
} }
//func (r *Robot) Listen(record *accountFiee.ChatRecordData) { //func (r *Robot) Listen(record *accountFiee.ChatRecordData) {
@ -147,8 +144,6 @@ func (r *Robot) Run() {
for { for {
select { select {
default:
time.Sleep(200 * time.Millisecond)
case <-r.ticker.C: case <-r.ticker.C:
r.mu.Lock() r.mu.Lock()
if len(r.DelayTask) == 0 { if len(r.DelayTask) == 0 {
@ -162,7 +157,7 @@ func (r *Robot) Run() {
if now.After(task.RunTime) { if now.After(task.RunTime) {
// 执行任务 // 执行任务
go func() { go func() {
err := task.Run(task.Response, r.cache, task.ChatUser) err := task.Run(task.Response)
if err != nil { if err != nil {
log.Printf("聊天机器人[%d]回复消息失败:%v", r.Info.ID, err) log.Printf("聊天机器人[%d]回复消息失败:%v", r.Info.ID, err)
} }
@ -177,23 +172,41 @@ func (r *Robot) Run() {
case <-r.stopChan: case <-r.stopChan:
return return
case event := <-r.EventListener.Chan: case event := <-r.EventListener.Chan:
fmt.Printf("robot listen event:%#v\n", event) fmt.Printf("listen event:%#v\n", event)
switch event.EventType {
case ws.EventUserJoin: //用户加入聊天室
for _, ruleResponse := range r.Rules { for _, ruleResponse := range r.Rules {
hit, task := ruleResponse.Hit(event, r.Info) hit, runtime, logic := ruleResponse.Hit(ws.EventUserJoin, nil, event.Client, nil, r.Info)
if hit { if hit {
if task.RunTime.IsZero() { if runtime.IsZero() {
err := task.Run(ruleResponse.Response, r.cache, r.Info) err := logic(ruleResponse.Response)
if err != nil { if err != nil {
log.Printf("robot 执行任务失败:%v\n", err) log.Printf("robot 执行任务失败:%v\n", err)
} }
} else { } else {
task.Response = ruleResponse.Response r.DelayTask = append(r.DelayTask, RobotTask{
r.RegisterDelayTask(task) RunTime: runtime,
Run: logic,
Response: ruleResponse.Response,
})
} }
break break
} }
} }
case ws.EventChatMessage:
for _, ruleResponse := range r.Rules {
hit, runtime, logic := ruleResponse.Hit(ws.EventUserJoin, nil, event.Client, nil, r.Info)
if hit {
if !runtime.IsZero() {
err := logic(ruleResponse.Response)
if err != nil {
log.Printf("robot 执行任务失败:%v\n", err)
}
}
break
}
}
}
} }
} }
} }
@ -206,11 +219,3 @@ func (r *Robot) Stop() {
} }
r.mu.Unlock() r.mu.Unlock()
} }
func (r *Robot) RegisterDelayTask(task RobotTask) {
r.mu.Lock()
defer r.mu.Unlock()
if task.Run == nil {
return
}
r.DelayTask = append(r.DelayTask, task)
}

View File

@ -21,7 +21,7 @@ func ParseReplyRule(data *dto.ChatAutoReplyData) (r Reply) {
switch ruleName { switch ruleName {
case "keywords": //关键字回复 case "keywords": //关键字回复
var keywords []string var keywords []string
if v.Content == "" { if v.Content != "" {
continue continue
} else { } else {
keywords = strings.Split(v.Content, ",") keywords = strings.Split(v.Content, ",")

View File

@ -6,15 +6,10 @@
// ------------------------------------------- // -------------------------------------------
package robot package robot
import ( import "time"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/service/asChat/chatCache"
"time"
)
type RobotTask struct { type RobotTask struct {
RunTime time.Time RunTime time.Time
Run func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error Run func(msg string) error
Response string Response string
ChatUser *accountFiee.ChatUserData
} }