mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-06-16 08:41:44 +08:00
feat: CLI 改密、自定义 TLS、移动端适配与扩展校验
- 新增 one-kvm user set-password(交互式),改密后吊销该用户全部会话 - /api/config/web 支持 PEM 证书/密钥上传与清除,响应含 has_custom_cert - 移动端:ActionBar 溢出菜单、ATX/粘贴底部 Sheet、BrandMark 与控制台等响应式优化 - GOSTC:校验服务器地址非空,管理器启动条件与 HTTP 热更新一致 - RustDesk:中继密钥 relay_key 校验为标准 Base64 且解码后恰好 32 字节 - StatusCard、InfoBar:合并精简冗余状态信息
This commit is contained in:
@@ -42,81 +42,70 @@ const keysDisplay = computed(() => {
|
||||
|
||||
<template>
|
||||
<div class="w-full border-t border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-900">
|
||||
<!-- Compact mode for small screens -->
|
||||
<div v-if="compact" class="flex items-center justify-between text-xs px-2 py-0.5">
|
||||
<!-- LED indicator only in compact mode -->
|
||||
<div v-if="keyboardLedEnabled" class="flex items-center gap-1">
|
||||
<span
|
||||
v-if="capsLock"
|
||||
class="px-1.5 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium"
|
||||
>C</span>
|
||||
<span v-else class="text-muted-foreground/40 text-[10px]">C</span>
|
||||
<span
|
||||
:class="numLock ? 'px-1.5 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium' : 'text-muted-foreground/40 text-[10px]'"
|
||||
>N</span>
|
||||
<span
|
||||
:class="scrollLock ? 'px-1.5 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium' : 'text-muted-foreground/40 text-[10px]'"
|
||||
>S</span>
|
||||
</div>
|
||||
<div v-else class="text-[10px] text-muted-foreground/60">
|
||||
{{ t('infobar.keyboardLedUnavailable') }}
|
||||
</div>
|
||||
<!-- Keys in compact mode -->
|
||||
<div v-if="keysDisplay" class="text-[10px] text-muted-foreground truncate max-w-[150px]">
|
||||
{{ keysDisplay }}
|
||||
<!-- Compact mode (explicit prop or auto on small screens via sm:hidden) -->
|
||||
<div :class="compact ? '' : 'sm:hidden'">
|
||||
<div class="flex items-center justify-between text-xs px-2 py-0.5">
|
||||
<div v-if="keyboardLedEnabled" class="flex items-center gap-1">
|
||||
<span
|
||||
:class="capsLock ? 'px-1.5 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium' : 'text-muted-foreground/40 text-[10px]'"
|
||||
>C</span>
|
||||
<span
|
||||
:class="numLock ? 'px-1.5 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium' : 'text-muted-foreground/40 text-[10px]'"
|
||||
>N</span>
|
||||
<span
|
||||
:class="scrollLock ? 'px-1.5 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium' : 'text-muted-foreground/40 text-[10px]'"
|
||||
>S</span>
|
||||
</div>
|
||||
<div v-else class="text-[10px] text-muted-foreground/60">
|
||||
{{ t('infobar.keyboardLedUnavailable') }}
|
||||
</div>
|
||||
<div v-if="keysDisplay" class="text-[10px] text-muted-foreground truncate max-w-[200px]">
|
||||
{{ keysDisplay }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Normal mode -->
|
||||
<div v-else class="flex flex-wrap items-center justify-between text-xs">
|
||||
<!-- Left side: Debug info and pressed keys -->
|
||||
<div class="flex items-center gap-4 px-3 py-1 min-w-0 flex-1">
|
||||
<!-- Pressed Keys -->
|
||||
<div class="flex items-center gap-1.5 min-w-0">
|
||||
<span class="font-medium text-muted-foreground shrink-0 hidden sm:inline">{{ t('infobar.keys') }}:</span>
|
||||
<span class="text-foreground truncate">{{ keysDisplay || '-' }}</span>
|
||||
<!-- Normal mode (hidden on small screens unless compact is explicitly set) -->
|
||||
<div :class="compact ? 'hidden' : 'hidden sm:block'">
|
||||
<div class="flex flex-wrap items-center justify-between text-xs">
|
||||
<!-- Left side: Debug info and pressed keys -->
|
||||
<div class="flex items-center gap-4 px-3 py-1 min-w-0 flex-1">
|
||||
<div class="flex items-center gap-1.5 min-w-0">
|
||||
<span class="font-medium text-muted-foreground shrink-0">{{ t('infobar.keys') }}:</span>
|
||||
<span class="text-foreground truncate">{{ keysDisplay || '-' }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="debugMode && mousePosition" class="flex items-center gap-1.5 hidden md:flex">
|
||||
<span class="font-medium text-muted-foreground">{{ t('infobar.pointer') }}:</span>
|
||||
<span class="text-foreground">{{ mousePosition.x }}, {{ mousePosition.y }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Debug: Mouse Position -->
|
||||
<div v-if="debugMode && mousePosition" class="flex items-center gap-1.5 hidden md:flex">
|
||||
<span class="font-medium text-muted-foreground">{{ t('infobar.pointer') }}:</span>
|
||||
<span class="text-foreground">{{ mousePosition.x }}, {{ mousePosition.y }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right side: Keyboard LED states -->
|
||||
<div class="flex items-center shrink-0">
|
||||
<template v-if="keyboardLedEnabled">
|
||||
<div
|
||||
:class="cn(
|
||||
'px-2 py-1 select-none transition-colors',
|
||||
capsLock ? 'text-foreground font-medium bg-primary/5' : 'text-muted-foreground/40'
|
||||
)"
|
||||
>
|
||||
<span class="hidden sm:inline">{{ t('infobar.caps') }}</span>
|
||||
<span class="sm:hidden">C</span>
|
||||
<!-- Right side: Keyboard LED states -->
|
||||
<div class="flex items-center shrink-0">
|
||||
<template v-if="keyboardLedEnabled">
|
||||
<div
|
||||
:class="cn(
|
||||
'px-2 py-1 select-none transition-colors',
|
||||
capsLock ? 'text-foreground font-medium bg-primary/5' : 'text-muted-foreground/40'
|
||||
)"
|
||||
>{{ t('infobar.caps') }}</div>
|
||||
<div
|
||||
:class="cn(
|
||||
'px-2 py-1 select-none transition-colors',
|
||||
numLock ? 'text-foreground font-medium bg-primary/5' : 'text-muted-foreground/40'
|
||||
)"
|
||||
>{{ t('infobar.num') }}</div>
|
||||
<div
|
||||
:class="cn(
|
||||
'px-2 py-1 select-none transition-colors',
|
||||
scrollLock ? 'text-foreground font-medium bg-primary/5' : 'text-muted-foreground/40'
|
||||
)"
|
||||
>{{ t('infobar.scroll') }}</div>
|
||||
</template>
|
||||
<div v-else class="px-3 py-1 text-muted-foreground/60">
|
||||
{{ t('infobar.keyboardLedUnavailable') }}
|
||||
</div>
|
||||
<div
|
||||
:class="cn(
|
||||
'px-2 py-1 select-none transition-colors',
|
||||
numLock ? 'text-foreground font-medium bg-primary/5' : 'text-muted-foreground/40'
|
||||
)"
|
||||
>
|
||||
<span class="hidden sm:inline">{{ t('infobar.num') }}</span>
|
||||
<span class="sm:hidden">N</span>
|
||||
</div>
|
||||
<div
|
||||
:class="cn(
|
||||
'px-2 py-1 select-none transition-colors',
|
||||
scrollLock ? 'text-foreground font-medium bg-primary/5' : 'text-muted-foreground/40'
|
||||
)"
|
||||
>
|
||||
<span class="hidden sm:inline">{{ t('infobar.scroll') }}</span>
|
||||
<span class="sm:hidden">S</span>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="px-3 py-1 text-muted-foreground/60">
|
||||
{{ t('infobar.keyboardLedUnavailable') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user