mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-05-05 05:30:44 +08:00
feat: expose user activity timestamps in admin list
This commit is contained in:
@@ -1391,6 +1391,8 @@ export default {
|
||||
usage: 'Usage',
|
||||
concurrency: 'Concurrency',
|
||||
status: 'Status',
|
||||
lastLogin: 'Last Login',
|
||||
lastActive: 'Last Active',
|
||||
created: 'Created',
|
||||
actions: 'Actions'
|
||||
},
|
||||
|
||||
@@ -1417,6 +1417,8 @@ export default {
|
||||
usage: '用量',
|
||||
concurrency: '并发数',
|
||||
status: '状态',
|
||||
lastLogin: '最后登录',
|
||||
lastActive: '最后使用',
|
||||
created: '创建时间',
|
||||
actions: '操作'
|
||||
},
|
||||
|
||||
@@ -47,6 +47,8 @@ export interface User {
|
||||
balance_notify_threshold: number | null
|
||||
balance_notify_extra_emails: NotifyEmailEntry[]
|
||||
subscriptions?: UserSubscription[] // User's active subscriptions
|
||||
last_login_at?: string | null
|
||||
last_active_at?: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
@@ -455,6 +455,18 @@
|
||||
<span class="text-sm text-gray-500 dark:text-dark-400">{{ formatDateTime(value) }}</span>
|
||||
</template>
|
||||
|
||||
<template #cell-last_login_at="{ value }">
|
||||
<span class="text-sm text-gray-500 dark:text-dark-400">
|
||||
{{ value ? formatDateTime(value) : '-' }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #cell-last_active_at="{ value }">
|
||||
<span class="text-sm text-gray-500 dark:text-dark-400">
|
||||
{{ value ? formatDateTime(value) : '-' }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #cell-actions="{ row }">
|
||||
<div class="flex items-center gap-1">
|
||||
<!-- Edit Button -->
|
||||
@@ -700,6 +712,8 @@ const allColumns = computed<Column[]>(() => [
|
||||
{ key: 'usage', label: t('admin.users.columns.usage'), sortable: false },
|
||||
{ key: 'concurrency', label: t('admin.users.columns.concurrency'), sortable: true },
|
||||
{ key: 'status', label: t('admin.users.columns.status'), sortable: true },
|
||||
{ key: 'last_login_at', label: t('admin.users.columns.lastLogin'), sortable: true },
|
||||
{ key: 'last_active_at', label: t('admin.users.columns.lastActive'), sortable: true },
|
||||
{ key: 'created_at', label: t('admin.users.columns.created'), sortable: true },
|
||||
{ key: 'actions', label: t('admin.users.columns.actions'), sortable: false }
|
||||
])
|
||||
@@ -714,7 +728,7 @@ const toggleableColumns = computed(() =>
|
||||
const hiddenColumns = reactive<Set<string>>(new Set())
|
||||
|
||||
// Default hidden columns (columns hidden by default on first load)
|
||||
const DEFAULT_HIDDEN_COLUMNS = ['notes', 'groups', 'subscriptions', 'usage', 'concurrency']
|
||||
const DEFAULT_HIDDEN_COLUMNS = ['notes', 'groups', 'subscriptions', 'usage', 'concurrency', 'last_login_at', 'last_active_at']
|
||||
|
||||
// localStorage key for column settings
|
||||
const HIDDEN_COLUMNS_KEY = 'user-hidden-columns'
|
||||
@@ -787,7 +801,7 @@ const searchQuery = ref('')
|
||||
const USER_SORT_STORAGE_KEY = 'admin-users-table-sort'
|
||||
const loadInitialSortState = (): { sort_by: string; sort_order: 'asc' | 'desc' } => {
|
||||
const fallback = { sort_by: 'created_at', sort_order: 'desc' as 'asc' | 'desc' }
|
||||
const sortable = new Set(['email', 'id', 'username', 'role', 'balance', 'concurrency', 'status', 'created_at'])
|
||||
const sortable = new Set(['email', 'id', 'username', 'role', 'balance', 'concurrency', 'status', 'last_login_at', 'last_active_at', 'created_at'])
|
||||
try {
|
||||
const raw = localStorage.getItem(USER_SORT_STORAGE_KEY)
|
||||
if (!raw) return fallback
|
||||
|
||||
Reference in New Issue
Block a user