feat(后台用户): 新增「在线优先」排序,列表直接显示在线标记
在线状态库里没有、会话也判定不了 —— session 的 TTL 是 7 天且每次请求续期, 「有会话」只说明这人一周内来过。新开一个 Redis sorted set(auth/presence.ts) 记最后活动时间,5 分钟内有活动算在线。 写入全搭在已有的 pipeline 上,不多一趟往返:登录、每个带鉴权请求的续期、 以及 touchSession —— 只挂着 WebSocket 不发请求的人靠最后这条,sweepSessions 每 60 秒一轮,所以窗口取 5 分钟,明显大于那个间隔。登出、改密码、禁用账号 会立刻把人摘掉;过期成员在后台读列表时顺手清理(整个 key 不能设 TTL, ZADD 不重置 key 的 TTL,到期会把还在线的人一起抹掉)。 排序 orderBy=-online 先捞在线 id,SQL 里 case when 分两档,档内继续按 最近登录排;没人在线时那个 case 恒等于 1,直接省掉。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xu912Rv5JUUuy6MqMcQW2
This commit is contained in:
@@ -150,7 +150,8 @@ export function getUserList(
|
||||
orderBy = "",
|
||||
) {
|
||||
return api.get<AdminUserList>("admin/users", {
|
||||
// 旧接口的 order_by 只有 "-last_login" 一个取值
|
||||
// "-last_login" 是旧接口传下来的取值(路由 query 里可能还存着),改叫 "-lastLogin";
|
||||
// "-online" 是新增的,原样透传
|
||||
params: {
|
||||
offset,
|
||||
limit,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { DataTableRowKey, SelectOption } from "naive-ui"
|
||||
import { DataTableRowKey, NFlex, NTag, SelectOption } from "naive-ui"
|
||||
import Pagination from "shared/components/Pagination.vue"
|
||||
import { usePagination } from "shared/composables/pagination"
|
||||
import { parseTime } from "utils/functions"
|
||||
@@ -47,6 +47,7 @@ const adminOptions = [
|
||||
const sortOptions = [
|
||||
{ label: "默认排序", value: "" },
|
||||
{ label: "最近登录", value: "-last_login" },
|
||||
{ label: "在线优先", value: "-online" },
|
||||
]
|
||||
const [create, toggleCreate] = useToggle(false)
|
||||
const password = ref("")
|
||||
@@ -87,11 +88,18 @@ const columns: DataTableColumn<User>[] = [
|
||||
{
|
||||
title: "上次登录",
|
||||
key: "last_login",
|
||||
width: 200,
|
||||
width: 240,
|
||||
// 在线是 5 分钟内有过活动(后端 auth/presence.ts),不是「有会话」——
|
||||
// 会话能留 7 天。上次登录时间照旧显示,在线的人前面多一个标记
|
||||
render: (row) =>
|
||||
row.lastLogin
|
||||
? parseTime(row.lastLogin, "YYYY-MM-DD HH:mm:ss")
|
||||
: "从未登录",
|
||||
h(NFlex, { align: "center", size: "small" }, () => [
|
||||
row.isOnline
|
||||
? h(NTag, { type: "success", size: "small" }, () => "在线")
|
||||
: null,
|
||||
row.lastLogin
|
||||
? parseTime(row.lastLogin, "YYYY-MM-DD HH:mm:ss")
|
||||
: "从未登录",
|
||||
]),
|
||||
},
|
||||
{
|
||||
title: "真名",
|
||||
@@ -188,6 +196,7 @@ function createNewUser() {
|
||||
createTime: null,
|
||||
lastLogin: null,
|
||||
isDisabled: false,
|
||||
isOnline: false,
|
||||
rawPassword: null,
|
||||
className: null,
|
||||
password: "",
|
||||
|
||||
Reference in New Issue
Block a user