再次合并 master

合入 origin/master 最新订阅消息与计费相关更新

保留作品架 actions 收口并接入统一分享弹窗

修复创作生成泥点预检与本地余额扣减回归
This commit is contained in:
2026-06-08 17:18:38 +08:00
342 changed files with 4153 additions and 2483 deletions

View File

@@ -1,6 +1,8 @@
import { useEffect, useMemo, useState } from 'react';
import { resolveSelectionStageFromPath } from '../../routing/appPageRoutes';
import type { CreationEntryConfig } from '../../services/creationEntryConfigService';
import type { PublishShareModalPayload } from '../common/publishShareModalModel';
import type {
PlatformCreationTypeCard,
PlatformCreationTypeId,
@@ -43,6 +45,7 @@ type CustomWorldCreationHubProps = {
deletingWorkId?: string | null;
claimingPuzzleProfileId?: string | null;
onOpenShelfItem?: (item: CreationWorkShelfItem) => void;
onShareWork?: ((payload: PublishShareModalPayload) => void) | null;
// 中文注释:底部加号入口可传入后端作品架摘要,用于推导最近使用过的模板。
recentWorkItems?: CreationWorkShelfItem[];
mode?: 'full' | 'start-only' | 'works-only';
@@ -111,6 +114,41 @@ function writeWorkMetricSnapshot(items: CreationWorkShelfItem[]) {
}
}
function resolveShelfShareStage(
sharePath: string,
): PublishShareModalPayload['stage'] | null {
let pathname = '';
try {
pathname = new URL(sharePath, 'https://genarrative.local').pathname;
} catch {
pathname = sharePath.split(/[?#]/u)[0] ?? '';
}
const stage = resolveSelectionStageFromPath(pathname);
return stage === 'platform' ? null : stage;
}
function buildCreationWorkShelfSharePayload(
item: CreationWorkShelfItem,
): PublishShareModalPayload | null {
const publicWorkCode = item.publicWorkCode?.trim();
const sharePath = item.sharePath?.trim();
if (!publicWorkCode || !sharePath) {
return null;
}
const stage = resolveShelfShareStage(sharePath);
if (!stage) {
return null;
}
return {
title: item.title,
publicWorkCode,
stage,
};
}
/** 渲染底部加号创作入口页与草稿作品架,最近创作复用最近使用过的模板入口。 */
export function CustomWorldCreationHub({
shelfItems,
@@ -124,6 +162,7 @@ export function CustomWorldCreationHub({
deletingWorkId = null,
claimingPuzzleProfileId = null,
onOpenShelfItem,
onShareWork = null,
recentWorkItems: recentWorkSourceItems,
mode = 'full',
}: CustomWorldCreationHubProps) {
@@ -178,6 +217,17 @@ export function CustomWorldCreationHub({
return item.actions.delete ?? null;
}
function buildShareAction(item: CreationWorkShelfItem) {
const payload = buildCreationWorkShelfSharePayload(item);
if (!payload) {
return null;
}
return () => {
onShareWork?.(payload);
};
}
function buildPointIncentiveAction(item: CreationWorkShelfItem) {
return item.actions.claimPointIncentive ?? null;
}
@@ -253,6 +303,7 @@ export function CustomWorldCreationHub({
}}
onDelete={buildDeleteAction(item)}
deleteBusy={deletingWorkId === item.id}
onShare={buildShareAction(item)}
onClaimPointIncentive={buildPointIncentiveAction(item)}
pointIncentiveBusy={
item.source.kind === 'puzzle' &&