fix: 修复远程桌面键盘输入问题 - 添加iframe自动聚焦功能

This commit is contained in:
lvfengfree 2026-01-21 16:36:58 +08:00
parent 915a5ac60b
commit bd64e889fd
2 changed files with 85 additions and 6 deletions

View File

@ -95,8 +95,19 @@
</div> </div>
<!-- 远程桌面 iframe --> <!-- 远程桌面 iframe -->
<div v-else class="remote-desktop-container"> <div v-else class="remote-desktop-container" @click="focusIframe">
<iframe ref="rdpFrame" :src="connectionUrl" class="rdp-iframe" allowfullscreen /> <div class="focus-hint" v-if="showFocusHint">
<span>点击此处激活键盘输入</span>
</div>
<iframe
ref="rdpFrame"
:src="connectionUrl"
class="rdp-iframe"
allowfullscreen
@load="onIframeLoad"
@mouseenter="focusIframe"
tabindex="0"
/>
</div> </div>
</ElDialog> </ElDialog>
</template> </template>
@ -131,6 +142,22 @@ const tokenForm = ref({ expiresInMinutes: 30, maxUseCount: 1, note: '' })
const generatedToken = ref<any>(null) const generatedToken = ref<any>(null)
const deviceTokens = ref<any[]>([]) const deviceTokens = ref<any[]>([])
const loadingTokens = ref(false) const loadingTokens = ref(false)
const showFocusHint = ref(true)
// iframe
const focusIframe = () => {
if (rdpFrame.value) {
rdpFrame.value.focus()
showFocusHint.value = false
}
}
// iframe
const onIframeLoad = () => {
setTimeout(() => {
focusIframe()
}, 500)
}
const loadDeviceTokens = async () => { const loadDeviceTokens = async () => {
if (!props.device?.id) return if (!props.device?.id) return
@ -227,6 +254,7 @@ watch(() => props.modelValue, (newVal) => {
connectionUrl.value = '' connectionUrl.value = ''
generatedToken.value = null generatedToken.value = null
activeTab.value = 'quick' activeTab.value = 'quick'
showFocusHint.value = true
loadDeviceTokens() loadDeviceTokens()
} }
}) })
@ -241,8 +269,10 @@ watch(() => props.modelValue, (newVal) => {
.generated-link { margin-top: 20px; } .generated-link { margin-top: 20px; }
.link-box { margin-top: 10px; } .link-box { margin-top: 10px; }
.tokens-list { padding: 10px; } .tokens-list { padding: 10px; }
.remote-desktop-container { width: 100%; height: calc(85vh - 100px); min-height: 600px; display: flex; justify-content: center; align-items: center; background: #1a1a1a; } .remote-desktop-container { width: 100%; height: calc(85vh - 100px); min-height: 600px; display: flex; flex-direction: column; justify-content: center; align-items: center; background: #1a1a1a; position: relative; }
.rdp-iframe { width: 100%; height: 100%; border: none; background: transparent; } .focus-hint { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); background: rgba(0, 0, 0, 0.7); color: #fff; padding: 8px 16px; border-radius: 4px; font-size: 14px; z-index: 10; animation: fadeOut 3s forwards; }
@keyframes fadeOut { 0% { opacity: 1; } 70% { opacity: 1; } 100% { opacity: 0; pointer-events: none; } }
.rdp-iframe { width: 100%; height: 100%; border: none; background: transparent; outline: none; }
:deep(.el-dialog__body) { padding: 0; overflow: hidden; } :deep(.el-dialog__body) { padding: 0; overflow: hidden; }
:deep(.el-dialog__header) { padding: 15px 20px; margin: 0; border-bottom: 1px solid #e4e7ed; } :deep(.el-dialog__header) { padding: 15px 20px; margin: 0; border-bottom: 1px solid #e4e7ed; }
</style> </style>

View File

@ -39,7 +39,7 @@
</div> </div>
<!-- 远程桌面 iframe --> <!-- 远程桌面 iframe -->
<div v-else class="remote-desktop-container"> <div v-else class="remote-desktop-container" @click="focusIframe">
<div class="toolbar"> <div class="toolbar">
<span>远程桌面 - {{ tokenInfo?.deviceIp }}</span> <span>远程桌面 - {{ tokenInfo?.deviceIp }}</span>
<div class="toolbar-actions"> <div class="toolbar-actions">
@ -49,7 +49,18 @@
</el-button> </el-button>
</div> </div>
</div> </div>
<iframe ref="rdpFrame" :src="connectionUrl" class="rdp-iframe" allowfullscreen /> <div class="focus-hint" v-if="showFocusHint">
<span>点击此处激活键盘输入</span>
</div>
<iframe
ref="rdpFrame"
:src="connectionUrl"
class="rdp-iframe"
allowfullscreen
@load="onIframeLoad"
@mouseenter="focusIframe"
tabindex="0"
/>
</div> </div>
</div> </div>
</template> </template>
@ -73,6 +84,22 @@ const connectionUrl = ref('')
const connecting = ref(false) const connecting = ref(false)
const isFullscreen = ref(false) const isFullscreen = ref(false)
const rdpFrame = ref<HTMLIFrameElement | null>(null) const rdpFrame = ref<HTMLIFrameElement | null>(null)
const showFocusHint = ref(true)
// iframe
const focusIframe = () => {
if (rdpFrame.value) {
rdpFrame.value.focus()
showFocusHint.value = false
}
}
// iframe
const onIframeLoad = () => {
setTimeout(() => {
focusIframe()
}, 500)
}
onMounted(async () => { onMounted(async () => {
const token = route.params.token as string const token = route.params.token as string
@ -183,6 +210,7 @@ const formatDate = (dateStr: string) => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: #1a1a1a; background: #1a1a1a;
position: relative;
} }
.toolbar { .toolbar {
@ -204,5 +232,26 @@ const formatDate = (dateStr: string) => {
width: 100%; width: 100%;
border: none; border: none;
background: transparent; background: transparent;
outline: none;
}
.focus-hint {
position: absolute;
top: 60px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
color: #fff;
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
z-index: 10;
animation: fadeOut 3s forwards;
}
@keyframes fadeOut {
0% { opacity: 1; }
70% { opacity: 1; }
100% { opacity: 0; pointer-events: none; }
} }
</style> </style>