架构及用户管理静态页完成
This commit is contained in:
@@ -221,7 +221,8 @@ export const generatedRoutes: GeneratedRoute[] = [
|
||||
meta: {
|
||||
title: 'systemmanage_role',
|
||||
i18nKey: 'route.systemmanage_role',
|
||||
icon: ''
|
||||
icon: '',
|
||||
order: 2
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -231,7 +232,8 @@ export const generatedRoutes: GeneratedRoute[] = [
|
||||
meta: {
|
||||
title: 'systemmanage_template',
|
||||
i18nKey: 'route.systemmanage_template',
|
||||
icon: ''
|
||||
icon: '',
|
||||
order: 3
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -241,7 +243,8 @@ export const generatedRoutes: GeneratedRoute[] = [
|
||||
meta: {
|
||||
title: 'systemmanage_user',
|
||||
i18nKey: 'route.systemmanage_user',
|
||||
icon: ''
|
||||
icon: '',
|
||||
order: 1
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Vendored
+4
@@ -74,6 +74,8 @@ declare module 'vue' {
|
||||
NTabs: typeof import('naive-ui')['NTabs']
|
||||
NTag: typeof import('naive-ui')['NTag']
|
||||
NTooltip: typeof import('naive-ui')['NTooltip']
|
||||
NTree: typeof import('naive-ui')['NTree']
|
||||
NTreeSelect: typeof import('naive-ui')['NTreeSelect']
|
||||
NWatermark: typeof import('naive-ui')['NWatermark']
|
||||
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
||||
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
||||
@@ -154,6 +156,8 @@ declare global {
|
||||
const NTabs: typeof import('naive-ui')['NTabs']
|
||||
const NTag: typeof import('naive-ui')['NTag']
|
||||
const NTooltip: typeof import('naive-ui')['NTooltip']
|
||||
const NTree: typeof import('naive-ui')['NTree']
|
||||
const NTreeSelect: typeof import('naive-ui')['NTreeSelect']
|
||||
const NWatermark: typeof import('naive-ui')['NWatermark']
|
||||
const PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
||||
const ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
||||
|
||||
@@ -1,30 +1,586 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, h, onMounted } from 'vue';
|
||||
import { ref, computed, h, onMounted, defineComponent } from 'vue';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { NButton, NPopconfirm } from 'naive-ui';
|
||||
import { NButton, NPopconfirm, NTag, NDropdown } from 'naive-ui';
|
||||
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const gap = computed(() => (appStore.isMobile ? 0 : 16));
|
||||
|
||||
onMounted(() => {
|
||||
const loading = ref<boolean>(false);
|
||||
const btnLoading = ref<boolean>(false);
|
||||
const currentType = ref<string>('add');
|
||||
const formRef = ref<any>(null);
|
||||
const keyword = ref<string>('');
|
||||
// 当前用户
|
||||
const currentUser = ref<{ id: number, name: string, dept: string[], mobile: string, email: string, account: string, role: string | null, dataPermission: string[], status: number, gender: number }>({
|
||||
id: 0,
|
||||
name: '',
|
||||
dept: [],
|
||||
mobile: '',
|
||||
email: '',
|
||||
account: '',
|
||||
role: null,
|
||||
dataPermission: [],
|
||||
status: 1,
|
||||
gender: 1,
|
||||
});
|
||||
// 校验规则
|
||||
const rules = ref({
|
||||
name: { required: true, message: '角色名称不能为空', trigger: ['blur'] },
|
||||
dept: {
|
||||
type: 'array',
|
||||
required: true,
|
||||
trigger: ['blur', 'change'],
|
||||
message: '请选择所属部门'
|
||||
},
|
||||
account: { required: true, message: '账号不能为空', trigger: ['blur'] },
|
||||
role: { required: true, message: '请选择账号角色', trigger: ['blur', 'change'] },
|
||||
dataPermission: {
|
||||
type: 'array',
|
||||
required: true,
|
||||
trigger: ['blur', 'change'],
|
||||
message: '请选择数据权限'
|
||||
},
|
||||
status: { required: true, message: '请选择状态', trigger: ['blur', 'change'] },
|
||||
gender: { required: true, message: '请选择性别', trigger: ['blur', 'change'] },
|
||||
})
|
||||
const userModal = ref<boolean>(false);
|
||||
const pagination = ref<{ page: number, pageSize: number, pageCount: number }>({
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
pageCount: 0,
|
||||
})
|
||||
const columns = ref([
|
||||
{
|
||||
title: '序号',
|
||||
key: 'index',
|
||||
width: 5,
|
||||
align: 'center',
|
||||
render: (_row: any, index: number) => {
|
||||
return h('span', {}, { default: () => (pagination.value.page - 1) * pagination.value.pageSize + index + 1 })
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '姓名',
|
||||
key: 'name',
|
||||
width: 8,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
key: 'dept',
|
||||
width: 10,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '手机号码',
|
||||
key: 'mobile',
|
||||
width: 12,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '账号',
|
||||
key: 'account',
|
||||
width: 10,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '账号角色',
|
||||
key: 'role',
|
||||
width: 10,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
width: 8,
|
||||
align: 'center',
|
||||
render: (row: any) => {
|
||||
return h(NTag, {
|
||||
size: 'small',
|
||||
type: `${row.status===1?'success':'error'}`
|
||||
}, { default: () => `${row.status===1?'开启':'关闭'}` })
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 14,
|
||||
align: 'center',
|
||||
render: (row: any) => {
|
||||
return h('div', { class: 'flex items-center justify-center gap-3' }, {
|
||||
default: () => [
|
||||
h(NButton, {
|
||||
text: true,
|
||||
size: 'tiny',
|
||||
type: 'primary',
|
||||
onClick: () => handleEdit(row)
|
||||
}, {
|
||||
// 渲染按钮文本
|
||||
default: () => '编辑'
|
||||
}),
|
||||
h(NPopconfirm, {
|
||||
// 组件 Props
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
handleDelete(row)
|
||||
},
|
||||
// 可选:自定义确认/取消按钮的样式
|
||||
positiveButtonProps: { size: 'tiny', type: 'primary' },
|
||||
negativeButtonProps: { size: 'tiny' }
|
||||
}, {
|
||||
// 插槽 (Slots)
|
||||
trigger: () => h(NButton,
|
||||
{
|
||||
text: true,
|
||||
size: 'tiny',
|
||||
type: 'error',
|
||||
},
|
||||
{
|
||||
default: () => '删除' // 按钮文字
|
||||
}
|
||||
),
|
||||
default: () => '确定要删除吗?' // 弹出框的提示内容
|
||||
}),
|
||||
h(NPopconfirm, {
|
||||
// 组件 Props
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
resetPassword(row)
|
||||
},
|
||||
// 可选:自定义确认/取消按钮的样式
|
||||
positiveButtonProps: { size: 'tiny', type: 'primary' },
|
||||
negativeButtonProps: { size: 'tiny' }
|
||||
}, {
|
||||
// 插槽 (Slots)
|
||||
trigger: () => h(NButton,
|
||||
{
|
||||
text: true,
|
||||
size: 'tiny',
|
||||
type: 'primary',
|
||||
},
|
||||
{
|
||||
default: () => '重置密码' // 按钮文字
|
||||
}
|
||||
),
|
||||
default: () => '是否重置该用户密码为)cVLO%M(c08)' // 弹出框的提示内容
|
||||
}),
|
||||
]
|
||||
})
|
||||
}
|
||||
},
|
||||
])
|
||||
const list = ref<{ id: number, name: string, dept: string[], mobile: string, email: string, account: string, role: string | null, dataPermission: string[], status: number, gender: number }[]>([])
|
||||
// 账号角色选项
|
||||
const roleOptions = ref([
|
||||
{ label: '管理员', value: 'admin' },
|
||||
{ label: '普通用户', value: 'user' },
|
||||
])
|
||||
// 左侧组织树
|
||||
const orgTree = ref([
|
||||
{
|
||||
id: "factory", label: "演示工厂", key: "YS",
|
||||
children: [
|
||||
{
|
||||
id: "scb", label: "生产部", key: "SCB",
|
||||
children: [
|
||||
{ id: "cj1", label: "测试车间一", key: "CJ1" },
|
||||
{ id: "cj2", label: "测试车间二", key: "CJ2" },
|
||||
{ id: "cj3", label: "测试车间三", key: "CJ3" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "ahb", label: "安环部", key: "AHB",
|
||||
children: [
|
||||
{ id: "aqk", label: "安全科", key: "AQK" },
|
||||
{ id: "hbk", label: "环保科", key: "HBK" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "sbb", label: "设备部", key: "SBB",
|
||||
children: [
|
||||
{ id: "sbk", label: "设备科", key: "SBK" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "zlb", label: "质量部", key: "ZLB",
|
||||
children: [
|
||||
{ id: "zjk", label: "质检科", key: "ZJK" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
const defaultExpandedKeys = ref<string[]>(['YS'])
|
||||
const defaultSelectedKeys = ref<string[]>(['YS'])
|
||||
// 右键菜单相关
|
||||
const menuVisible = ref(false)
|
||||
const menuX = ref(0)
|
||||
const menuY = ref(0)
|
||||
const currentNode = ref(null)
|
||||
// 菜单选项
|
||||
const menuOptions = [
|
||||
{ label: '编辑', key: 'edit' },
|
||||
{ label: '添加子级', key: 'addChild' },
|
||||
{ label: '删除', key: 'delete' },
|
||||
]
|
||||
const handleSelectKeys = (keys: string[]) => {
|
||||
defaultSelectedKeys.value = keys
|
||||
}
|
||||
// 处理右键点击树节点
|
||||
const treeProps = ({ option }: { option: any }) => {
|
||||
return {
|
||||
onContextmenu(e: MouseEvent) {
|
||||
e.preventDefault()
|
||||
currentNode.value = option
|
||||
menuX.value = e.clientX
|
||||
menuY.value = e.clientY
|
||||
menuVisible.value = true
|
||||
},
|
||||
}
|
||||
}
|
||||
// 点击菜单项
|
||||
const handleMenuSelect = (key: string) => {
|
||||
const node = currentNode.value
|
||||
switch (key) {
|
||||
case 'edit':
|
||||
console.log('编辑节点', node)
|
||||
break
|
||||
case 'delete':
|
||||
console.log('删除节点', node)
|
||||
break
|
||||
case 'addChild':
|
||||
console.log('添加子节点到', node)
|
||||
break
|
||||
}
|
||||
closeMenu()
|
||||
}
|
||||
// 关闭菜单
|
||||
const closeMenu = () => {
|
||||
menuVisible.value = false
|
||||
currentNode.value = null
|
||||
}
|
||||
const renderSwitcherIcon = () => {
|
||||
return h(Icon, { icon: 'formkit:right',class:'size-14px' }, {})
|
||||
}
|
||||
const renderSuffix = ({ option }: { option: any }) => {
|
||||
return h(
|
||||
NButton,
|
||||
{
|
||||
text: true,
|
||||
type: 'primary',
|
||||
onClick: (e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
currentNode.value = option
|
||||
menuX.value = e.clientX
|
||||
menuY.value = e.clientY
|
||||
menuVisible.value = true
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: () =>
|
||||
h(Icon, { icon: 'lucide:more-horizontal', class: 'size-14px' }),
|
||||
}
|
||||
)
|
||||
};
|
||||
// 处理部门选择变化
|
||||
const handleUpdateDept = (value: any) => {
|
||||
currentUser.value.dept = value
|
||||
}
|
||||
|
||||
// 获取列表
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
list.value = [
|
||||
{id:1,name:'姓名1',dept:['YS'],mobile:'13800000000',email:'user1@example.com',account:'user1',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:2,name:'姓名2',dept:[],mobile:'13800000001',email:'user1@example.com',account:'user2',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:2,name:'姓名2',dept:[],mobile:'13800000001',email:'user1@example.com',account:'user2',role:'普通用户',dataPermission:[],gender:1,status:2},
|
||||
{id:3,name:'姓名3',dept:[],mobile:'13800000002',email:'user1@example.com',account:'user3',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:4,name:'姓名4',dept:[],mobile:'13800000003',email:'user1@example.com',account:'user3',role:'普通用户',dataPermission:[],gender:1,status:2},
|
||||
{id:4,name:'姓名4',dept:['YS'],mobile:'13800000003',email:'user1@example.com',account:'user4',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:5,name:'姓名5',dept:[],mobile:'13800000004',email:'user1@example.com',account:'user5',role:'普通用户',dataPermission:[],gender:1,status:2},
|
||||
{id:6,name:'姓名6',dept:['YS'],mobile:'13800000005',email:'user1@example.com',account:'user6',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:7,name:'姓名7',dept:[],mobile:'13800000006',email:'user1@example.com',account:'user7',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:8,name:'姓名8',dept:[],mobile:'13800000007',email:'user1@example.com',account:'user8',role:'普通用户',dataPermission:[],gender:1,status:2},
|
||||
{id:9,name:'姓名9',dept:['YS'],mobile:'13800000008',email:'user1@example.com',account:'user9',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:10,name:'姓名10',dept:[],mobile:'13800000009',email:'user1@example.com',account:'user10',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:11,name:'姓名11',dept:['YS'],mobile:'13800000010',email:'user1@example.com',account:'user11',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:12,name:'姓名12',dept:[],mobile:'13800000011',email:'user1@example.com',account:'user12',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:12,name:'姓名12',dept:[],mobile:'13800000011',email:'user1@example.com',account:'user12',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:12,name:'姓名12',dept:[],mobile:'13800000011',email:'user1@example.com',account:'user12',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:12,name:'姓名12',dept:[],mobile:'13800000011',email:'user1@example.com',account:'user12',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:12,name:'姓名12',dept:[],mobile:'13800000011',email:'user1@example.com',account:'user12',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:12,name:'姓名12',dept:[],mobile:'13800000011',email:'user1@example.com',account:'user12',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:12,name:'姓名12',dept:[],mobile:'13800000011',email:'user1@example.com',account:'user12',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:12,name:'姓名12',dept:[],mobile:'13800000011',email:'user1@example.com',account:'user12',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
{id:12,name:'姓名12',dept:[],mobile:'13800000011',email:'user1@example.com',account:'user12',role:'普通用户',dataPermission:[],gender:1,status:1},
|
||||
]
|
||||
}, 1000)
|
||||
}
|
||||
// 处理数据权限选择变化
|
||||
const handleUpdateChecked = (keys: string[]) => {
|
||||
currentUser.value.dataPermission = keys
|
||||
}
|
||||
|
||||
// 打开添加用户弹框
|
||||
const addUser = () => {
|
||||
currentType.value = 'add';
|
||||
currentUser.value = {
|
||||
id: 0,
|
||||
name: '',
|
||||
dept: [],
|
||||
mobile: '',
|
||||
email: '',
|
||||
account: '',
|
||||
role: null,
|
||||
dataPermission: [],
|
||||
status: 1,
|
||||
gender: 1,
|
||||
};
|
||||
userModal.value = true;
|
||||
}
|
||||
// 重置密码
|
||||
const resetPassword = (row: any) => {
|
||||
currentUser.value = {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
dept: row.dept,
|
||||
mobile: row.mobile,
|
||||
email: row.email,
|
||||
account: row.account,
|
||||
role: row.role,
|
||||
dataPermission: row.dataPermission,
|
||||
status: row.status,
|
||||
gender: row.gender,
|
||||
};
|
||||
}
|
||||
// 编辑用户
|
||||
const handleEdit = (row: any) => {
|
||||
currentType.value = 'edit';
|
||||
currentUser.value = {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
dept: row.dept,
|
||||
mobile: row.mobile,
|
||||
email: row.email,
|
||||
account: row.account,
|
||||
role: row.role,
|
||||
dataPermission: row.dataPermission,
|
||||
status: row.status,
|
||||
gender: row.gender,
|
||||
};
|
||||
userModal.value = true;
|
||||
}
|
||||
// 删除用户
|
||||
const handleDelete = (row: any) => {
|
||||
loading.value = true;
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
list.value = list.value.filter((item: any) => item.id !== row.id);
|
||||
window.$message?.success('删除成功')
|
||||
}, 1000)
|
||||
}
|
||||
// 导入用户
|
||||
const importUser = () => {
|
||||
|
||||
}
|
||||
// 刷新数据
|
||||
const refreshData = () => {
|
||||
|
||||
}
|
||||
// 保存用户
|
||||
const saveUser = async (e: MouseEvent) => {
|
||||
e.preventDefault()
|
||||
formRef.value?.validate((errors: any) => {
|
||||
if (!errors) {
|
||||
btnLoading.value = true;
|
||||
setTimeout(() => {
|
||||
// 新增
|
||||
if(currentType.value === 'add'){
|
||||
list.value.push({id:list.value.length+1,name:currentUser.value?.name,dept:currentUser.value?.dept,mobile:currentUser.value?.mobile,email:currentUser.value?.email,account:currentUser.value?.account,role:currentUser.value?.role,dataPermission:currentUser.value?.dataPermission,status:currentUser.value?.status,gender:currentUser.value?.gender})
|
||||
}
|
||||
// 编辑
|
||||
if(currentType.value === 'edit'){
|
||||
const target = list.value.find((item:any) => item.id === currentUser.value.id);
|
||||
if (target) {
|
||||
target.name = currentUser.value?.name;
|
||||
}
|
||||
}
|
||||
window.$message?.success('保存成功')
|
||||
btnLoading.value = false;
|
||||
userModal.value = false;
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NSpace vertical :size="16">
|
||||
用户
|
||||
<!-- 用户管理 -->
|
||||
<NCard :bordered="false" size="small" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
|
||||
<div class="border mb-3 py-2 px-3" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
|
||||
<NGrid :x-gap="gap" :y-gap="16" responsive="screen" item-responsive>
|
||||
<NGi span="24 s:24 m:16">
|
||||
<div class="h-100% flex items-center gap-2">
|
||||
<Icon icon="lucide:users-round" class="size-16px" :style="{ color: themeStore.themeColor }" />
|
||||
<p class="text-[16px] font-600">架构及用户管理</p>
|
||||
</div>
|
||||
</NGi>
|
||||
<NGi span="24 s:24 m:8" class="flex items-center justify-end gap-12px">
|
||||
<NButton type="primary" size="small" @click="addUser">
|
||||
<Icon icon="ic:round-plus" class="size-16px" />添加成员
|
||||
</NButton>
|
||||
<NButton type="warning" size="small" @click="importUser">
|
||||
<Icon icon="material-symbols:download" class="size-16px" />导入用户
|
||||
</NButton>
|
||||
<NButton text @click="refreshData">
|
||||
<Icon icon="tdesign:refresh" class="size-14px" />
|
||||
</NButton>
|
||||
</NGi>
|
||||
</NGrid>
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<div class="border p-3 w-300px" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
|
||||
<NInput v-model:value="keyword" placeholder="请输入人员">
|
||||
<template #suffix>
|
||||
<Icon icon="akar-icons:search" class="size-14px text-slate-400 cursor-pointer" />
|
||||
</template>
|
||||
</NInput>
|
||||
<!-- 树 -->
|
||||
<div class="mt-2 scroll">
|
||||
<NTree
|
||||
block-line
|
||||
:data="orgTree"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
:default-selected-keys="defaultSelectedKeys"
|
||||
:render-switcher-icon="renderSwitcherIcon"
|
||||
:render-suffix="renderSuffix"
|
||||
selectable
|
||||
:cancelable="false"
|
||||
:on-update:selected-keys="handleSelectKeys"
|
||||
:node-props="treeProps"
|
||||
/>
|
||||
<NDropdown
|
||||
:show="menuVisible"
|
||||
:options="menuOptions"
|
||||
size="small"
|
||||
:x="menuX"
|
||||
:y="menuY"
|
||||
placement="bottom-start"
|
||||
trigger="manual"
|
||||
@clickoutside="closeMenu"
|
||||
@select="handleMenuSelect"
|
||||
/>
|
||||
</div>
|
||||
<p class="mt-2 border-t pt-2 text-[11px] leading-4 text-slate-400">
|
||||
点击层级查看该层级全员名录;右键(或悬停点 ···)可编辑、添加子级、删除。
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<NDataTable
|
||||
size="small"
|
||||
:loading="loading"
|
||||
:single-line="false"
|
||||
:columns="columns"
|
||||
:data="list"
|
||||
:pagination="pagination"
|
||||
max-height="calc(100vh - 285px)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 新增或编辑弹框 -->
|
||||
<NDrawer v-model:show="userModal" :width="400" placement="right">
|
||||
<NDrawerContent :title="currentType === 'add' ? '新增成员' : '编辑成员'" closable>
|
||||
<NForm ref="formRef" :model="currentUser" :rules="rules" label-placement="left" label-width="auto">
|
||||
<NFormItem label="姓名" path="name">
|
||||
<NInput
|
||||
v-model:value="currentUser.name"
|
||||
placeholder="请输入姓名"
|
||||
/>
|
||||
</NFormItem>
|
||||
<NFormItem label="所属部门" path="dept">
|
||||
<NTreeSelect
|
||||
:value="currentUser.dept"
|
||||
multiple
|
||||
:options="orgTree"
|
||||
@update:value="handleUpdateDept"
|
||||
/>
|
||||
</NFormItem>
|
||||
<NFormItem label="性别">
|
||||
<NRadioGroup v-model:value="currentUser.gender" name="gender">
|
||||
<n-radio :value="1">男</n-radio>
|
||||
<n-radio :value="2">女</n-radio>
|
||||
</NRadioGroup>
|
||||
</NFormItem>
|
||||
<NFormItem label="账号" path="account">
|
||||
<NInput
|
||||
v-model:value="currentUser.account"
|
||||
placeholder="请输入账号"
|
||||
/>
|
||||
</NFormItem>
|
||||
<NFormItem label="手机号码">
|
||||
<NInput
|
||||
v-model:value="currentUser.mobile"
|
||||
placeholder="请输入11位手机号码"
|
||||
/>
|
||||
</NFormItem>
|
||||
<NFormItem label="电子邮箱">
|
||||
<NInput
|
||||
v-model:value="currentUser.email"
|
||||
placeholder="请输入电子邮箱"
|
||||
/>
|
||||
</NFormItem>
|
||||
<NFormItem label="账号角色" path="role">
|
||||
<NSelect
|
||||
v-model:value="currentUser.role"
|
||||
:options="roleOptions"
|
||||
placeholder="请选择账号角色"
|
||||
/>
|
||||
</NFormItem>
|
||||
<NFormItem label="数据权限" path="dataPermission">
|
||||
<n-tree
|
||||
:data="orgTree"
|
||||
block-line
|
||||
checkable
|
||||
cascade
|
||||
:checked-keys="currentUser.dataPermission"
|
||||
:on-update:checked-keys="handleUpdateChecked"
|
||||
/>
|
||||
</NFormItem>
|
||||
<NFormItem label="状态">
|
||||
<NRadioGroup v-model:value="currentUser.status" name="status">
|
||||
<n-radio :value="1">正常</n-radio>
|
||||
<n-radio :value="2">禁用</n-radio>
|
||||
</NRadioGroup>
|
||||
</NFormItem>
|
||||
</NForm>
|
||||
<template #footer>
|
||||
<div class="flex justify-end gap-[10px]">
|
||||
<NButton @click="userModal = false">取消</NButton>
|
||||
<NButton type="primary" :loading="btnLoading" @click="saveUser">保存</NButton>
|
||||
</div>
|
||||
</template>
|
||||
</NDrawerContent>
|
||||
</NDrawer>
|
||||
</NCard>
|
||||
</NSpace>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.scroll {
|
||||
height: calc(100vh - 205px);
|
||||
height: calc(100vh - 322px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user