"use client" import { useState, useEffect, useRef } from "react" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { Checkbox } from "@/components/ui/checkbox" import { Progress } from "@/components/ui/progress" import { Badge } from "@/components/ui/badge" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { ScrollArea } from "@/components/ui/scroll-area" import { toast } from "@/components/ui/use-toast" import { Camera, Download, FileText, ImageIcon, Settings, Eye, Trash2, RefreshCw, Monitor, Smartphone, Tablet, Globe, CheckCircle, XCircle, Clock, Zap, } from "lucide-react" import { enhancedScreenshotService, type EnhancedScreenshotOptions, } from "@/lib/documentation/enhanced-screenshot-service" import { generateDocx } from "@/lib/documentation/docx-generator" import { pageRegistry } from "@/lib/documentation/page-registry" interface Screenshot { id: string name: string url: string dataUrl?: string timestamp: Date status: "pending" | "success" | "failed" | "capturing" error?: string method?: string size?: { width: number; height: number } } interface DocumentSettings { title: string author: string description: string includeTimestamp: boolean includePageUrls: boolean imageFormat: "png" | "jpeg" | "webp" imageQuality: number pageSize: "A4" | "A3" | "Letter" orientation: "portrait" | "landscape" } export default function DocumentationPage() { const [screenshots, setScreenshots] = useState([]) const [selectedPages, setSelectedPages] = useState([]) const [isCapturing, setIsCapturing] = useState(false) const [captureProgress, setCaptureProgress] = useState(0) const [isGeneratingDoc, setIsGeneratingDoc] = useState(false) const [previewMode, setPreviewMode] = useState<"desktop" | "tablet" | "mobile">("desktop") const [currentPreviewUrl, setCurrentPreviewUrl] = useState("") const [documentSettings, setDocumentSettings] = useState({ title: "用户数据资产中台文档", author: "系统管理员", description: "自动生成的系统文档", includeTimestamp: true, includePageUrls: true, imageFormat: "png", imageQuality: 0.9, pageSize: "A4", orientation: "portrait", }) const previewRef = useRef(null) const [screenshotOptions, setScreenshotOptions] = useState({ format: "png", quality: 0.9, scale: 1, backgroundColor: "#ffffff", timeout: 30000, waitForImages: true, waitForFonts: true, addWatermark: true, }) const pages = pageRegistry.getAllPages() useEffect(() => { setSelectedPages(pages.map((p) => p.path)) }, []) const handlePageSelection = (pagePath: string, checked: boolean) => { if (checked) { setSelectedPages((prev) => [...prev, pagePath]) } else { setSelectedPages((prev) => prev.filter((p) => p !== pagePath)) } } const selectAllPages = () => { setSelectedPages(pages.map((p) => p.path)) } const deselectAllPages = () => { setSelectedPages([]) } const getViewportSize = () => { switch (previewMode) { case "mobile": return { width: 375, height: 667 } case "tablet": return { width: 768, height: 1024 } default: return { width: 1920, height: 1080 } } } const captureScreenshot = async (page: (typeof pages)[0]): Promise => { const screenshot: Screenshot = { id: `${page.path}-${Date.now()}`, name: page.name, url: page.path, timestamp: new Date(), status: "capturing", } try { const result = await enhancedScreenshotService.captureViewport({ ...screenshotOptions, ...getViewportSize(), watermarkText: `${page.name} - ${new Date().toLocaleString()}`, }) if (result.success && result.dataUrl) { return { ...screenshot, status: "success", dataUrl: result.dataUrl, method: result.method, size: getViewportSize(), } } else { throw new Error(result.error || "截图失败") } } catch (error) { console.error(`截图失败 ${page.name}:`, error) return { ...screenshot, status: "failed", error: error instanceof Error ? error.message : "未知错误", } } } const startCapture = async () => { if (selectedPages.length === 0) { toast({ title: "请选择页面", description: "请至少选择一个页面进行截图", variant: "destructive", }) return } setIsCapturing(true) setCaptureProgress(0) setScreenshots([]) const selectedPageObjects = pages.filter((p) => selectedPages.includes(p.path)) const newScreenshots: Screenshot[] = [] for (let i = 0; i < selectedPageObjects.length; i++) { const page = selectedPageObjects[i] setCaptureProgress((i / selectedPageObjects.length) * 100) const pendingScreenshot: Screenshot = { id: `${page.path}-${Date.now()}`, name: page.name, url: page.path, timestamp: new Date(), status: "capturing", } newScreenshots.push(pendingScreenshot) setScreenshots([...newScreenshots]) try { const screenshot = await captureScreenshot(page) const updatedScreenshots = [...newScreenshots] updatedScreenshots[i] = screenshot setScreenshots(updatedScreenshots) newScreenshots[i] = screenshot if (screenshot.status === "success") { toast({ title: "截图成功", description: `${page.name} 截图完成`, }) } else { toast({ title: "截图失败", description: `${page.name}: ${screenshot.error}`, variant: "destructive", }) } } catch (error) { console.error(`截图过程出错:`, error) const failedScreenshot: Screenshot = { ...pendingScreenshot, status: "failed", error: error instanceof Error ? error.message : "未知错误", } const updatedScreenshots = [...newScreenshots] updatedScreenshots[i] = failedScreenshot setScreenshots(updatedScreenshots) newScreenshots[i] = failedScreenshot } if (i < selectedPageObjects.length - 1) { await new Promise((resolve) => setTimeout(resolve, 1000)) } } setCaptureProgress(100) setIsCapturing(false) const successCount = newScreenshots.filter((s) => s.status === "success").length const failedCount = newScreenshots.filter((s) => s.status === "failed").length toast({ title: "截图完成", description: `成功: ${successCount}, 失败: ${failedCount}`, variant: successCount > 0 ? "default" : "destructive", }) } const generateDocument = async () => { const successfulScreenshots = screenshots.filter((s) => s.status === "success" && s.dataUrl) if (successfulScreenshots.length === 0) { toast({ title: "没有可用的截图", description: "请先成功截图至少一个页面", variant: "destructive", }) return } setIsGeneratingDoc(true) try { const docBuffer = await generateDocx(successfulScreenshots, documentSettings) const blob = new Blob([docBuffer], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", }) const url = URL.createObjectURL(blob) const a = document.createElement("a") a.href = url a.download = `${documentSettings.title.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, "_")}_${new Date().toISOString().split("T")[0]}.docx` document.body.appendChild(a) a.click() document.body.removeChild(a) URL.revokeObjectURL(url) toast({ title: "文档生成成功", description: `已生成包含 ${successfulScreenshots.length} 个截图的文档`, }) } catch (error) { console.error("文档生成失败:", error) toast({ title: "文档生成失败", description: error instanceof Error ? error.message : "未知错误", variant: "destructive", }) } finally { setIsGeneratingDoc(false) } } const deleteScreenshot = (id: string) => { setScreenshots((prev) => prev.filter((s) => s.id !== id)) toast({ title: "截图已删除", description: "截图已从列表中移除", }) } const clearAllScreenshots = () => { setScreenshots([]) toast({ title: "已清空所有截图", description: "所有截图已从列表中移除", }) } const previewPage = (url: string) => { setCurrentPreviewUrl(url) } const getStatusIcon = (status: Screenshot["status"]) => { switch (status) { case "success": return case "failed": return case "capturing": return default: return } } const getPreviewIcon = () => { switch (previewMode) { case "mobile": return case "tablet": return default: return } } return (

文档生成器

自动截图并生成系统文档

增强版截图
页面截图 截图管理 文档设置
选择页面 选择需要截图的页面,支持多选
已选择 {selectedPages.length} / {pages.length} 个页面
{pages.map((page) => (
handlePageSelection(page.path, checked as boolean)} />
{page.name}
{page.path}
{page.description && (
{page.description}
)}
))}
开始截图 {isCapturing && (
截图进度 {Math.round(captureProgress)}%
)}
总页面数: {pages.length}
已选择: {selectedPages.length}
已截图: {screenshots.length}
截图管理
{screenshots.filter((s) => s.status === "success").length} 成功 {screenshots.filter((s) => s.status === "failed").length} 失败 {screenshots.length > 0 && ( )}
管理已截取的页面截图
{screenshots.length === 0 ? (

暂无截图

请先在"页面截图"标签页中截取页面

) : (
{screenshots.map((screenshot) => (
{screenshot.dataUrl ? ( {screenshot.name} ) : (
{screenshot.status === "capturing" ? ( ) : ( )}
)}
{getStatusIcon(screenshot.status)}
{screenshot.name}
{screenshot.url}
{screenshot.method && ( {screenshot.method} )} {screenshot.error &&
{screenshot.error}
}
{screenshot.timestamp.toLocaleString()}
{screenshot.size && `${screenshot.size.width}×${screenshot.size.height}`}
))}
)}
{screenshots.some((s) => s.status === "success") && ( 生成文档 将成功的截图生成为Word文档 )}
文档设置 配置生成的Word文档格式和内容
setDocumentSettings((prev) => ({ ...prev, title: e.target.value, })) } placeholder="输入文档标题" />
setDocumentSettings((prev) => ({ ...prev, author: e.target.value, })) } placeholder="输入作者姓名" />