fix(system): 修复菜单树半选父节点权限丢失
- 回显时还原完整选中节点,提交时补齐祖先菜单 - 去重 Tree 级联选择产生的重复节点 - 对齐五端租户套餐菜单接口与详情回填 - 修复五端租户套餐及角色菜单授权 - 补全租户套餐详情 API 返回类型 - 增加 Tree 工具和组件回归测试
This commit is contained in:
@@ -27,7 +27,9 @@ export function getTenantPackagePage(params: PageParam) {
|
||||
|
||||
/** 查询租户套餐详情 */
|
||||
export function getTenantPackage(id: number) {
|
||||
return requestClient.get(`/system/tenant-package/get?id=${id}`);
|
||||
return requestClient.get<SystemTenantPackageApi.TenantPackage>(
|
||||
`/system/tenant-package/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 新增租户套餐 */
|
||||
|
||||
@@ -8,7 +8,11 @@ import { nextTick, ref } from 'vue';
|
||||
|
||||
import { Tree, useVbenModal } from '@vben/common-ui';
|
||||
import { SystemMenuTypeEnum } from '@vben/constants';
|
||||
import { handleTree } from '@vben/utils';
|
||||
import {
|
||||
getTreeCheckedValues,
|
||||
getTreeValuesWithAncestors,
|
||||
handleTree,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { Checkbox, message, Spin } from 'ant-design-vue';
|
||||
|
||||
@@ -52,7 +56,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
try {
|
||||
await assignRoleMenu({
|
||||
roleId: data.id,
|
||||
menuIds: data.menuIds,
|
||||
menuIds: getTreeValuesWithAncestors(
|
||||
menuTree.value,
|
||||
data.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
),
|
||||
});
|
||||
// 关闭并提示
|
||||
await modalApi.close();
|
||||
@@ -76,7 +84,10 @@ const [Modal, modalApi] = useVbenModal({
|
||||
try {
|
||||
// 加载角色菜单
|
||||
const menuIds = await getRoleMenuList(data.id);
|
||||
await formApi.setFieldValue('menuIds', menuIds);
|
||||
await formApi.setFieldValue(
|
||||
'menuIds',
|
||||
getTreeCheckedValues(menuTree.value, menuIds, (menu) => menu.id),
|
||||
);
|
||||
|
||||
await formApi.setValues(data);
|
||||
} finally {
|
||||
|
||||
@@ -5,12 +5,16 @@ import type { SystemTenantPackageApi } from '#/api/system/tenant-package';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { Tree, useVbenModal } from '@vben/common-ui';
|
||||
import { handleTree } from '@vben/utils';
|
||||
import {
|
||||
getTreeCheckedValues,
|
||||
getTreeValuesWithAncestors,
|
||||
handleTree,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { Checkbox, message, Spin } from 'ant-design-vue';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { getMenuList } from '#/api/system/menu';
|
||||
import { getSimpleMenusList } from '#/api/system/menu';
|
||||
import {
|
||||
createTenantPackage,
|
||||
getTenantPackage,
|
||||
@@ -56,6 +60,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
// 提交表单
|
||||
const data =
|
||||
(await formApi.getValues()) as SystemTenantPackageApi.TenantPackage;
|
||||
data.menuIds = getTreeValuesWithAncestors(
|
||||
menuTree.value,
|
||||
data.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
);
|
||||
try {
|
||||
await (formData.value
|
||||
? updateTenantPackage(data)
|
||||
@@ -82,8 +91,16 @@ const [Modal, modalApi] = useVbenModal({
|
||||
}
|
||||
modalApi.lock();
|
||||
try {
|
||||
formData.value = await getTenantPackage(data.id);
|
||||
await formApi.setValues(data);
|
||||
const detail = await getTenantPackage(data.id);
|
||||
formData.value = detail;
|
||||
await formApi.setValues({
|
||||
...detail,
|
||||
menuIds: getTreeCheckedValues(
|
||||
menuTree.value,
|
||||
detail.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
),
|
||||
});
|
||||
} finally {
|
||||
modalApi.unlock();
|
||||
}
|
||||
@@ -94,7 +111,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
async function loadMenuTree() {
|
||||
menuLoading.value = true;
|
||||
try {
|
||||
const data = await getMenuList();
|
||||
const data = await getSimpleMenusList();
|
||||
menuTree.value = handleTree(data) as SystemMenuApi.Menu[];
|
||||
} finally {
|
||||
menuLoading.value = false;
|
||||
|
||||
@@ -27,7 +27,9 @@ export function getTenantPackagePage(params: PageParam) {
|
||||
|
||||
/** 查询租户套餐详情 */
|
||||
export function getTenantPackage(id: number) {
|
||||
return requestClient.get(`/system/tenant-package/get?id=${id}`);
|
||||
return requestClient.get<SystemTenantPackageApi.TenantPackage>(
|
||||
`/system/tenant-package/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 新增租户套餐 */
|
||||
|
||||
@@ -8,7 +8,11 @@ import { nextTick, ref } from 'vue';
|
||||
|
||||
import { Tree, useVbenModal } from '@vben/common-ui';
|
||||
import { SystemMenuTypeEnum } from '@vben/constants';
|
||||
import { handleTree } from '@vben/utils';
|
||||
import {
|
||||
getTreeCheckedValues,
|
||||
getTreeValuesWithAncestors,
|
||||
handleTree,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { Checkbox, message, Spin } from 'antdv-next';
|
||||
|
||||
@@ -52,7 +56,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
try {
|
||||
await assignRoleMenu({
|
||||
roleId: data.id,
|
||||
menuIds: data.menuIds,
|
||||
menuIds: getTreeValuesWithAncestors(
|
||||
menuTree.value,
|
||||
data.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
),
|
||||
});
|
||||
// 关闭并提示
|
||||
await modalApi.close();
|
||||
@@ -76,7 +84,10 @@ const [Modal, modalApi] = useVbenModal({
|
||||
try {
|
||||
// 加载角色菜单
|
||||
const menuIds = await getRoleMenuList(data.id);
|
||||
await formApi.setFieldValue('menuIds', menuIds);
|
||||
await formApi.setFieldValue(
|
||||
'menuIds',
|
||||
getTreeCheckedValues(menuTree.value, menuIds, (menu) => menu.id),
|
||||
);
|
||||
|
||||
await formApi.setValues(data);
|
||||
} finally {
|
||||
|
||||
@@ -5,12 +5,16 @@ import type { SystemTenantPackageApi } from '#/api/system/tenant-package';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { Tree, useVbenModal } from '@vben/common-ui';
|
||||
import { handleTree } from '@vben/utils';
|
||||
import {
|
||||
getTreeCheckedValues,
|
||||
getTreeValuesWithAncestors,
|
||||
handleTree,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { Checkbox, message, Spin } from 'antdv-next';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { getMenuList } from '#/api/system/menu';
|
||||
import { getSimpleMenusList } from '#/api/system/menu';
|
||||
import {
|
||||
createTenantPackage,
|
||||
getTenantPackage,
|
||||
@@ -56,6 +60,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
// 提交表单
|
||||
const data =
|
||||
(await formApi.getValues()) as SystemTenantPackageApi.TenantPackage;
|
||||
data.menuIds = getTreeValuesWithAncestors(
|
||||
menuTree.value,
|
||||
data.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
);
|
||||
try {
|
||||
await (formData.value
|
||||
? updateTenantPackage(data)
|
||||
@@ -82,8 +91,16 @@ const [Modal, modalApi] = useVbenModal({
|
||||
}
|
||||
modalApi.lock();
|
||||
try {
|
||||
formData.value = await getTenantPackage(data.id);
|
||||
await formApi.setValues(data);
|
||||
const detail = await getTenantPackage(data.id);
|
||||
formData.value = detail;
|
||||
await formApi.setValues({
|
||||
...detail,
|
||||
menuIds: getTreeCheckedValues(
|
||||
menuTree.value,
|
||||
detail.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
),
|
||||
});
|
||||
} finally {
|
||||
modalApi.unlock();
|
||||
}
|
||||
@@ -94,7 +111,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
async function loadMenuTree() {
|
||||
menuLoading.value = true;
|
||||
try {
|
||||
const data = await getMenuList();
|
||||
const data = await getSimpleMenusList();
|
||||
menuTree.value = handleTree(data) as SystemMenuApi.Menu[];
|
||||
} finally {
|
||||
menuLoading.value = false;
|
||||
|
||||
@@ -27,7 +27,9 @@ export function getTenantPackagePage(params: PageParam) {
|
||||
|
||||
/** 查询租户套餐详情 */
|
||||
export function getTenantPackage(id: number) {
|
||||
return requestClient.get(`/system/tenant-package/get?id=${id}`);
|
||||
return requestClient.get<SystemTenantPackageApi.TenantPackage>(
|
||||
`/system/tenant-package/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 新增租户套餐 */
|
||||
|
||||
@@ -8,7 +8,11 @@ import { nextTick, ref } from 'vue';
|
||||
|
||||
import { Tree, useVbenModal } from '@vben/common-ui';
|
||||
import { SystemMenuTypeEnum } from '@vben/constants';
|
||||
import { handleTree } from '@vben/utils';
|
||||
import {
|
||||
getTreeCheckedValues,
|
||||
getTreeValuesWithAncestors,
|
||||
handleTree,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { ElCheckbox, ElMessage } from 'element-plus';
|
||||
|
||||
@@ -52,7 +56,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
try {
|
||||
await assignRoleMenu({
|
||||
roleId: data.id,
|
||||
menuIds: data.menuIds,
|
||||
menuIds: getTreeValuesWithAncestors(
|
||||
menuTree.value,
|
||||
data.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
),
|
||||
});
|
||||
// 关闭并提示
|
||||
await modalApi.close();
|
||||
@@ -76,7 +84,10 @@ const [Modal, modalApi] = useVbenModal({
|
||||
try {
|
||||
// 加载角色菜单
|
||||
const menuIds = await getRoleMenuList(data.id);
|
||||
await formApi.setFieldValue('menuIds', menuIds);
|
||||
await formApi.setFieldValue(
|
||||
'menuIds',
|
||||
getTreeCheckedValues(menuTree.value, menuIds, (menu) => menu.id),
|
||||
);
|
||||
|
||||
await formApi.setValues(data);
|
||||
} finally {
|
||||
|
||||
@@ -5,12 +5,16 @@ import type { SystemTenantPackageApi } from '#/api/system/tenant-package';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { Tree, useVbenModal } from '@vben/common-ui';
|
||||
import { handleTree } from '@vben/utils';
|
||||
import {
|
||||
getTreeCheckedValues,
|
||||
getTreeValuesWithAncestors,
|
||||
handleTree,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { ElCheckbox, ElMessage } from 'element-plus';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { getMenuList } from '#/api/system/menu';
|
||||
import { getSimpleMenusList } from '#/api/system/menu';
|
||||
import {
|
||||
createTenantPackage,
|
||||
getTenantPackage,
|
||||
@@ -56,6 +60,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
// 提交表单
|
||||
const data =
|
||||
(await formApi.getValues()) as SystemTenantPackageApi.TenantPackage;
|
||||
data.menuIds = getTreeValuesWithAncestors(
|
||||
menuTree.value,
|
||||
data.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
);
|
||||
try {
|
||||
await (formData.value
|
||||
? updateTenantPackage(data)
|
||||
@@ -82,8 +91,16 @@ const [Modal, modalApi] = useVbenModal({
|
||||
}
|
||||
modalApi.lock();
|
||||
try {
|
||||
formData.value = await getTenantPackage(data.id);
|
||||
await formApi.setValues(data);
|
||||
const detail = await getTenantPackage(data.id);
|
||||
formData.value = detail;
|
||||
await formApi.setValues({
|
||||
...detail,
|
||||
menuIds: getTreeCheckedValues(
|
||||
menuTree.value,
|
||||
detail.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
),
|
||||
});
|
||||
} finally {
|
||||
modalApi.unlock();
|
||||
}
|
||||
@@ -94,7 +111,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
async function loadMenuTree() {
|
||||
menuLoading.value = true;
|
||||
try {
|
||||
const data = await getMenuList();
|
||||
const data = await getSimpleMenusList();
|
||||
menuTree.value = handleTree(data) as SystemMenuApi.Menu[];
|
||||
} finally {
|
||||
menuLoading.value = false;
|
||||
|
||||
@@ -27,7 +27,9 @@ export function getTenantPackagePage(params: PageParam) {
|
||||
|
||||
/** 查询租户套餐详情 */
|
||||
export function getTenantPackage(id: number) {
|
||||
return requestClient.get(`/system/tenant-package/get?id=${id}`);
|
||||
return requestClient.get<SystemTenantPackageApi.TenantPackage>(
|
||||
`/system/tenant-package/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 新增租户套餐 */
|
||||
|
||||
@@ -8,7 +8,11 @@ import { nextTick, ref } from 'vue';
|
||||
|
||||
import { Tree, useVbenModal } from '@vben/common-ui';
|
||||
import { SystemMenuTypeEnum } from '@vben/constants';
|
||||
import { handleTree } from '@vben/utils';
|
||||
import {
|
||||
getTreeCheckedValues,
|
||||
getTreeValuesWithAncestors,
|
||||
handleTree,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { NCheckbox, NSpin } from 'naive-ui';
|
||||
|
||||
@@ -53,7 +57,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
try {
|
||||
await assignRoleMenu({
|
||||
roleId: data.id,
|
||||
menuIds: data.menuIds,
|
||||
menuIds: getTreeValuesWithAncestors(
|
||||
menuTree.value,
|
||||
data.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
),
|
||||
});
|
||||
// 关闭并提示
|
||||
await modalApi.close();
|
||||
@@ -77,7 +85,10 @@ const [Modal, modalApi] = useVbenModal({
|
||||
try {
|
||||
// 加载角色菜单
|
||||
const menuIds = await getRoleMenuList(data.id);
|
||||
await formApi.setFieldValue('menuIds', menuIds);
|
||||
await formApi.setFieldValue(
|
||||
'menuIds',
|
||||
getTreeCheckedValues(menuTree.value, menuIds, (menu) => menu.id),
|
||||
);
|
||||
|
||||
await formApi.setValues(data);
|
||||
} finally {
|
||||
|
||||
@@ -5,13 +5,17 @@ import type { SystemTenantPackageApi } from '#/api/system/tenant-package';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { Tree, useVbenModal } from '@vben/common-ui';
|
||||
import { handleTree } from '@vben/utils';
|
||||
import {
|
||||
getTreeCheckedValues,
|
||||
getTreeValuesWithAncestors,
|
||||
handleTree,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { NCheckbox, NSpin } from 'naive-ui';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { message } from '#/adapter/naive';
|
||||
import { getMenuList } from '#/api/system/menu';
|
||||
import { getSimpleMenusList } from '#/api/system/menu';
|
||||
import {
|
||||
createTenantPackage,
|
||||
getTenantPackage,
|
||||
@@ -57,6 +61,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
// 提交表单
|
||||
const data =
|
||||
(await formApi.getValues()) as SystemTenantPackageApi.TenantPackage;
|
||||
data.menuIds = getTreeValuesWithAncestors(
|
||||
menuTree.value,
|
||||
data.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
);
|
||||
try {
|
||||
await (formData.value
|
||||
? updateTenantPackage(data)
|
||||
@@ -83,8 +92,16 @@ const [Modal, modalApi] = useVbenModal({
|
||||
}
|
||||
modalApi.lock();
|
||||
try {
|
||||
formData.value = await getTenantPackage(data.id);
|
||||
await formApi.setValues(data);
|
||||
const detail = await getTenantPackage(data.id);
|
||||
formData.value = detail;
|
||||
await formApi.setValues({
|
||||
...detail,
|
||||
menuIds: getTreeCheckedValues(
|
||||
menuTree.value,
|
||||
detail.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
),
|
||||
});
|
||||
} finally {
|
||||
modalApi.unlock();
|
||||
}
|
||||
@@ -95,7 +112,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
async function loadMenuTree() {
|
||||
menuLoading.value = true;
|
||||
try {
|
||||
const data = await getMenuList();
|
||||
const data = await getSimpleMenusList();
|
||||
menuTree.value = handleTree(data) as SystemMenuApi.Menu[];
|
||||
} finally {
|
||||
menuLoading.value = false;
|
||||
|
||||
@@ -27,7 +27,9 @@ export function getTenantPackagePage(params: PageParam) {
|
||||
|
||||
/** 查询租户套餐详情 */
|
||||
export function getTenantPackage(id: number) {
|
||||
return requestClient.get(`/system/tenant-package/get?id=${id}`);
|
||||
return requestClient.get<SystemTenantPackageApi.TenantPackage>(
|
||||
`/system/tenant-package/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 新增租户套餐 */
|
||||
|
||||
@@ -8,7 +8,11 @@ import { nextTick, ref } from 'vue';
|
||||
|
||||
import { Tree, useVbenModal } from '@vben/common-ui';
|
||||
import { SystemMenuTypeEnum } from '@vben/constants';
|
||||
import { handleTree } from '@vben/utils';
|
||||
import {
|
||||
getTreeCheckedValues,
|
||||
getTreeValuesWithAncestors,
|
||||
handleTree,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { Checkbox } from 'tdesign-vue-next';
|
||||
|
||||
@@ -53,7 +57,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
try {
|
||||
await assignRoleMenu({
|
||||
roleId: data.id,
|
||||
menuIds: data.menuIds,
|
||||
menuIds: getTreeValuesWithAncestors(
|
||||
menuTree.value,
|
||||
data.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
),
|
||||
});
|
||||
// 关闭并提示
|
||||
await modalApi.close();
|
||||
@@ -77,7 +85,10 @@ const [Modal, modalApi] = useVbenModal({
|
||||
try {
|
||||
// 加载角色菜单
|
||||
const menuIds = await getRoleMenuList(data.id);
|
||||
await formApi.setFieldValue('menuIds', menuIds);
|
||||
await formApi.setFieldValue(
|
||||
'menuIds',
|
||||
getTreeCheckedValues(menuTree.value, menuIds, (menu) => menu.id),
|
||||
);
|
||||
|
||||
await formApi.setValues(data);
|
||||
} finally {
|
||||
|
||||
@@ -5,13 +5,17 @@ import type { SystemTenantPackageApi } from '#/api/system/tenant-package';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { Tree, useVbenModal } from '@vben/common-ui';
|
||||
import { handleTree } from '@vben/utils';
|
||||
import {
|
||||
getTreeCheckedValues,
|
||||
getTreeValuesWithAncestors,
|
||||
handleTree,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { Checkbox } from 'tdesign-vue-next';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { message } from '#/adapter/tdesign';
|
||||
import { getMenuList } from '#/api/system/menu';
|
||||
import { getSimpleMenusList } from '#/api/system/menu';
|
||||
import {
|
||||
createTenantPackage,
|
||||
getTenantPackage,
|
||||
@@ -57,6 +61,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||
// 提交表单
|
||||
const data =
|
||||
(await formApi.getValues()) as SystemTenantPackageApi.TenantPackage;
|
||||
data.menuIds = getTreeValuesWithAncestors(
|
||||
menuTree.value,
|
||||
data.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
);
|
||||
try {
|
||||
await (formData.value
|
||||
? updateTenantPackage(data)
|
||||
@@ -83,8 +92,16 @@ const [Modal, modalApi] = useVbenModal({
|
||||
}
|
||||
modalApi.lock();
|
||||
try {
|
||||
formData.value = await getTenantPackage(data.id);
|
||||
await formApi.setValues(data);
|
||||
const detail = await getTenantPackage(data.id);
|
||||
formData.value = detail;
|
||||
await formApi.setValues({
|
||||
...detail,
|
||||
menuIds: getTreeCheckedValues(
|
||||
menuTree.value,
|
||||
detail.menuIds ?? [],
|
||||
(menu) => menu.id,
|
||||
),
|
||||
});
|
||||
} finally {
|
||||
modalApi.unlock();
|
||||
}
|
||||
@@ -95,7 +112,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
async function loadMenuTree() {
|
||||
menuLoading.value = true;
|
||||
try {
|
||||
const data = await getMenuList();
|
||||
const data = await getSimpleMenusList();
|
||||
menuTree.value = handleTree(data) as SystemMenuApi.Menu[];
|
||||
} finally {
|
||||
menuLoading.value = false;
|
||||
|
||||
Reference in New Issue
Block a user