diff --git a/entity/friend.go b/entity/friend.go index 69d4b6c8..8012c27d 100644 --- a/entity/friend.go +++ b/entity/friend.go @@ -1,22 +1,24 @@ package entity import ( + "go-wechat/common/types" "time" ) // Friend // @description: 好友列表 type Friend struct { - Wxid string `json:"wxid"` // 微信原始Id - CustomAccount string `json:"customAccount"` // 微信号 - Nickname string `json:"nickname"` // 昵称 - Pinyin string `json:"pinyin"` // 昵称拼音大写首字母 - PinyinAll string `json:"pinyinAll"` // 昵称全拼 - EnableAi bool `json:"enableAI" gorm:"type:tinyint(1) default 0 not null"` // 是否使用AI - AiModel string `json:"aiModel"` // AI模型 - EnableChatRank bool `json:"enableChatRank" gorm:"type:tinyint(1) default 0 not null"` // 是否使用聊天排行 - EnableWelcome bool `json:"enableWelcome" gorm:"type:tinyint(1) default 0 not null"` // 是否启用迎新 - IsOk bool `json:"isOk" gorm:"type:tinyint(1) default 0 not null"` // 是否正常 + Wxid string `json:"wxid"` // 微信原始Id + CustomAccount string `json:"customAccount"` // 微信号 + Nickname string `json:"nickname"` // 昵称 + Pinyin string `json:"pinyin"` // 昵称拼音大写首字母 + PinyinAll string `json:"pinyinAll"` // 昵称全拼 + LastActive types.DateTime `json:"lastActive"` // 最后活跃时间 + EnableAi bool `json:"enableAI" gorm:"type:tinyint(1) default 0 not null"` // 是否使用AI + AiModel string `json:"aiModel"` // AI模型 + EnableChatRank bool `json:"enableChatRank" gorm:"type:tinyint(1) default 0 not null"` // 是否使用聊天排行 + EnableWelcome bool `json:"enableWelcome" gorm:"type:tinyint(1) default 0 not null"` // 是否启用迎新 + IsOk bool `json:"isOk" gorm:"type:tinyint(1) default 0 not null"` // 是否正常 } func (Friend) TableName() string { @@ -34,6 +36,7 @@ type GroupUser struct { IsMember bool `json:"isMember" gorm:"type:tinyint(1) default 0 not null"` // 是否群成员 IsAdmin bool `json:"isAdmin" gorm:"type:tinyint(1) default 0 not null"` // 是否群主 JoinTime time.Time `json:"joinTime"` // 加入时间 + LastActive time.Time `json:"lastActive"` // 最后活跃时间 LeaveTime *time.Time `json:"leaveTime"` // 离开时间 SkipChatRank bool `json:"skipChatRank" gorm:"type:tinyint(1) default 0 not null"` // 是否跳过聊天排行 } diff --git a/service/friend.go b/service/friend.go index ce2b92e0..f5e44a41 100644 --- a/service/friend.go +++ b/service/friend.go @@ -4,6 +4,7 @@ import ( "go-wechat/client" "go-wechat/entity" "go-wechat/vo" + "log" "strings" ) @@ -16,10 +17,11 @@ func GetAllFriend() (friends, groups []vo.FriendItem, err error) { var records []vo.FriendItem err = client.MySQL. Table("t_friend AS tf"). - Joins("LEFT JOIN t_message AS tm ON tf.wxid = tm.from_user"). - Select("tf.*", "MAX(tm.create_at) AS last_active_time"). - Group("tf.wxid"). - Order("last_active_time DESC"). + //Joins("LEFT JOIN t_message AS tm ON tf.wxid = tm.from_user"). + //Select("tf.*", "MAX(tm.create_at) AS last_active"). + Select("tf.*"). + //Group("tf.wxid"). + Order("tf.last_active DESC"). Find(&records).Error if err != nil { return @@ -60,3 +62,27 @@ func CheckIsEnableCommand(userId string) (flag bool) { client.MySQL.Model(&entity.Friend{}).Where("enable_command = 1").Where("wxid = ?", userId).Count(&coo) return coo > 0 } + +// updateLastActive +// @description: 更新最后活跃时间 +// @param msg +func updateLastActive(msg entity.Message) { + var err error + // 如果是群,更新群成员最后活跃时间 + if strings.HasSuffix(msg.FromUser, "@chatroom") { + err = client.MySQL.Model(&entity.GroupUser{}). + Where("group_id = ?", msg.FromUser). + Where("wxid = ?", msg.GroupUser). + Update("last_active", msg.CreateTime).Error + if err != nil { + log.Printf("更新群成员最后活跃时间失败, 错误信息: %v", err) + } + } + // 更新群或者好友活跃时间 + err = client.MySQL.Model(&entity.Friend{}). + Where("wxid = ?", msg.FromUser). + Update("last_active", msg.CreateTime).Error + if err != nil { + log.Printf("更新群或者好友活跃时间失败, 错误信息: %v", err) + } +} diff --git a/service/group.go b/service/group.go index 85c3187d..14754972 100644 --- a/service/group.go +++ b/service/group.go @@ -13,10 +13,9 @@ import ( func GetGroupUsersByGroupId(groupId string) (records []vo.GroupUserItem, err error) { err = client.MySQL. Table("t_group_user AS tgu"). - Joins("LEFT JOIN t_message AS tm ON tm.from_user = tgu.group_id AND tm.group_user = tgu.wxid"). - //Select("tgu.wxid", "tgu.nickname", "tgu.head_image", "tgu.is_member", "tgu.leave_time", - // "tgu.skip_chat_rank", "MAX(tm.create_at) AS last_active_time"). - Select("tgu.*", "MAX(tm.create_at) AS last_active_time"). + //Joins("LEFT JOIN t_message AS tm ON tm.from_user = tgu.group_id AND tm.group_user = tgu.wxid"). + //Select("tgu.*", "MAX(tm.create_at) AS last_active"). + Select("tgu.*"). Where("tgu.group_id = ?", groupId). Group("tgu.group_id, tgu.wxid"). Order("tgu.join_time DESC"). diff --git a/service/message.go b/service/message.go index 18c2a0b5..2e0c9cf1 100644 --- a/service/message.go +++ b/service/message.go @@ -32,4 +32,10 @@ func SaveMessage(msg entity.Message) { log.Printf("消息入库失败, 错误信息: %v", err) } log.Printf("消息入库成功,消息Id: %d", msg.MsgId) + + // 更新最后活跃时间 + // 只处理收到的消息 + if msg.MsgId > 1 { + go updateLastActive(msg) + } } diff --git a/views/index.html b/views/index.html index 1339217c..c197d940 100644 --- a/views/index.html +++ b/views/index.html @@ -47,10 +47,10 @@ {{ .CustomAccount }} {{ .Nickname }} - {{ if eq .LastActiveTime.IsNil true }} + {{ if eq .LastActive.IsNil true }} 无数据 {{ else }} - {{ .LastActiveTime }} + {{ .LastActive }} {{ end }} @@ -110,10 +110,10 @@ {{ .Wxid }} {{ .Nickname }} - {{ if eq .LastActiveTime.IsNil true }} + {{ if eq .LastActive.IsNil true }} 无数据 {{ else }} - {{ .LastActiveTime }} + {{ .LastActive }} {{ end }} diff --git a/views/static/js/index.js b/views/static/js/index.js index c01a214f..200c8196 100644 --- a/views/static/js/index.js +++ b/views/static/js/index.js @@ -113,7 +113,8 @@ function getGroupUsers(groupId, groupName) { const groupUsers = response.data // 循环渲染数据 groupUsers.forEach((groupUser, i) => { - const { wxid, nickname, isMember, isAdmin, joinTime, lastActiveTime, leaveTime, skipChatRank } = groupUser; + console.log(groupUser) + const { wxid, nickname, isMember, isAdmin, joinTime, lastActive, leaveTime, skipChatRank } = groupUser; let row = tbody.insertRow(i); // Insert data into cells @@ -122,7 +123,7 @@ function getGroupUsers(groupId, groupName) { row.insertCell(2).innerHTML = `
${isMember ? '是' : '否'}
`; row.insertCell(3).innerHTML = `
${isAdmin ? '是' : '否'}
`; row.insertCell(4).innerHTML = joinTime; - row.insertCell(5).innerHTML = lastActiveTime; + row.insertCell(5).innerHTML = lastActive; row.insertCell(6).innerHTML = leaveTime; row.insertCell(7).innerHTML = ``; }); diff --git a/vo/friend.go b/vo/friend.go index 874d368c..335a526d 100644 --- a/vo/friend.go +++ b/vo/friend.go @@ -12,26 +12,26 @@ type FriendItem struct { Pinyin string // 昵称拼音大写首字母 PinyinAll string // 昵称全拼 Wxid string // 微信原始Id + LastActive types.DateTime // 最后活跃时间 EnableAi bool // 是否使用AI AiModel string // AI模型 EnableChatRank bool // 是否使用聊天排行 EnableWelcome bool // 是否使用迎新 EnableCommand bool // 是否启用指令 IsOk bool // 是否还在通讯库(群聊是要还在群里也算) - LastActiveTime types.DateTime // 最后活跃时间 } // GroupUserItem // @description: 群成员列表数据 type GroupUserItem struct { - Wxid string `json:"wxid"` // 微信Id - Account string `json:"account"` // 账号 - HeadImage string `json:"headImage"` // 头像 - Nickname string `json:"nickname"` // 昵称 - IsMember bool `json:"isMember" ` // 是否群成员 - IsAdmin bool `json:"isAdmin"` // 是否群主 - JoinTime types.DateTime `json:"joinTime"` // 加入时间 - LastActiveTime types.DateTime `json:"lastActiveTime"` // 最后活跃时间 - LeaveTime types.DateTime `json:"leaveTime"` // 离开时间 - SkipChatRank bool `json:"skipChatRank" ` // 是否跳过聊天排行 + Wxid string `json:"wxid"` // 微信Id + Account string `json:"account"` // 账号 + HeadImage string `json:"headImage"` // 头像 + Nickname string `json:"nickname"` // 昵称 + IsMember bool `json:"isMember" ` // 是否群成员 + IsAdmin bool `json:"isAdmin"` // 是否群主 + JoinTime types.DateTime `json:"joinTime"` // 加入时间 + LastActive types.DateTime `json:"lastActive"` // 最后活跃时间 + LeaveTime types.DateTime `json:"leaveTime"` // 离开时间 + SkipChatRank bool `json:"skipChatRank" ` // 是否跳过聊天排行 }