Skip to content

Commit 860830c

Browse files
committed
fix(admin): 修复按站点筛选时统计数据计算错误
之前当提供 siteId 参数时,SQL 查询会添加 WHERE 子句进行过滤,导致 domains 数据也只包含该站点的评论,这与预期行为不符。预期是 domains 应始终返回所有站点的统计数据,而 summary 才根据 siteId 进行过滤。 现在改为始终查询所有评论,然后在内存中根据 siteId 过滤 rowsForSummary 以计算 summary,确保 domains 包含全局数据。
1 parent a39689e commit 860830c

File tree

2 files changed

+104
-9
lines changed

2 files changed

+104
-9
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { describe, it, expect, vi } from 'vitest';
2+
import { getStats } from './getStats';
3+
4+
describe('getStats siteId filtering behavior', () => {
5+
const createMockContext = (rows: any[], siteId?: string) => {
6+
const allMock = vi.fn().mockResolvedValue({ results: rows });
7+
const prepareMock = vi.fn().mockReturnValue({
8+
all: allMock
9+
});
10+
11+
const c = {
12+
req: {
13+
query: (key: string) => {
14+
if (key === 'siteId') return siteId;
15+
return undefined;
16+
}
17+
},
18+
env: {
19+
CWD_DB: {
20+
prepare: prepareMock
21+
}
22+
},
23+
json: vi.fn()
24+
} as any;
25+
26+
return { c, prepareMock, allMock };
27+
};
28+
29+
it('returns global domains while summary is filtered by siteId', async () => {
30+
const now = Date.now();
31+
const baseDay = new Date(now);
32+
baseDay.setUTCHours(0, 0, 0, 0);
33+
const today = baseDay.getTime();
34+
35+
const rows = [
36+
{
37+
created: today,
38+
status: 'approved',
39+
site_id: 'blog'
40+
},
41+
{
42+
created: today,
43+
status: 'pending',
44+
site_id: 'docs'
45+
},
46+
{
47+
created: today,
48+
status: 'rejected',
49+
site_id: ''
50+
}
51+
];
52+
53+
const { c } = createMockContext(rows, 'blog');
54+
55+
await getStats(c);
56+
57+
expect(c.json).toHaveBeenCalledTimes(1);
58+
const response = (c.json as any).mock.calls[0][0];
59+
60+
expect(response.summary).toEqual({
61+
total: 1,
62+
approved: 1,
63+
pending: 0,
64+
rejected: 0
65+
});
66+
67+
expect(response.domains).toEqual([
68+
{
69+
domain: 'blog',
70+
total: 1,
71+
approved: 1,
72+
pending: 0,
73+
rejected: 0
74+
},
75+
{
76+
domain: 'docs',
77+
total: 1,
78+
approved: 0,
79+
pending: 1,
80+
rejected: 0
81+
},
82+
{
83+
domain: 'default',
84+
total: 1,
85+
approved: 0,
86+
pending: 0,
87+
rejected: 1
88+
}
89+
]);
90+
});
91+
});
92+

cwd-api/src/api/admin/getStats.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,9 @@ export const getStats = async (c: Context<{ Bindings: Bindings }>) => {
1717
const rawSiteId = c.req.query('siteId');
1818
const siteId = rawSiteId && rawSiteId !== 'default' ? rawSiteId : null;
1919

20-
let sql = 'SELECT created, status, site_id FROM Comment';
21-
const params: any[] = [];
22-
23-
if (siteId) {
24-
sql += ' WHERE site_id = ?';
25-
params.push(siteId);
26-
}
27-
28-
const { results } = await c.env.CWD_DB.prepare(sql).bind(...params).all<{
20+
const { results } = await c.env.CWD_DB.prepare(
21+
'SELECT created, status, site_id FROM Comment'
22+
).all<{
2923
created: number;
3024
status: string;
3125
site_id: string | null;
@@ -65,7 +59,16 @@ export const getStats = async (c: Context<{ Bindings: Bindings }>) => {
6559
} else if (row.status === 'rejected') {
6660
counts.rejected += 1;
6761
}
62+
}
63+
64+
const rowsForSummary = siteId
65+
? results.filter((row) => {
66+
const key = row.site_id && row.site_id.trim() ? row.site_id.trim() : 'default';
67+
return key === siteId;
68+
})
69+
: results;
6870

71+
for (const row of rowsForSummary) {
6972
summary.total += 1;
7073
if (row.status === 'approved') {
7174
summary.approved += 1;

0 commit comments

Comments
 (0)