feat: 搭建后台管理框架

This commit is contained in:
Vicky committed 2026-10-13 13:58:05 +08:00
1 parent 6d28bab72b
commit 40546bfd01
238 files changed
+18160 -3837

No files matched your search

+7 -8
View File
@@ -15,12 +15,16 @@ const {
paginated,
queryUsers,
toggleStatus,
addUser,
addUser
} = useAdminUsers()
</script>
<template>
<PageHeading eyebrow="后台管理" title="管理员用户列表" description="查询和维护后台管理员账号及权限角色。" />
<PageHeading
eyebrow="后台管理"
title="管理员用户列表"
description="查询和维护后台管理员账号及权限角色。"
/>
<section class="panel admin-users-panel">
<div class="admin-user-toolbar">
@@ -32,12 +36,7 @@ const {
@keyup.enter="queryUsers"
@clear="queryUsers"
/>
<el-select
v-model="roleFilter"
clearable
placeholder="搜索权限角色"
@change="queryUsers"
>
<el-select v-model="roleFilter" clearable placeholder="搜索权限角色" @change="queryUsers">
<el-option
v-for="role in roleData"
:key="role.name"
@@ -10,21 +10,34 @@ export function useAdminUsers() {
const pageSize = ref(10)
const dialogVisible = ref(false)
const form = reactive({ username: '', name: '', role: '', ipWhitelist: '' })
const users = ref(demoAdminUsers.map(user => ({ ...user })))
const filtered = computed(() => users.value.filter(user => {
const query = keyword.value.trim().toLowerCase()
const matchesKeyword = !query || `${user.id} ${user.username} ${user.name}`.toLowerCase().includes(query)
return matchesKeyword && (!roleFilter.value || user.role === roleFilter.value)
}))
const paginated = computed(() => filtered.value.slice((currentPage.value - 1) * pageSize.value, currentPage.value * pageSize.value))
const users = ref(demoAdminUsers.map((user) => ({ ...user })))
const filtered = computed(() =>
users.value.filter((user) => {
const query = keyword.value.trim().toLowerCase()
const matchesKeyword =
!query || `${user.id} ${user.username} ${user.name}`.toLowerCase().includes(query)
return matchesKeyword && (!roleFilter.value || user.role === roleFilter.value)
})
)
const paginated = computed(() =>
filtered.value.slice(
(currentPage.value - 1) * pageSize.value,
currentPage.value * pageSize.value
)
)
function queryUsers() { currentPage.value = 1 }
function toggleStatus(user) { user.status = user.status === '启用' ? '停用' : '启用' }
function queryUsers() {
currentPage.value = 1
}
function toggleStatus(user) {
user.status = user.status === '启用' ? '停用' : '启用'
}
function addUser() {
if (!form.username.trim() || !form.name.trim() || !form.role) return ElMessage.warning('请填写用户名、姓名并选择权限角色')
const role = roleData.find(item => item.name === form.role)
if (!form.username.trim() || !form.name.trim() || !form.role)
return ElMessage.warning('请填写用户名、姓名并选择权限角色')
const role = roleData.find((item) => item.name === form.role)
users.value.unshift({
id: Math.max(0, ...users.value.map(user => user.id)) + 1,
id: Math.max(0, ...users.value.map((user) => user.id)) + 1,
username: form.username.trim(),
name: form.name.trim(),
roleId: role?.id || 0,
@@ -33,7 +46,7 @@ export function useAdminUsers() {
status: '启用',
twoFactor: '未开启',
createdAt: new Date().toLocaleString('sv-SE'),
lastLogin: '—',
lastLogin: '—'
})
Object.assign(form, { username: '', name: '', role: '', ipWhitelist: '' })
dialogVisible.value = false
@@ -41,5 +54,18 @@ export function useAdminUsers() {
ElMessage.success('管理员已添加')
}
return { keyword, roleFilter, currentPage, pageSize, dialogVisible, form, users, filtered, paginated, queryUsers, toggleStatus, addUser }
return {
keyword,
roleFilter,
currentPage,
pageSize,
dialogVisible,
form,
users,
filtered,
paginated,
queryUsers,
toggleStatus,
addUser
}
}
+60 -5
View File
@@ -1,7 +1,62 @@
export const demoAdminUsers = [
{ id: 1001, username: 'lin.xiaoman', name: '林小满', roleId: 1, role: '超级管理员', ipWhitelist: '不限', status: '启用', twoFactor: '已开启', createdAt: '2026-09-18 09:30:00', lastLogin: '2026-10-12 09:41:22' },
{ id: 1002, username: 'content.editor01', name: '陈一诺', roleId: 2, role: '内容运营', ipWhitelist: '不限', status: '启用', twoFactor: '未开启', createdAt: '2026-09-21 10:15:00', lastLogin: '2026-10-11 16:20:15' },
{ id: 1003, username: 'content.editor02', name: '周子瑜', roleId: 2, role: '内容运营', ipWhitelist: '不限', status: '启用', twoFactor: '未开启', createdAt: '2026-09-25 14:20:00', lastLogin: '2026-10-11 13:34:10' },
{ id: 1004, username: 'content.reviewer01', name: '林晓彤', roleId: 3, role: '审核专员', ipWhitelist: '不限', status: '启用', twoFactor: '已开启', createdAt: '2026-10-02 11:05:00', lastLogin: '2026-10-10 11:20:08' },
{ id: 1005, username: 'data.analyst01', name: '程予安', roleId: 4, role: '数据分析师', ipWhitelist: '不限', status: '启用', twoFactor: '未开启', createdAt: '2026-10-05 13:02:00', lastLogin: '2026-10-09 14:10:02' },
{
id: 1001,
username: 'lin.xiaoman',
name: '林小满',
roleId: 1,
role: '超级管理员',
ipWhitelist: '不限',
status: '启用',
twoFactor: '已开启',
createdAt: '2026-09-18 09:30:00',
lastLogin: '2026-10-12 09:41:22'
},
{
id: 1002,
username: 'content.editor01',
name: '陈一诺',
roleId: 2,
role: '内容运营',
ipWhitelist: '不限',
status: '启用',
twoFactor: '未开启',
createdAt: '2026-09-21 10:15:00',
lastLogin: '2026-10-11 16:20:15'
},
{
id: 1003,
username: 'content.editor02',
name: '周子瑜',
roleId: 2,
role: '内容运营',
ipWhitelist: '不限',
status: '启用',
twoFactor: '未开启',
createdAt: '2026-09-25 14:20:00',
lastLogin: '2026-10-11 13:34:10'
},
{
id: 1004,
username: 'content.reviewer01',
name: '林晓彤',
roleId: 3,
role: '审核专员',
ipWhitelist: '不限',
status: '启用',
twoFactor: '已开启',
createdAt: '2026-10-02 11:05:00',
lastLogin: '2026-10-10 11:20:08'
},
{
id: 1005,
username: 'data.analyst01',
name: '程予安',
roleId: 4,
role: '数据分析师',
ipWhitelist: '不限',
status: '启用',
twoFactor: '未开启',
createdAt: '2026-10-05 13:02:00',
lastLogin: '2026-10-09 14:10:02'
}
]