forked from FloatTech/ZeroBot-Plugin
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a5a24e7
commit 1d69f80
Showing
4 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Package chatcount 聊天时长统计 | ||
package chatcount | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
|
||
zero "github.com/wdvxdr1123/ZeroBot" | ||
"github.com/wdvxdr1123/ZeroBot/message" | ||
|
||
ctrl "github.com/FloatTech/zbpctrl" | ||
"github.com/FloatTech/zbputils/control" | ||
"github.com/FloatTech/zbputils/ctxext" | ||
) | ||
|
||
const ( | ||
rankSize = 15 | ||
) | ||
|
||
func init() { | ||
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{ | ||
DisableOnDefault: false, | ||
Brief: "聊天时长统计", | ||
Help: "- 查询水群@xxx\n- 查看水群排名", | ||
PrivateDataFolder: "chatcount", | ||
}) | ||
go func() { | ||
ctdb = initialize(engine.DataFolder() + "chatcount.db") | ||
}() | ||
engine.OnMessage(zero.OnlyGroup).SetBlock(false). | ||
Handle(func(ctx *zero.Ctx) { | ||
todayTime, remindFlag := ctdb.updateChatTime(ctx.Event.GroupID, ctx.Event.UserID) | ||
if remindFlag { | ||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(fmt.Sprintf("BOT提醒:你今天已经水群%d分钟了!", todayTime))) | ||
} | ||
}) | ||
|
||
engine.OnPrefix(`查询水群`, zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) { | ||
name := ctx.NickName() | ||
todayTime, totalTime := ctdb.getChatTime(ctx.Event.GroupID, ctx.Event.UserID) | ||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(fmt.Sprintf("%s今天水了%d分钟,总计%d分钟。", name, todayTime, totalTime))) | ||
}) | ||
engine.OnFullMatch("查看水群排名", zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true). | ||
Handle(func(ctx *zero.Ctx) { | ||
text := strings.Builder{} | ||
text.WriteString("今日水群排行榜:\n") | ||
chatTimeList := ctdb.getChatRank(ctx.Event.GroupID) | ||
for i := 0; i < len(chatTimeList) && i < rankSize; i++ { | ||
text.WriteString("第") | ||
text.WriteString(strconv.Itoa(i + 1)) | ||
text.WriteString("名:") | ||
text.WriteString(ctx.GetGroupMemberInfo(ctx.Event.GroupID, chatTimeList[i].UserID, false).Get("nickname").Str) | ||
text.WriteString(" - ") | ||
text.WriteString(strconv.FormatInt(chatTimeList[i].TodayTime/60, 10)) | ||
text.WriteString("分钟\n") | ||
} | ||
ctx.SendChain(message.Text(text.String())) | ||
}) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package chatcount | ||
|
||
import ( | ||
"os" | ||
"time" | ||
|
||
"github.com/jinzhu/gorm" | ||
) | ||
|
||
const ( | ||
chatInterval = 300 | ||
) | ||
|
||
var ( | ||
// ctdb 聊天时长数据库全局变量 | ||
ctdb *chattimedb | ||
// 水群提醒时间提醒段,单位分钟 | ||
levelArray = [...]int{15, 30, 60, 120, 240} | ||
) | ||
|
||
// chattimedb 聊天时长数据库结构体 | ||
type chattimedb gorm.DB | ||
|
||
// initialize 初始化 | ||
func initialize(dbpath string) *chattimedb { | ||
var err error | ||
if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) { | ||
// 生成文件 | ||
f, err := os.Create(dbpath) | ||
if err != nil { | ||
return nil | ||
} | ||
defer f.Close() | ||
} | ||
gdb, err := gorm.Open("sqlite3", dbpath) | ||
if err != nil { | ||
panic(err) | ||
} | ||
gdb.AutoMigrate(&ChatTime{}) | ||
return (*chattimedb)(gdb) | ||
} | ||
|
||
// Close 关闭 | ||
func (ctdb *chattimedb) Close() error { | ||
db := (*gorm.DB)(ctdb) | ||
return db.Close() | ||
} | ||
|
||
// ChatTime 聊天时长,时间的单位都是秒 | ||
type ChatTime struct { | ||
ID uint `gorm:"primary_key"` | ||
GroupID int64 `gorm:"column:group_id"` | ||
UserID int64 `gorm:"column:user_id"` | ||
LastTime time.Time `gorm:"column:last_time"` | ||
TodayTime int64 `gorm:"column:today_time;default:0"` | ||
TotalTime int64 `gorm:"column:total_time;default:0"` | ||
} | ||
|
||
// TableName 表名 | ||
func (ChatTime) TableName() string { | ||
return "chat_time" | ||
} | ||
|
||
// sleep 更新发言时间,todayTime的单位是分钟 | ||
func (ctdb *chattimedb) updateChatTime(gid, uid int64) (todayTime int64, remindFlag bool) { | ||
db := (*gorm.DB)(ctdb) | ||
now := time.Now() | ||
st := ChatTime{ | ||
GroupID: gid, | ||
UserID: uid, | ||
LastTime: now, | ||
} | ||
if err := db.Model(&ChatTime{}).Where("group_id = ? and user_id = ?", gid, uid).First(&st).Error; err != nil { | ||
if gorm.IsRecordNotFoundError(err) { | ||
db.Model(&ChatTime{}).Create(&st) | ||
} | ||
} else { | ||
// 如果不是同一天,把todayTime重置 | ||
if st.LastTime.YearDay() != now.YearDay() { | ||
db.Model(&ChatTime{}).Where("group_id = ? and user_id = ?", gid, uid).Update( | ||
map[string]any{ | ||
"last_time": now, | ||
"today_time": 0, | ||
}) | ||
} else { | ||
userChatTime := int64(now.Sub(st.LastTime).Seconds()) | ||
// 当聊天时间间隔很大的话,则不计入时长 | ||
if userChatTime < chatInterval { | ||
db.Model(&ChatTime{}).Where("group_id = ? and user_id = ?", gid, uid).Update( | ||
map[string]any{ | ||
"last_time": now, | ||
"today_time": st.TodayTime + userChatTime, | ||
"total_time": st.TotalTime + userChatTime, | ||
}) | ||
todayTime = (st.TodayTime + userChatTime) / 60 | ||
remindFlag = getLevel(int(st.TodayTime+userChatTime)/60) > getLevel(int(st.TodayTime/60)) | ||
} | ||
|
||
} | ||
} | ||
return | ||
} | ||
|
||
// getChatTime 获得用户聊天时长,todayTime,totalTime的单位是分钟 | ||
func (ctdb *chattimedb) getChatTime(gid, uid int64) (todayTime int64, totalTime int64) { | ||
db := (*gorm.DB)(ctdb) | ||
st := ChatTime{} | ||
_ = db.Model(&ChatTime{}).Where("group_id = ? and user_id = ?", gid, uid).First(&st) | ||
todayTime = st.TodayTime / 60 | ||
totalTime = st.TotalTime / 60 | ||
return | ||
} | ||
|
||
// getChatRank 获得水群排名 | ||
func (ctdb *chattimedb) getChatRank(gid int64) (chatTimeList []ChatTime) { | ||
db := (*gorm.DB)(ctdb) | ||
_ = db.Model(&ChatTime{}).Where("group_id = ?", gid).Order("today_time DESC").Find(&chatTimeList) | ||
return | ||
} | ||
|
||
// getLevel 用时长判断等级 | ||
func getLevel(t int) int { | ||
for i := len(levelArray) - 1; i >= 0; i-- { | ||
if t >= levelArray[i] { | ||
return i + 1 | ||
} | ||
} | ||
return 0 | ||
} |