1
0
forked from lxh/go-wxhelper

Merge pull request '🎨 逻辑优化,那个网页,大大地提速' (#18) from hotfix into main

Reviewed-on: lxh/go-wxhelper#18
This commit is contained in:
李寻欢 2024-01-25 16:27:51 +08:00
commit c6da056f98
7 changed files with 70 additions and 35 deletions

View File

@ -1,22 +1,24 @@
package entity package entity
import ( import (
"go-wechat/common/types"
"time" "time"
) )
// Friend // Friend
// @description: 好友列表 // @description: 好友列表
type Friend struct { type Friend struct {
Wxid string `json:"wxid"` // 微信原始Id Wxid string `json:"wxid"` // 微信原始Id
CustomAccount string `json:"customAccount"` // 微信号 CustomAccount string `json:"customAccount"` // 微信号
Nickname string `json:"nickname"` // 昵称 Nickname string `json:"nickname"` // 昵称
Pinyin string `json:"pinyin"` // 昵称拼音大写首字母 Pinyin string `json:"pinyin"` // 昵称拼音大写首字母
PinyinAll string `json:"pinyinAll"` // 昵称全拼 PinyinAll string `json:"pinyinAll"` // 昵称全拼
EnableAi bool `json:"enableAI" gorm:"type:tinyint(1) default 0 not null"` // 是否使用AI LastActive types.DateTime `json:"lastActive"` // 最后活跃时间
AiModel string `json:"aiModel"` // AI模型 EnableAi bool `json:"enableAI" gorm:"type:tinyint(1) default 0 not null"` // 是否使用AI
EnableChatRank bool `json:"enableChatRank" gorm:"type:tinyint(1) default 0 not null"` // 是否使用聊天排行 AiModel string `json:"aiModel"` // AI模型
EnableWelcome bool `json:"enableWelcome" gorm:"type:tinyint(1) default 0 not null"` // 是否启用迎新 EnableChatRank bool `json:"enableChatRank" gorm:"type:tinyint(1) default 0 not null"` // 是否使用聊天排行
IsOk bool `json:"isOk" 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 { func (Friend) TableName() string {
@ -34,6 +36,7 @@ type GroupUser struct {
IsMember bool `json:"isMember" gorm:"type:tinyint(1) default 0 not null"` // 是否群成员 IsMember bool `json:"isMember" gorm:"type:tinyint(1) default 0 not null"` // 是否群成员
IsAdmin bool `json:"isAdmin" 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"` // 加入时间 JoinTime time.Time `json:"joinTime"` // 加入时间
LastActive time.Time `json:"lastActive"` // 最后活跃时间
LeaveTime *time.Time `json:"leaveTime"` // 离开时间 LeaveTime *time.Time `json:"leaveTime"` // 离开时间
SkipChatRank bool `json:"skipChatRank" gorm:"type:tinyint(1) default 0 not null"` // 是否跳过聊天排行 SkipChatRank bool `json:"skipChatRank" gorm:"type:tinyint(1) default 0 not null"` // 是否跳过聊天排行
} }

View File

@ -4,6 +4,7 @@ import (
"go-wechat/client" "go-wechat/client"
"go-wechat/entity" "go-wechat/entity"
"go-wechat/vo" "go-wechat/vo"
"log"
"strings" "strings"
) )
@ -16,10 +17,11 @@ func GetAllFriend() (friends, groups []vo.FriendItem, err error) {
var records []vo.FriendItem var records []vo.FriendItem
err = client.MySQL. err = client.MySQL.
Table("t_friend AS tf"). Table("t_friend AS tf").
Joins("LEFT JOIN t_message AS tm ON tf.wxid = tm.from_user"). //Joins("LEFT JOIN t_message AS tm ON tf.wxid = tm.from_user").
Select("tf.*", "MAX(tm.create_at) AS last_active_time"). //Select("tf.*", "MAX(tm.create_at) AS last_active").
Group("tf.wxid"). Select("tf.*").
Order("last_active_time DESC"). //Group("tf.wxid").
Order("tf.last_active DESC").
Find(&records).Error Find(&records).Error
if err != nil { if err != nil {
return 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) client.MySQL.Model(&entity.Friend{}).Where("enable_command = 1").Where("wxid = ?", userId).Count(&coo)
return coo > 0 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)
}
}

View File

@ -13,10 +13,9 @@ import (
func GetGroupUsersByGroupId(groupId string) (records []vo.GroupUserItem, err error) { func GetGroupUsersByGroupId(groupId string) (records []vo.GroupUserItem, err error) {
err = client.MySQL. err = client.MySQL.
Table("t_group_user AS tgu"). 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"). //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", //Select("tgu.*", "MAX(tm.create_at) AS last_active").
// "tgu.skip_chat_rank", "MAX(tm.create_at) AS last_active_time"). Select("tgu.*").
Select("tgu.*", "MAX(tm.create_at) AS last_active_time").
Where("tgu.group_id = ?", groupId). Where("tgu.group_id = ?", groupId).
Group("tgu.group_id, tgu.wxid"). Group("tgu.group_id, tgu.wxid").
Order("tgu.join_time DESC"). Order("tgu.join_time DESC").

View File

@ -32,4 +32,10 @@ func SaveMessage(msg entity.Message) {
log.Printf("消息入库失败, 错误信息: %v", err) log.Printf("消息入库失败, 错误信息: %v", err)
} }
log.Printf("消息入库成功消息Id: %d", msg.MsgId) log.Printf("消息入库成功消息Id: %d", msg.MsgId)
// 更新最后活跃时间
// 只处理收到的消息
if msg.MsgId > 1 {
go updateLastActive(msg)
}
} }

View File

@ -47,10 +47,10 @@
<td>{{ .CustomAccount }}</td> <td>{{ .CustomAccount }}</td>
<td>{{ .Nickname }}</td> <td>{{ .Nickname }}</td>
<td> <td>
{{ if eq .LastActiveTime.IsNil true }} {{ if eq .LastActive.IsNil true }}
无数据 无数据
{{ else }} {{ else }}
{{ .LastActiveTime }} {{ .LastActive }}
{{ end }} {{ end }}
</td> </td>
<td> <td>
@ -110,10 +110,10 @@
<td>{{ .Wxid }}</td> <td>{{ .Wxid }}</td>
<td>{{ .Nickname }}</td> <td>{{ .Nickname }}</td>
<td> <td>
{{ if eq .LastActiveTime.IsNil true }} {{ if eq .LastActive.IsNil true }}
无数据 无数据
{{ else }} {{ else }}
{{ .LastActiveTime }} {{ .LastActive }}
{{ end }} {{ end }}
</td> </td>
<td> <td>

View File

@ -113,7 +113,8 @@ function getGroupUsers(groupId, groupName) {
const groupUsers = response.data const groupUsers = response.data
// 循环渲染数据 // 循环渲染数据
groupUsers.forEach((groupUser, i) => { 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); let row = tbody.insertRow(i);
// Insert data into cells // Insert data into cells
@ -122,7 +123,7 @@ function getGroupUsers(groupId, groupName) {
row.insertCell(2).innerHTML = `<div class="badge badge-${isMember ? 'info' : 'error'} gap-2">${isMember ? '是' : '否'}</div>`; row.insertCell(2).innerHTML = `<div class="badge badge-${isMember ? 'info' : 'error'} gap-2">${isMember ? '是' : '否'}</div>`;
row.insertCell(3).innerHTML = `<div class="badge badge-${isAdmin ? 'info' : 'error'} gap-2">${isAdmin ? '是' : '否'}</div>`; row.insertCell(3).innerHTML = `<div class="badge badge-${isAdmin ? 'info' : 'error'} gap-2">${isAdmin ? '是' : '否'}</div>`;
row.insertCell(4).innerHTML = joinTime; row.insertCell(4).innerHTML = joinTime;
row.insertCell(5).innerHTML = lastActiveTime; row.insertCell(5).innerHTML = lastActive;
row.insertCell(6).innerHTML = leaveTime; row.insertCell(6).innerHTML = leaveTime;
row.insertCell(7).innerHTML = `<input type="checkbox" class="toggle toggle-error" ${skipChatRank ? 'checked' : ''} onclick="changeUserGroupRankSkipStatus('${groupId}', '${wxid}')" />`; row.insertCell(7).innerHTML = `<input type="checkbox" class="toggle toggle-error" ${skipChatRank ? 'checked' : ''} onclick="changeUserGroupRankSkipStatus('${groupId}', '${wxid}')" />`;
}); });

View File

@ -12,26 +12,26 @@ type FriendItem struct {
Pinyin string // 昵称拼音大写首字母 Pinyin string // 昵称拼音大写首字母
PinyinAll string // 昵称全拼 PinyinAll string // 昵称全拼
Wxid string // 微信原始Id Wxid string // 微信原始Id
LastActive types.DateTime // 最后活跃时间
EnableAi bool // 是否使用AI EnableAi bool // 是否使用AI
AiModel string // AI模型 AiModel string // AI模型
EnableChatRank bool // 是否使用聊天排行 EnableChatRank bool // 是否使用聊天排行
EnableWelcome bool // 是否使用迎新 EnableWelcome bool // 是否使用迎新
EnableCommand bool // 是否启用指令 EnableCommand bool // 是否启用指令
IsOk bool // 是否还在通讯库(群聊是要还在群里也算) IsOk bool // 是否还在通讯库(群聊是要还在群里也算)
LastActiveTime types.DateTime // 最后活跃时间
} }
// GroupUserItem // GroupUserItem
// @description: 群成员列表数据 // @description: 群成员列表数据
type GroupUserItem struct { type GroupUserItem struct {
Wxid string `json:"wxid"` // 微信Id Wxid string `json:"wxid"` // 微信Id
Account string `json:"account"` // 账号 Account string `json:"account"` // 账号
HeadImage string `json:"headImage"` // 头像 HeadImage string `json:"headImage"` // 头像
Nickname string `json:"nickname"` // 昵称 Nickname string `json:"nickname"` // 昵称
IsMember bool `json:"isMember" ` // 是否群成员 IsMember bool `json:"isMember" ` // 是否群成员
IsAdmin bool `json:"isAdmin"` // 是否群主 IsAdmin bool `json:"isAdmin"` // 是否群主
JoinTime types.DateTime `json:"joinTime"` // 加入时间 JoinTime types.DateTime `json:"joinTime"` // 加入时间
LastActiveTime types.DateTime `json:"lastActiveTime"` // 最后活跃时间 LastActive types.DateTime `json:"lastActive"` // 最后活跃时间
LeaveTime types.DateTime `json:"leaveTime"` // 离开时间 LeaveTime types.DateTime `json:"leaveTime"` // 离开时间
SkipChatRank bool `json:"skipChatRank" ` // 是否跳过聊天排行 SkipChatRank bool `json:"skipChatRank" ` // 是否跳过聊天排行
} }