diff --git a/src/main/java/com/mini/capi/config/component/AppPathInfo.java b/src/main/java/com/mini/capi/config/component/AppPathInfo.java index 0f1834a..d35f136 100644 --- a/src/main/java/com/mini/capi/config/component/AppPathInfo.java +++ b/src/main/java/com/mini/capi/config/component/AppPathInfo.java @@ -1,9 +1,11 @@ package com.mini.capi.config.component; import org.springframework.stereotype.Component; + import java.io.File; -import java.net.URISyntaxException; +import java.net.JarURLConnection; import java.net.URL; +import java.net.URLConnection; @Component public class AppPathInfo { @@ -13,14 +15,29 @@ public class AppPathInfo { return System.getProperty("user.dir"); } - // 获取 Jar 包所在目录(仅 Jar 运行时有效;IDE 中返回 classes 目录父级) - public String getJarDir() throws URISyntaxException { - URL jarUrl = getClass().getProtectionDomain().getCodeSource().getLocation(); - File jarFile = new File(jarUrl.toURI()); - return jarFile.getParentFile().getAbsolutePath(); + public String getJarDir() { + URL url = getClass().getProtectionDomain().getCodeSource().getLocation(); + String path = null; + try { + URLConnection connection = url.openConnection(); + if (connection instanceof JarURLConnection) { + // 处理Jar包环境:获取Jar文件路径并截取目录 + JarURLConnection jarConn = (JarURLConnection) connection; + String jarFilePath = jarConn.getJarFile().getName(); // 获取Jar文件完整路径(如:/xxx/xxx/xxx.jar) + // 截取Jar文件所在目录(去掉文件名部分) + path = jarFilePath.substring(0, jarFilePath.lastIndexOf(File.separator)); + } else { + // 处理本地开发环境(文件夹形式运行) + path = new File(url.toURI()).getParentFile().getAbsolutePath(); + } + } catch (Exception e) { + e.printStackTrace(); + // 兜底方案:获取当前工作目录 + path = System.getProperty("user.dir"); + } + return path; } - // 获取类路径下的资源目录(IDE 中是 target/classes,Jar 中是 jar 内部路径) public String getResourceDir() { URL resourceUrl = getClass().getClassLoader().getResource(""); if (resourceUrl != null) { diff --git a/src/main/resources/templates/field.html b/src/main/resources/templates/field.html index 408a4c5..74f44ef 100644 --- a/src/main/resources/templates/field.html +++ b/src/main/resources/templates/field.html @@ -297,16 +297,55 @@ } // 复制文本到剪贴板并显示提示 + // 优化后的复制文本到剪贴板函数(兼容云服务器环境) function copyToClipboard(elementId) { - const text = document.getElementById(elementId).textContent; - navigator.clipboard.writeText(text) - .then(() => { + const textElement = document.getElementById(elementId); + const text = textElement.textContent; + + // 方案1:尝试现代 Clipboard API(优先使用,支持 HTTPS) + if (navigator.clipboard && window.isSecureContext) { + navigator.clipboard.writeText(text) + .then(() => { + showNotification('复制成功!', true); + }) + .catch(() => { + // 现代 API 失败,降级到方案2 + fallbackCopy(textElement, text); + }); + } else { + // 非 HTTPS 环境直接使用方案2 + fallbackCopy(textElement, text); + } + } + + // 降级方案:使用 document.execCommand(兼容 HTTP/旧浏览器) + function fallbackCopy(textElement, text) { + // 创建临时文本区域(避免影响原有 DOM) + const tempTextArea = document.createElement('textarea'); + tempTextArea.value = text; + // 隐藏临时元素(避免页面闪烁) + tempTextArea.style.position = 'absolute'; + tempTextArea.style.left = '-9999px'; + document.body.appendChild(tempTextArea); + + // 选中文本并执行复制 + tempTextArea.select(); + tempTextArea.setSelectionRange(0, text.length); // 适配移动设备 + + try { + const success = document.execCommand('copy'); + if (success) { showNotification('复制成功!', true); - }) - .catch(err => { - console.error('复制失败: ', err); - showNotification('复制失败,请手动复制', false); - }); + } else { + throw new Error('执行复制命令失败'); + } + } catch (err) { + console.error('复制失败: ', err); + showNotification('复制失败,请手动复制', false); + } finally { + // 移除临时元素 + document.body.removeChild(tempTextArea); + } }