add user pagination

This commit is contained in:
2025-03-05 20:50:13 +08:00
parent ea5393242a
commit 838a703023
7 changed files with 89 additions and 10 deletions

2
components.d.ts vendored
View File

@@ -29,6 +29,7 @@ declare module 'vue' {
NMessageProvider: typeof import('naive-ui')['NMessageProvider'] NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NModal: typeof import('naive-ui')['NModal'] NModal: typeof import('naive-ui')['NModal']
NModalProvider: typeof import('naive-ui')['NModalProvider'] NModalProvider: typeof import('naive-ui')['NModalProvider']
NPagination: typeof import('naive-ui')['NPagination']
NSplit: typeof import('naive-ui')['NSplit'] NSplit: typeof import('naive-ui')['NSplit']
NSwitch: typeof import('naive-ui')['NSwitch'] NSwitch: typeof import('naive-ui')['NSwitch']
NTabPane: typeof import('naive-ui')['NTabPane'] NTabPane: typeof import('naive-ui')['NTabPane']
@@ -39,5 +40,6 @@ declare module 'vue' {
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
Tutorial: typeof import('./src/components/Tutorial.vue')['default'] Tutorial: typeof import('./src/components/Tutorial.vue')['default']
UserActions: typeof import('./src/components/dashboard/UserActions.vue')['default']
} }
} }

View File

@@ -51,12 +51,17 @@ export class Account {
return res.data return res.data
} }
static async list(query: { username: string }) { static async list(query: { username: string; page: number }) {
const res = await http.get("/account/list", { const res = await http.get("/account/list", {
params: query, params: query,
}) })
return res.data return res.data
} }
static async toggleActive(id: number) {
const res = await http.put(`/account/active/${id}`)
return res.data
}
} }
export class Tutorial { export class Tutorial {

View File

@@ -0,0 +1,52 @@
<template>
<n-flex>
<n-button
secondary
v-if="user.role !== Role.Super"
@click="edit"
>
修改
</n-button>
<n-button
secondary
type="error"
v-if="user.role !== Role.Super && user.is_active"
@click="toggleUserActive"
>
封号
</n-button>
<n-button
secondary
type="primary"
v-if="user.role !== Role.Super && !user.is_active"
@click="toggleUserActive"
>
解封
</n-button>
</n-flex>
</template>
<script lang="ts" setup>
import { useMessage } from "naive-ui"
import { Account } from "../../api"
import { ADMIN_URL } from "../../utils/const"
import { Role, type User } from "../../utils/type"
interface Props {
user: User
}
const props = defineProps<Props>()
const emits = defineEmits(["reload"])
const message = useMessage()
function edit() {
window.open(`${ADMIN_URL}/account/user/${props.user.id}/change/`)
}
async function toggleUserActive() {
const data = await Account.toggleActive(props.user.id)
message.success(data.message)
emits("reload")
}
</script>

View File

@@ -25,7 +25,7 @@ const menu = [
label: "教程", label: "教程",
route: { name: "tutorial", params: { display: step.value } }, route: { name: "tutorial", params: { display: step.value } },
}, },
{ label: "用户", route: { name: "user-manage" } }, { label: "用户", route: { name: "user-manage", params: { page: 1 } } },
] ]
</script> </script>
<style scoped> <style scoped>

View File

@@ -7,23 +7,33 @@
<n-button @click="init">搜索</n-button> <n-button @click="init">搜索</n-button>
<n-button @click="goDjangoUserAdd">新建一个</n-button> <n-button @click="goDjangoUserAdd">新建一个</n-button>
<n-button>批量新建</n-button> <n-button>批量新建</n-button>
<n-pagination
v-model:page="query.page"
:page-size="20"
:item-count="count"
simple
/>
</n-flex> </n-flex>
<n-flex> <n-data-table :columns="columns" :data="users"></n-data-table>
<n-data-table :columns="columns" :data="data"></n-data-table>
</n-flex>
</n-flex> </n-flex>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, reactive, ref } from "vue" import { onMounted, reactive, ref, h, watch } from "vue"
import { Account } from "../api" import { Account } from "../api"
import { parseTime } from "../utils/helper" import { parseTime } from "../utils/helper"
import type { DataTableColumn } from "naive-ui" import type { DataTableColumn } from "naive-ui"
import { getRole, type User } from "../utils/type" import { getRole, type User } from "../utils/type"
import { ADMIN_URL } from "../utils/const" import { ADMIN_URL } from "../utils/const"
import UserActions from "../components/dashboard/UserActions.vue"
import { useRoute, useRouter } from "vue-router"
const data = ref([]) const users = ref([])
const count = ref(0)
const route = useRoute()
const router = useRouter()
const query = reactive({ const query = reactive({
username: "", username: "",
page: Number(route.params.page),
}) })
const columns: DataTableColumn<User>[] = [ const columns: DataTableColumn<User>[] = [
@@ -32,7 +42,7 @@ const columns: DataTableColumn<User>[] = [
key: "username", key: "username",
}, },
{ {
title: "凭证", title: "密码",
key: "raw_password", key: "raw_password",
}, },
{ {
@@ -56,6 +66,7 @@ const columns: DataTableColumn<User>[] = [
{ {
title: "选项", title: "选项",
key: "actions", key: "actions",
render: (row) => h(UserActions, { user: row, onReload: init }),
}, },
] ]
@@ -64,9 +75,17 @@ function goDjangoUserAdd() {
} }
async function init() { async function init() {
data.value = await Account.list(query) const data = await Account.list(query)
users.value = data.items
count.value = data.count
} }
watch(query, init)
watch(
() => query.page,
(v) => router.push({ params: { page: v } }),
)
onMounted(init) onMounted(init)
</script> </script>
<style scoped> <style scoped>

View File

@@ -18,7 +18,7 @@ const routes = [
component: () => import("./pages/Markdown.vue"), component: () => import("./pages/Markdown.vue"),
}, },
{ {
path: "user-manage", path: "user-manage/:page",
name: "user-manage", name: "user-manage",
component: () => import("./pages/UserManage.vue"), component: () => import("./pages/UserManage.vue"),
}, },

View File

@@ -29,6 +29,7 @@ export interface TutorialIn {
} }
export interface User { export interface User {
id: number
username: string username: string
date_joined: Date date_joined: Date
last_login: Date last_login: Date