fix(Content_type): Content type fix to fit Weixin documenation
This commit is contained in:
@@ -325,6 +325,7 @@ func (s *Service) handleDashboard(c *gin.Context) {
|
||||
"撤回消息":0,
|
||||
}
|
||||
for k, v := range gstats.ByType { if _, ok := msgTypes[k]; ok { msgTypes[k] += v } }
|
||||
for k, v := range gstats.ByType { if _, ok := msgTypes[k]; ok { msgTypes[k] += v } }
|
||||
|
||||
// 时间轴
|
||||
durationDays := 0.0
|
||||
@@ -404,7 +405,7 @@ func (s *Service) handleDashboard(c *gin.Context) {
|
||||
WeeklyAvg int `json:"weekly_avg"`
|
||||
MostActiveHour string `json:"most_active_hour"`
|
||||
}
|
||||
type ContentAnalysis struct { Text int64 `json:"text_messages"`; Images int64 `json:"images"`; Voice int64 `json:"voice_messages"`; Files int64 `json:"files"`; Links int64 `json:"links"`; FileLinkTotal int64 `json:"file_link_total"`; Others int64 `json:"others"` }
|
||||
type ContentAnalysis struct { Text int64 `json:"text_messages"`; Images int64 `json:"images"`; Voice int64 `json:"voice_messages"`; Files int64 `json:"files"`; Links int64 `json:"links"`; Others int64 `json:"others"` }
|
||||
type GroupListItem struct { Name string `json:"name"`; Members int `json:"members"`; Messages int64 `json:"messages"`; Active bool `json:"active"` }
|
||||
type HourlyActivity struct { Hour string `json:"hour"`; Messages int64 `json:"messages"` }
|
||||
type GroupAnalysis struct {
|
||||
@@ -510,16 +511,8 @@ func (s *Service) handleDashboard(c *gin.Context) {
|
||||
GroupAnalysis: GroupAnalysis{
|
||||
Title: "群聊分析",
|
||||
Overview: GroupOverview{ TotalGroups: len(overviewGroups), ActiveGroups: activeGroups, TodayMessages: int(todayMessages), WeeklyAvg: weeklyAvg, MostActiveHour: mostActiveHour },
|
||||
// 扩展:增加 links 与汇总 file_link_total
|
||||
ContentAnalysis: ContentAnalysis{
|
||||
Text: msgTypes["文本消息"],
|
||||
Images: msgTypes["图片消息"],
|
||||
Voice: msgTypes["语音消息"],
|
||||
Files: msgTypes["文件消息"],
|
||||
Links: msgTypes["链接消息"],
|
||||
FileLinkTotal: msgTypes["文件消息"] + msgTypes["链接消息"],
|
||||
Others: totalMsgs - (msgTypes["文本消息"] + msgTypes["图片消息"] + msgTypes["语音消息"] + msgTypes["文件消息"] + msgTypes["链接消息"]),
|
||||
},
|
||||
// 扩展:增加 links 字段(结构体需更新)
|
||||
ContentAnalysis: ContentAnalysis{ Text: msgTypes["文本消息"], Images: msgTypes["图片消息"], Voice: msgTypes["语音消息"], Files: msgTypes["文件消息"], Links: msgTypes["链接消息"], Others: totalMsgs - (msgTypes["文本消息"]+msgTypes["图片消息"]+msgTypes["语音消息"]+msgTypes["文件消息"]+msgTypes["链接消息"]) },
|
||||
GroupList: glist,
|
||||
HourlyActivity: hacts,
|
||||
},
|
||||
|
||||
@@ -982,6 +982,39 @@ func (ds *DataSource) MonthlyTrend(ctx context.Context, months int) ([]model.Mon
|
||||
return trends, nil
|
||||
}
|
||||
|
||||
// GroupMessageTypeStats 统计群聊消息类型分布(Darwin v3)
|
||||
func (ds *DataSource) GroupMessageTypeStats(ctx context.Context) (map[string]int64, error) {
|
||||
result := make(map[string]int64)
|
||||
// 构建群聊 md5 映射
|
||||
mapping := make(map[string]string)
|
||||
if cdb, err := ds.dbm.GetDB(ChatRoom); err == nil {
|
||||
if rows, err2 := cdb.QueryContext(ctx, `SELECT IFNULL(m_nsUsrName,"") FROM GroupContact`); err2 == nil {
|
||||
for rows.Next() { var uname string; if rows.Scan(&uname)==nil && uname!="" { sum := md5.Sum([]byte(uname)); mapping["Chat_"+hex.EncodeToString(sum[:])] = uname } }
|
||||
rows.Close()
|
||||
}
|
||||
}
|
||||
dbs, err := ds.dbm.GetDBs(Message)
|
||||
if err != nil { return result, nil }
|
||||
for _, db := range dbs {
|
||||
trows, err := db.QueryContext(ctx, `SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'Chat_%' AND name NOT LIKE '%_dels'`)
|
||||
if err != nil { continue }
|
||||
var tables []string
|
||||
for trows.Next() { var name string; if trows.Scan(&name)==nil { tables = append(tables, name) } }
|
||||
trows.Close()
|
||||
for _, tbl := range tables { if _, ok := mapping[tbl]; !ok { continue }
|
||||
// 非49
|
||||
q := fmt.Sprintf(`SELECT messageType, COUNT(*) FROM %s WHERE messageType != 49 GROUP BY messageType`, tbl)
|
||||
rows, err2 := db.QueryContext(ctx, q)
|
||||
if err2 == nil { for rows.Next(){ var t int64; var cnt int64; if rows.Scan(&t,&cnt)==nil { label := mapV4TypeToLabel(t); if label!="" { result[label]+=cnt } } }; rows.Close() }
|
||||
// 49
|
||||
q49 := fmt.Sprintf(`SELECT msgContent FROM %s WHERE messageType = 49`, tbl)
|
||||
orows, err3 := db.QueryContext(ctx, q49)
|
||||
if err3 == nil { for orows.Next(){ var mc string; if orows.Scan(&mc)==nil { lc := strings.ToLower(mc); if strings.Contains(lc,"<appmsg"){ if strings.Contains(lc,"<type>") && strings.Contains(lc,"</type>"){ i1:=strings.Index(lc,"<type>"); i2:=strings.Index(lc[i1+6:],"</type>"); if i1>=0 && i2>0 { val := strings.TrimSpace(lc[i1+6:i1+6+i2]); if val=="6" { result["文件消息"]++; continue }; if val=="5" || val=="33" { result["链接消息"]++; continue } } } }; if strings.Contains(lc,"http://") || strings.Contains(lc,"https://") { result["链接消息"]++; continue }; result["XML消息"]++ } }; orows.Close() }
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Heatmap 小时x星期(wday: 0=Sunday..6)
|
||||
func (ds *DataSource) Heatmap(ctx context.Context) ([24][7]int64, error) {
|
||||
var grid [24][7]int64
|
||||
|
||||
@@ -38,6 +38,8 @@ type DataSource interface {
|
||||
GlobalMessageStats(ctx context.Context) (*model.GlobalMessageStats, error)
|
||||
// 群聊消息计数:返回 talker(群名) -> count
|
||||
GroupMessageCounts(ctx context.Context) (map[string]int64, error)
|
||||
// 群聊消息类型分布:返回 typeLabel -> count(只统计群消息)
|
||||
GroupMessageTypeStats(ctx context.Context) (map[string]int64, error)
|
||||
// 群聊今日消息计数:返回 talker(群名) -> today_count
|
||||
GroupTodayMessageCounts(ctx context.Context) (map[string]int64, error)
|
||||
// 本周(从周一00:00起)群聊消息总数(所有群合计)
|
||||
|
||||
@@ -1181,4 +1181,33 @@ func (ds *DataSource) GlobalTodayHourly(ctx context.Context) ([24]int64, error)
|
||||
}
|
||||
}
|
||||
return hours, nil
|
||||
}
|
||||
|
||||
// GroupMessageTypeStats 统计群聊消息类型分布(v4)
|
||||
func (ds *DataSource) GroupMessageTypeStats(ctx context.Context) (map[string]int64, error) {
|
||||
result := make(map[string]int64)
|
||||
cdb, err := ds.dbm.GetDB(Contact)
|
||||
if err != nil { return result, nil }
|
||||
urows, err := cdb.QueryContext(ctx, `SELECT username FROM chat_room`)
|
||||
if err != nil { return result, nil }
|
||||
var rooms []string
|
||||
for urows.Next() { var u string; if urows.Scan(&u)==nil { rooms = append(rooms, u) } }
|
||||
urows.Close()
|
||||
if len(rooms) == 0 { return result, nil }
|
||||
dbs, err := ds.dbm.GetDBs(Message)
|
||||
if err != nil { return result, nil }
|
||||
for _, db := range dbs {
|
||||
for _, uname := range rooms {
|
||||
md5sum := md5.Sum([]byte(uname)); tbl := "Msg_" + hex.EncodeToString(md5sum[:])
|
||||
// 先统计非49
|
||||
q := fmt.Sprintf(`SELECT local_type, COUNT(*) FROM %s WHERE local_type != 49 GROUP BY local_type`, tbl)
|
||||
rows, err := db.QueryContext(ctx, q)
|
||||
if err == nil { for rows.Next(){ var t int64; var cnt int64; if rows.Scan(&t,&cnt)==nil { label := mapV4TypeToLabel(t); if label!="" { result[label]+=cnt } } }; rows.Close() }
|
||||
// 处理49
|
||||
q49 := fmt.Sprintf(`SELECT message_content FROM %s WHERE local_type=49`, tbl)
|
||||
orows, err := db.QueryContext(ctx, q49)
|
||||
if err == nil { for orows.Next(){ var mc []byte; if err := orows.Scan(&mc); err==nil { lc := strings.ToLower(string(mc)); if strings.Contains(lc,"<appmsg"){ if strings.Contains(lc,"<type>") && strings.Contains(lc,"</type>"){ i1:=strings.Index(lc,"<type>"); i2:=strings.Index(lc[i1+6:],"</type>"); if i1>=0 && i2>0 { val := strings.TrimSpace(lc[i1+6:i1+6+i2]); if val=="6" { result["文件消息"]++; continue }; if val=="5" || val=="33" { result["链接消息"]++; continue } } } }; if strings.Contains(lc,"http://") || strings.Contains(lc,"https://") { result["链接消息"]++; continue }; result["XML消息"]++ } }; orows.Close() }
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -902,6 +902,26 @@ func (ds *DataSource) GroupWeekMessageCount(ctx context.Context) (int64, error)
|
||||
return total, nil
|
||||
}
|
||||
|
||||
// GroupMessageTypeStats 统计群聊消息类型分布(Windows v3)
|
||||
func (ds *DataSource) GroupMessageTypeStats(ctx context.Context) (map[string]int64, error) {
|
||||
result := make(map[string]int64)
|
||||
dbs, err := ds.dbm.GetDBs(Message)
|
||||
if err != nil { return result, nil }
|
||||
for _, db := range dbs {
|
||||
rows, err := db.QueryContext(ctx, `SELECT Type, SubType, COUNT(*) FROM MSG WHERE StrTalker LIKE '%@chatroom' GROUP BY Type, SubType`)
|
||||
if err != nil { continue }
|
||||
for rows.Next() {
|
||||
var t int64; var st int64; var cnt int64
|
||||
if rows.Scan(&t,&st,&cnt)==nil {
|
||||
label := mapV3TypeToLabel(t, st)
|
||||
if label != "" { result[label] += cnt }
|
||||
}
|
||||
}
|
||||
rows.Close()
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// MonthlyTrend 返回每月 sent/received(近 months 月,若 months<=0 则返回全部)
|
||||
func (ds *DataSource) MonthlyTrend(ctx context.Context, months int) ([]model.MonthlyTrend, error) {
|
||||
agg := make(map[string][2]int64)
|
||||
|
||||
@@ -153,3 +153,10 @@ func (r *Repository) GroupWeekMessageCount(ctx context.Context) (int64, error) {
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (r *Repository) GroupMessageTypeStats(ctx context.Context) (map[string]int64, error) {
|
||||
if ds, ok := r.ds.(interface{ GroupMessageTypeStats(context.Context) (map[string]int64, error) }); ok {
|
||||
return ds.GroupMessageTypeStats(ctx)
|
||||
}
|
||||
return map[string]int64{}, nil
|
||||
}
|
||||
|
||||
@@ -163,3 +163,7 @@ func (w *DB) GroupTodayMessageCounts() (map[string]int64, error) {
|
||||
func (w *DB) GroupWeekMessageCount() (int64, error) {
|
||||
return w.repo.GroupWeekMessageCount(context.Background())
|
||||
}
|
||||
|
||||
func (w *DB) GroupMessageTypeStats() (map[string]int64, error) {
|
||||
return w.repo.GroupMessageTypeStats(context.Background())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user