fix(admin): 修复按站点筛选时统计数据计算错误

之前当提供 siteId 参数时,SQL 查询会添加 WHERE 子句进行过滤,导致 domains 数据也只包含该站点的评论,这与预期行为不符。预期是 domains 应始终返回所有站点的统计数据,而 summary 才根据 siteId 进行过滤。

现在改为始终查询所有评论,然后在内存中根据 siteId 过滤 rowsForSummary 以计算 summary,确保 domains 包含全局数据。
This commit is contained in:
anghunk
2026-02-09 17:51:51 +08:00
parent a39689ed42
commit 860830cee2
2 changed files with 104 additions and 9 deletions

View File

@@ -0,0 +1,92 @@
import { describe, it, expect, vi } from 'vitest';
import { getStats } from './getStats';
describe('getStats siteId filtering behavior', () => {
const createMockContext = (rows: any[], siteId?: string) => {
const allMock = vi.fn().mockResolvedValue({ results: rows });
const prepareMock = vi.fn().mockReturnValue({
all: allMock
});
const c = {
req: {
query: (key: string) => {
if (key === 'siteId') return siteId;
return undefined;
}
},
env: {
CWD_DB: {
prepare: prepareMock
}
},
json: vi.fn()
} as any;
return { c, prepareMock, allMock };
};
it('returns global domains while summary is filtered by siteId', async () => {
const now = Date.now();
const baseDay = new Date(now);
baseDay.setUTCHours(0, 0, 0, 0);
const today = baseDay.getTime();
const rows = [
{
created: today,
status: 'approved',
site_id: 'blog'
},
{
created: today,
status: 'pending',
site_id: 'docs'
},
{
created: today,
status: 'rejected',
site_id: ''
}
];
const { c } = createMockContext(rows, 'blog');
await getStats(c);
expect(c.json).toHaveBeenCalledTimes(1);
const response = (c.json as any).mock.calls[0][0];
expect(response.summary).toEqual({
total: 1,
approved: 1,
pending: 0,
rejected: 0
});
expect(response.domains).toEqual([
{
domain: 'blog',
total: 1,
approved: 1,
pending: 0,
rejected: 0
},
{
domain: 'docs',
total: 1,
approved: 0,
pending: 1,
rejected: 0
},
{
domain: 'default',
total: 1,
approved: 0,
pending: 0,
rejected: 1
}
]);
});
});

View File

@@ -17,15 +17,9 @@ export const getStats = async (c: Context<{ Bindings: Bindings }>) => {
const rawSiteId = c.req.query('siteId');
const siteId = rawSiteId && rawSiteId !== 'default' ? rawSiteId : null;
let sql = 'SELECT created, status, site_id FROM Comment';
const params: any[] = [];
if (siteId) {
sql += ' WHERE site_id = ?';
params.push(siteId);
}
const { results } = await c.env.CWD_DB.prepare(sql).bind(...params).all<{
const { results } = await c.env.CWD_DB.prepare(
'SELECT created, status, site_id FROM Comment'
).all<{
created: number;
status: string;
site_id: string | null;
@@ -65,7 +59,16 @@ export const getStats = async (c: Context<{ Bindings: Bindings }>) => {
} else if (row.status === 'rejected') {
counts.rejected += 1;
}
}
const rowsForSummary = siteId
? results.filter((row) => {
const key = row.site_id && row.site_id.trim() ? row.site_id.trim() : 'default';
return key === siteId;
})
: results;
for (const row of rowsForSummary) {
summary.total += 1;
if (row.status === 'approved') {
summary.approved += 1;