用户管理左侧树编辑、添加、删除弹框添加
This commit is contained in:
@@ -3,11 +3,12 @@ import { ref, computed, h, onMounted, defineComponent } from 'vue';
|
|||||||
import { useAppStore } from '@/store/modules/app';
|
import { useAppStore } from '@/store/modules/app';
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
import { useThemeStore } from '@/store/modules/theme';
|
import { useThemeStore } from '@/store/modules/theme';
|
||||||
import { NButton, NPopconfirm, NTag, NDropdown } from 'naive-ui';
|
import { NButton, NPopconfirm, NTag, NDropdown, useDialog } from 'naive-ui';
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
const gap = computed(() => (appStore.isMobile ? 0 : 16));
|
const gap = computed(() => (appStore.isMobile ? 0 : 16));
|
||||||
|
const dialog = useDialog()
|
||||||
|
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
const btnLoading = ref<boolean>(false);
|
const btnLoading = ref<boolean>(false);
|
||||||
@@ -102,7 +103,7 @@ const columns = ref([
|
|||||||
return h(NTag, {
|
return h(NTag, {
|
||||||
size: 'small',
|
size: 'small',
|
||||||
type: `${row.status===1?'success':'error'}`
|
type: `${row.status===1?'success':'error'}`
|
||||||
}, { default: () => `${row.status===1?'开启':'关闭'}` })
|
}, { default: () => `${row.status===1?'启用':'禁用'}` })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -181,36 +182,64 @@ const roleOptions = ref([
|
|||||||
{ label: '管理员', value: 'admin' },
|
{ label: '管理员', value: 'admin' },
|
||||||
{ label: '普通用户', value: 'user' },
|
{ label: '普通用户', value: 'user' },
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const formNodeRef = ref<any>(null);
|
||||||
|
const treeModal = ref<boolean>(false);
|
||||||
|
const currentNode = ref<{ id: string, label: string, key: string, children: any[], shortLabel: string, parent: string, isLeaf: number, sort: number }>({
|
||||||
|
id: '',
|
||||||
|
label: '',
|
||||||
|
key: '',
|
||||||
|
children: [],
|
||||||
|
shortLabel: '',
|
||||||
|
parent: '',
|
||||||
|
isLeaf: 1,
|
||||||
|
sort: 0,
|
||||||
|
})
|
||||||
|
const formNode = ref<{ id: string, label: string, key: string, children: any[], shortLabel: string, parent: string, isLeaf: number, sort: number }>({
|
||||||
|
id: '',
|
||||||
|
label: '',
|
||||||
|
key: '',
|
||||||
|
children: [],
|
||||||
|
shortLabel: '',
|
||||||
|
parent: '',
|
||||||
|
isLeaf: 1,
|
||||||
|
sort: 0,
|
||||||
|
})
|
||||||
|
const currentNodeType = ref<string>('edit')
|
||||||
|
// 树节点规则
|
||||||
|
const treeRules = ref({
|
||||||
|
label: [{ required: true, message: '请输入层级名称', trigger: ['blur'] }],
|
||||||
|
})
|
||||||
// 左侧组织树
|
// 左侧组织树
|
||||||
const orgTree = ref([
|
const orgTree = ref([
|
||||||
{
|
{
|
||||||
id: "factory", label: "演示工厂", key: "YS",
|
id: "factory", label: "演示工厂", key: "YS", shortLabel: 'YS', parent: '', isLeaf: 0, sort: 0,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: "scb", label: "生产部", key: "SCB",
|
id: "scb", label: "生产部", key: "SCB", shortLabel: 'SCB', parent: '演示工厂', isLeaf: 0, sort: 0,
|
||||||
children: [
|
children: [
|
||||||
{ id: "cj1", label: "测试车间一", key: "CJ1" },
|
{ id: "cj1", label: "测试车间一", key: "CJ1", shortLabel: 'CJ1', parent: '生产部', isLeaf: 1, sort: 0 },
|
||||||
{ id: "cj2", label: "测试车间二", key: "CJ2" },
|
{ id: "cj2", label: "测试车间二", key: "CJ2", shortLabel: 'CJ2', parent: '生产部', isLeaf: 1, sort: 0 },
|
||||||
{ id: "cj3", label: "测试车间三", key: "CJ3" },
|
{ id: "cj3", label: "测试车间三", key: "CJ3", shortLabel: 'CJ3', parent: '生产部', isLeaf: 1, sort: 0 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "ahb", label: "安环部", key: "AHB",
|
id: "ahb", label: "安环部", key: "AHB", shortLabel: 'AHB', parent: '演示工厂', isLeaf: 0, sort: 0,
|
||||||
children: [
|
children: [
|
||||||
{ id: "aqk", label: "安全科", key: "AQK" },
|
{ id: "aqk", label: "安全科", key: "AQK", shortLabel: 'AQK', parent: '安环部', isLeaf: 1, sort: 0 },
|
||||||
{ id: "hbk", label: "环保科", key: "HBK" },
|
{ id: "hbk", label: "环保科", key: "HBK", shortLabel: 'HBK', parent: '安环部', isLeaf: 1, sort: 0 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "sbb", label: "设备部", key: "SBB",
|
id: "sbb", label: "设备部", key: "SBB", shortLabel: 'SBB', parent: '演示工厂', isLeaf: 0, sort: 0,
|
||||||
children: [
|
children: [
|
||||||
{ id: "sbk", label: "设备科", key: "SBK" },
|
{ id: "sbk", label: "设备科", key: "SBK", shortLabel: 'SBK', parent: '设备部', isLeaf: 1, sort: 0 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "zlb", label: "质量部", key: "ZLB",
|
id: "zlb", label: "质量部", key: "ZLB", shortLabel: 'ZLB', parent: '演示工厂', isLeaf: 0, sort: 0,
|
||||||
children: [
|
children: [
|
||||||
{ id: "zjk", label: "质检科", key: "ZJK" },
|
{ id: "zjk", label: "质检科", key: "ZJK", shortLabel: 'ZJK', parent: '质量部', isLeaf: 1, sort: 0 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -222,11 +251,10 @@ const defaultSelectedKeys = ref<string[]>(['YS'])
|
|||||||
const menuVisible = ref(false)
|
const menuVisible = ref(false)
|
||||||
const menuX = ref(0)
|
const menuX = ref(0)
|
||||||
const menuY = ref(0)
|
const menuY = ref(0)
|
||||||
const currentNode = ref(null)
|
|
||||||
// 菜单选项
|
// 菜单选项
|
||||||
const menuOptions = [
|
const menuOptions = [
|
||||||
{ label: '编辑', key: 'edit' },
|
{ label: '编辑', key: 'edit' },
|
||||||
{ label: '添加子级', key: 'addChild' },
|
{ label: '添加子级', key: 'add' },
|
||||||
{ label: '删除', key: 'delete' },
|
{ label: '删除', key: 'delete' },
|
||||||
]
|
]
|
||||||
const handleSelectKeys = (keys: string[]) => {
|
const handleSelectKeys = (keys: string[]) => {
|
||||||
@@ -238,6 +266,7 @@ const treeProps = ({ option }: { option: any }) => {
|
|||||||
onContextmenu(e: MouseEvent) {
|
onContextmenu(e: MouseEvent) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
currentNode.value = option
|
currentNode.value = option
|
||||||
|
console.log(currentNode.value)
|
||||||
menuX.value = e.clientX
|
menuX.value = e.clientX
|
||||||
menuY.value = e.clientY
|
menuY.value = e.clientY
|
||||||
menuVisible.value = true
|
menuVisible.value = true
|
||||||
@@ -246,16 +275,44 @@ const treeProps = ({ option }: { option: any }) => {
|
|||||||
}
|
}
|
||||||
// 点击菜单项
|
// 点击菜单项
|
||||||
const handleMenuSelect = (key: string) => {
|
const handleMenuSelect = (key: string) => {
|
||||||
const node = currentNode.value
|
currentNodeType.value = key
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'edit':
|
case 'edit':
|
||||||
console.log('编辑节点', node)
|
formNode.value = currentNode.value
|
||||||
|
treeModal.value = true
|
||||||
|
break
|
||||||
|
case 'add':
|
||||||
|
formNode.value = {
|
||||||
|
id: '',
|
||||||
|
label: '',
|
||||||
|
key: '',
|
||||||
|
children: [],
|
||||||
|
shortLabel: '',
|
||||||
|
parent: currentNode.value.label,
|
||||||
|
isLeaf: 0,
|
||||||
|
sort: 0,
|
||||||
|
}
|
||||||
|
treeModal.value = true
|
||||||
break
|
break
|
||||||
case 'delete':
|
case 'delete':
|
||||||
console.log('删除节点', node)
|
const d = dialog.info({
|
||||||
break
|
title: '删除',
|
||||||
case 'addChild':
|
content: `确定删除层级「${currentNode.value.label}」吗? 该操作不可恢复`,
|
||||||
console.log('添加子节点到', node)
|
positiveText: '确定',
|
||||||
|
negativeText: '取消',
|
||||||
|
onPositiveClick: () => {
|
||||||
|
d.loading = true
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
d.loading = false
|
||||||
|
resolve(true)
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onNegativeClick: () => {
|
||||||
|
d.loading = false
|
||||||
|
}
|
||||||
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
closeMenu()
|
closeMenu()
|
||||||
@@ -263,7 +320,6 @@ const handleMenuSelect = (key: string) => {
|
|||||||
// 关闭菜单
|
// 关闭菜单
|
||||||
const closeMenu = () => {
|
const closeMenu = () => {
|
||||||
menuVisible.value = false
|
menuVisible.value = false
|
||||||
currentNode.value = null
|
|
||||||
}
|
}
|
||||||
const renderSwitcherIcon = () => {
|
const renderSwitcherIcon = () => {
|
||||||
return h(Icon, { icon: 'formkit:right',class:'size-14px' }, {})
|
return h(Icon, { icon: 'formkit:right',class:'size-14px' }, {})
|
||||||
@@ -313,14 +369,6 @@ const getList = async () => {
|
|||||||
{id:10,name:'姓名10',dept:[],mobile:'13800000009',email:'user1@example.com',account:'user10',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: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},
|
|
||||||
{id:12,name:'姓名12',dept:[],mobile:'13800000011',email:'user1@example.com',account:'user12',role:'普通用户',dataPermission:[],gender:1,status:1},
|
|
||||||
]
|
]
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
@@ -420,6 +468,20 @@ const saveUser = async (e: MouseEvent) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 保存节点
|
||||||
|
const saveNode = async (e: MouseEvent) => {
|
||||||
|
e.preventDefault()
|
||||||
|
formNodeRef.value?.validate((errors: any) => {
|
||||||
|
if (!errors) {
|
||||||
|
btnLoading.value = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
window.$message?.success(`${currentNodeType.value === 'edit' ? '编辑' : '添加'}成功`)
|
||||||
|
btnLoading.value = false;
|
||||||
|
treeModal.value = false;
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
@@ -500,7 +562,7 @@ onMounted(() => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 新增或编辑弹框 -->
|
<!-- 新增或编辑抽屉 -->
|
||||||
<NDrawer v-model:show="userModal" :width="400" placement="right">
|
<NDrawer v-model:show="userModal" :width="400" placement="right">
|
||||||
<NDrawerContent :title="currentType === 'add' ? '新增成员' : '编辑成员'" closable>
|
<NDrawerContent :title="currentType === 'add' ? '新增成员' : '编辑成员'" closable>
|
||||||
<NForm ref="formRef" :model="currentUser" :rules="rules" label-placement="left" label-width="auto">
|
<NForm ref="formRef" :model="currentUser" :rules="rules" label-placement="left" label-width="auto">
|
||||||
@@ -561,7 +623,7 @@ onMounted(() => {
|
|||||||
</NFormItem>
|
</NFormItem>
|
||||||
<NFormItem label="状态">
|
<NFormItem label="状态">
|
||||||
<NRadioGroup v-model:value="currentUser.status" name="status">
|
<NRadioGroup v-model:value="currentUser.status" name="status">
|
||||||
<n-radio :value="1">正常</n-radio>
|
<n-radio :value="1">启用</n-radio>
|
||||||
<n-radio :value="2">禁用</n-radio>
|
<n-radio :value="2">禁用</n-radio>
|
||||||
</NRadioGroup>
|
</NRadioGroup>
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
@@ -574,6 +636,64 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
</NDrawerContent>
|
</NDrawerContent>
|
||||||
</NDrawer>
|
</NDrawer>
|
||||||
|
<!-- 左侧树添加/编辑弹框 -->
|
||||||
|
<NModal
|
||||||
|
v-model:show="treeModal"
|
||||||
|
preset="card"
|
||||||
|
:title="currentNodeType === 'edit' ? '编辑层级' : '添加子级'"
|
||||||
|
:auto-focus="false"
|
||||||
|
:style="{ width: '450px', height: 'auto' }"
|
||||||
|
:segmented="{ content: true, footer: true }"
|
||||||
|
>
|
||||||
|
<template #default>
|
||||||
|
<NForm ref="formNodeRef" :model="formNode" :rules="treeRules" label-placement="left" label-width="auto">
|
||||||
|
<NFormItem label="层级名称" path="label">
|
||||||
|
<NInput
|
||||||
|
v-model:value="formNode.label"
|
||||||
|
maxlength="10"
|
||||||
|
show-count
|
||||||
|
placeholder="请输入层级名称"
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="层级简称">
|
||||||
|
<NInput
|
||||||
|
v-model:value="formNode.shortLabel"
|
||||||
|
maxlength="10"
|
||||||
|
show-count
|
||||||
|
placeholder="请输入层级简称"
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="所属层级">
|
||||||
|
<NInput
|
||||||
|
v-model:value="formNode.parent"
|
||||||
|
:disabled="true"
|
||||||
|
placeholder=""
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="末端层级">
|
||||||
|
<NRadioGroup v-model:value="formNode.isLeaf" name="isLeaf">
|
||||||
|
<n-radio :value="1">是</n-radio>
|
||||||
|
<n-radio :value="0">否</n-radio>
|
||||||
|
</NRadioGroup>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem label="排序">
|
||||||
|
<NInputNumber
|
||||||
|
class="w-full"
|
||||||
|
v-model:value="formNode.sort"
|
||||||
|
:min="0"
|
||||||
|
:show-button="false"
|
||||||
|
placeholder="请输入排序"
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
</NForm>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<div class="flex justify-end gap-[10px]">
|
||||||
|
<NButton @click="treeModal = false">取消</NButton>
|
||||||
|
<NButton type="primary" :loading="btnLoading" @click="saveNode">确定</NButton>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</NModal>
|
||||||
</NCard>
|
</NCard>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user