fix(admin): 修复按站点筛选时统计数据计算错误
之前当提供 siteId 参数时,SQL 查询会添加 WHERE 子句进行过滤,导致 domains 数据也只包含该站点的评论,这与预期行为不符。预期是 domains 应始终返回所有站点的统计数据,而 summary 才根据 siteId 进行过滤。 现在改为始终查询所有评论,然后在内存中根据 siteId 过滤 rowsForSummary 以计算 summary,确保 domains 包含全局数据。
This commit is contained in:
92
cwd-api/src/api/admin/getStats.spec.ts
Normal file
92
cwd-api/src/api/admin/getStats.spec.ts
Normal 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
|
||||
}
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user