·fix: 完善用户模块,角色模块

This commit is contained in:
chansee97 2025-08-29 07:24:55 +08:00
parent 8db80b1fc1
commit 3124d0b923
18 changed files with 571 additions and 259 deletions

View File

@ -125,6 +125,7 @@
"setting": "System settings", "setting": "System settings",
"userCenter": "Personal Center", "userCenter": "Personal Center",
"accountSetting": "User settings", "accountSetting": "User settings",
"roleSetting": "Role settings",
"cascader": "Administrative region selection", "cascader": "Administrative region selection",
"dict": "Dictionary example" "dict": "Dictionary example"
}, },

View File

@ -150,6 +150,7 @@
"justSuper": "super可见", "justSuper": "super可见",
"setting": "系统设置", "setting": "系统设置",
"accountSetting": "用户设置", "accountSetting": "用户设置",
"roleSetting": "角色设置",
"dictionarySetting": "字典设置", "dictionarySetting": "字典设置",
"menuSetting": "菜单设置", "menuSetting": "菜单设置",
"userCenter": "个人中心", "userCenter": "个人中心",

View File

@ -44,6 +44,6 @@ export function deleteMenu(id: number) {
* *
* GET /menu/selectTree * GET /menu/selectTree
*/ */
export function selectMenuTree() { export function getMenuOptions() {
return request.Get<Api.Response<Entity.TreeNode[]>>('/menu/selectTree') return request.Get<Api.Response<Entity.TreeNode[]>>('/menu/options')
} }

View File

@ -25,6 +25,14 @@ export function getRoleList(params?: RoleQueryParams) {
return request.Get<Api.ListResponse<Entity.Role>>('/role', { params }) return request.Get<Api.ListResponse<Entity.Role>>('/role', { params })
} }
/**
*
* GET /role/options
*/
export function getRoleOptions() {
return request.Get<Api.Response<Entity.TreeNode[]>>('/role/options')
}
/** /**
* *
* GET /role/{id} * GET /role/{id}

View File

@ -38,7 +38,6 @@ export function setupRouterGuard(router: Router) {
// 如果是login路由直接放行 // 如果是login路由直接放行
if (to.name === 'login') { if (to.name === 'login') {
// login页面不需要任何认证检查直接放行 // login页面不需要任何认证检查直接放行
// 继续执行后面的逻辑
} }
// 如果路由明确设置了requiresAuth为false直接放行 // 如果路由明确设置了requiresAuth为false直接放行
else if (to.meta.requiresAuth === false) { else if (to.meta.requiresAuth === false) {
@ -70,6 +69,7 @@ export function setupRouterGuard(router: Router) {
} }
catch { catch {
// 如果路由初始化失败(比如 401 错误),重定向到登录页 // 如果路由初始化失败(比如 401 错误),重定向到登录页
local.remove('accessToken')
const redirect = to.fullPath !== '/' ? to.fullPath : undefined const redirect = to.fullPath !== '/' ? to.fullPath : undefined
next({ path: '/login', query: redirect ? { redirect } : undefined }) next({ path: '/login', query: redirect ? { redirect } : undefined })
return return

View File

@ -350,6 +350,16 @@ export const staticRoutes: AppRoute.RowRoute[] = [
id: 701, id: 701,
parentId: 7, parentId: 7,
}, },
{
name: 'roleSetting',
path: '/setting/role',
title: '角色设置',
requiresAuth: true,
icon: 'icon-park-outline:every-user',
component: '/setting/role/index.vue',
id: 702,
parentId: 7,
},
{ {
name: 'dictionarySetting', name: 'dictionarySetting',
path: '/setting/dict', path: '/setting/dict',
@ -357,7 +367,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
requiresAuth: true, requiresAuth: true,
icon: 'icon-park-outline:book-one', icon: 'icon-park-outline:book-one',
component: '/setting/dict/index.vue', component: '/setting/dict/index.vue',
id: 702, id: 703,
parentId: 7, parentId: 7,
}, },
{ {
@ -367,7 +377,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
requiresAuth: true, requiresAuth: true,
icon: 'icon-park-outline:application-menu', icon: 'icon-park-outline:application-menu',
component: '/setting/menu/index.vue', component: '/setting/menu/index.vue',
id: 703, id: 704,
parentId: 7, parentId: 7,
}, },
{ {

View File

@ -5,6 +5,10 @@ namespace Entity {
type RoleType = string type RoleType = string
interface Role { interface Role {
/**
* ID
*/
roleId: number
/** /**
* ID数组 * ID数组
*/ */
@ -29,6 +33,14 @@ namespace Entity {
* *
*/ */
sort: number sort: number
/**
*
*/
createTime?: string
/**
*
*/
updateTime?: string
[property: string]: any [property: string]: any
} }
} }

View File

@ -17,7 +17,7 @@ export function createMenuColumns(actions: MenuColumnActions): DataTableColumns<
{ {
title: '菜单名称', title: '菜单名称',
key: 'title', key: 'title',
width: 200, width: 400,
}, },
{ {
title: '图标', title: '图标',
@ -55,7 +55,7 @@ export function createMenuColumns(actions: MenuColumnActions): DataTableColumns<
const menuTypeMap = { const menuTypeMap = {
directory: { label: '目录', type: 'primary' }, directory: { label: '目录', type: 'primary' },
page: { label: '菜单', type: 'warning' }, page: { label: '菜单', type: 'warning' },
permission: { label: '按钮', type: 'success' }, permission: { label: '权限', type: 'info' },
} as const } as const
const menuInfo = menuTypeMap[row.menuType] const menuInfo = menuTypeMap[row.menuType]
return <NTag type={menuInfo.type} bordered={false}>{menuInfo.label}</NTag> return <NTag type={menuInfo.type} bordered={false}>{menuInfo.label}</NTag>
@ -82,13 +82,15 @@ export function createMenuColumns(actions: MenuColumnActions): DataTableColumns<
render: (row) => { render: (row) => {
return ( return (
<NSpace justify="center"> <NSpace justify="center">
<NButton {row.menuType !== 'permission' && (
text <NButton
type="primary" text
onClick={() => onAdd(row)} type="primary"
> onClick={() => onAdd(row)}
>
</NButton>
</NButton>
)}
<NButton <NButton
text text
onClick={() => onEdit(row)} onClick={() => onEdit(row)}

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { useBoolean } from '@/hooks' import { useBoolean } from '@/hooks'
import { createMenu, getMenuById, selectMenuTree, updateMenu } from '@/api' import { createMenu, getMenuById, getMenuOptions, updateMenu } from '@/api'
import { createProModalForm } from 'pro-naive-ui' import { createProModalForm } from 'pro-naive-ui'
import DirectoryForm from './DirectoryForm.vue' import DirectoryForm from './DirectoryForm.vue'
import PageForm from './PageForm.vue' import PageForm from './PageForm.vue'
@ -63,7 +63,7 @@ const currentFormComponent = computed(() => {
}) })
async function openModal(type: ModalType = 'add', data?: Partial<Entity.Menu>) { async function openModal(type: ModalType = 'add', data?: Partial<Entity.Menu>) {
selectMenuTree().then((res) => { getMenuOptions().then((res) => {
treeData.value = res.data treeData.value = res.data
}) })
@ -74,6 +74,7 @@ async function openModal(type: ModalType = 'add', data?: Partial<Entity.Menu>) {
// menuId // menuId
if (data?.id) { if (data?.id) {
modalForm.values.value.parentId = data.id modalForm.values.value.parentId = data.id
modalForm.values.value.path = `${data.path}/`
} }
}, },
async edit() { async edit() {

View File

@ -22,6 +22,7 @@
path="path" path="path"
class="col-span-2" class="col-span-2"
placeholder="Eg: /system/user" placeholder="Eg: /system/user"
@update:value="$emit('path', $event)"
/> />
<pro-input <pro-input
title="高亮菜单路径" title="高亮菜单路径"

View File

@ -71,7 +71,7 @@ onMounted(() => {
<template> <template>
<div> <div>
<pro-data-table <pro-data-table
row-key="menuId" row-key="id"
:columns="columns" :columns="columns"
:data="tableData" :data="tableData"
:loading="loading" :loading="loading"

View File

@ -0,0 +1,132 @@
import type { DataTableColumns } from 'naive-ui'
import { NButton, NPopconfirm, NSpace, NSwitch } from 'naive-ui'
import type { ProSearchFormColumns } from 'pro-naive-ui'
import { renderProCopyableText, renderProDateText } from 'pro-naive-ui'
export const searchColumns: ProSearchFormColumns<Entity.Role> = [
{
title: '角色名称',
path: 'roleName',
},
{
title: '角色权限',
path: 'roleKey',
},
{
title: '状态',
path: 'roleStatus',
field: 'select',
fieldProps: {
options: [
{
label: '启用',
value: 1,
},
{
label: '禁用',
value: 0,
},
],
},
},
]
// 角色管理columns配置函数
interface RoleColumnActions {
onEdit: (row: Entity.Role) => void
onDelete: (id: number) => void
onStatusChange: (value: 0 | 1, id: number) => void
}
export function createRoleColumns(actions: RoleColumnActions): DataTableColumns<Entity.Role> {
return [
{
title: '角色ID',
align: 'center',
key: 'roleId',
width: 80,
},
{
title: '角色名称',
align: 'center',
key: 'roleName',
},
{
title: '角色权限',
align: 'center',
key: 'roleKey',
render: row => renderProCopyableText(row.roleKey),
},
{
title: '备注',
align: 'center',
key: 'remark',
width: 200,
},
{
title: '排序',
align: 'center',
key: 'sort',
width: 80,
},
{
title: '状态',
align: 'center',
key: 'roleStatus',
width: 100,
render: (row) => {
return (
<NSwitch
value={row.roleStatus || 1}
checked-value={1}
unchecked-value={0}
onUpdateValue={(value: 0 | 1) =>
actions.onStatusChange(value, row.roleId)}
>
{{ checked: () => '启用', unchecked: () => '禁用' }}
</NSwitch>
)
},
},
{
title: '创建时间',
align: 'center',
key: 'createTime',
width: 200,
render: row => renderProDateText(row.createTime, {
pattern: 'datetime',
}),
},
{
title: '操作',
align: 'center',
key: 'actions',
width: 200,
render: (row) => {
return (
<NSpace justify="center">
<NButton
size="small"
type="primary"
onClick={() => actions.onEdit(row)}
>
</NButton>
<NPopconfirm
onPositiveClick={() => actions.onDelete(row.roleId)}
>
{{
default: () => '确认删除该角色?',
trigger: () => (
<NButton size="small" type="error">
</NButton>
),
}}
</NPopconfirm>
</NSpace>
)
},
},
]
}

View File

@ -0,0 +1,134 @@
<script setup lang="ts">
import { useBoolean } from '@/hooks'
import { createRole, getRoleById, updateRole } from '@/api'
import { createProModalForm } from 'pro-naive-ui'
interface Props {
modalName?: string
}
const {
modalName = '',
} = defineProps<Props>()
const emit = defineEmits<{
success: []
}>()
const { bool: submitLoading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
const modalForm = createProModalForm<Partial<Entity.Role>>({
omitEmptyString: false,
initialValues: {
roleName: '',
roleKey: '',
remark: '',
sort: 0,
roleStatus: 1,
},
onSubmit: submitModal,
})
type ModalType = 'add' | 'edit'
const modalType = shallowRef<ModalType>('add')
const modalTitle = computed(() => {
const titleMap: Record<ModalType, string> = {
add: '添加',
edit: '编辑',
}
return `${titleMap[modalType.value]}${modalName}`
})
async function openModal(type: ModalType = 'add', data?: Partial<Entity.Role>) {
modalType.value = type
modalForm.open()
const handlers = {
async add() {
// 使
},
async edit() {
if (!data)
return
const { data: role } = await getRoleById(data.roleId!)
modalForm.values.value = role
},
}
await handlers[type]()
}
async function submitModal(filedValues: Partial<Entity.Role>) {
const handlers = {
async add() {
try {
await createRole(filedValues)
window.$message.success('角色创建成功')
}
catch (error) {
console.error('创建角色失败', error)
window.$message.error('创建角色失败')
}
},
async edit() {
try {
await updateRole(modalForm.values.value.roleId!, filedValues)
window.$message.success('角色更新成功')
}
catch (error) {
console.error('更新角色失败', error)
window.$message.error('更新角色失败')
}
},
}
startLoading()
await handlers[modalType.value]()
endLoading()
emit('success')
modalForm.close()
}
defineExpose({
openModal,
})
</script>
<template>
<pro-modal-form
:title="modalTitle"
:form="modalForm"
:loading="submitLoading"
width="600px"
>
<div class="grid grid-cols-2 gap-4">
<pro-input
required
title="角色名称"
path="roleName"
placeholder="请输入角色名称"
/>
<pro-input
required
title="角色权限"
path="roleKey"
placeholder="请输入角色权限"
/>
<pro-textarea
class="col-span-2"
title="备注"
path="remark"
placeholder="请输入备注信息"
/>
<pro-digit
title="排序"
path="sort"
:field-props="{ min: 0, max: 999 }"
/>
<pro-switch
title="状态"
path="roleStatus"
:field-props="{ checkedValue: 1, uncheckedValue: 0 }"
/>
</div>
</pro-modal-form>
</template>

View File

@ -0,0 +1,90 @@
<script setup lang="tsx">
import { createProSearchForm, useNDataTable } from 'pro-naive-ui'
import { deleteRole, getRoleList } from '@/api'
import { createRoleColumns, searchColumns } from './columns'
import RoleModal from './components/RoleModal.vue'
const searchForm = createProSearchForm({
initialValues: {
},
})
const {
table: {
tableProps,
},
search: {
proSearchFormProps,
},
refresh,
} = useNDataTable(getRolePage, {
form: searchForm,
})
const modalRef = ref()
async function deleteRoleData(id: number) {
try {
await deleteRole(id)
window.$message.success('角色删除成功')
refresh() //
}
catch {
window.$message.error('角色删除失败')
}
}
const tablecolumns = createRoleColumns({
onEdit: (row: Entity.Role) => modalRef.value?.openModal('edit', row),
onDelete: deleteRoleData,
onStatusChange: () => {},
})
async function getRolePage({ current, pageSize }: any, formData: Entity.Role[]) {
try {
const { data } = await getRoleList({
...formData,
pageNum: current,
pageSize,
})
return {
list: data.list,
total: data.total,
}
}
catch {
return {
list: [],
total: 0,
}
}
}
</script>
<template>
<n-space vertical>
<n-card>
<pro-search-form
:form="searchForm"
:columns="searchColumns"
v-bind="proSearchFormProps"
:collapse-button-props="false"
/>
</n-card>
<pro-data-table
:columns="tablecolumns"
v-bind="tableProps"
>
<template #title>
<n-button type="primary" @click="modalRef.openModal('add')">
<template #icon>
<icon-park-outline-plus />
</template>
新建角色
</n-button>
</template>
</pro-data-table>
<RoleModal ref="modalRef" modal-name="角色" @success="refresh" />
</n-space>
</template>

View File

@ -72,6 +72,7 @@ export function createUserColumns(actions: UserColumnActions): DataTableColumns<
title: '邮箱', title: '邮箱',
align: 'center', align: 'center',
key: 'email', key: 'email',
render: row => renderProCopyableText(row.email),
}, },
{ {
title: '手机号', title: '手机号',
@ -83,6 +84,7 @@ export function createUserColumns(actions: UserColumnActions): DataTableColumns<
title: '状态', title: '状态',
align: 'center', align: 'center',
key: 'userStatus', key: 'userStatus',
width: 100,
render: (row) => { render: (row) => {
return ( return (
<NSwitch <NSwitch
@ -101,6 +103,7 @@ export function createUserColumns(actions: UserColumnActions): DataTableColumns<
title: '创建时间', title: '创建时间',
align: 'center', align: 'center',
key: 'createTime', key: 'createTime',
width: 200,
render: row => renderProDateText(row.createTime, { render: row => renderProDateText(row.createTime, {
pattern: 'datetime', pattern: 'datetime',
}), }),
@ -109,6 +112,7 @@ export function createUserColumns(actions: UserColumnActions): DataTableColumns<
title: '操作', title: '操作',
align: 'center', align: 'center',
key: 'actions', key: 'actions',
width: 120,
render: (row) => { render: (row) => {
return ( return (
<NSpace justify="center"> <NSpace justify="center">

View File

@ -1,238 +0,0 @@
<script setup lang="ts">
import { useBoolean } from '@/hooks'
import { createUser, fetchRoleList, updateUser } from '@/api'
interface Props {
modalName?: string
}
const {
modalName = '',
} = defineProps<Props>()
const emit = defineEmits<{
open: []
close: []
success: []
}>()
const { bool: modalVisible, setTrue: showModal, setFalse: hiddenModal } = useBoolean(false)
const { bool: submitLoading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
const formDefault = {
userId: 0,
username: '',
nickName: '',
email: '',
phone: '',
gender: 'unknown' as 'male' | 'female' | 'unknown',
deptId: undefined,
userStatus: 1,
roles: [] as any[],
remark: '',
}
const formModel = ref<Partial<Entity.User>>({ ...formDefault })
type ModalType = 'add' | 'view' | 'edit'
const modalType = shallowRef<ModalType>('add')
const modalTitle = computed(() => {
const titleMap: Record<ModalType, string> = {
add: '添加',
view: '查看',
edit: '编辑',
}
return `${titleMap[modalType.value]}${modalName}`
})
async function openModal(type: ModalType = 'add', data: any) {
emit('open')
modalType.value = type
showModal()
getRoleList()
const handlers = {
async add() {
formModel.value = { ...formDefault }
},
async view() {
if (!data)
return
formModel.value = { ...data }
},
async edit() {
if (!data)
return
formModel.value = { ...data }
},
}
await handlers[type]()
}
function closeModal() {
hiddenModal()
endLoading()
emit('close')
}
defineExpose({
openModal,
})
const formRef = ref()
async function submitModal() {
const handlers = {
async add() {
try {
await createUser({
username: formModel.value.username!,
password: '123456', //
nickName: formModel.value.nickName,
email: formModel.value.email,
phone: formModel.value.phone,
gender: formModel.value.gender,
deptId: formModel.value.deptId,
remark: formModel.value.remark,
})
window.$message.success('用户创建成功')
emit('success')
return true
}
catch {
window.$message.error('创建用户失败')
return false
}
},
async edit() {
try {
await updateUser(formModel.value.userId!, {
nickName: formModel.value.nickName,
email: formModel.value.email,
phone: formModel.value.phone,
gender: formModel.value.gender,
userStatus: formModel.value.userStatus,
deptId: formModel.value.deptId,
remark: formModel.value.remark,
})
window.$message.success('用户更新成功')
emit('success')
return true
}
catch {
window.$message.error('更新用户失败')
return false
}
},
async view() {
return true
},
}
await formRef.value?.validate()
startLoading()
const success = await handlers[modalType.value]()
endLoading()
if (success) {
closeModal()
}
}
const rules = {
username: {
required: true,
message: '请输入用户名',
trigger: 'blur',
},
email: {
required: false,
pattern: /^[^\s@]+@[^\s@][^\s.@]*\.[^\s@]+$/,
message: '请输入正确的邮箱格式',
trigger: 'blur',
},
phone: {
required: false,
pattern: /^1[3-9]\d{9}$/,
message: '请输入正确的手机号格式',
trigger: 'blur',
},
}
const options = ref()
async function getRoleList() {
const { data } = await fetchRoleList()
options.value = data
}
</script>
<template>
<n-modal
v-model:show="modalVisible"
:mask-closable="false"
preset="card"
:title="modalTitle"
class="w-700px"
:segmented="{
content: true,
action: true,
}"
>
<n-form ref="formRef" :rules="rules" label-placement="left" :model="formModel" :label-width="100" :disabled="modalType === 'view'">
<n-grid :cols="2" :x-gap="18">
<n-form-item-grid-item :span="1" label="用户名" path="username">
<n-input v-model:value="formModel.username" :disabled="modalType === 'edit'" />
</n-form-item-grid-item>
<n-form-item-grid-item :span="1" label="昵称" path="nickName">
<n-input v-model:value="formModel.nickName" />
</n-form-item-grid-item>
<n-form-item-grid-item :span="1" label="性别" path="gender">
<n-radio-group v-model:value="formModel.gender">
<n-space>
<n-radio value="male">
</n-radio>
<n-radio value="female">
</n-radio>
<n-radio value="unknown">
未知
</n-radio>
</n-space>
</n-radio-group>
</n-form-item-grid-item>
<n-form-item-grid-item :span="1" label="部门ID" path="deptId">
<n-input-number v-model:value="formModel.deptId" class="w-full" />
</n-form-item-grid-item>
<n-form-item-grid-item :span="1" label="邮箱" path="email">
<n-input v-model:value="formModel.email" />
</n-form-item-grid-item>
<n-form-item-grid-item :span="1" label="手机号" path="phone">
<n-input v-model:value="formModel.phone" />
</n-form-item-grid-item>
<n-form-item-grid-item :span="2" label="备注" path="remark">
<n-input v-model:value="formModel.remark" type="textarea" />
</n-form-item-grid-item>
<n-form-item-grid-item :span="1" label="用户状态" path="userStatus">
<n-switch
v-model:value="formModel.userStatus"
:checked-value="1" :unchecked-value="0"
>
<template #checked>
启用
</template>
<template #unchecked>
禁用
</template>
</n-switch>
</n-form-item-grid-item>
</n-grid>
</n-form>
<template #action>
<n-space justify="center">
<n-button @click="closeModal">
取消
</n-button>
<n-button type="primary" :loading="submitLoading" @click="submitModal">
提交
</n-button>
</n-space>
</template>
</n-modal>
</template>

View File

@ -0,0 +1,154 @@
<script setup lang="ts">
import { useBoolean } from '@/hooks'
import { createUser, getRoleOptions, getUserById, updateUser } from '@/api'
import { createProModalForm } from 'pro-naive-ui'
interface Props {
modalName?: string
}
const {
modalName = '',
} = defineProps<Props>()
const emit = defineEmits<{
success: []
}>()
const { bool: submitLoading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
const modalForm = createProModalForm<Partial<Entity.User>>({
omitEmptyString: false,
initialValues: {
gender: 'unknown',
userStatus: 1,
roles: [],
},
onSubmit: submitModal,
})
type ModalType = 'add' | 'edit'
const modalType = shallowRef<ModalType>('add')
const modalTitle = computed(() => {
const titleMap: Record<ModalType, string> = {
add: '添加',
edit: '编辑',
}
return `${titleMap[modalType.value]}${modalName}`
})
const roleOptions = ref<Entity.TreeNode[]>([])
async function openModal(type: ModalType = 'add', data?: Partial<Entity.User>) {
modalType.value = type
getRoleOptions().then((res) => {
roleOptions.value = res.data
})
modalForm.open()
const handlers = {
async add() {
},
async edit() {
if (!data)
return
const { data: user } = await getUserById(data.userId!)
modalForm.values.value = user
},
}
await handlers[type]()
}
async function submitModal(filedValues: Partial<Entity.User>) {
const handlers = {
async add() {
try {
await createUser(filedValues)
window.$message.success('用户创建成功')
}
catch (error) {
console.error('创建用户失败', error)
}
},
async edit() {
try {
await updateUser(modalForm.values.value.userId!, filedValues)
window.$message.success('用户更新成功')
}
catch (error) {
console.error('更新用户失败', error)
}
},
}
startLoading()
await handlers[modalType.value]()
endLoading()
emit('success')
modalForm.close()
}
defineExpose({
openModal,
})
</script>
<template>
<pro-modal-form
:title="modalTitle"
:form="modalForm"
:loading="submitLoading"
width="700px"
>
<div class="grid grid-cols-2">
<pro-input
required
title="用户名"
path="username"
:readonly="modalType === 'edit'"
/>
<pro-input
title="昵称"
path="nickName"
/>
<pro-radio-group
title="性别"
path="gender"
:field-props="{
type: 'button',
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' },
],
}"
/>
<pro-digit
title="部门ID"
path="deptId"
/>
<pro-input
title="邮箱"
path="email"
placeholder="example@domain.com"
/>
<pro-input
title="手机号"
path="phone"
placeholder="11位手机号"
/>
<pro-textarea
class="col-span-2"
title="备注"
path="remark"
/>
<pro-switch
title="用户状态"
path="userStatus"
:field-props="{ checkedValue: 1, uncheckedValue: 0 }"
/>
<pro-select
class="col-span-2"
title="角色"
path="roles"
:field-props="{ multiple: true, options: roleOptions }"
/>
</div>
</pro-modal-form>
</template>

View File

@ -2,7 +2,7 @@
import { createProSearchForm, useNDataTable } from 'pro-naive-ui' import { createProSearchForm, useNDataTable } from 'pro-naive-ui'
import { deleteUser, getUserList } from '@/api' import { deleteUser, getUserList } from '@/api'
import { createUserColumns, searchColumns } from './columns' import { createUserColumns, searchColumns } from './columns'
import TableModal from './components/TableModal.vue' import UserModal from './components/UserModal.vue'
const searchForm = createProSearchForm({ const searchForm = createProSearchForm({
initialValues: { initialValues: {
@ -39,11 +39,11 @@ const tablecolumns = createUserColumns({
onStatusChange: () => {}, onStatusChange: () => {},
}) })
async function getUserPage({ curent, pageSize }, formData) { async function getUserPage({ current, pageSize }: any, formData: Entity.User[]) {
try { try {
const { data } = await getUserList({ const { data } = await getUserList({
...formData, ...formData,
pageNum: curent, pageNum: current,
pageSize, pageSize,
}) })
return { return {
@ -121,6 +121,6 @@ const treeData = ref([
</template> </template>
</pro-data-table> </pro-data-table>
</n-space> </n-space>
<TableModal ref="modalRef" modal-name="用户" @success="refresh" /> <UserModal ref="modalRef" modal-name="用户" @success="refresh" />
</n-flex> </n-flex>
</template> </template>