feat(key-detail): live TTL countdown with expiry check and i18n
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, ref, watch, onUnmounted } from 'vue'
|
||||
import { useKeyStore } from '@renderer/stores/key'
|
||||
import { useConnectionStore } from '@renderer/stores/connection'
|
||||
import { useI18n } from '@renderer/i18n'
|
||||
@@ -34,13 +34,46 @@ const typeColor = computed(() => {
|
||||
return colors[keyStore.selectedType || ''] || 'var(--text-muted)'
|
||||
})
|
||||
|
||||
const liveTTL = ref(keyStore.selectedTTL)
|
||||
|
||||
watch(() => keyStore.selectedTTL, (v) => {
|
||||
liveTTL.value = v
|
||||
})
|
||||
|
||||
let ttlTimer: ReturnType<typeof setInterval> | null = setInterval(async () => {
|
||||
if (liveTTL.value > 0) {
|
||||
liveTTL.value--
|
||||
if (liveTTL.value === 0) {
|
||||
const connId = connStore.activeId
|
||||
const key = keyStore.selectedKey
|
||||
if (!connId || !key) return
|
||||
const exists = await window.electronAPI.redis.existsKey(connId, key)
|
||||
// 用户可能已切换 key,跳过过期检查
|
||||
if (keyStore.selectedKey !== key) return
|
||||
if (!exists) {
|
||||
keyStore.selectedType = 'none'
|
||||
} else {
|
||||
// key 仍存在(TTL 可能被其他客户端刷新),同步实际 TTL
|
||||
const ttl = await window.electronAPI.redis.getKeyTTL(connId, key)
|
||||
if (keyStore.selectedKey !== key) return
|
||||
keyStore.selectedTTL = ttl
|
||||
liveTTL.value = ttl
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
onUnmounted(() => {
|
||||
if (ttlTimer) clearInterval(ttlTimer)
|
||||
})
|
||||
|
||||
const ttlDisplay = computed(() => {
|
||||
if (keyStore.selectedTTL < 0) return 'No expiry'
|
||||
if (keyStore.selectedTTL === 0) return 'Expired'
|
||||
const sec = keyStore.selectedTTL
|
||||
if (liveTTL.value < 0) return t('key.noExpiry')
|
||||
if (liveTTL.value === 0) return t('key.expired')
|
||||
const sec = liveTTL.value
|
||||
if (sec < 60) return `${sec}s`
|
||||
if (sec < 3600) return `${Math.floor(sec / 60)}m ${sec % 60}s`
|
||||
return `${Math.floor(sec / 3600)}h ${Math.floor((sec % 3600) / 60)}m`
|
||||
return `${Math.floor(sec / 3600)}h ${Math.floor((sec % 3600) / 60)}m ${sec % 60}s`
|
||||
})
|
||||
|
||||
function openTtlDialog() {
|
||||
@@ -53,6 +86,7 @@ async function saveTtl() {
|
||||
try {
|
||||
await window.electronAPI.redis.setTTL(connStore.activeId, keyStore.selectedKey, ttlValue.value)
|
||||
keyStore.selectedTTL = ttlValue.value
|
||||
liveTTL.value = ttlValue.value
|
||||
showTtlDialog.value = false
|
||||
ElMessage.success('TTL updated')
|
||||
} catch (err: any) {
|
||||
@@ -246,7 +280,7 @@ async function refreshKey() {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 300px;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
|
||||
@@ -105,6 +105,8 @@ export default {
|
||||
ttlTitle: 'TTL festlegen',
|
||||
ttlHint: '-1 = kein Ablauf, 0 = sofort ablaufen',
|
||||
ttlUpdated: 'TTL aktualisiert',
|
||||
noExpiry: 'Kein Ablauf',
|
||||
expired: 'Abgelaufen',
|
||||
exists: 'Schlüssel existiert bereits',
|
||||
batchDelete: 'Ausgewählte löschen',
|
||||
batchConfirm: '{n} Schlüssel löschen?',
|
||||
|
||||
@@ -105,6 +105,8 @@ export default {
|
||||
ttlTitle: 'Set TTL',
|
||||
ttlHint: '-1 = no expiry, 0 = expire now',
|
||||
ttlUpdated: 'TTL updated',
|
||||
noExpiry: 'No expiry',
|
||||
expired: 'Expired',
|
||||
exists: 'Key already exists',
|
||||
batchDelete: 'Delete Selected',
|
||||
batchConfirm: 'Delete {n} key(s)?',
|
||||
|
||||
@@ -105,6 +105,8 @@ export default {
|
||||
ttlTitle: 'TTLを設定',
|
||||
ttlHint: '-1 = 無期限, 0 = 即時期限切れ',
|
||||
ttlUpdated: 'TTLを更新しました',
|
||||
noExpiry: '無期限',
|
||||
expired: '期限切れ',
|
||||
exists: 'キーは既に存在します',
|
||||
batchDelete: '選択を削除',
|
||||
batchConfirm: '{n} 個のキーを削除しますか?',
|
||||
|
||||
@@ -105,6 +105,8 @@ export default {
|
||||
ttlTitle: 'TTL 설정',
|
||||
ttlHint: '-1 = 만료 없음, 0 = 즉시 만료',
|
||||
ttlUpdated: 'TTL이 업데이트되었습니다',
|
||||
noExpiry: '만료 없음',
|
||||
expired: '만료됨',
|
||||
exists: '키가 이미 존재합니다',
|
||||
batchDelete: '선택 삭제',
|
||||
batchConfirm: '{n}개 키를 삭제하시겠습니까?',
|
||||
|
||||
@@ -105,6 +105,8 @@ export default {
|
||||
ttlTitle: '设置 TTL',
|
||||
ttlHint: '-1 = 永不过期, 0 = 立即过期',
|
||||
ttlUpdated: 'TTL 已更新',
|
||||
noExpiry: '永不过期',
|
||||
expired: '已过期',
|
||||
exists: '键已存在',
|
||||
batchDelete: '删除选中',
|
||||
batchConfirm: '删除 {n} 个键?',
|
||||
|
||||
Reference in New Issue
Block a user