fix: 全站页面保活机制、登录拦截优化、UI修复与功能完善

- 移除未登录全页面拦截,改为浏览自由 + 功能使用时弹窗
- 修复PageTransition退出动画卡死导致黑屏的bug
- CanvasPage添加加载中状态避免首次访问黑屏假死
- 全站7个工具页添加页面保活机制,切页后台任务不中断
- 修复未登录时401误触发"用户已在别处登录"弹窗
- 删除MorePage模板板块、微信登录、EcommerceTemplates/SizeTemplate路由
- 剧本评分接入DashScope qwen3.7-max直连API
- 电商视频生成重构为3阶段可视管线(策划→生成图片→生成视频)
- 电商视频保活增强:异步函数直接写localStorage避免卸载丢失
- Workbench侧边栏移除mode过滤,三模式共用同一对话列表
- 首页更新轮播图/背景视频、按钮跳转修正、文案优化
- AppShell顶栏新增网站备案信息按钮
- 多个页面的terminate/cancel按钮覆盖、单镜头重试、批量保存下载

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-06-03 01:39:06 +08:00
parent 8f57e08004
commit 468d1d27dd
35 changed files with 1263 additions and 441 deletions
+8 -61
View File
@@ -42,8 +42,6 @@ const CommunityReviewPage = lazy(() => import("./features/community-review/Commu
const AvatarConsolePage = lazy(() => import("./features/digital-human/AvatarConsolePage"));
const DigitalHumanPage = lazy(() => import("./features/digital-human/DigitalHumanPage"));
const EcommercePage = lazy(() => import("./features/ecommerce/EcommercePage"));
const EcommerceTemplatesPage = lazy(() => import("./features/ecommerce/EcommerceTemplatesPage"));
import type { TemplateCase } from "./features/ecommerce/ecommerceTemplates";
const HomePage = lazy(() => import("./features/home/HomePage"));
const ImageWorkbenchPage = lazy(() => import("./features/image-workbench/ImageWorkbenchPage"));
const MorePage = lazy(() => import("./features/more/MorePage"));
@@ -54,7 +52,6 @@ const ResolutionUpscalePage = lazy(() => import("./features/resolution-upscale/R
const WatermarkRemovalPage = lazy(() => import("./features/watermark-removal/WatermarkRemovalPage"));
const SubtitleRemovalPage = lazy(() => import("./features/subtitle-removal/SubtitleRemovalPage"));
const ScriptTokensPage = lazy(() => import("./features/script-tokens/ScriptTokensPage"));
const SizeTemplatePage = lazy(() => import("./features/size-template/SizeTemplatePage"));
const TokenUsagePage = lazy(() => import("./features/script-tokens/TokenUsagePage"));
const SettingsPage = lazy(() => import("./features/settings/SettingsPage"));
const WorkbenchPage = lazy(() => import("./features/workbench/WorkbenchPage"));
@@ -101,7 +98,6 @@ const VIEW_KEYS = new Set<WebViewKey>([
"assets",
"ecommerceHub",
"ecommerce",
"ecommerceTemplates",
"scriptTokens",
"tokenUsage",
"settings",
@@ -113,14 +109,13 @@ const VIEW_KEYS = new Set<WebViewKey>([
"avatarConsole",
"characterMix",
"more",
"sizeTemplate",
"communityReview",
"communityCaseAdd",
"report",
"providerHealth",
]);
const PUBLIC_VIEW_SET = new Set<WebViewKey>(["home", "login", "community", "more", "ecommerceTemplates", "sizeTemplate"]);
const PUBLIC_VIEW_SET = new Set<WebViewKey>(["home", "login", "community", "more"]);
function normalizeViewKey(rawView: string): WebViewKey {
const normalized =
@@ -312,12 +307,6 @@ function App() {
hint: "AI创作与海报生成",
icon: <ShoppingOutlined />,
},
{
key: "sizeTemplate",
label: "示例模板",
hint: "平台比例与导出尺寸",
icon: <LayoutOutlined />,
},
{ key: "canvas", label: "画布", hint: "进入自由画布编排", icon: <BranchesOutlined /> },
{ key: "community", label: "社区", hint: "案例分享与导入", icon: <GlobalOutlined /> },
{ key: "scriptTokens", label: "剧本评分", hint: "剧本评分系统", icon: <BarChartOutlined /> },
@@ -380,11 +369,6 @@ function App() {
};
}, [showSessionReplacedModal]);
const handleOpenEcommerceTemplate = useCallback((template: TemplateCase) => {
setPendingEcommerceTemplate(template);
handleSetView("ecommerce");
}, [setPendingEcommerceTemplate, handleSetView]);
const hydrateAccountData = useCallback(async (nextSession: WebUserSession | null) => {
setProjectsLoaded(false);
if (!nextSession) {
@@ -681,11 +665,14 @@ function App() {
}
canvasAutoOpenedRecentRef.current = true;
void handleOpenProject(projects[0]);
handleOpenProject(projects[0]).catch(() => {
// Reset flag on failure so auto-open can retry on next dependency change
canvasAutoOpenedRecentRef.current = false;
});
}, [
activeView,
canvasWorkflow?.nodes.length,
canvasWorkflow?.source,
canvasWorkflow.nodes.length,
canvasWorkflow.source,
currentCanvasProjectId,
handleOpenProject,
projects,
@@ -987,25 +974,6 @@ function App() {
}, [activeView, session]); // eslint-disable-line react-hooks/exhaustive-deps
const activePage = (() => {
if (!session && !PUBLIC_VIEWS.has(activeView)) {
return (
<ProfilePage
session={session}
usage={usage}
projects={projects}
tasks={tasks}
pendingActionLabel={pendingAction?.label ?? null}
onLogin={handleLogin}
onRegister={handleRegister}
onAuthComplete={completeAuth}
onSessionChange={setSession}
onLogout={handleLogout}
onOpenWorkbench={() => handleSetView("workbench")}
onOpenCommunity={() => handleSetView("community")}
onDeleteProject={handleDeleteProject}
/>
);
}
switch (activeView) {
case "login":
return (
@@ -1049,7 +1017,7 @@ function App() {
case "canvas":
return (
<CanvasPage
workflow={canvasWorkflow!}
workflow={canvasWorkflow}
projectId={currentCanvasProjectId}
projects={projects}
projectsLoaded={projectsLoaded}
@@ -1081,18 +1049,6 @@ function App() {
onInitialTemplateConsumed={() => setPendingEcommerceTemplate(null)}
/>
);
case "ecommerceTemplates":
return (
<EcommerceTemplatesPage
projects={projects}
onOpenMore={() => handleSetView("more")}
onOpenEcommerce={() => handleSetView("ecommerce")}
onSelectTemplate={handleOpenEcommerceTemplate}
onStartCreate={handleStartTemplateCanvasCreate}
onOpenProject={handleOpenProject}
onDeleteProject={handleDeleteProject}
/>
);
case "digitalHuman":
return (
<DigitalHumanPage
@@ -1118,15 +1074,6 @@ function App() {
);
case "more":
return <MorePage onSelectView={handleSetView} onOpenImageTool={handleOpenImageWorkbenchTool} />;
case "sizeTemplate":
return (
<SizeTemplatePage
isAuthenticated={Boolean(session)}
onOpenMore={() => handleSetView("more")}
onOpenEcommerce={() => handleSetView("ecommerce")}
onSelectView={handleSetView}
/>
);
case "scriptTokens":
return <ScriptTokensPage />;
case "tokenUsage":