8
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* 兼容所有浏览器的复制到剪贴板函数
|
||||||
|
* 解决 iOS Safari 不支持 navigator.clipboard.writeText() 的问题
|
||||||
|
*/
|
||||||
|
export async function copyToClipboard(text) {
|
||||||
|
// 方法1: 现代 Clipboard API(Chrome/Firefox/Edge 桌面端)
|
||||||
|
if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(text);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
// Safari 可能抛出 NotAllowedError,继续尝试 fallback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 方法2: 传统 execCommand(iOS Safari 兼容方案)
|
||||||
|
try {
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.value = text;
|
||||||
|
// 防止页面滚动
|
||||||
|
textarea.style.position = 'fixed';
|
||||||
|
textarea.style.left = '-9999px';
|
||||||
|
textarea.style.top = '-9999px';
|
||||||
|
textarea.style.opacity = '0';
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
// iOS Safari 需要设置 selection range
|
||||||
|
textarea.focus();
|
||||||
|
textarea.select();
|
||||||
|
textarea.setSelectionRange(0, textarea.value.length);
|
||||||
|
const success = document.execCommand('copy');
|
||||||
|
document.body.removeChild(textarea);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* 兼容所有浏览器的复制到剪贴板函数
|
||||||
|
* 解决 iOS Safari 不支持 navigator.clipboard.writeText() 的问题
|
||||||
|
*/
|
||||||
|
export async function copyToClipboard(text: string): Promise<boolean> {
|
||||||
|
// 方法1: 现代 Clipboard API(Chrome/Firefox/Edge 桌面端)
|
||||||
|
if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(text)
|
||||||
|
return true
|
||||||
|
} catch {
|
||||||
|
// Safari 可能抛出 NotAllowedError,继续尝试 fallback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方法2: 传统 execCommand(iOS Safari 兼容方案)
|
||||||
|
try {
|
||||||
|
const textarea = document.createElement('textarea')
|
||||||
|
textarea.value = text
|
||||||
|
|
||||||
|
// 防止页面滚动
|
||||||
|
textarea.style.position = 'fixed'
|
||||||
|
textarea.style.left = '-9999px'
|
||||||
|
textarea.style.top = '-9999px'
|
||||||
|
textarea.style.opacity = '0'
|
||||||
|
|
||||||
|
document.body.appendChild(textarea)
|
||||||
|
|
||||||
|
// iOS Safari 需要设置 selection range
|
||||||
|
textarea.focus()
|
||||||
|
textarea.select()
|
||||||
|
textarea.setSelectionRange(0, textarea.value.length)
|
||||||
|
|
||||||
|
const success = document.execCommand('copy')
|
||||||
|
document.body.removeChild(textarea)
|
||||||
|
return success
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import { ref, onMounted, computed } from 'vue'
|
|||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import apiClient from '@/api/client'
|
import apiClient from '@/api/client'
|
||||||
|
import { copyToClipboard } from '@/utils/clipboard'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const kbId = route.params.id as string
|
const kbId = route.params.id as string
|
||||||
@@ -173,10 +174,12 @@ async function handleReprocess(doc: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleCopyLink() {
|
async function handleCopyLink() {
|
||||||
try {
|
const success = await copyToClipboard(aiUrl.value)
|
||||||
await navigator.clipboard.writeText(aiUrl.value)
|
if (success) {
|
||||||
ElMessage.success('AI 链接已复制!')
|
ElMessage.success('AI 链接已复制!')
|
||||||
} catch { /* ignore */ }
|
} else {
|
||||||
|
ElMessage.error('复制失败,请手动长按复制。')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重新生成 AI 链接
|
// 重新生成 AI 链接
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { ref, onMounted } from 'vue';
|
|||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import apiClient from '@/api/client';
|
import apiClient from '@/api/client';
|
||||||
|
import { copyToClipboard } from '@/utils/clipboard';
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const kbId = route.params.id;
|
const kbId = route.params.id;
|
||||||
const isMobile = ref(window.innerWidth <= 768);
|
const isMobile = ref(window.innerWidth <= 768);
|
||||||
@@ -162,11 +163,13 @@ async function handleReprocess(doc) {
|
|||||||
catch { /* ignore */ }
|
catch { /* ignore */ }
|
||||||
}
|
}
|
||||||
async function handleCopyLink() {
|
async function handleCopyLink() {
|
||||||
try {
|
const success = await copyToClipboard(aiUrl.value);
|
||||||
await navigator.clipboard.writeText(aiUrl.value);
|
if (success) {
|
||||||
ElMessage.success('AI 链接已复制!');
|
ElMessage.success('AI 链接已复制!');
|
||||||
}
|
}
|
||||||
catch { /* ignore */ }
|
else {
|
||||||
|
ElMessage.error('复制失败,请手动长按复制。');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 重新生成 AI 链接
|
// 重新生成 AI 链接
|
||||||
async function handleRegenerateLink() {
|
async function handleRegenerateLink() {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"root":["./src/env.d.ts","./src/main.ts","./src/api/client.ts","./src/router/index.ts","./src/stores/user.ts","./src/app.vue","./src/layouts/defaultlayout.vue","./src/views/dashboard.vue","./src/views/kbdetail.vue","./src/views/knowledgebases.vue","./src/views/login.vue","./src/views/register.vue","./src/views/settings.vue"],"version":"5.9.3"}
|
{"root":["./src/env.d.ts","./src/main.ts","./src/api/client.ts","./src/router/index.ts","./src/stores/user.ts","./src/utils/clipboard.ts","./src/app.vue","./src/layouts/defaultlayout.vue","./src/views/dashboard.vue","./src/views/kbdetail.vue","./src/views/knowledgebases.vue","./src/views/login.vue","./src/views/register.vue","./src/views/settings.vue"],"version":"5.9.3"}
|
||||||
Reference in New Issue
Block a user