task-105(任务与重复分析中心): 实现视频任务批量选择

新增 src/pages/tasks/image-video-selection.ts:卡片选择的纯 Set 操作
(切换/批量/全选判定/半选判定)。

TDD: task-105.test.ts 8 用例先 RED 后 GREEN。
This commit is contained in:
2026-09-05 17:10:08 +08:00
parent a816bfa899
commit 64f9ac54cf
2 changed files with 115 additions and 0 deletions
@@ -0,0 +1,48 @@
/** 视频卡片批量选择状态(任务 105):不变量优先的纯 Set 操作,无框架依赖。 */
/** 空选择集。 */
export function clearVideoSelection(): Set<string> {
return new Set<string>()
}
function validKey(key: string): boolean {
return typeof key === 'string' && key.length > 0
}
/** 切换单卡选择(有则移除、无则加入)。 */
export function videoSelectionToggle(selection: Set<string>, key: string): Set<string> {
const next = new Set(selection)
if (!validKey(key)) return next
if (next.has(key)) next.delete(key)
else next.add(key)
return next
}
/** 批量加入(幂等)。 */
export function videoSelectionAdd(selection: Set<string>, keys: readonly string[]): Set<string> {
const next = new Set(selection)
for (const key of keys) if (validKey(key)) next.add(key)
return next
}
/** 批量移除(缺失键无操作)。 */
export function videoSelectionRemove(selection: Set<string>, keys: readonly string[]): Set<string> {
const next = new Set(selection)
for (const key of keys) next.delete(key)
return next
}
export function countVideoSelection(selection: Set<string>): number {
return selection.size
}
/** 是否全部卡被选中(空卡列表视作未全选)。 */
export function allCardsSelected(selection: Set<string>, keys: readonly string[]): boolean {
return keys.length > 0 && keys.every((key) => selection.has(key))
}
/** 是否部分卡被选中(部分但非全部)。 */
export function partialCardsSelected(selection: Set<string>, keys: readonly string[]): boolean {
const selectedCount = keys.filter((key) => selection.has(key)).length
return selectedCount > 0 && selectedCount < keys.length
}