refactor(网页发布): 首次发布与更新共用统一发布组装
- handleSubmit 与 handleUpdateSubmit 原先逐字复制 压包→媒体→metadata→parts→submitGamePublish - 抽成组件内 runUnifiedPublish(target, versionNumber, priceMudPoints),成功收尾仍各模式自理 - 新增字段或校验变化不再需要改两处
This commit is contained in:
@@ -48,7 +48,11 @@ import {
|
||||
resolveGamePublishPriceMudPoints,
|
||||
resolvePublishMetadataError,
|
||||
} from './gamePublishMetadata';
|
||||
import { createGamePublishSubmission } from './gamePublishSubmission';
|
||||
import {
|
||||
createGamePublishSubmission,
|
||||
type GamePublishSubmissionSuccess,
|
||||
type GamePublishSubmissionTarget,
|
||||
} from './gamePublishSubmission';
|
||||
import { prepareGamePackage } from './gameZipPackage';
|
||||
|
||||
type GamePublishPageProps = {
|
||||
@@ -418,6 +422,42 @@ export function GamePublishPage({
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一发布接口的一次完整组装:压包 → 读媒体 → 组 metadata/parts → 提交。
|
||||
*
|
||||
* 首次发布与更新模式只差 `target` 与冻结版本号;编排必须共用一处,否则新增字段或校验变化时
|
||||
* 两条链路会各自漂移。成功后的收尾由调用方按模式各自处理。
|
||||
*/
|
||||
async function runUnifiedPublish(input: {
|
||||
target: GamePublishSubmissionTarget;
|
||||
versionNumber: number;
|
||||
priceMudPoints: number;
|
||||
}): Promise<GamePublishSubmissionSuccess> {
|
||||
const prepared = await prepareGamePackage(packageFile as File);
|
||||
const submission = buildGamePublishMediaSubmission(
|
||||
coverImage,
|
||||
screenshotImages,
|
||||
);
|
||||
const gameMetadata = buildPublishGameMetadata(submission);
|
||||
const media = buildPublishMediaParts(submission);
|
||||
return submitGamePublish({
|
||||
ownerUserId: currentUserId,
|
||||
title,
|
||||
target: input.target,
|
||||
versionNumber: input.versionNumber,
|
||||
packageSha256: prepared.sha256,
|
||||
packageBytes: prepared.totalBytes,
|
||||
packageFileCount: prepared.fileCount,
|
||||
packageEntryPath: 'index.html',
|
||||
priceMudPoints: input.priceMudPoints,
|
||||
gameMetadata,
|
||||
packageBody: new Blob([prepared.bytes as unknown as BlobPart], {
|
||||
type: 'application/zip',
|
||||
}),
|
||||
media,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新模式:走统一发布接口在既有 `gameId` 下创建不可变新版本并送审;
|
||||
* 公开版本只在管理员通过后切换,期间旧版本继续在线。
|
||||
@@ -453,29 +493,11 @@ export function GamePublishPage({
|
||||
setIsSubmitting(true);
|
||||
setError('');
|
||||
try {
|
||||
const prepared = await prepareGamePackage(packageFile);
|
||||
const submission = buildGamePublishMediaSubmission(
|
||||
coverImage,
|
||||
screenshotImages,
|
||||
);
|
||||
const gameMetadata = buildPublishGameMetadata(submission);
|
||||
const media = buildPublishMediaParts(submission);
|
||||
// 统一发布接口只用 gameId + 冻结版本号做身份,不再读后端版本上限。
|
||||
const result = await submitGamePublish({
|
||||
ownerUserId: currentUserId,
|
||||
title,
|
||||
const result = await runUnifiedPublish({
|
||||
target: { mode: 'update', gameId: updateContext.gameId },
|
||||
versionNumber: updateContext.versionNumber + 1,
|
||||
packageSha256: prepared.sha256,
|
||||
packageBytes: prepared.totalBytes,
|
||||
packageFileCount: prepared.fileCount,
|
||||
packageEntryPath: 'index.html',
|
||||
priceMudPoints: price.priceMudPoints,
|
||||
gameMetadata,
|
||||
packageBody: new Blob([prepared.bytes as unknown as BlobPart], {
|
||||
type: 'application/zip',
|
||||
}),
|
||||
media,
|
||||
});
|
||||
setPublishedGameId(updateContext.gameId);
|
||||
setUpdateContext((current) =>
|
||||
@@ -528,30 +550,12 @@ export function GamePublishPage({
|
||||
setIsSubmitting(true);
|
||||
setError('');
|
||||
try {
|
||||
const prepared = await prepareGamePackage(packageFile);
|
||||
const submission = buildGamePublishMediaSubmission(
|
||||
coverImage,
|
||||
screenshotImages,
|
||||
);
|
||||
const gameMetadata = buildPublishGameMetadata(submission);
|
||||
const media = buildPublishMediaParts(submission);
|
||||
// 首次发布只调一次统一接口:草稿里的 projectKey + versionNumber 是自然幂等键,
|
||||
// 响应丢失后重试会命中同一个游戏与版本,而不是新建第二份。
|
||||
const result = await submitGamePublish({
|
||||
ownerUserId: currentUserId,
|
||||
title,
|
||||
const result = await runUnifiedPublish({
|
||||
target: { mode: 'create' },
|
||||
versionNumber: 1,
|
||||
packageSha256: prepared.sha256,
|
||||
packageBytes: prepared.totalBytes,
|
||||
packageFileCount: prepared.fileCount,
|
||||
packageEntryPath: 'index.html',
|
||||
priceMudPoints: price.priceMudPoints,
|
||||
gameMetadata,
|
||||
packageBody: new Blob([prepared.bytes as unknown as BlobPart], {
|
||||
type: 'application/zip',
|
||||
}),
|
||||
media,
|
||||
});
|
||||
setPublishedGameId(result.gameId);
|
||||
} catch (submitError: unknown) {
|
||||
|
||||
Reference in New Issue
Block a user