53 lines
1.9 KiB
Vue
53 lines
1.9 KiB
Vue
<script setup lang="ts">
|
||
import { onMounted, ref } from 'vue'
|
||
import { getUsers } from '../services/auth'
|
||
import type { CurrentUser } from '../types/auth'
|
||
|
||
const pageSize = 20
|
||
const users = ref<CurrentUser[]>([])
|
||
const offset = ref(0)
|
||
const loading = ref(false)
|
||
const error = ref('')
|
||
|
||
async function load(nextOffset = offset.value) {
|
||
loading.value = true
|
||
error.value = ''
|
||
try {
|
||
users.value = await getUsers(pageSize, nextOffset)
|
||
offset.value = nextOffset
|
||
} catch (cause) {
|
||
error.value = cause instanceof Error ? cause.message : '无法读取用户列表'
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
onMounted(() => load(0))
|
||
</script>
|
||
|
||
<template>
|
||
<main>
|
||
<h1>管理员用户管理</h1>
|
||
<p>用户数据由受服务端管理员权限保护的接口实时提供。</p>
|
||
<p><RouterLink to="/reviews">进入知识审核工作台</RouterLink> <RouterLink to="/documents">进入文档管理</RouterLink> <RouterLink to="/indexes">进入索引管理</RouterLink></p>
|
||
<p v-if="error" role="alert">{{ error }}</p>
|
||
<p v-else-if="loading">正在读取用户列表…</p>
|
||
<template v-else>
|
||
<table>
|
||
<thead><tr><th>用户名</th><th>昵称</th><th>邮箱</th><th>角色</th><th>注册时间</th></tr></thead>
|
||
<tbody>
|
||
<tr v-for="user in users" :key="user.id">
|
||
<td>{{ user.username }}</td><td>{{ user.nickname || '—' }}</td><td>{{ user.email || '—' }}</td><td>{{ user.role }}</td><td>{{ new Date(user.created_at).toLocaleString() }}</td>
|
||
</tr>
|
||
<tr v-if="!users.length"><td colspan="5">暂无用户记录。</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<div>
|
||
<button :disabled="offset === 0" @click="load(Math.max(0, offset - pageSize))">上一页</button>
|
||
<span>第 {{ Math.floor(offset / pageSize) + 1 }} 页</span>
|
||
<button :disabled="users.length < pageSize" @click="load(offset + pageSize)">下一页</button>
|
||
</div>
|
||
</template>
|
||
</main>
|
||
</template>
|