fix(ui): 报告复制在 HTTP 非安全上下文下失效,增加 execCommand 降级
Claude-Session: https://claude.ai/code/session_01Bs2rrsVHUBTxRusm9espwB
This commit is contained in:
1 parent
d14ce4d9f4
commit
ed96f256a4
1 file changed
+37
-5
@@ -10,6 +10,34 @@ import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { api } from "@/lib/api";
|
||||
|
||||
async function copyText(text: string): Promise<boolean> {
|
||||
// 优先使用异步剪贴板 API(仅在 HTTPS / localhost 等安全上下文可用)
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
return true;
|
||||
} catch {
|
||||
// 继续走降级方案
|
||||
}
|
||||
}
|
||||
// 降级:HTTP 等非安全上下文下用 execCommand
|
||||
try {
|
||||
const textarea = document.createElement("textarea");
|
||||
textarea.value = text;
|
||||
textarea.style.position = "fixed";
|
||||
textarea.style.left = "-9999px";
|
||||
textarea.style.top = "0";
|
||||
document.body.appendChild(textarea);
|
||||
textarea.focus();
|
||||
textarea.select();
|
||||
const ok = document.execCommand("copy");
|
||||
document.body.removeChild(textarea);
|
||||
return ok;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function ReportTab({ taskId }: { taskId: string }) {
|
||||
const [report, setReport] = React.useState<string>("");
|
||||
const [loading, setLoading] = React.useState(true);
|
||||
@@ -34,12 +62,16 @@ export function ReportTab({ taskId }: { taskId: string }) {
|
||||
};
|
||||
}, [taskId]);
|
||||
|
||||
function copy() {
|
||||
async function copy() {
|
||||
if (!report) return;
|
||||
navigator.clipboard?.writeText(report);
|
||||
setCopied(true);
|
||||
toast.success("已复制 Markdown");
|
||||
setTimeout(() => setCopied(false), 1500);
|
||||
const ok = await copyText(report);
|
||||
if (ok) {
|
||||
setCopied(true);
|
||||
toast.success("已复制 Markdown");
|
||||
setTimeout(() => setCopied(false), 1500);
|
||||
} else {
|
||||
toast.error("复制失败,请手动选择文本复制");
|
||||
}
|
||||
}
|
||||
|
||||
let content: React.ReactNode;
|
||||
|
||||
Reference in new issue
Block a user