|
46 | 46 | <div class="flex flex-col md:flex-row items-start md:items-center gap-6"> |
47 | 47 | <div class="min-w-0 flex-1 text-left"> |
48 | 48 | <div class="text-sm mb-2" style="color:var(--tf-text-muted)">{{ $t('result.created') }}</div> |
49 | | - <button @click="redirectViaApi({ shortUrl })" class="underline break-all text-[16px] font-medium" style="color:var(--tf-brand-primary);background:none;border:none;padding:0;cursor:pointer"> |
| 49 | + <a :href="shortUrl" target="_blank" class="underline break-all text-[16px] font-medium hover:opacity-80" style="color:var(--tf-brand-primary);text-decoration:underline;cursor:pointer;display:inline-block"> |
50 | 50 | {{ decodeUrlText(shortUrl) }} |
51 | | - </button> |
| 51 | + </a> |
52 | 52 | <div class="mt-4 flex gap-3"> |
53 | 53 | <button @click="copyShortUrl" class="fs-btn-secondary px-4 py-2"> |
54 | 54 | {{ $t('result.copy') }} |
|
94 | 94 | <Favicon :long-url="normalizeUrl(resolveLongUrl(item)) || (location.origin + (item.shortUrl || ''))" /> |
95 | 95 | <div class="min-w-0"> |
96 | 96 | <div class="flex items-center gap-2 min-w-0"> |
97 | | - <button @click="redirectViaApi(item)" class="truncate text-[14px] font-medium hover:underline" style="color:var(--tf-brand-primary);max-width:52vw;background:none;border:none;padding:0;cursor:pointer">{{ displayShortUrlText(item) }}</button> |
| 97 | + <a :href="displayShortUrl(item)" target="_blank" class="truncate text-[14px] font-medium hover:underline hover:opacity-80" style="color:var(--tf-brand-primary);max-width:52vw;text-decoration:none">{{ displayShortUrlText(item) }}</a> |
98 | 98 | <span class="px-2 py-0.5 text-[12px] rounded" style="background:var(--tf-brand-lighter);color:var(--tf-brand-primary)">{{ extractCode(item) }}</span> |
99 | 99 | </div> |
100 | 100 | <div class="mt-1 truncate text-[13px]" style="color:var(--tf-text-muted);max-width:60vw">{{ item.longUrl }}</div> |
@@ -164,6 +164,7 @@ import LoadingSpinner from '../components/LoadingSpinner.vue' |
164 | 164 | import QrcodeVue from 'qrcode.vue' |
165 | 165 | import Favicon from '../components/Favicon.vue' |
166 | 166 | import { SHORT_BASE } from '/src/composables/shortBase' |
| 167 | +import { copyToClipboard } from '../composables/useCopy' |
167 | 168 |
|
168 | 169 | const api = axios |
169 | 170 |
|
@@ -292,12 +293,13 @@ export default { |
292 | 293 | async copyShortUrl() { |
293 | 294 | if (!this.shortUrl) return |
294 | 295 | try { |
295 | | - await navigator.clipboard.writeText(this.shortUrl) |
| 296 | + await copyToClipboard(this.shortUrl) |
296 | 297 | this.copyLabel = '已复制' |
297 | 298 | clearTimeout(this.copyTimer) |
298 | 299 | this.copyTimer = setTimeout(() => { this.copyLabel = '复制链接' }, 2000) |
299 | 300 | } catch (e) { |
300 | 301 | console.error('复制失败:', e) |
| 302 | + alert('复制失败,请手动复制') |
301 | 303 | } |
302 | 304 | }, |
303 | 305 | confirmClearAll() { |
@@ -374,12 +376,13 @@ export default { |
374 | 376 | }, |
375 | 377 | async copyLink(url, id) { |
376 | 378 | try { |
377 | | - await navigator.clipboard.writeText(url) |
| 379 | + await copyToClipboard(url) |
378 | 380 | this.copiedId = id |
379 | 381 | clearTimeout(this.copyItemTimer) |
380 | 382 | this.copyItemTimer = setTimeout(() => { this.copiedId = null }, 2000) |
381 | 383 | } catch (e) { |
382 | 384 | console.error('复制失败:', e) |
| 385 | + alert('复制失败,请手动复制') |
383 | 386 | } |
384 | 387 | }, |
385 | 388 | async refreshHistory() { |
|
0 commit comments