|
|
@@ -77,7 +77,14 @@ import {
|
|
|
styleUrls: ['./message-dashboard.component.css'],
|
|
|
})
|
|
|
export class MessageDashboardComponent implements OnInit {
|
|
|
- isLoading = false;
|
|
|
+ overallLoading = false;
|
|
|
+ strategyLoading = false;
|
|
|
+ templateLoading = false;
|
|
|
+ ccLoading = false;
|
|
|
+ imageLoading = false;
|
|
|
+ dailyTrendsLoading = false;
|
|
|
+ chartLoading = false;
|
|
|
+
|
|
|
overallStats: any = null;
|
|
|
strategyStats: any[] = [];
|
|
|
templateStats: any[] = [];
|
|
|
@@ -317,15 +324,11 @@ export class MessageDashboardComponent implements OnInit {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- this.isLoading = true;
|
|
|
-
|
|
|
- console.log(this.dateRange[0], this.dateRange[1]); // 打印: Mon Sep 15 2025 02:22:55 GMT+0800 (中国标准时间) Mon Sep 15 2025 02:22:55 GMT+0800 (中国标准时间)
|
|
|
- this.dateRange[0]
|
|
|
- ? console.log(this.formatDateForApi(this.dateRange[0]))
|
|
|
- : ''; // 打印 2025-09-14
|
|
|
- this.dateRange[1]
|
|
|
- ? console.log(this.formatDateForApi(this.dateRange[1]))
|
|
|
- : ''; // 打印 2025-09-14 为什么
|
|
|
+ // 仅重置当前激活标签页的数据
|
|
|
+ if (this.activeTab === 0) this.strategyStats = [];
|
|
|
+ if (this.activeTab === 1) this.templateStats = [];
|
|
|
+ if (this.activeTab === 2) this.ccStats = [];
|
|
|
+ if (this.activeTab === 3) this.imageStats = [];
|
|
|
|
|
|
const params = new HttpParams()
|
|
|
.set(
|
|
|
@@ -338,104 +341,174 @@ export class MessageDashboardComponent implements OnInit {
|
|
|
)
|
|
|
.set('strategyName', this.selectedStrategy || '');
|
|
|
|
|
|
- forkJoin({
|
|
|
- overall: this.http
|
|
|
- .get(`/api/message/statistics/overall`, { params })
|
|
|
- .pipe(
|
|
|
- map((res: any) => res?.data || null),
|
|
|
- catchError((err) => {
|
|
|
- console.error('Failed to load overall statistics:', err);
|
|
|
- this.message.error('加载整体统计失败');
|
|
|
- return of(null);
|
|
|
- })
|
|
|
- ),
|
|
|
- strategies: this.http
|
|
|
- .get(`/api/message/statistics/by-strategy`, { params })
|
|
|
- .pipe(
|
|
|
- map((res: any) => res?.data || []),
|
|
|
- catchError((err) => {
|
|
|
- console.error('Failed to load strategy statistics:', err);
|
|
|
- this.message.error('加载策略统计失败');
|
|
|
- return of([]);
|
|
|
- })
|
|
|
- ),
|
|
|
- templates: this.http
|
|
|
- .get(`/api/message/statistics/by-template`, { params })
|
|
|
- .pipe(
|
|
|
- map((res: any) => res?.data || []),
|
|
|
- catchError((err) => {
|
|
|
- console.error('Failed to load template statistics:', err);
|
|
|
- this.message.error('加载模板统计失败');
|
|
|
- return of([]);
|
|
|
- })
|
|
|
- ),
|
|
|
- ccs: this.http.get(`/api/message/statistics/by-cc`, { params }).pipe(
|
|
|
+ // 始终加载整体统计和图表数据
|
|
|
+ this.overallLoading = true;
|
|
|
+ this.http
|
|
|
+ .get(`/api/message/statistics/overall`, { params })
|
|
|
+ .pipe(
|
|
|
+ map((res: any) => res?.data || null),
|
|
|
+ catchError((err) => {
|
|
|
+ console.error('Failed to load overall statistics:', err);
|
|
|
+ this.message.error('加载整体统计失败');
|
|
|
+ return of(null);
|
|
|
+ }),
|
|
|
+ finalize(() => (this.overallLoading = false))
|
|
|
+ )
|
|
|
+ .subscribe((data) => {
|
|
|
+ this.overallStats = data;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 加载每日趋势(图表数据)
|
|
|
+ this.chartLoading = true;
|
|
|
+ this.http
|
|
|
+ .get(`/api/message/statistics/daily-trends`, { params })
|
|
|
+ .pipe(
|
|
|
map((res: any) => res?.data || []),
|
|
|
catchError((err) => {
|
|
|
- console.error('Failed to load cc statistics:', err);
|
|
|
- this.message.error('加载国家统计失败');
|
|
|
+ console.error('Failed to load daily trends:', err);
|
|
|
+ this.message.error('加载每日趋势失败');
|
|
|
return of([]);
|
|
|
- })
|
|
|
- ),
|
|
|
- images: this.http
|
|
|
- .get(`/api/message/statistics/by-image`, { params })
|
|
|
- .pipe(
|
|
|
- map((res: any) => res?.data || []),
|
|
|
- catchError((err) => {
|
|
|
- console.error('Failed to load image statistics:', err);
|
|
|
- this.message.error('加载图片统计失败');
|
|
|
- return of([]);
|
|
|
- })
|
|
|
- ),
|
|
|
- dailyTrends: this.http
|
|
|
- .get(`/api/message/statistics/daily-trends`, { params })
|
|
|
- .pipe(
|
|
|
- map((res: any) => res?.data || []),
|
|
|
- catchError((err) => {
|
|
|
- console.error('Failed to load daily trends:', err);
|
|
|
- this.message.error('加载每日趋势失败');
|
|
|
- return of([]);
|
|
|
- })
|
|
|
- ),
|
|
|
- })
|
|
|
+ }),
|
|
|
+ finalize(() => (this.chartLoading = false))
|
|
|
+ )
|
|
|
+ .subscribe((data) => {
|
|
|
+ this.dailyTrends = data;
|
|
|
+ this.updateChartData();
|
|
|
+ });
|
|
|
+
|
|
|
+ // 根据当前激活的标签页加载对应数据
|
|
|
+ this.loadActiveTabData(params);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载当前激活标签页的数据
|
|
|
+ loadActiveTabData(params: HttpParams): void {
|
|
|
+ switch (this.activeTab) {
|
|
|
+ case 0: // 策略统计
|
|
|
+ this.loadStrategyData(params);
|
|
|
+ break;
|
|
|
+ case 1: // 模板统计
|
|
|
+ this.loadTemplateData(params);
|
|
|
+ break;
|
|
|
+ case 2: // 国家统计
|
|
|
+ this.loadCcData(params);
|
|
|
+ break;
|
|
|
+ case 3: // 图片统计
|
|
|
+ this.loadImageData(params);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 拆分各标签页数据加载方法
|
|
|
+ private loadStrategyData(params: HttpParams): void {
|
|
|
+ this.strategyLoading = true;
|
|
|
+ this.http
|
|
|
+ .get(`/api/message/statistics/by-strategy`, { params })
|
|
|
.pipe(
|
|
|
- finalize(() => {
|
|
|
- this.isLoading = false;
|
|
|
- this.cd.detectChanges();
|
|
|
- })
|
|
|
+ map((res: any) => res?.data || []),
|
|
|
+ catchError((err) => {
|
|
|
+ console.error('Failed to load strategy statistics:', err);
|
|
|
+ this.message.error('加载策略统计失败');
|
|
|
+ return of([]);
|
|
|
+ }),
|
|
|
+ finalize(() => (this.strategyLoading = false))
|
|
|
)
|
|
|
- .subscribe((results: any) => {
|
|
|
- this.overallStats = results.overall;
|
|
|
- this.strategyStats = results.strategies.map((item: any) => ({
|
|
|
+ .subscribe((data) => {
|
|
|
+ this.strategyStats = data.map((item: any) => ({
|
|
|
...item,
|
|
|
expanded: false,
|
|
|
dailyData: null,
|
|
|
loading: false,
|
|
|
}));
|
|
|
- this.templateStats = results.templates.map((item: any) => ({
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private loadTemplateData(params: HttpParams): void {
|
|
|
+ this.templateLoading = true;
|
|
|
+ this.http
|
|
|
+ .get(`/api/message/statistics/by-template`, { params })
|
|
|
+ .pipe(
|
|
|
+ map((res: any) => res?.data || []),
|
|
|
+ catchError((err) => {
|
|
|
+ console.error('Failed to load template statistics:', err);
|
|
|
+ this.message.error('加载模板统计失败');
|
|
|
+ return of([]);
|
|
|
+ }),
|
|
|
+ finalize(() => (this.templateLoading = false))
|
|
|
+ )
|
|
|
+ .subscribe((data) => {
|
|
|
+ this.templateStats = data.map((item: any) => ({
|
|
|
...item,
|
|
|
expanded: false,
|
|
|
dailyData: null,
|
|
|
loading: false,
|
|
|
}));
|
|
|
- this.ccStats = results.ccs.map((item: any) => ({
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private loadCcData(params: HttpParams): void {
|
|
|
+ this.ccLoading = true;
|
|
|
+ this.http
|
|
|
+ .get(`/api/message/statistics/by-cc`, { params })
|
|
|
+ .pipe(
|
|
|
+ map((res: any) => res?.data || []),
|
|
|
+ catchError((err) => {
|
|
|
+ console.error('Failed to load cc statistics:', err);
|
|
|
+ this.message.error('加载国家统计失败');
|
|
|
+ return of([]);
|
|
|
+ }),
|
|
|
+ finalize(() => (this.ccLoading = false))
|
|
|
+ )
|
|
|
+ .subscribe((data) => {
|
|
|
+ this.ccStats = data.map((item: any) => ({
|
|
|
...item,
|
|
|
expanded: false,
|
|
|
dailyData: null,
|
|
|
loading: false,
|
|
|
}));
|
|
|
- this.imageStats = results.images.map((item: any) => ({
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private loadImageData(params: HttpParams): void {
|
|
|
+ this.imageLoading = true;
|
|
|
+ this.http
|
|
|
+ .get(`/api/message/statistics/by-image`, { params })
|
|
|
+ .pipe(
|
|
|
+ map((res: any) => res?.data || []),
|
|
|
+ catchError((err) => {
|
|
|
+ console.error('Failed to load image statistics:', err);
|
|
|
+ this.message.error('加载图片统计失败');
|
|
|
+ return of([]);
|
|
|
+ }),
|
|
|
+ finalize(() => (this.imageLoading = false))
|
|
|
+ )
|
|
|
+ .subscribe((data) => {
|
|
|
+ this.imageStats = data.map((item: any) => ({
|
|
|
...item,
|
|
|
expanded: false,
|
|
|
dailyData: null,
|
|
|
loading: false,
|
|
|
}));
|
|
|
- this.dailyTrends = results.dailyTrends;
|
|
|
-
|
|
|
- this.updateChartData();
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ // 添加标签页切换事件处理
|
|
|
+ onTabChange(index: number): void {
|
|
|
+ this.activeTab = index;
|
|
|
+ // 当切换到新标签页时加载对应数据
|
|
|
+ const params = new HttpParams()
|
|
|
+ .set(
|
|
|
+ 'startDate',
|
|
|
+ this.dateRange[0] ? this.formatDateForApi(this.dateRange[0]) : ''
|
|
|
+ )
|
|
|
+ .set(
|
|
|
+ 'endDate',
|
|
|
+ this.dateRange[1] ? this.formatDateForApi(this.dateRange[1]) : ''
|
|
|
+ )
|
|
|
+ .set('strategyName', this.selectedStrategy || '');
|
|
|
+
|
|
|
+ this.loadActiveTabData(params);
|
|
|
+ }
|
|
|
+
|
|
|
// 验证日期范围是否有效
|
|
|
private isDateRangeValid(): boolean {
|
|
|
// 如果只选择了一个日期或未选择日期,视为有效
|
|
|
@@ -707,6 +780,11 @@ export class MessageDashboardComponent implements OnInit {
|
|
|
|
|
|
// 加载每日数据
|
|
|
private loadDailyData(element: any, type: string): void {
|
|
|
+ // 如果已有请求,先取消
|
|
|
+ if (element.subscription) {
|
|
|
+ element.subscription.unsubscribe();
|
|
|
+ }
|
|
|
+
|
|
|
element.loading = true;
|
|
|
let url = '';
|
|
|
const params = new HttpParams()
|
|
|
@@ -747,7 +825,8 @@ export class MessageDashboardComponent implements OnInit {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- this.http
|
|
|
+ // 保存订阅以便取消
|
|
|
+ element.subscription = this.http
|
|
|
.get(url, { params })
|
|
|
.pipe(
|
|
|
map((res: any) => res?.data || []),
|
|
|
@@ -758,6 +837,7 @@ export class MessageDashboardComponent implements OnInit {
|
|
|
}),
|
|
|
finalize(() => {
|
|
|
element.loading = false;
|
|
|
+ element.subscription = null;
|
|
|
})
|
|
|
)
|
|
|
.subscribe((data) => {
|