Skip to content

Commit 38459aa

Browse files
committed
feat (core): 支持复制执行结果
1 parent 96f33ab commit 38459aa

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@ dist-ssr
2323
*.sln
2424
*.sw?
2525
pnpm-lock.yaml
26+
*.csv
27+
*.json

src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ const clearOutput = () => {
285285
showToast('输出已清空', 'info')
286286
}
287287
288-
// window.addEventListener("contextmenu", (e) => e.preventDefault(), false);
288+
window.addEventListener("contextmenu", (e) => e.preventDefault(), false);
289289
290290
onMounted(async () => {
291291
await getSupportedLanguages()

src/components/OutputPanel.vue

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,23 @@
33
<div class="p-2 border-b border-gray-700 flex items-center justify-between">
44
<div class="flex items-center space-x-2">
55
<Terminal class="w-4 h-4"/>
6-
<span class="text-sm font-medium">输出</span>
6+
<span class="text-sm font-medium">控制台</span>
77
</div>
8-
<div v-if="executionTime > 0" class="text-xs text-gray-400 flex items-center space-x-1">
9-
<Clock class="w-3 h-3"/>
10-
<span>{{ executionTime }} 毫秒</span>
8+
<div class="flex items-center space-x-3">
9+
<span v-if="isCopied" class="text-xs text-gray-400">{{ isCopied ? '已复制' : '复制失败' }}</span>
10+
11+
<!-- 复制按钮 -->
12+
<button v-if="output && !isRunning"
13+
@click="copyOutput"
14+
class="text-gray-400 hover:text-white transition-colors duration-200 p-1 rounded hover:bg-gray-700 cursor-pointer"
15+
title="复制输出内容">
16+
<component :is="copyIcon" class="w-3 h-3"/>
17+
</button>
18+
19+
<div v-if="executionTime > 0" class="text-xs text-gray-400 flex items-center space-x-1">
20+
<Clock class="w-3 h-3"/>
21+
<span>{{ executionTime }} 毫秒</span>
22+
</div>
1123
</div>
1224
</div>
1325

@@ -31,12 +43,55 @@
3143
</template>
3244

3345
<script setup lang="ts">
34-
import { Clock, Loader, Terminal } from 'lucide-vue-next'
46+
import { computed, ref } from 'vue'
47+
import { Check, Clock, Copy, Loader, Terminal } from 'lucide-vue-next'
3548
36-
defineProps<{
49+
const props = defineProps<{
3750
output: string
3851
isRunning: boolean
3952
isSuccess: boolean
4053
executionTime: number
4154
}>()
55+
56+
const isCopied = ref(false)
57+
58+
// 动态切换图标
59+
const copyIcon = computed(() => isCopied.value ? Check : Copy)
60+
61+
const copyOutput = async () => {
62+
if (!props.output) {
63+
return
64+
}
65+
66+
try {
67+
await navigator.clipboard.writeText(props.output)
68+
isCopied.value = true
69+
70+
// 2秒后恢复复制图标
71+
setTimeout(() => {
72+
isCopied.value = false
73+
}, 2000)
74+
}
75+
catch (error) {
76+
console.error('复制失败:', error)
77+
78+
// 降级方案:使用传统方法复制
79+
try {
80+
const textArea = document.createElement('textarea')
81+
textArea.value = props.output
82+
document.body.appendChild(textArea)
83+
textArea.select()
84+
document.execCommand('copy')
85+
document.body.removeChild(textArea)
86+
87+
isCopied.value = true
88+
setTimeout(() => {
89+
isCopied.value = false
90+
}, 2000)
91+
}
92+
catch (fallbackError) {
93+
console.error('降级复制也失败了:', fallbackError)
94+
}
95+
}
96+
}
4297
</script>

0 commit comments

Comments
 (0)