主要变更: - RDP 远程桌面:新增 backend/pkg/rdp(RDP 引擎 + credssp/display/rle/trace)、 backend/controller/rdp*(连接/凭证/文件/会话/实时)、frontend RDP 组件与 API - Windows SMB 文件传输:backend/pkg/winsmb - 云账单同步:backend/pkg/billingsync + billing_sync/aliyun_billing,前端账单详情 - Agent CLI Kubernetes 工具:kubernetes_action/get、pod_execute/logs - 服务器导入助手:server_import_helpers、ImportCredentialSettings - 国际化与组件重构(cloud/deploy/monitor/server/system 等多模块) - 清理编译产物二进制:移除 backend/server、backend/agent/bin/aiops-agent-* - .gitignore:新增 backend/agent/ 与 .cache/(避免 334MB go-build 缓存误入库) Co-Authored-By: Claude <noreply@anthropic.com>
66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
// clipboard.ts — 统一剪贴板复制(Clipboard API + execCommand 回退)// Logan.Li
|
||
|
||
/** 复制文本到剪贴板,兼容 HTTP / 非安全上下文 // Logan.Li */
|
||
export async function copyToClipboard(text: string): Promise<boolean> {
|
||
if (!text) return false;
|
||
|
||
// 优先使用 Clipboard API
|
||
try {
|
||
if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {
|
||
await navigator.clipboard.writeText(text);
|
||
return true;
|
||
}
|
||
} catch {
|
||
/* 回退 execCommand */
|
||
}
|
||
|
||
// execCommand 回退(参考 AgentWizard)// Logan.Li
|
||
if (typeof document === 'undefined') return false;
|
||
|
||
const textArea = document.createElement('textarea');
|
||
textArea.value = text;
|
||
textArea.style.position = 'fixed';
|
||
textArea.style.top = '0';
|
||
textArea.style.left = '0';
|
||
textArea.style.width = '2em';
|
||
textArea.style.height = '2em';
|
||
textArea.style.padding = '0';
|
||
textArea.style.border = 'none';
|
||
textArea.style.outline = 'none';
|
||
textArea.style.boxShadow = 'none';
|
||
textArea.style.background = 'transparent';
|
||
textArea.style.opacity = '0';
|
||
textArea.style.pointerEvents = 'none';
|
||
textArea.style.zIndex = '-1';
|
||
textArea.style.fontSize = '16px';
|
||
textArea.contentEditable = 'true';
|
||
textArea.readOnly = true;
|
||
document.body.appendChild(textArea);
|
||
|
||
textArea.focus();
|
||
textArea.select();
|
||
if (textArea.setSelectionRange) {
|
||
textArea.setSelectionRange(0, text.length);
|
||
}
|
||
|
||
let success = false;
|
||
try {
|
||
success = document.execCommand('copy');
|
||
} catch {
|
||
success = false;
|
||
}
|
||
document.body.removeChild(textArea);
|
||
return success;
|
||
}
|
||
|
||
/** 从剪贴板读取文本;非 HTTPS / 无权限时返回 null,由调用方走手动粘贴回退 // Logan.Li */
|
||
export async function readFromClipboard(): Promise<string | null> {
|
||
try {
|
||
if (typeof navigator !== 'undefined' && navigator.clipboard?.readText) {
|
||
return await navigator.clipboard.readText();
|
||
}
|
||
} catch {
|
||
return null;
|
||
}
|
||
return null;
|
||
} |