diff --git a/src/main/resources/templates/views/data/detail.html b/src/main/resources/templates/views/data/detail.html index f48f3fe..3a28e88 100644 --- a/src/main/resources/templates/views/data/detail.html +++ b/src/main/resources/templates/views/data/detail.html @@ -222,20 +222,21 @@ background: #e8f5e9; } - .col-name{ + .col-name { display: inline-block; - font-family: "JetBrains Mono",SFMono-Regular,Consolas,monospace; + font-family: "JetBrains Mono", SFMono-Regular, Consolas, monospace; font-weight: 600; font-size: 0.875rem; - color: #0c4a6e; /* 深蓝字 */ + color: #0c4a6e; /* 深蓝字 */ padding: 3px 8px 4px; border-radius: 4px; background: linear-gradient(90deg, #e0f2fe 0%, #bae6fd 100%); /* 浅蓝渐变 */ - box-shadow: 0 1px 2px rgba(14,165,233,.15); + box-shadow: 0 1px 2px rgba(14, 165, 233, .15); transition: box-shadow .2s; } - .col-name:hover{ - box-shadow: 0 2px 6px rgba(14,165,233,.25); + + .col-name:hover { + box-shadow: 0 2px 6px rgba(14, 165, 233, .25); } @@ -490,16 +491,82 @@ }); /* 复制/导出 */ - document.getElementById('export-field').addEventListener('click', () => showModal('提示', '导出功能待实现')); - document.getElementById('copy-select').addEventListener('click', () => { - navigator.clipboard.writeText(document.querySelector('#select-content .code-block').textContent) - .then(() => showModal('复制成功', 'SQL已复制到剪贴板')) - .catch(err => showModal('复制失败', '无法访问剪贴板: ' + err)); + /* 优化后的复制功能:支持HTTPS/HTTP、兼容旧浏览器、增强错误处理 */ + // 通用复制函数:接收代码块容器ID,返回复制结果 + async function copyToClipboard(codeBlockContainerId) { + try { + // 1. 安全获取代码块元素(避免选择器失效) + const container = document.getElementById(codeBlockContainerId); + if (!container) { + throw new Error("复制失败:未找到代码块容器,请检查页面结构"); + } + const codeBlock = container.querySelector(".code-block"); + if (!codeBlock) { + throw new Error("复制失败:代码块元素不存在"); + } + + // 2. 获取纯净文本(排除HTML标签,处理换行格式) + const codeText = codeBlock.textContent.trim(); + if (!codeText) { + throw new Error("复制失败:代码块内容为空"); + } + + // 3. 优先使用现代剪贴板API(HTTPS环境),降级使用execCommand(HTTP/旧浏览器) + if (navigator.clipboard && window.isSecureContext) { + // 现代浏览器:HTTPS环境下使用clipboard API + await navigator.clipboard.writeText(codeText); + } else { + // 降级方案:创建临时文本框,用execCommand复制(兼容HTTP/旧浏览器) + const tempTextarea = document.createElement("textarea"); + // 隐藏临时文本框(避免影响页面布局) + tempTextarea.style.position = "fixed"; + tempTextarea.style.top = "-999px"; + tempTextarea.style.left = "-999px"; + tempTextarea.value = codeText; + document.body.appendChild(tempTextarea); + + // 选中文本并复制 + tempTextarea.select(); + const copySuccess = document.execCommand("copy"); + document.body.removeChild(tempTextarea); // 复制后删除临时元素 + + if (!copySuccess) { + throw new Error("复制失败:浏览器不支持传统复制方法,请升级浏览器或切换HTTPS环境"); + } + } + + // 4. 复制成功提示 + showModal("复制成功", "代码已成功复制到剪贴板,可直接粘贴使用"); + } catch (err) { + // 5. 区分错误类型,给出明确提示(方便生产环境排查) + let errorMsg = "复制失败:"; + if (err.message.includes("HTTPS")) { + errorMsg += "当前为HTTP环境,建议切换到HTTPS以使用更稳定的复制功能"; + } else if (err.message.includes("不存在") || err.message.includes("容器")) { + errorMsg += "页面元素异常,请刷新页面重试"; + } else if (err.message.includes("空")) { + errorMsg += "代码块无内容,无需复制"; + } else { + errorMsg += err.message || "未知错误,请检查浏览器权限"; + } + showModal("复制失败", errorMsg); + console.error("复制功能错误详情:", err); // 生产环境可上报日志 + } + } + + // 绑定SELECT复制按钮事件(传入SELECT代码块容器ID) + document.getElementById("copy-select").addEventListener("click", () => { + copyToClipboard("select-content"); }); - document.getElementById('copy-ddl').addEventListener('click', () => { - navigator.clipboard.writeText(document.querySelector('#ddl-content .code-block').textContent) - .then(() => showModal('复制成功', 'DDL已复制到剪贴板')) - .catch(err => showModal('复制失败', '无法访问剪贴板: ' + err)); + + // 绑定DDL复制按钮事件(传入DDL代码块容器ID) + document.getElementById("copy-ddl").addEventListener("click", () => { + copyToClipboard("ddl-content"); + }); + + // 导出功能提示优化(原功能待实现,增强用户体验) + document.getElementById("export-field").addEventListener("click", () => { + showModal("提示", "导出功能暂未实现,您可先复制字段信息表格内容"); });