Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
downloadUpdate,
getUpdateSavePath,
consumeUpdateCompleteInfo,
savePendingUpdateInfo,
completeUpdateDownload,
getPendingUpdateInfo,
hasInstallFailedInSession,
clearPendingUpdateInfo,
Expand Down Expand Up @@ -525,22 +525,9 @@ function App() {

if (result.success) {
// 使用实际保存路径(可能与请求路径不同,如果从 302 重定向检测到正确文件名)
setDownloadSavePath(result.actualSavePath);
setDownloadStatus('completed');
completeUpdateDownload(updateResult, result.actualSavePath);
log.info('更新下载完成');

// 保存待安装更新信息,以便下次启动时自动安装
savePendingUpdateInfo({
versionName: updateResult.versionName,
releaseNote: updateResult.releaseNote,
channel: updateResult.channel,
downloadSavePath: result.actualSavePath,
fileSize: updateResult.fileSize,
updateType: updateResult.updateType,
downloadSource: updateResult.downloadSource,
timestamp: Date.now(),
});

// 尝试自动安装更新
tryAutoInstallUpdate();
} else {
Expand Down Expand Up @@ -1165,12 +1152,16 @@ function App() {
// 检查是否有待安装的更新(上次下载完成但未安装)
// 调试版本跳过待安装更新检测
if (!isDebugVersion(result.interface.version)) {
const pendingUpdate = await getPendingUpdateInfo(result.interface.version);
const pendingUpdate = await getPendingUpdateInfo(
result.interface.version,
result.interface.mirrorchyan_rid,
);
if (pendingUpdate) {
log.info('检测到待安装更新:', pendingUpdate.versionName);
// 恢复更新状态
setUpdateInfo({
hasUpdate: true,
origin: pendingUpdate.origin,
versionName: pendingUpdate.versionName,
releaseNote: pendingUpdate.releaseNote,
channel: pendingUpdate.channel,
Expand Down
16 changes: 2 additions & 14 deletions src/components/UpdatePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
downloadUpdate,
getUpdateSavePath,
MIRRORCHYAN_ERROR_CODES,
savePendingUpdateInfo,
completeUpdateDownload,
} from '@/services/updateService';
import { proxySettingsForUpdateDownload } from '@/services/proxyService';
import { DownloadProgressBar, useOpenUpdateSettings } from './UpdateInfoCard';
Expand Down Expand Up @@ -79,19 +79,7 @@ export function UpdatePanel({ onClose, anchorRef }: UpdatePanelProps) {

if (result.success) {
// 使用实际保存路径(可能与请求路径不同,如果从 302 重定向检测到正确文件名)
setDownloadSavePath(result.actualSavePath);
setDownloadStatus('completed');
// 保存待安装更新信息,以便下次启动时自动安装
savePendingUpdateInfo({
versionName: updateInfo.versionName,
releaseNote: updateInfo.releaseNote,
channel: updateInfo.channel,
downloadSavePath: result.actualSavePath,
fileSize: updateInfo.fileSize,
updateType: updateInfo.updateType,
downloadSource: updateInfo.downloadSource,
timestamp: Date.now(),
});
completeUpdateDownload(updateInfo, result.actualSavePath);
} else {
setDownloadStatus('failed');
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/settings/UpdateSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
checkAndPrepareDownload,
openMirrorChyanWebsite,
downloadUpdate,
completeUpdateDownload,
getUpdateSavePath,
cancelDownload,
MIRRORCHYAN_ERROR_CODES,
Expand Down Expand Up @@ -157,8 +158,7 @@ export function UpdateSection() {

if (result.success) {
// 使用实际保存路径(可能与请求路径不同,如果从 302 重定向检测到正确文件名)
setDownloadSavePath(result.actualSavePath);
setDownloadStatus('completed');
completeUpdateDownload(info, result.actualSavePath);
} else {
setDownloadStatus('failed');
}
Expand Down
40 changes: 39 additions & 1 deletion src/services/updateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,12 @@ export async function checkAndPrepareDownload(

// 始终使用 Mirror酱 检查更新
const updateInfo = await checkUpdate({ ...checkOptions, cdk, channel });
if (updateInfo) {
updateInfo.origin = {
resourceId: checkOptions.resourceId,
baseVersion: checkOptions.currentVersion,
};
}

if (!updateInfo || !updateInfo.hasUpdate) {
return updateInfo;
Expand Down Expand Up @@ -1292,6 +1298,7 @@ export interface UpdateCompleteInfo {
* 待安装的更新信息(下载完成后保存,用于下次启动时自动安装)
*/
export interface PendingUpdateInfo {
origin?: UpdateInfo['origin'];
versionName: string;
releaseNote: string;
channel?: string;
Expand Down Expand Up @@ -1361,19 +1368,50 @@ export function savePendingUpdateInfo(info: PendingUpdateInfo): void {
}
}

/** 保存下载来源和实际包路径后,再发布可安装状态。 */
export function completeUpdateDownload(info: UpdateInfo, downloadSavePath: string): void {
savePendingUpdateInfo({
origin: info.origin,
versionName: info.versionName,
releaseNote: info.releaseNote,
channel: info.channel,
downloadSavePath,
fileSize: info.fileSize,
updateType: info.updateType,
downloadSource: info.downloadSource,
timestamp: Date.now(),
});
const state = useAppStore.getState();
state.setDownloadSavePath(downloadSavePath);
state.setDownloadStatus('completed');
}

/**
* 读取待安装更新信息;仍有效的记录由安装流程清除
* 如果更新包文件丢失,或待安装版本不高于当前安装版本,则自动清除记录
* 来源或基线不匹配、更新包丢失、目标版本过期时,清除记录后重新检查更新。
*/
export async function getPendingUpdateInfo(
installedVersion: string | undefined,
resourceId: string | undefined,
): Promise<PendingUpdateInfo | null> {
try {
const data = localStorage.getItem(PENDING_UPDATE_STORAGE_KEY);
if (!data) return null;

const info = JSON.parse(data) as PendingUpdateInfo;

// 历史记录没有来源时也重新检查,避免猜测旧增量包适用的安装基线。
if (
!resourceId ||
!installedVersion ||
info.origin?.resourceId !== resourceId ||
info.origin.baseVersion !== installedVersion
) {
log.info('待安装更新来源或基线不匹配,清除记录并重新检查更新');
localStorage.removeItem(PENDING_UPDATE_STORAGE_KEY);
return null;
}

// 外部安装器可能已升级程序,旧增量更新不能再覆盖当前安装。
if (isPendingUpdateObsolete(info.versionName, installedVersion)) {
log.info('待安装更新不高于已安装版本,清除过期记录:', info.versionName, installedVersion);
Expand Down
2 changes: 2 additions & 0 deletions src/stores/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export interface ScheduleExecutionInfo {

// 更新信息类型
export interface UpdateInfo {
/** 检查更新时的项目和基线,用于下次启动校验待安装包。 */
origin?: { resourceId: string; baseVersion: string };
hasUpdate: boolean;
versionName: string;
releaseNote: string;
Expand Down
Loading
Loading