feat:优化 dept、menu 支持选择“当前层级”
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
:label="label"
|
||||
label-width="180rpx"
|
||||
:columns="deptColumns"
|
||||
value-key="id"
|
||||
label-key="name"
|
||||
:column-change="handleColumnChange"
|
||||
:display-format="displayFormat"
|
||||
@confirm="handleConfirm"
|
||||
@@ -64,17 +66,25 @@ function initFirstColumn() {
|
||||
if (props.showRoot) {
|
||||
deptColumns.value = [
|
||||
[
|
||||
{ label: '顶级部门', value: 0 },
|
||||
...topDepts.map(item => ({ value: item.id, label: item.name })),
|
||||
{ id: 0, name: '顶级部门' },
|
||||
...topDepts,
|
||||
],
|
||||
]
|
||||
} else {
|
||||
deptColumns.value = [
|
||||
topDepts.map(item => ({ value: item.id, label: item.name })),
|
||||
]
|
||||
deptColumns.value = [topDepts]
|
||||
}
|
||||
}
|
||||
|
||||
/** 构建带"选择当前"选项的子列表 */
|
||||
function buildChildrenWithCurrent(parentId: number) {
|
||||
const children = deptList.value.filter(item => item.parentId === parentId)
|
||||
// 添加"选择当前"选项,使用父节点 ID 的负数作为标识
|
||||
return [
|
||||
{ id: -parentId, name: '✓ 选择当前' },
|
||||
...children,
|
||||
]
|
||||
}
|
||||
|
||||
/** 加载部门列表 */
|
||||
async function loadDeptList() {
|
||||
deptList.value = await getSimpleDeptList()
|
||||
@@ -122,7 +132,7 @@ function buildColumnsForPath(path: number[]) {
|
||||
const parentId = path[i]
|
||||
const children = deptList.value.filter(item => item.parentId === parentId)
|
||||
if (children.length > 0) {
|
||||
columns.push(children.map(item => ({ value: item.id, label: item.name })))
|
||||
columns.push(children)
|
||||
}
|
||||
}
|
||||
deptColumns.value = columns
|
||||
@@ -130,13 +140,14 @@ function buildColumnsForPath(path: number[]) {
|
||||
|
||||
/** 列变化 */
|
||||
function handleColumnChange({ selectedItem, resolve, finish }: any) {
|
||||
if (selectedItem.value === 0) {
|
||||
// 选择顶级部门或"选择当前",结束
|
||||
if (selectedItem.id === 0 || selectedItem.id < 0) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
const children = deptList.value.filter(item => item.parentId === selectedItem.value)
|
||||
const children = deptList.value.filter(item => item.parentId === selectedItem.id)
|
||||
if (children.length > 0) {
|
||||
resolve(children.map(item => ({ value: item.id, label: item.name })))
|
||||
resolve(buildChildrenWithCurrent(selectedItem.id))
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
@@ -144,13 +155,23 @@ function handleColumnChange({ selectedItem, resolve, finish }: any) {
|
||||
|
||||
/** 格式化显示 */
|
||||
function displayFormat(selectedItems: any[]) {
|
||||
return selectedItems.map(item => item.label).join('/')
|
||||
// 过滤掉"选择当前"选项
|
||||
return selectedItems
|
||||
.filter(item => item.id >= 0)
|
||||
.map(item => item.name)
|
||||
.join('/')
|
||||
}
|
||||
|
||||
/** 确认选择 */
|
||||
function handleConfirm({ value }: { value: number[] }) {
|
||||
if (value && value.length > 0) {
|
||||
emit('update:modelValue', value[value.length - 1])
|
||||
const lastValue = value[value.length - 1]
|
||||
// 如果选择的是"选择当前"(负数 ID),取其绝对值作为实际选中的部门 ID
|
||||
if (lastValue < 0) {
|
||||
emit('update:modelValue', Math.abs(lastValue))
|
||||
} else {
|
||||
emit('update:modelValue', lastValue)
|
||||
}
|
||||
} else {
|
||||
// 如果允许 root,默认顶级 0;否则 undefined
|
||||
emit('update:modelValue', props.showRoot ? 0 : undefined)
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
label="上级菜单"
|
||||
label-width="180rpx"
|
||||
:columns="menuColumns"
|
||||
value-key="id"
|
||||
label-key="name"
|
||||
:column-change="handleColumnChange"
|
||||
:display-format="displayFormat"
|
||||
@confirm="handleConfirm"
|
||||
@@ -50,8 +52,8 @@ async function loadMenuList() {
|
||||
// 构建第一列数据(主类目 + 顶级菜单)
|
||||
const topMenus = menuList.value.filter(item => item.parentId === 0)
|
||||
menuColumns.value = [[
|
||||
{ value: 0, label: '主类目' },
|
||||
...topMenus.map(item => ({ value: item.id, label: item.name })),
|
||||
{ id: 0, name: '主类目' },
|
||||
...topMenus,
|
||||
]]
|
||||
// 如果有初始值,回显
|
||||
if (props.modelValue !== undefined && props.modelValue !== 0) {
|
||||
@@ -101,22 +103,32 @@ function buildColumnsForPath(path: number[]) {
|
||||
}
|
||||
const children = menuList.value.filter(item => item.parentId === parentId)
|
||||
if (children.length > 0) {
|
||||
columns.push(children.map(item => ({ value: item.id, label: item.name })))
|
||||
columns.push(children)
|
||||
}
|
||||
}
|
||||
menuColumns.value = columns
|
||||
}
|
||||
|
||||
/** 构建带"选择当前"选项的子列表 */
|
||||
function buildChildrenWithCurrent(parentId: number) {
|
||||
const children = menuList.value.filter(item => item.parentId === parentId)
|
||||
// 添加"选择当前"选项,使用父节点 ID 的负数作为标识
|
||||
return [
|
||||
{ id: -parentId, name: '✓ 选择当前' },
|
||||
...children,
|
||||
]
|
||||
}
|
||||
|
||||
/** 列变化 */
|
||||
function handleColumnChange({ selectedItem, resolve, finish }: any) {
|
||||
if (selectedItem.value === 0) {
|
||||
// 选择主类目,结束
|
||||
// 选择主类目或"选择当前",结束
|
||||
if (selectedItem.id === 0 || selectedItem.id < 0) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
const children = menuList.value.filter(item => item.parentId === selectedItem.value)
|
||||
const children = menuList.value.filter(item => item.parentId === selectedItem.id)
|
||||
if (children.length > 0) {
|
||||
resolve(children.map(item => ({ value: item.id, label: item.name })))
|
||||
resolve(buildChildrenWithCurrent(selectedItem.id))
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
@@ -124,13 +136,23 @@ function handleColumnChange({ selectedItem, resolve, finish }: any) {
|
||||
|
||||
/** 格式化显示 */
|
||||
function displayFormat(selectedItems: any[]) {
|
||||
return selectedItems.map(item => item.label).join(' / ')
|
||||
// 过滤掉"选择当前"选项
|
||||
return selectedItems
|
||||
.filter(item => item.id >= 0)
|
||||
.map(item => item.name)
|
||||
.join(' / ')
|
||||
}
|
||||
|
||||
/** 确认选择 */
|
||||
function handleConfirm({ value }: { value: number[] }) {
|
||||
if (value && value.length > 0) {
|
||||
emit('update:modelValue', value[value.length - 1])
|
||||
const lastValue = value[value.length - 1]
|
||||
// 如果选择的是"选择当前"(负数 ID),取其绝对值作为实际选中的菜单 ID
|
||||
if (lastValue < 0) {
|
||||
emit('update:modelValue', Math.abs(lastValue))
|
||||
} else {
|
||||
emit('update:modelValue', lastValue)
|
||||
}
|
||||
} else {
|
||||
emit('update:modelValue', 0)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
v-model="selectedIds"
|
||||
label="岗位"
|
||||
label-width="180rpx"
|
||||
:columns="columns"
|
||||
:columns="postList"
|
||||
value-key="id"
|
||||
label-key="name"
|
||||
type="checkbox"
|
||||
filterable
|
||||
@confirm="handleConfirm"
|
||||
@@ -12,7 +14,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Post } from '@/api/system/post'
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import { getSimplePostList } from '@/api/system/post'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -26,14 +28,6 @@ const emit = defineEmits<{
|
||||
const postList = ref<Post[]>([])
|
||||
const selectedIds = ref<number[]>([])
|
||||
|
||||
/** 构建 columns 数据 */
|
||||
const columns = computed(() => {
|
||||
return postList.value.map(item => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}))
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
|
||||
Reference in New Issue
Block a user