import type { NormalizedOfficeDocumentConfig } from '../types';
|
|
/** 只恢复可重新鉴权的预览;预览请求失败后最多换票重试三次。 */
|
export async function withDmsPreviewTicketRefresh<T>(
|
config: NormalizedOfficeDocumentConfig,
|
isCurrent: () => boolean,
|
load: () => Promise<T>,
|
): Promise<T | undefined> {
|
if (config.fileType !== 'dms' || !config.refreshDmsPreviewTicket) return load();
|
|
const refresh = async () => {
|
const ticket = await config.refreshDmsPreviewTicket!();
|
if (!isCurrent()) return false;
|
if (!ticket?.accessTicket || !ticket.fileName || ticket.fileVersionId !== config.file.fileId) {
|
throw new Error('后端返回的 DMS 预览票据不完整或文件版本不匹配');
|
}
|
config.dmsAccessTicket = ticket.accessTicket;
|
config.dmsPreviewExpiresAt = ticket.expiresAt;
|
config.file = { ...config.file, name: ticket.fileName, fileSize: ticket.sizeBytes };
|
return true;
|
};
|
|
const expiresAt = config.dmsPreviewExpiresAt ? new Date(config.dmsPreviewExpiresAt).getTime() : NaN;
|
const needsRefresh = expiresAt <= Date.now() + 5000;
|
if (needsRefresh && !(await refresh())) return;
|
if (!isCurrent()) return;
|
for (let retryCount = 0; ; retryCount++) {
|
try {
|
return await load();
|
} catch (error: any) {
|
const message = error?.response?.data?.msg ?? error?.message;
|
if (retryCount >= 3 || message !== 'DMS 预览票据无效或已过期' || !isCurrent()) throw error;
|
if (!(await refresh())) return;
|
}
|
}
|
}
|