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