This commit is contained in:
2026-06-13 10:58:53 +08:00
parent f9311292cc
commit c6b2bb7800
5 changed files with 46 additions and 32 deletions

View File

@@ -1,27 +1,26 @@
import assert from 'node:assert/strict';
import { buildVocabularySummaryFilters } from './vocabularyAuditFilters';
import {
applyVocabularySummaryItemFilters,
buildVocabularySummaryFilters
} from './vocabularyAuditFilters';
const correctWordFilter = buildVocabularySummaryFilters({ minCorrectWords: '40' });
assert.deepEqual(correctWordFilter, {
minCorrectWords: 40,
const uniqueWordFilter = buildVocabularySummaryFilters({ minUniqueWords: '40' });
assert.deepEqual(uniqueWordFilter, {
minUniqueWords: 40,
userMatchStages: [],
baseMatch: {
'stats.correctWords': { $gte: 40 }
}
baseMatch: {}
});
const legacyFilter = buildVocabularySummaryFilters({ minWords: '35' });
const legacyFilter = buildVocabularySummaryFilters({ minCorrectWords: '35' });
assert.deepEqual(legacyFilter, {
minCorrectWords: 35,
minUniqueWords: 35,
userMatchStages: [],
baseMatch: {
'stats.correctWords': { $gte: 35 }
}
baseMatch: {}
});
const emptyFilter = buildVocabularySummaryFilters({});
assert.deepEqual(emptyFilter, {
minCorrectWords: undefined,
minUniqueWords: undefined,
userMatchStages: [],
baseMatch: {}
});
@@ -36,7 +35,14 @@ assert.deepEqual(studentFilter.userMatchStages, [{
}
}]);
const invalidFilter = buildVocabularySummaryFilters({ minCorrectWords: '4.5' });
assert.deepEqual(invalidFilter, { error: '正确单词数量必须是正整数' });
const invalidFilter = buildVocabularySummaryFilters({ minUniqueWords: '4.5' });
assert.deepEqual(invalidFilter, { error: '去重单词数量必须是正整数' });
const filteredItems = applyVocabularySummaryItemFilters([
{ userId: 'below', uniqueWords: 39 },
{ userId: 'equal', uniqueWords: 40 },
{ userId: 'above', uniqueWords: 41 }
], 40);
assert.deepEqual(filteredItems.map(item => item.userId), ['equal', 'above']);
console.log('vocabularyAuditFilters tests passed');

View File

@@ -18,11 +18,11 @@ const parseOptionalPositiveInt = (value: unknown, fieldName: string) => {
export const buildVocabularySummaryFilters = (query: Record<string, any>) => {
const studentNo = String(query.studentNo || '').trim();
const rawMinCorrectWords = query.minCorrectWords ?? query.minWords;
const wordCountResult = parseOptionalPositiveInt(rawMinCorrectWords, '正确单词数量');
const rawMinUniqueWords = query.minUniqueWords ?? query.minCorrectWords ?? query.minWords;
const wordCountResult = parseOptionalPositiveInt(rawMinUniqueWords, '去重单词数量');
if ('error' in wordCountResult) return { error: wordCountResult.error };
const minCorrectWords = wordCountResult.value;
const minUniqueWords = wordCountResult.value;
const userMatchStages = studentNo
? [{
$match: {
@@ -35,13 +35,18 @@ export const buildVocabularySummaryFilters = (query: Record<string, any>) => {
: [];
const baseMatch: Record<string, any> = {};
if (typeof minCorrectWords === 'number') {
baseMatch['stats.correctWords'] = { $gte: minCorrectWords };
}
return {
minCorrectWords,
minUniqueWords,
userMatchStages,
baseMatch
};
};
export const applyVocabularySummaryItemFilters = <T extends { uniqueWords?: number }>(
items: T[],
minUniqueWords?: number
): T[] => {
if (typeof minUniqueWords !== 'number') return items;
return items.filter(item => Number(item.uniqueWords || 0) >= minUniqueWords);
};