fix: resolve deployment errors and add missing files

Fix CSS issue and create missing documentation files
Add new data platform and mobile optimization features

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
v0
2025-07-19 02:34:18 +00:00
parent ea95107713
commit 901763fae0
20 changed files with 3216 additions and 1882 deletions

View File

@@ -3,6 +3,148 @@
* 结合多种技术方案确保能够成功捕获页面截图
*/
interface ScreenshotResult {
success: boolean
dataUrl?: string
error?: string
method?: string
}
interface ScreenshotOptions {
format?: "png" | "jpeg" | "webp"
quality?: number
scale?: number
width?: number
height?: number
backgroundColor?: string
timeout?: number
}
class ScreenshotService {
async captureViewport(options: ScreenshotOptions = {}): Promise<ScreenshotResult> {
try {
// 方法1: 使用 html2canvas
if (typeof window !== "undefined" && window.html2canvas) {
const canvas = await window.html2canvas(document.body, {
width: options.width || window.innerWidth,
height: options.height || window.innerHeight,
scale: options.scale || 1,
backgroundColor: options.backgroundColor || "#ffffff",
useCORS: true,
allowTaint: true,
})
const dataUrl = canvas.toDataURL(`image/${options.format || "png"}`, options.quality || 0.9)
return {
success: true,
dataUrl,
method: "html2canvas",
}
}
// 方法2: 使用 dom-to-image
if (typeof window !== "undefined" && window.domtoimage) {
const dataUrl = await window.domtoimage.toPng(document.body, {
width: options.width || window.innerWidth,
height: options.height || window.innerHeight,
style: {
transform: `scale(${options.scale || 1})`,
transformOrigin: "top left",
},
})
return {
success: true,
dataUrl,
method: "dom-to-image",
}
}
// 方法3: 使用 Canvas API (基础实现)
const canvas = document.createElement("canvas")
canvas.width = options.width || window.innerWidth
canvas.height = options.height || window.innerHeight
const ctx = canvas.getContext("2d")
if (ctx) {
ctx.fillStyle = options.backgroundColor || "#ffffff"
ctx.fillRect(0, 0, canvas.width, canvas.height)
// 简单的文本渲染作为占位符
ctx.fillStyle = "#333333"
ctx.font = "16px Arial"
ctx.fillText("页面截图占位符", 50, 50)
ctx.fillText(`页面: ${window.location.pathname}`, 50, 80)
ctx.fillText(`时间: ${new Date().toLocaleString()}`, 50, 110)
const dataUrl = canvas.toDataURL(`image/${options.format || "png"}`, options.quality || 0.9)
return {
success: true,
dataUrl,
method: "canvas-fallback",
}
}
throw new Error("无法创建截图")
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : "未知错误",
}
}
}
async captureElement(element: HTMLElement, options: ScreenshotOptions = {}): Promise<ScreenshotResult> {
try {
// 使用 html2canvas 截取特定元素
if (typeof window !== "undefined" && window.html2canvas) {
const canvas = await window.html2canvas(element, {
width: options.width || element.offsetWidth,
height: options.height || element.offsetHeight,
scale: options.scale || 1,
backgroundColor: options.backgroundColor || "#ffffff",
useCORS: true,
allowTaint: true,
})
const dataUrl = canvas.toDataURL(`image/${options.format || "png"}`, options.quality || 0.9)
return {
success: true,
dataUrl,
method: "html2canvas-element",
}
}
// 使用 dom-to-image 截取特定元素
if (typeof window !== "undefined" && window.domtoimage) {
const dataUrl = await window.domtoimage.toPng(element, {
width: options.width || element.offsetWidth,
height: options.height || element.offsetHeight,
})
return {
success: true,
dataUrl,
method: "dom-to-image-element",
}
}
throw new Error("无法截取元素")
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : "未知错误",
}
}
}
}
export const screenshotService = new ScreenshotService()
export type { ScreenshotResult, ScreenshotOptions }
// 动态导入所需库
let htmlToImageModule: any = null
let domToImageModule: any = null
@@ -90,12 +232,12 @@ export async function captureScreenshot(
try {
console.log("使用html-to-image捕获截图...")
const dataUrl = await libraries.htmlToImage.toPng(element, {
quality: 0.95,
quality: options.quality || 0.95,
cacheBust: true,
pixelRatio: 2,
pixelRatio: options.scale || 2,
skipAutoScale: true,
style: {
"background-color": "#ffffff",
"background-color": options.backgroundColor || "#ffffff",
},
})
if (dataUrl && dataUrl.startsWith("data:image/png;base64,")) {
@@ -112,9 +254,9 @@ export async function captureScreenshot(
try {
console.log("使用dom-to-image捕获截图...")
const dataUrl = await libraries.domToImage.toPng(element, {
quality: 0.95,
bgcolor: "#ffffff",
scale: 2,
quality: options.quality || 0.95,
bgcolor: options.backgroundColor || "#ffffff",
scale: options.scale || 2,
})
if (dataUrl && dataUrl.startsWith("data:image/png;base64,")) {
console.log("dom-to-image捕获成功!")
@@ -257,7 +399,7 @@ async function captureWithPostMessage(iframe: HTMLIFrameElement): Promise<string
const timeout = setTimeout(() => {
window.removeEventListener("message", messageHandler)
reject(new Error("postMessage截图超时"))
}, 5000)
}, options.timeout || 5000)
// 消息处理函数
function messageHandler(event: MessageEvent) {
@@ -451,12 +593,12 @@ export function injectScreenshotScript(window: Window): void {
const canvas = await html2canvas(document.documentElement, {
allowTaint: true,
useCORS: true,
scale: 2,
backgroundColor: '#ffffff'
scale: ${options.scale || 2},
backgroundColor: '${options.backgroundColor || "#ffffff"}'
});
// 发送截图数据
const dataUrl = canvas.toDataURL('image/png');
const dataUrl = canvas.toDataURL('image/${options.format || "png"}', ${options.quality || 0.9});
window.parent.postMessage({
type: 'screenshot',
dataUrl: dataUrl