@@ -33,12 +33,12 @@ import 'analytics_service.dart';
3333class AdvancedAnalyticsService {
3434 final DatabaseService _databaseService;
3535 final AnalyticsService _analyticsService;
36+ Set <String > _excludedUsernames = {};
3637
3738 int ? _filterYear; // 年份过滤器,null表示显示全部年份
3839
3940 // 系统账号和无效账号的黑名单,避免分析时包含无关数据
4041 static const _systemAccounts = {
41- 'filehelper' ,
4242 'fmessage' ,
4343 'medianote' ,
4444 'newsapp' ,
@@ -55,6 +55,11 @@ class AdvancedAnalyticsService {
5555 AdvancedAnalyticsService (this ._databaseService)
5656 : _analyticsService = AnalyticsService (_databaseService);
5757
58+ void setExcludedUsernames (Set <String > usernames) {
59+ _excludedUsernames =
60+ usernames.map ((name) => name.trim ().toLowerCase ()).toSet ();
61+ }
62+
5863 /// 设置年份过滤器,用于限定分析的数据范围
5964 void setYearFilter (int ? year) {
6065 _filterYear = year;
@@ -95,11 +100,17 @@ class AdvancedAnalyticsService {
95100 return false ;
96101 }
97102
103+ bool _isCustomExcluded (String username) {
104+ if (username.isEmpty) return false ;
105+ return _excludedUsernames.contains (username.toLowerCase ());
106+ }
107+
98108 /// 分析作息规律(24小时×7天热力图)
99109 Future <ActivityHeatmap > analyzeActivityPattern () async {
100110 // 使用SQL直接统计,避免加载所有消息到内存
101111 final data = await _databaseService.getActivityHeatmapData (
102112 year: _filterYear,
113+ excludedUsernames: _excludedUsernames,
103114 );
104115
105116 // 计算最大值
@@ -121,7 +132,12 @@ class AdvancedAnalyticsService {
121132 final myWxid = _databaseService.currentAccountWxid;
122133 final normalizedMyWxid = myWxid? .toLowerCase ();
123134 final privateSessions = sessions
124- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
135+ .where (
136+ (s) =>
137+ ! s.isGroup &&
138+ ! _isSystemAccount (s.username) &&
139+ ! _isCustomExcluded (s.username),
140+ )
125141 .where ((s) {
126142 final username = s.username.toLowerCase ();
127143 if (username == 'filehelper' ) return false ;
@@ -346,7 +362,12 @@ class AdvancedAnalyticsService {
346362 final myWxid = _databaseService.currentAccountWxid;
347363 final normalizedMyWxid = myWxid? .toLowerCase ();
348364 final privateSessions = sessions
349- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
365+ .where (
366+ (s) =>
367+ ! s.isGroup &&
368+ ! _isSystemAccount (s.username) &&
369+ ! _isCustomExcluded (s.username),
370+ )
350371 .where ((s) {
351372 final username = s.username.toLowerCase ();
352373 if (username == 'filehelper' ) return false ;
@@ -407,7 +428,12 @@ class AdvancedAnalyticsService {
407428 final myWxid = _databaseService.currentAccountWxid;
408429 final normalizedMyWxid = myWxid? .toLowerCase ();
409430 final privateSessions = sessions
410- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
431+ .where (
432+ (s) =>
433+ ! s.isGroup &&
434+ ! _isSystemAccount (s.username) &&
435+ ! _isCustomExcluded (s.username),
436+ )
411437 .where ((s) {
412438 final username = s.username.toLowerCase ();
413439 if (username == 'filehelper' ) return false ;
@@ -556,7 +582,12 @@ class AdvancedAnalyticsService {
556582 final myWxid = _databaseService.currentAccountWxid;
557583 final normalizedMyWxid = myWxid? .toLowerCase ();
558584 final privateSessions = sessions
559- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
585+ .where (
586+ (s) =>
587+ ! s.isGroup &&
588+ ! _isSystemAccount (s.username) &&
589+ ! _isCustomExcluded (s.username),
590+ )
560591 .where ((s) {
561592 final username = s.username.toLowerCase ();
562593 if (username == 'filehelper' ) return false ;
@@ -625,7 +656,12 @@ class AdvancedAnalyticsService {
625656 final myWxid = _databaseService.currentAccountWxid;
626657 final normalizedMyWxid = myWxid? .toLowerCase ();
627658 final privateSessions = sessions
628- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
659+ .where (
660+ (s) =>
661+ ! s.isGroup &&
662+ ! _isSystemAccount (s.username) &&
663+ ! _isCustomExcluded (s.username),
664+ )
629665 .where ((s) {
630666 final username = s.username.toLowerCase ();
631667 if (username == 'filehelper' ) return false ;
@@ -702,7 +738,12 @@ class AdvancedAnalyticsService {
702738 final myWxid = _databaseService.currentAccountWxid;
703739 final normalizedMyWxid = myWxid? .toLowerCase ();
704740 final privateSessions = sessions
705- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
741+ .where (
742+ (s) =>
743+ ! s.isGroup &&
744+ ! _isSystemAccount (s.username) &&
745+ ! _isCustomExcluded (s.username),
746+ )
706747 .where ((s) {
707748 final username = s.username.toLowerCase ();
708749 if (username == 'filehelper' ) return false ;
@@ -778,7 +819,12 @@ class AdvancedAnalyticsService {
778819 final myWxid = _databaseService.currentAccountWxid;
779820 final normalizedMyWxid = myWxid? .toLowerCase ();
780821 final privateSessions = sessions
781- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
822+ .where (
823+ (s) =>
824+ ! s.isGroup &&
825+ ! _isSystemAccount (s.username) &&
826+ ! _isCustomExcluded (s.username),
827+ )
782828 .where ((s) {
783829 final username = s.username.toLowerCase ();
784830 if (username == 'filehelper' ) return false ;
@@ -869,7 +915,12 @@ class AdvancedAnalyticsService {
869915 Future <List <FriendshipRanking >> getMutualFriendsRanking (int limit) async {
870916 final sessions = await _databaseService.getSessions ();
871917 final privateSessions = sessions
872- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
918+ .where (
919+ (s) =>
920+ ! s.isGroup &&
921+ ! _isSystemAccount (s.username) &&
922+ ! _isCustomExcluded (s.username),
923+ )
873924 .toList ();
874925
875926 final balanceList = < Map <String , dynamic >> [];
@@ -941,7 +992,12 @@ class AdvancedAnalyticsService {
941992 final myWxid = _databaseService.currentAccountWxid;
942993 final normalizedMyWxid = myWxid? .toLowerCase ();
943994 final privateSessions = sessions
944- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
995+ .where (
996+ (s) =>
997+ ! s.isGroup &&
998+ ! _isSystemAccount (s.username) &&
999+ ! _isCustomExcluded (s.username),
1000+ )
9451001 .where ((s) {
9461002 final username = s.username.toLowerCase ();
9471003 if (username == 'filehelper' ) return false ;
@@ -1027,7 +1083,12 @@ class AdvancedAnalyticsService {
10271083 final myWxid = _databaseService.currentAccountWxid;
10281084 final normalizedMyWxid = myWxid? .toLowerCase ();
10291085 final privateSessions = sessions
1030- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
1086+ .where (
1087+ (s) =>
1088+ ! s.isGroup &&
1089+ ! _isSystemAccount (s.username) &&
1090+ ! _isCustomExcluded (s.username),
1091+ )
10311092 .where ((s) {
10321093 final username = s.username.toLowerCase ();
10331094 if (username == 'filehelper' ) return false ;
@@ -1130,7 +1191,12 @@ class AdvancedAnalyticsService {
11301191 final myWxid = _databaseService.currentAccountWxid;
11311192 final normalizedMyWxid = myWxid? .toLowerCase ();
11321193 final privateSessions = sessions
1133- .where ((s) => ! s.isGroup && ! _isSystemAccount (s.username))
1194+ .where (
1195+ (s) =>
1196+ ! s.isGroup &&
1197+ ! _isSystemAccount (s.username) &&
1198+ ! _isCustomExcluded (s.username),
1199+ )
11341200 .where ((s) {
11351201 final username = s.username.toLowerCase ();
11361202 if (username == 'filehelper' ) return false ;
@@ -1150,7 +1216,10 @@ class AdvancedAnalyticsService {
11501216
11511217 // 批量获取所有会话的消息日期
11521218 final allSessionsDates = await _databaseService
1153- .getAllPrivateSessionsMessageDates (filterYear: _filterYear);
1219+ .getAllPrivateSessionsMessageDates (
1220+ filterYear: _filterYear,
1221+ excludedUsernames: _excludedUsernames,
1222+ );
11541223
11551224 int globalMaxStreak = 0 ;
11561225 String ? bestFriendUsername;
@@ -1221,6 +1290,7 @@ class AdvancedAnalyticsService {
12211290 Future <List <MessageTypeStats >> analyzeMessageTypeDistribution () async {
12221291 final typeCount = await _databaseService.getAllMessageTypeDistribution (
12231292 filterYear: _filterYear,
1293+ excludedUsernames: _excludedUsernames,
12241294 );
12251295
12261296 if (typeCount.isEmpty) return [];
@@ -1289,6 +1359,7 @@ class AdvancedAnalyticsService {
12891359 Future <MessageLengthData > analyzeMessageLength () async {
12901360 final stats = await _databaseService.getTextMessageLengthStats (
12911361 year: _filterYear,
1362+ excludedUsernames: _excludedUsernames,
12921363 );
12931364
12941365 final averageLength = stats['averageLength' ] as double ;
0 commit comments