task-144: 前端 live progress 合并补强(mergeHistoryItemPreservingLiveProgress 纯函数:缺失保留/有效覆盖/可下载不合并/幂等)+ 11 条测试

This commit is contained in:
2026-09-02 05:48:09 +08:00
parent 5e5056b99d
commit 6c674f0f1d
2 changed files with 186 additions and 0 deletions
@@ -0,0 +1,52 @@
/**
* live progress 合并(Task 144)。
*
* history 条目缺失 file 进度时保留实时缓存(live)进度;live 有值且有效时
* 以 live 为准;history 已可下载(fileReady/downloadUrl 就绪)时不覆盖——
* 结果文件既成,实时进度无意义。纯函数无副作用,入参不修改。
*/
export const FILE_PROGRESS_KEYS = [
'fileProgressPercent',
'fileProgressCurrent',
'fileProgressTotal',
'fileProgressMessage',
'fileReady',
'fileStatus',
] as const
export interface DownloadableItem {
resultId?: number | null
fileReady?: boolean | null
downloadUrl?: string | null
}
/** 可下载判定:有结果记录且文件已就绪(fileReady 或 downloadUrl 非空)。 */
export function canDownloadItem(item: DownloadableItem | null | undefined): boolean {
if (!item) return false
return Boolean(item.resultId && (item.fileReady || item.downloadUrl))
}
/** 有效进度值:仅 fileProgressPercent 需要严格 >0,其余字段非空即可(0 是合法计数)。 */
export function hasMeaningfulProgress(key: string, value: unknown): boolean {
if (value === undefined || value === null) return false
if (key === 'fileProgressPercent' && typeof value === 'number') {
return value > 0
}
return true
}
export function mergeHistoryItemPreservingLiveProgress<T extends Record<string, unknown>>(
history: T,
live: T | undefined,
): T {
if (!live) return history
if (canDownloadItem(history as unknown as DownloadableItem)) return history
const result: Record<string, unknown> = { ...history }
for (const key of FILE_PROGRESS_KEYS) {
const value = (live as Record<string, unknown>)[key]
if (hasMeaningfulProgress(key, value)) {
result[key] = value
}
}
return result as T
}