按后台配置扣除创作泥点

前端创作表单泥点预校验改为读取入口契约配置

拼图和抓大鹅初始生成后端扣费改为解析后台配置

汪汪声浪初始三图生成按入口总成本拆分扣费

创作工作台按钮和确认弹窗展示后台配置泥点成本

补充泥点扣费回归测试并同步文档与共享记忆
This commit is contained in:
2026-06-08 15:47:48 +08:00
parent 3ca5a460f1
commit 5ea9f0a120
21 changed files with 425 additions and 45 deletions

View File

@@ -159,6 +159,7 @@ import {
} from '../../services/big-fish-works';
import {
type CreationEntryConfig,
DEFAULT_UNIFIED_CREATION_MUD_POINT_COST,
fetchCreationEntryConfig,
} from '../../services/creationEntryConfigService';
import {
@@ -686,10 +687,6 @@ async function buildRecommendRuntimeAuthOptions(
return RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
}
const PUZZLE_DRAFT_GENERATION_POINT_COST = 2;
const MATCH3D_DRAFT_GENERATION_POINT_COST = 10;
const BARK_BATTLE_DRAFT_GENERATION_POINT_COST = 3;
function getPlatformPublicGalleryEntryTime(entry: PlatformPublicGalleryCard) {
const rawTime = entry.publishedAt ?? entry.updatedAt;
const timestamp = new Date(rawTime).getTime();
@@ -4128,6 +4125,18 @@ export function PlatformEntryFlowShellImpl({
creationEntryTypes,
'visual-novel',
);
const resolveCreationEntryMudPointCost = useCallback(
(id: PlatformCreationTypeId) =>
creationEntryTypes.find((item) => item.id === id)?.mudPointCost ??
DEFAULT_UNIFIED_CREATION_MUD_POINT_COST,
[creationEntryTypes],
);
const puzzleDraftGenerationPointCost =
resolveCreationEntryMudPointCost('puzzle');
const match3DDraftGenerationPointCost =
resolveCreationEntryMudPointCost('match3d');
const barkBattleDraftGenerationPointCost =
resolveCreationEntryMudPointCost('bark-battle');
const [profilePlayStats, setProfilePlayStats] =
useState<ProfilePlayStatsResponse | null>(null);
const [profilePlayStatsError, setProfilePlayStatsError] = useState<
@@ -6944,21 +6953,30 @@ export function PlatformEntryFlowShellImpl({
setPuzzleCreationError(null);
setPuzzleError(null);
return ensureEnoughDraftGenerationPointsFromServer(
PUZZLE_DRAFT_GENERATION_POINT_COST,
puzzleDraftGenerationPointCost,
);
}, [ensureEnoughDraftGenerationPointsFromServer]);
}, [
ensureEnoughDraftGenerationPointsFromServer,
puzzleDraftGenerationPointCost,
]);
const preflightMatch3DDraftGeneration = useCallback(async () => {
setMatch3DError(null);
return ensureEnoughDraftGenerationPointsFromServer(
MATCH3D_DRAFT_GENERATION_POINT_COST,
match3DDraftGenerationPointCost,
);
}, [ensureEnoughDraftGenerationPointsFromServer]);
}, [
ensureEnoughDraftGenerationPointsFromServer,
match3DDraftGenerationPointCost,
]);
const preflightBarkBattleDraftGeneration = useCallback(async () => {
setBarkBattleError(null);
return ensureEnoughDraftGenerationPointsFromServer(
BARK_BATTLE_DRAFT_GENERATION_POINT_COST,
barkBattleDraftGenerationPointCost,
);
}, [ensureEnoughDraftGenerationPointsFromServer]);
}, [
barkBattleDraftGenerationPointCost,
ensureEnoughDraftGenerationPointsFromServer,
]);
const draftGenerationPointNoticeDescription = draftGenerationPointNotice
? draftGenerationPointNotice.title === '读取泥点余额失败'
? '当前表单不会丢失,关闭后可继续编辑,稍后再试。'
@@ -7973,7 +7991,7 @@ export function PlatformEntryFlowShellImpl({
buildPendingPuzzleDraftMetadata(payload),
);
if (shouldConsumePuzzleDraftPoints) {
adjustProfileWalletBalanceLocally(-PUZZLE_DRAFT_GENERATION_POINT_COST);
adjustProfileWalletBalanceLocally(-puzzleDraftGenerationPointCost);
}
selectionStageRef.current = 'puzzle-generating';
activePuzzleGenerationSessionIdRef.current = nextSession.sessionId;
@@ -8126,7 +8144,7 @@ export function PlatformEntryFlowShellImpl({
return;
}
if (shouldConsumePuzzleDraftPoints) {
adjustProfileWalletBalanceLocally(PUZZLE_DRAFT_GENERATION_POINT_COST);
adjustProfileWalletBalanceLocally(puzzleDraftGenerationPointCost);
}
const failedGenerationState =
resolveFinishedMiniGameDraftGenerationState(
@@ -8176,6 +8194,7 @@ export function PlatformEntryFlowShellImpl({
isViewingPuzzleGeneration,
preflightPuzzleDraftGeneration,
puzzleFlow,
puzzleDraftGenerationPointCost,
refreshPuzzleShelf,
recoverCompletedPuzzleDraftGeneration,
refreshPlatformDashboardSilently,
@@ -8235,7 +8254,7 @@ export function PlatformEntryFlowShellImpl({
nextSession.sessionId,
buildPendingMatch3DDraftMetadata(payload),
);
adjustProfileWalletBalanceLocally(-MATCH3D_DRAFT_GENERATION_POINT_COST);
adjustProfileWalletBalanceLocally(-match3DDraftGenerationPointCost);
selectionStageRef.current = 'match3d-generating';
activeMatch3DGenerationSessionIdRef.current = nextSession.sessionId;
setSelectionStage('match3d-generating');
@@ -8378,7 +8397,7 @@ export function PlatformEntryFlowShellImpl({
await refreshMatch3DShelf().catch(() => undefined);
}
}
adjustProfileWalletBalanceLocally(MATCH3D_DRAFT_GENERATION_POINT_COST);
adjustProfileWalletBalanceLocally(match3DDraftGenerationPointCost);
const failedGenerationState =
resolveFinishedMiniGameDraftGenerationState(
generationState,
@@ -8453,6 +8472,7 @@ export function PlatformEntryFlowShellImpl({
[
adjustProfileWalletBalanceLocally,
match3dRuntimeAdapter,
match3DDraftGenerationPointCost,
isViewingMatch3DGeneration,
markDraftGenerating,
markDraftFailed,
@@ -18384,7 +18404,10 @@ export function PlatformEntryFlowShellImpl({
>
<UnifiedCreationWorkspace
playId="match3d"
spec={getUnifiedSpec('match3d')}
spec={{
...getUnifiedSpec('match3d'),
mudPointCost: match3DDraftGenerationPointCost,
}}
session={match3dSession}
isBusy={isStreamingMatch3DReply}
error={match3dError}
@@ -19491,7 +19514,10 @@ export function PlatformEntryFlowShellImpl({
>
<UnifiedCreationWorkspace
playId="puzzle"
spec={getUnifiedSpec('puzzle')}
spec={{
...getUnifiedSpec('puzzle'),
mudPointCost: puzzleDraftGenerationPointCost,
}}
session={puzzleSession}
isBusy={isStreamingPuzzleReply}
error={puzzleError}

View File

@@ -16,6 +16,7 @@ export type PlatformCreationTypeCard = {
subtitle: string;
badge: string;
imageSrc: string;
mudPointCost: number;
mudPointCostLabel: string;
locked: boolean;
categoryId: string;
@@ -144,6 +145,9 @@ export function derivePlatformCreationTypes(
subtitle: item.subtitle,
badge: item.badge,
imageSrc: item.imageSrc,
mudPointCost: normalizeMudPointCost(
item.unifiedCreationSpec?.mudPointCost,
),
mudPointCostLabel: formatMudPointCostText(
item.unifiedCreationSpec?.mudPointCost,
),