import { CameraOutlined, ClockCircleOutlined, ColumnWidthOutlined, CustomerServiceOutlined, DashboardOutlined, DeleteOutlined, EditOutlined, HighlightOutlined, MessageOutlined, SwapOutlined, ThunderboltOutlined, VideoCameraOutlined, } from "@ant-design/icons"; import type { CSSProperties, ReactNode } from "react"; import { useCallback, useEffect, useState } from "react"; import "../../styles/pages/more.css"; import type { WebImageWorkbenchTool, WebViewKey } from "../../types"; interface MorePageProps { onSelectView?: (view: WebViewKey) => void; onOpenImageTool?: (tool: WebImageWorkbenchTool) => void; } type ToolCategory = "image" | "video"; type FilterKey = "all" | ToolCategory | "upcoming"; interface MoreTool { id: string; title: string; text: string; useCase: string; tags: string[]; icon: ReactNode; category: ToolCategory; target?: WebViewKey; imageTool?: WebImageWorkbenchTool; ready: boolean; badge?: string; } const toolPreviewImages: Record = { inpaint: "https://stringtest.oss-cn-hangzhou.aliyuncs.com/toolbox/images/%E5%B1%80%E9%83%A8%E9%87%8D%E7%BB%98.PNG", camera: "https://stringtest.oss-cn-hangzhou.aliyuncs.com/toolbox/images/%E9%95%9C%E5%A4%B4%E5%AE%9E%E9%AA%8C%E5%AE%A4.PNG", upscale: "https://stringtest.oss-cn-hangzhou.aliyuncs.com/toolbox/images/%E5%88%86%E8%BE%A8%E7%8E%87%E6%8F%90%E5%8D%87.PNG", watermarkRemoval: "https://stringtest.oss-cn-hangzhou.aliyuncs.com/toolbox/images/%E5%8E%BB%E6%B0%B4%E5%8D%B0.PNG", dialogGenerator: "https://stringtest.oss-cn-hangzhou.aliyuncs.com/toolbox/images/%E4%BA%A4%E4%BA%92%E5%BC%8F%E5%AF%B9%E8%AF%9D%E6%A1%86%E7%94%9F%E6%88%90%E5%99%A8.PNG", subtitleRemoval: "https://stringtest.oss-cn-hangzhou.aliyuncs.com/toolbox/images/%E5%AD%97%E5%B9%95%E5%8E%BB%E9%99%A4.PNG", characterMix: "https://stringtest.oss-cn-hangzhou.aliyuncs.com/toolbox/images/%E8%A7%92%E8%89%B2%E8%BF%81%E7%A7%BB.PNG", avatarConsole: "https://stringtest.oss-cn-hangzhou.aliyuncs.com/toolbox/images/%E6%95%B0%E5%AD%97%E4%BA%BA%E6%8E%A7%E5%88%B6%E5%8F%B0.PNG", }; function ToolPreviewPanel({ toolId }: { toolId: string }) { const imageUrl = toolPreviewImages[toolId]; if (!imageUrl) return null; return ( ); } function getPreviewClassName(toolId: string) { return toolPreviewImages[toolId] ? " more-card--has-preview" : " more-card--no-preview"; } const tools: MoreTool[] = [ { id: "workbench", title: "图片工作台", text: "融合、修复、局部增强", useCase: "适合商品图精修、创意合成和局部画面重做", tags: ["热门", "一站式", "商品图"], icon: , category: "image", imageTool: "workbench", ready: true, }, { id: "inpaint", title: "局部重绘", text: "修掉瑕疵、替换物体、重做局部画面", useCase: "适合快速处理商品瑕疵、人物细节和背景杂物", tags: ["新手推荐", "精修"], icon: , category: "image", imageTool: "inpaint", ready: true, }, { id: "camera", title: "镜头实验室", text: "快速生成俯拍、特写、广角等商业镜头", useCase: "适合做产品主图、种草图和不同机位方案", tags: ["电商常用", "镜头"], icon: , category: "image", imageTool: "camera", ready: true, }, { id: "upscale", title: "分辨率提升", text: "把低清图片或视频提升到可交付质感", useCase: "适合修复旧素材、放大商品图和增强短视频清晰度", tags: ["高清", "交付前"], icon: , category: "image", target: "resolutionUpscale", ready: true, }, { id: "watermarkRemoval", title: "去水印", text: "智能去除图片水印、文字和遮挡元素", useCase: "适合整理素材、清理参考图和恢复画面干净度", tags: ["素材清理", "高频"], icon: , category: "image", target: "watermarkRemoval", ready: true, }, { id: "dialogGenerator", title: "交互式对话框生成器", text: "上传背景图,快速制作可拖拽编辑的对话框", useCase: "适合剧情海报、社媒截图和角色对白设计", tags: ["内容创作", "可编辑"], icon: , category: "image", target: "dialogGenerator", ready: true, }, { id: "subtitleRemoval", title: "字幕去除", text: "擦除视频字幕,让画面重新变干净", useCase: "适合二创前素材整理、短视频重剪和画面修复", tags: ["视频增强", "素材清理"], icon: , category: "video", target: "subtitleRemoval", ready: true, }, { id: "digitalHuman", title: "数字人", text: "用一张人像和音频生成口播视频", useCase: "适合品牌讲解、课程口播和带货短视频", tags: ["热门", "口播", "视频"], icon: , category: "video", target: "digitalHuman", ready: true, }, { id: "characterMix", title: "角色迁移", text: "把人物图迁移到参考视频的动作里", useCase: "适合角色短片、动作复刻和虚拟人内容生产", tags: ["角色视频", "动作"], icon: , category: "video", target: "characterMix", ready: true, }, { id: "avatarConsole", title: "数字人控制台", text: "管理形象、播报、互动与接入配置", useCase: "适合持续运营数字人、配置品牌形象和复用口播模板", tags: ["运营台", "企业"], icon: , category: "video", target: "avatarConsole", ready: true, }, ]; const categoryLabels: Record = { image: "图像创作", video: "视频创作", }; const categoryIcons: Record = { image: , video: , }; const filters: { key: FilterKey; label: string }[] = [ { key: "all", label: "全部" }, { key: "image", label: "图像" }, { key: "video", label: "视频" }, { key: "upcoming", label: "即将上线" }, ]; const coreToolIds = new Set(["workbench", "inpaint", "watermarkRemoval"]); const coreToolGradients: Record = { workbench: "linear-gradient(135deg, rgba(99, 102, 241, 0.12), rgba(139, 92, 246, 0.06))", inpaint: "linear-gradient(135deg, rgba(var(--accent-rgb), 0.16), rgba(var(--accent-rgb), 0.055))", watermarkRemoval: "linear-gradient(135deg, rgba(16, 185, 129, 0.13), rgba(var(--accent-rgb), 0.055))", }; const coreToolSteps: Record = { workbench: ["上传素材", "局部修复", "高清导出"], inpaint: ["选定区域", "描述修改", "生成结果"], watermarkRemoval: ["上传素材", "智能识别", "干净导出"], }; const RECENT_STORAGE_KEY = "omniai:more-recent-tools"; const MAX_RECENT = 4; function getRecentToolIds(): string[] { try { const raw = localStorage.getItem(RECENT_STORAGE_KEY); return raw ? JSON.parse(raw) : []; } catch { return []; } } function pushRecentToolId(id: string) { const ids = getRecentToolIds().filter((x) => x !== id); ids.unshift(id); localStorage.setItem(RECENT_STORAGE_KEY, JSON.stringify(ids.slice(0, MAX_RECENT))); } function MorePage({ onSelectView, onOpenImageTool }: MorePageProps) { const [filter, setFilter] = useState("all"); const [recentIds, setRecentIds] = useState(getRecentToolIds); useEffect(() => { setRecentIds(getRecentToolIds()); }, []); const openTool = useCallback((tool: MoreTool) => { if (!tool.ready) return; pushRecentToolId(tool.id); setRecentIds(getRecentToolIds()); if (tool.imageTool && onOpenImageTool) { onOpenImageTool(tool.imageTool); return; } if (tool.target && onSelectView) { onSelectView(tool.target); } }, [onOpenImageTool, onSelectView]); const filteredTools = tools.filter((tool) => { if (coreToolIds.has(tool.id)) return false; if (filter === "all") return true; if (filter === "upcoming") return !tool.ready; return tool.category === filter; }); const filterCounts: Record = { all: tools.filter((tool) => !coreToolIds.has(tool.id)).length, image: tools.filter((tool) => !coreToolIds.has(tool.id) && tool.category === "image").length, video: tools.filter((tool) => !coreToolIds.has(tool.id) && tool.category === "video").length, upcoming: tools.filter((tool) => !coreToolIds.has(tool.id) && !tool.ready).length, }; const recentTools = recentIds .map((id) => tools.find((tool) => tool.id === id)) .filter((tool): tool is MoreTool => Boolean(tool) && (tool?.ready ?? false)); const coreTools = tools.filter((tool) => coreToolIds.has(tool.id)); const groupedTools = filteredTools.reduce>((acc, tool) => { if (!acc[tool.category]) acc[tool.category] = []; acc[tool.category].push(tool); return acc; }, {} as Record); const activeFilterLabel = filters.find((item) => item.key === filter)?.label ?? "全部"; const hasGroupedTools = (["image", "video"] as ToolCategory[]).some((cat) => groupedTools[cat]?.length); return (
AI Tool Hub

工具盒

{tools.filter((tool) => tool.ready).length} 个可用工具 {coreTools.length} 个核心入口
{recentTools.length > 0 && filter === "all" && (

最近使用 继续使用

{recentTools.map((tool) => ( ))}
)} {filter === "all" && (

核心工具

{coreTools.map((tool) => ( ))}
)} {(["image", "video"] as ToolCategory[]).map((cat) => { const group = groupedTools[cat]; if (!group || group.length === 0) return null; return (

{categoryIcons[cat]} {categoryLabels[cat]} {group.length}

{group.map((tool) => ( ))}
); })} {!hasGroupedTools && (
{activeFilterLabel}工具正在整理中

当前分类暂无可展示入口,后续能力上线后会在这里集中呈现。

)}
); } export default MorePage;