用户管理左侧树编辑、添加、删除弹框添加
This commit is contained in:
@@ -3,11 +3,12 @@ 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 { NButton, NPopconfirm, NTag, NDropdown } from 'naive-ui';
|
||||
import { NButton, NPopconfirm, NTag, NDropdown, useDialog } from 'naive-ui';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const gap = computed(() => (appStore.isMobile ? 0 : 16));
|
||||
const dialog = useDialog()
|
||||
|
||||
const loading = ref<boolean>(false);
|
||||
const btnLoading = ref<boolean>(false);
|
||||
@@ -102,7 +103,7 @@ const columns = ref([
|
||||
return h(NTag, {
|
||||
size: 'small',
|
||||
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: '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([
|
||||
{
|
||||
id: "factory", label: "演示工厂", key: "YS",
|
||||
id: "factory", label: "演示工厂", key: "YS", shortLabel: 'YS', parent: '', isLeaf: 0, sort: 0,
|
||||
children: [
|
||||
{
|
||||
id: "scb", label: "生产部", key: "SCB",
|
||||
id: "scb", label: "生产部", key: "SCB", shortLabel: 'SCB', parent: '演示工厂', isLeaf: 0, sort: 0,
|
||||
children: [
|
||||
{ id: "cj1", label: "测试车间一", key: "CJ1" },
|
||||
{ id: "cj2", label: "测试车间二", key: "CJ2" },
|
||||
{ id: "cj3", label: "测试车间三", key: "CJ3" },
|
||||
{ id: "cj1", label: "测试车间一", key: "CJ1", shortLabel: 'CJ1', parent: '生产部', isLeaf: 1, sort: 0 },
|
||||
{ id: "cj2", label: "测试车间二", key: "CJ2", shortLabel: 'CJ2', parent: '生产部', isLeaf: 1, sort: 0 },
|
||||
{ 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: [
|
||||
{ id: "aqk", label: "安全科", key: "AQK" },
|
||||
{ id: "hbk", label: "环保科", key: "HBK" },
|
||||
{ id: "aqk", label: "安全科", key: "AQK", shortLabel: 'AQK', parent: '安环部', isLeaf: 1, sort: 0 },
|
||||
{ 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: [
|
||||
{ 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: [
|
||||
{ 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 menuX = ref(0)
|
||||
const menuY = ref(0)
|
||||
const currentNode = ref(null)
|
||||
// 菜单选项
|
||||
const menuOptions = [
|
||||
{ label: '编辑', key: 'edit' },
|
||||
{ label: '添加子级', key: 'addChild' },
|
||||
{ label: '添加子级', key: 'add' },
|
||||
{ label: '删除', key: 'delete' },
|
||||
]
|
||||
const handleSelectKeys = (keys: string[]) => {
|
||||
@@ -238,6 +266,7 @@ const treeProps = ({ option }: { option: any }) => {
|
||||
onContextmenu(e: MouseEvent) {
|
||||
e.preventDefault()
|
||||
currentNode.value = option
|
||||
console.log(currentNode.value)
|
||||
menuX.value = e.clientX
|
||||
menuY.value = e.clientY
|
||||
menuVisible.value = true
|
||||
@@ -246,16 +275,44 @@ const treeProps = ({ option }: { option: any }) => {
|
||||
}
|
||||
// 点击菜单项
|
||||
const handleMenuSelect = (key: string) => {
|
||||
const node = currentNode.value
|
||||
currentNodeType.value = key
|
||||
switch (key) {
|
||||
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
|
||||
case 'delete':
|
||||
console.log('删除节点', node)
|
||||
break
|
||||
case 'addChild':
|
||||
console.log('添加子节点到', node)
|
||||
const d = dialog.info({
|
||||
title: '删除',
|
||||
content: `确定删除层级「${currentNode.value.label}」吗? 该操作不可恢复`,
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
d.loading = true
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
d.loading = false
|
||||
resolve(true)
|
||||
}, 1000)
|
||||
})
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
d.loading = false
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
closeMenu()
|
||||
@@ -263,7 +320,6 @@ const handleMenuSelect = (key: string) => {
|
||||
// 关闭菜单
|
||||
const closeMenu = () => {
|
||||
menuVisible.value = false
|
||||
currentNode.value = null
|
||||
}
|
||||
const renderSwitcherIcon = () => {
|
||||
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: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)
|
||||
}
|
||||
@@ -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(() => {
|
||||
getList()
|
||||
@@ -500,8 +562,8 @@ onMounted(() => {
|
||||
/>
|
||||
</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>
|
||||
<NForm ref="formRef" :model="currentUser" :rules="rules" label-placement="left" label-width="auto">
|
||||
<NFormItem label="姓名" path="name">
|
||||
@@ -561,7 +623,7 @@ onMounted(() => {
|
||||
</NFormItem>
|
||||
<NFormItem label="状态">
|
||||
<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>
|
||||
</NRadioGroup>
|
||||
</NFormItem>
|
||||
@@ -574,6 +636,64 @@ onMounted(() => {
|
||||
</template>
|
||||
</NDrawerContent>
|
||||
</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>
|
||||
</NSpace>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user