Skip to content

Commit 1d69f80

Browse files
committed
✨ 添加水群时长统计
1 parent a5a24e7 commit 1d69f80

File tree

4 files changed

+202
-0
lines changed

4 files changed

+202
-0
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@ zerobot [-h] [-m] [-n nickname] [-t token] [-u url] [-g url] [-p prefix] [-d|w]
176176

177177
- [x] 设置温度[正整数]
178178

179+
</details>
180+
<details>
181+
<summary>聊天时长统计</summary>
182+
183+
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/chatcount"`
184+
185+
- [x] 查询水群@xxx
186+
187+
- [x] 查看水群排名
188+
179189
</details>
180190
<details>
181191
<summary>睡眠管理</summary>

main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import (
3434

3535
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/chat" // 基础词库
3636

37+
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/chatcount" // 聊天时长统计
38+
3739
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/sleepmanage" // 统计睡眠时间
3840

3941
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/atri" // ATRI词库

plugin/chatcount/chatcount.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Package chatcount 聊天时长统计
2+
package chatcount
3+
4+
import (
5+
"fmt"
6+
"strconv"
7+
"strings"
8+
9+
zero "github.com/wdvxdr1123/ZeroBot"
10+
"github.com/wdvxdr1123/ZeroBot/message"
11+
12+
ctrl "github.com/FloatTech/zbpctrl"
13+
"github.com/FloatTech/zbputils/control"
14+
"github.com/FloatTech/zbputils/ctxext"
15+
)
16+
17+
const (
18+
rankSize = 15
19+
)
20+
21+
func init() {
22+
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
23+
DisableOnDefault: false,
24+
Brief: "聊天时长统计",
25+
Help: "- 查询水群@xxx\n- 查看水群排名",
26+
PrivateDataFolder: "chatcount",
27+
})
28+
go func() {
29+
ctdb = initialize(engine.DataFolder() + "chatcount.db")
30+
}()
31+
engine.OnMessage(zero.OnlyGroup).SetBlock(false).
32+
Handle(func(ctx *zero.Ctx) {
33+
todayTime, remindFlag := ctdb.updateChatTime(ctx.Event.GroupID, ctx.Event.UserID)
34+
if remindFlag {
35+
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(fmt.Sprintf("BOT提醒:你今天已经水群%d分钟了!", todayTime)))
36+
}
37+
})
38+
39+
engine.OnPrefix(`查询水群`, zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
40+
name := ctx.NickName()
41+
todayTime, totalTime := ctdb.getChatTime(ctx.Event.GroupID, ctx.Event.UserID)
42+
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(fmt.Sprintf("%s今天水了%d分钟,总计%d分钟。", name, todayTime, totalTime)))
43+
})
44+
engine.OnFullMatch("查看水群排名", zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true).
45+
Handle(func(ctx *zero.Ctx) {
46+
text := strings.Builder{}
47+
text.WriteString("今日水群排行榜:\n")
48+
chatTimeList := ctdb.getChatRank(ctx.Event.GroupID)
49+
for i := 0; i < len(chatTimeList) && i < rankSize; i++ {
50+
text.WriteString("第")
51+
text.WriteString(strconv.Itoa(i + 1))
52+
text.WriteString("名:")
53+
text.WriteString(ctx.GetGroupMemberInfo(ctx.Event.GroupID, chatTimeList[i].UserID, false).Get("nickname").Str)
54+
text.WriteString(" - ")
55+
text.WriteString(strconv.FormatInt(chatTimeList[i].TodayTime/60, 10))
56+
text.WriteString("分钟\n")
57+
}
58+
ctx.SendChain(message.Text(text.String()))
59+
})
60+
61+
}

plugin/chatcount/model.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package chatcount
2+
3+
import (
4+
"os"
5+
"time"
6+
7+
"github.com/jinzhu/gorm"
8+
)
9+
10+
const (
11+
chatInterval = 300
12+
)
13+
14+
var (
15+
// ctdb 聊天时长数据库全局变量
16+
ctdb *chattimedb
17+
// 水群提醒时间提醒段,单位分钟
18+
levelArray = [...]int{15, 30, 60, 120, 240}
19+
)
20+
21+
// chattimedb 聊天时长数据库结构体
22+
type chattimedb gorm.DB
23+
24+
// initialize 初始化
25+
func initialize(dbpath string) *chattimedb {
26+
var err error
27+
if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) {
28+
// 生成文件
29+
f, err := os.Create(dbpath)
30+
if err != nil {
31+
return nil
32+
}
33+
defer f.Close()
34+
}
35+
gdb, err := gorm.Open("sqlite3", dbpath)
36+
if err != nil {
37+
panic(err)
38+
}
39+
gdb.AutoMigrate(&ChatTime{})
40+
return (*chattimedb)(gdb)
41+
}
42+
43+
// Close 关闭
44+
func (ctdb *chattimedb) Close() error {
45+
db := (*gorm.DB)(ctdb)
46+
return db.Close()
47+
}
48+
49+
// ChatTime 聊天时长,时间的单位都是秒
50+
type ChatTime struct {
51+
ID uint `gorm:"primary_key"`
52+
GroupID int64 `gorm:"column:group_id"`
53+
UserID int64 `gorm:"column:user_id"`
54+
LastTime time.Time `gorm:"column:last_time"`
55+
TodayTime int64 `gorm:"column:today_time;default:0"`
56+
TotalTime int64 `gorm:"column:total_time;default:0"`
57+
}
58+
59+
// TableName 表名
60+
func (ChatTime) TableName() string {
61+
return "chat_time"
62+
}
63+
64+
// sleep 更新发言时间,todayTime的单位是分钟
65+
func (ctdb *chattimedb) updateChatTime(gid, uid int64) (todayTime int64, remindFlag bool) {
66+
db := (*gorm.DB)(ctdb)
67+
now := time.Now()
68+
st := ChatTime{
69+
GroupID: gid,
70+
UserID: uid,
71+
LastTime: now,
72+
}
73+
if err := db.Model(&ChatTime{}).Where("group_id = ? and user_id = ?", gid, uid).First(&st).Error; err != nil {
74+
if gorm.IsRecordNotFoundError(err) {
75+
db.Model(&ChatTime{}).Create(&st)
76+
}
77+
} else {
78+
// 如果不是同一天,把todayTime重置
79+
if st.LastTime.YearDay() != now.YearDay() {
80+
db.Model(&ChatTime{}).Where("group_id = ? and user_id = ?", gid, uid).Update(
81+
map[string]any{
82+
"last_time": now,
83+
"today_time": 0,
84+
})
85+
} else {
86+
userChatTime := int64(now.Sub(st.LastTime).Seconds())
87+
// 当聊天时间间隔很大的话,则不计入时长
88+
if userChatTime < chatInterval {
89+
db.Model(&ChatTime{}).Where("group_id = ? and user_id = ?", gid, uid).Update(
90+
map[string]any{
91+
"last_time": now,
92+
"today_time": st.TodayTime + userChatTime,
93+
"total_time": st.TotalTime + userChatTime,
94+
})
95+
todayTime = (st.TodayTime + userChatTime) / 60
96+
remindFlag = getLevel(int(st.TodayTime+userChatTime)/60) > getLevel(int(st.TodayTime/60))
97+
}
98+
99+
}
100+
}
101+
return
102+
}
103+
104+
// getChatTime 获得用户聊天时长,todayTime,totalTime的单位是分钟
105+
func (ctdb *chattimedb) getChatTime(gid, uid int64) (todayTime int64, totalTime int64) {
106+
db := (*gorm.DB)(ctdb)
107+
st := ChatTime{}
108+
_ = db.Model(&ChatTime{}).Where("group_id = ? and user_id = ?", gid, uid).First(&st)
109+
todayTime = st.TodayTime / 60
110+
totalTime = st.TotalTime / 60
111+
return
112+
}
113+
114+
// getChatRank 获得水群排名
115+
func (ctdb *chattimedb) getChatRank(gid int64) (chatTimeList []ChatTime) {
116+
db := (*gorm.DB)(ctdb)
117+
_ = db.Model(&ChatTime{}).Where("group_id = ?", gid).Order("today_time DESC").Find(&chatTimeList)
118+
return
119+
}
120+
121+
// getLevel 用时长判断等级
122+
func getLevel(t int) int {
123+
for i := len(levelArray) - 1; i >= 0; i-- {
124+
if t >= levelArray[i] {
125+
return i + 1
126+
}
127+
}
128+
return 0
129+
}

0 commit comments

Comments
 (0)