"use client" import { useCallback, useEffect, useMemo, useRef, useState } from "react" import { getDocumentationCatalog, type DocumentationPage } from "@/lib/documentation/catalog" import { FileText, Download, Loader2, CheckCircle, XCircle, Eye, RefreshCw } from "lucide-react" type PageStatus = "pending" | "loading" | "success" | "error" type PageState = { page: DocumentationPage status: PageStatus error?: string } export default function DocumentationToolPage() { const [isGenerating, setIsGenerating] = useState(false) const [error, setError] = useState(null) const [progress, setProgress] = useState(0) const [currentPage, setCurrentPage] = useState(null) const [pageStates, setPageStates] = useState([]) const [previewPath, setPreviewPath] = useState(null) const [showPreview, setShowPreview] = useState(false) const iframeRef = useRef(null) const pages = useMemo(() => getDocumentationCatalog(), []) const groupedPages = useMemo(() => { const groups: Record = {} for (const page of pages) { if (!groups[page.group]) groups[page.group] = [] groups[page.group].push(page) } return groups }, [pages]) useEffect(() => { setPageStates(pages.map((page) => ({ page, status: "pending" }))) }, [pages]) const handleGenerate = async () => { setError(null) setIsGenerating(true) setProgress(0) setCurrentPage(null) setPageStates(pages.map((page) => ({ page, status: "loading" }))) try { // Simulate progress while waiting for the API let progressValue = 0 const progressInterval = setInterval(() => { progressValue += 2 const pageIndex = Math.floor((progressValue / 100) * pages.length) const nextPage = pages[Math.min(pageIndex, pages.length - 1)] if (nextPage) setCurrentPage(nextPage.title) setProgress(Math.min(progressValue, 90)) // Update page states to show progress setPageStates((prev) => prev.map((s, idx) => ({ ...s, status: idx < pageIndex ? "success" : idx === pageIndex ? "loading" : "pending", })), ) }, 800) // Get token from URL if provided const urlParams = new URLSearchParams(window.location.search) const token = urlParams.get("token") || "" const response = await fetch(`/api/documentation/generate${token ? `?token=${token}` : ""}`, { method: "POST", headers: { "Content-Type": "application/json", ...(token ? { "x-documentation-token": token } : {}), }, }) clearInterval(progressInterval) if (!response.ok) { const text = await response.text().catch(() => "") let errorMessage = `生成失败(${response.status})` try { const json = JSON.parse(text) errorMessage = json.error || errorMessage } catch { if (text) errorMessage = text } throw new Error(errorMessage) } setProgress(100) setCurrentPage("完成") setPageStates(pages.map((page) => ({ page, status: "success" }))) const blob = await response.blob() const url = URL.createObjectURL(blob) const a = document.createElement("a") a.href = url a.download = `应用功能文档_${new Date().toISOString().slice(0, 10)}.docx` document.body.appendChild(a) a.click() a.remove() URL.revokeObjectURL(url) } catch (e) { const message = e instanceof Error ? e.message : String(e) setError(message) setPageStates((prev) => prev.map((s) => ({ ...s, status: "error" }))) } finally { setIsGenerating(false) } } const handlePreview = useCallback((path: string) => { setPreviewPath(path) setShowPreview(true) }, []) const getStatusIcon = (status: PageStatus) => { switch (status) { case "pending": return
case "loading": return case "success": return case "error": return } } return (
{/* Header */}

文档生成器

自动截图并导出专业文档

{/* Info Card */}
页面总数 {pages.length} 个
分组数量 {Object.keys(groupedPages).length} 组
输出格式 Word (.docx)
{/* Progress */} {isGenerating && (
生成进度 {Math.round(progress)}%
{currentPage &&

正在处理: {currentPage}

}
)} {/* Error */} {error && (

生成失败

{error}

提示: 如需授权,请在URL中添加 ?token=your_token

)} {/* Generate Button */} {/* Page List */}

文档目录预览 ({pages.length}个页面)

{Object.entries(groupedPages).map(([group, groupPages]) => (

{group}

{groupPages.map((page, index) => { const state = pageStates.find((s) => s.page.path === page.path) return (
{index + 1} {state && getStatusIcon(state.status)}

{page.title}

{page.subtitle &&

{page.subtitle}

}
) })}
))}
{/* Features */}

文档包含内容

  • 自动生成的目录结构
  • 所有页面的真实截图(iPhone 14 Pro Max尺寸)
  • 每个页面的功能说明与路径
  • 按功能模块分组整理
{/* Note */}

生成过程需要30-60秒,请耐心等待

{/* Preview Modal */} {showPreview && previewPath && (

页面预览