refactor: modal select
parent
5e77558efd
commit
7e8f2a1328
|
@ -9,7 +9,7 @@ import { ref } from 'vue';
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
import { handleTree } from '@vben/utils';
|
import { handleTree } from '@vben/utils';
|
||||||
|
|
||||||
import { Button, Card, Col, Row, Tree } from 'ant-design-vue';
|
import { Card, Col, Row, Tree } from 'ant-design-vue';
|
||||||
|
|
||||||
import { getSimpleDeptList } from '#/api/system/dept';
|
import { getSimpleDeptList } from '#/api/system/dept';
|
||||||
|
|
||||||
|
@ -41,24 +41,6 @@ const emit = defineEmits<{
|
||||||
confirm: [deptList: SystemDeptApi.Dept[]];
|
confirm: [deptList: SystemDeptApi.Dept[]];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// 对话框配置
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
|
||||||
title: props.title,
|
|
||||||
async onOpenChange(isOpen: boolean) {
|
|
||||||
if (!isOpen) {
|
|
||||||
resetData();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
modalApi.setState({ loading: true });
|
|
||||||
try {
|
|
||||||
deptData.value = await getSimpleDeptList();
|
|
||||||
deptTree.value = handleTree(deptData.value) as DataNode[];
|
|
||||||
} finally {
|
|
||||||
modalApi.setState({ loading: false });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
destroyOnClose: true,
|
|
||||||
});
|
|
||||||
type checkedKeys = number[] | { checked: number[]; halfChecked: number[] };
|
type checkedKeys = number[] | { checked: number[]; halfChecked: number[] };
|
||||||
// 部门树形结构
|
// 部门树形结构
|
||||||
const deptTree = ref<DataNode[]>([]);
|
const deptTree = ref<DataNode[]>([]);
|
||||||
|
@ -67,14 +49,40 @@ const selectedDeptIds = ref<checkedKeys>([]);
|
||||||
// 部门数据
|
// 部门数据
|
||||||
const deptData = ref<SystemDeptApi.Dept[]>([]);
|
const deptData = ref<SystemDeptApi.Dept[]>([]);
|
||||||
|
|
||||||
/** 打开对话框 */
|
// 对话框配置
|
||||||
const open = async (selectedList?: SystemDeptApi.Dept[]) => {
|
const [Modal, modalApi] = useVbenModal({
|
||||||
modalApi.open();
|
async onConfirm() {
|
||||||
|
// 获取选中的部门ID
|
||||||
|
const selectedIds: number[] = Array.isArray(selectedDeptIds.value)
|
||||||
|
? selectedDeptIds.value
|
||||||
|
: selectedDeptIds.value.checked || [];
|
||||||
|
const deptArray = deptData.value.filter((dept) =>
|
||||||
|
selectedIds.includes(dept.id!),
|
||||||
|
);
|
||||||
|
emit('confirm', deptArray);
|
||||||
|
// 关闭并提示
|
||||||
|
await modalApi.close();
|
||||||
|
},
|
||||||
|
async onOpenChange(isOpen: boolean) {
|
||||||
|
if (!isOpen) {
|
||||||
|
deptTree.value = [];
|
||||||
|
selectedDeptIds.value = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 加载数据
|
||||||
|
const data = modalApi.getData();
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
modalApi.lock();
|
||||||
|
try {
|
||||||
|
deptData.value = await getSimpleDeptList();
|
||||||
|
deptTree.value = handleTree(deptData.value) as DataNode[];
|
||||||
// // 设置已选择的部门
|
// // 设置已选择的部门
|
||||||
if (selectedList?.length) {
|
if (data.selectedList?.length) {
|
||||||
const selectedIds = selectedList
|
const selectedIds = data.selectedList
|
||||||
.map((dept) => dept.id)
|
.map((dept: SystemDeptApi.Dept) => dept.id)
|
||||||
.filter((id): id is number => id !== undefined);
|
.filter((id: number) => id !== undefined);
|
||||||
selectedDeptIds.value = props.checkStrictly
|
selectedDeptIds.value = props.checkStrictly
|
||||||
? {
|
? {
|
||||||
checked: selectedIds,
|
checked: selectedIds,
|
||||||
|
@ -82,10 +90,15 @@ const open = async (selectedList?: SystemDeptApi.Dept[]) => {
|
||||||
}
|
}
|
||||||
: selectedIds;
|
: selectedIds;
|
||||||
}
|
}
|
||||||
};
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destroyOnClose: true,
|
||||||
|
});
|
||||||
|
|
||||||
/** 处理选中状态变化 */
|
/** 处理选中状态变化 */
|
||||||
const handleCheck = () => {
|
function handleCheck() {
|
||||||
if (!props.multiple) {
|
if (!props.multiple) {
|
||||||
// 单选模式下,只保留最后选择的节点
|
// 单选模式下,只保留最后选择的节点
|
||||||
if (Array.isArray(selectedDeptIds.value)) {
|
if (Array.isArray(selectedDeptIds.value)) {
|
||||||
|
@ -106,37 +119,10 @@ const handleCheck = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 提交选择 */
|
|
||||||
const handleConfirm = async () => {
|
|
||||||
// 获取选中的部门ID
|
|
||||||
const selectedIds: number[] = Array.isArray(selectedDeptIds.value)
|
|
||||||
? selectedDeptIds.value
|
|
||||||
: selectedDeptIds.value.checked || [];
|
|
||||||
const deptArray = deptData.value.filter((dept) =>
|
|
||||||
selectedIds.includes(dept.id!),
|
|
||||||
);
|
|
||||||
// 关闭并提示
|
|
||||||
await modalApi.close();
|
|
||||||
emit('confirm', deptArray);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
modalApi.close();
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 重置数据 */
|
|
||||||
const resetData = () => {
|
|
||||||
deptTree.value = [];
|
|
||||||
selectedDeptIds.value = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 提供 open 方法,用于打开对话框 */
|
|
||||||
defineExpose({ open });
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Modal>
|
<Modal :title="title" key="dept-select-modal" class="w-[40%]">
|
||||||
<Row class="h-full">
|
<Row class="h-full">
|
||||||
<Col :span="24">
|
<Col :span="24">
|
||||||
<Card class="h-full">
|
<Card class="h-full">
|
||||||
|
@ -153,9 +139,5 @@ defineExpose({ open });
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<template #footer>
|
|
||||||
<Button @click="handleCancel">{{ cancelText }}</Button>
|
|
||||||
<Button type="primary" @click="handleConfirm">{{ confirmText }}</Button>
|
|
||||||
</template>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -17,7 +17,6 @@ import {
|
||||||
message,
|
message,
|
||||||
Pagination,
|
Pagination,
|
||||||
Row,
|
Row,
|
||||||
Spin,
|
|
||||||
Transfer,
|
Transfer,
|
||||||
Tree,
|
Tree,
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
|
@ -66,16 +65,66 @@ const expandedKeys = ref<Key[]>([]);
|
||||||
const selectedDeptId = ref<number>();
|
const selectedDeptId = ref<number>();
|
||||||
const deptSearchKeys = ref('');
|
const deptSearchKeys = ref('');
|
||||||
|
|
||||||
// 加载状态
|
|
||||||
const loading = ref(false);
|
|
||||||
|
|
||||||
// 用户数据管理
|
// 用户数据管理
|
||||||
const userList = ref<SystemUserApi.User[]>([]); // 存储所有已知用户
|
const userList = ref<SystemUserApi.User[]>([]); // 存储所有已知用户
|
||||||
const selectedUserIds = ref<string[]>([]);
|
const selectedUserIds = ref<string[]>([]);
|
||||||
|
|
||||||
|
// 弹窗配置
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
onCancel: handleCancel,
|
||||||
|
onClosed: handleClosed,
|
||||||
|
async onOpenChange(isOpen: boolean) {
|
||||||
|
if (!isOpen) {
|
||||||
|
resetData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 加载数据
|
||||||
|
const data = modalApi.getData();
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
modalApi.lock();
|
||||||
|
try {
|
||||||
|
// 加载部门数据
|
||||||
|
const deptData = await getSimpleDeptList();
|
||||||
|
deptList.value = deptData;
|
||||||
|
const treeData = handleTree(deptData);
|
||||||
|
deptTree.value = treeData.map((node) => processDeptNode(node));
|
||||||
|
expandedKeys.value = deptTree.value.map((node) => node.key);
|
||||||
|
|
||||||
|
// 加载初始用户数据
|
||||||
|
await loadUserData(1, leftListState.value.pagination.pageSize);
|
||||||
|
|
||||||
|
// 设置已选用户
|
||||||
|
if (data.userIds?.length) {
|
||||||
|
selectedUserIds.value = data.userIds.map(String);
|
||||||
|
// 加载已选用户的完整信息 TODO 目前接口暂不支持 多个用户ID 查询, 需要后端支持
|
||||||
|
const { list } = await getUserPage({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100, // 临时使用固定值确保能加载所有已选用户
|
||||||
|
userIds: data.userIds,
|
||||||
|
});
|
||||||
|
// 使用 Map 来去重,以用户 ID 为 key
|
||||||
|
const userMap = new Map(userList.value.map((user) => [user.id, user]));
|
||||||
|
list.forEach((user) => {
|
||||||
|
if (!userMap.has(user.id)) {
|
||||||
|
userMap.set(user.id, user);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
userList.value = [...userMap.values()];
|
||||||
|
updateRightListData();
|
||||||
|
}
|
||||||
|
|
||||||
|
modalApi.open();
|
||||||
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destroyOnClose: true,
|
||||||
|
});
|
||||||
|
|
||||||
// 左侧列表状态
|
// 左侧列表状态
|
||||||
const leftListState = ref({
|
const leftListState = ref({
|
||||||
loading: false,
|
|
||||||
searchValue: '',
|
searchValue: '',
|
||||||
dataSource: [] as SystemUserApi.User[],
|
dataSource: [] as SystemUserApi.User[],
|
||||||
pagination: {
|
pagination: {
|
||||||
|
@ -145,8 +194,7 @@ const filteredDeptTree = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// 加载用户数据
|
// 加载用户数据
|
||||||
const loadUserData = async (pageNo: number, pageSize: number) => {
|
async function loadUserData(pageNo: number, pageSize: number) {
|
||||||
leftListState.value.loading = true;
|
|
||||||
try {
|
try {
|
||||||
const { list, total } = await getUserPage({
|
const { list, total } = await getUserPage({
|
||||||
pageNo,
|
pageNo,
|
||||||
|
@ -167,13 +215,11 @@ const loadUserData = async (pageNo: number, pageSize: number) => {
|
||||||
if (newUsers.length > 0) {
|
if (newUsers.length > 0) {
|
||||||
userList.value.push(...newUsers);
|
userList.value.push(...newUsers);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {}
|
||||||
leftListState.value.loading = false;
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 更新右侧列表数据
|
// 更新右侧列表数据
|
||||||
const updateRightListData = () => {
|
function updateRightListData() {
|
||||||
// 使用 Set 来去重选中的用户ID
|
// 使用 Set 来去重选中的用户ID
|
||||||
const uniqueSelectedIds = new Set(selectedUserIds.value);
|
const uniqueSelectedIds = new Set(selectedUserIds.value);
|
||||||
|
|
||||||
|
@ -202,22 +248,22 @@ const updateRightListData = () => {
|
||||||
const endIndex = startIndex + pageSize;
|
const endIndex = startIndex + pageSize;
|
||||||
|
|
||||||
rightListState.value.dataSource = filteredUsers.slice(startIndex, endIndex);
|
rightListState.value.dataSource = filteredUsers.slice(startIndex, endIndex);
|
||||||
};
|
}
|
||||||
|
|
||||||
// 处理左侧分页变化
|
// 处理左侧分页变化
|
||||||
const handleLeftPaginationChange = async (page: number, pageSize: number) => {
|
async function handleLeftPaginationChange(page: number, pageSize: number) {
|
||||||
await loadUserData(page, pageSize);
|
await loadUserData(page, pageSize);
|
||||||
};
|
}
|
||||||
|
|
||||||
// 处理右侧分页变化
|
// 处理右侧分页变化
|
||||||
const handleRightPaginationChange = (page: number, pageSize: number) => {
|
function handleRightPaginationChange(page: number, pageSize: number) {
|
||||||
rightListState.value.pagination.current = page;
|
rightListState.value.pagination.current = page;
|
||||||
rightListState.value.pagination.pageSize = pageSize;
|
rightListState.value.pagination.pageSize = pageSize;
|
||||||
updateRightListData();
|
updateRightListData();
|
||||||
};
|
}
|
||||||
|
|
||||||
// 处理用户搜索
|
// 处理用户搜索
|
||||||
const handleUserSearch = async (direction: string, value: string) => {
|
async function handleUserSearch(direction: string, value: string) {
|
||||||
if (direction === 'left') {
|
if (direction === 'left') {
|
||||||
leftListState.value.searchValue = value;
|
leftListState.value.searchValue = value;
|
||||||
leftListState.value.pagination.current = 1;
|
leftListState.value.pagination.current = 1;
|
||||||
|
@ -227,18 +273,18 @@ const handleUserSearch = async (direction: string, value: string) => {
|
||||||
rightListState.value.pagination.current = 1;
|
rightListState.value.pagination.current = 1;
|
||||||
updateRightListData();
|
updateRightListData();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// 处理用户选择变化
|
// 处理用户选择变化
|
||||||
const handleUserChange = (targetKeys: string[]) => {
|
function handleUserChange(targetKeys: string[]) {
|
||||||
// 使用 Set 来去重选中的用户ID
|
// 使用 Set 来去重选中的用户ID
|
||||||
selectedUserIds.value = [...new Set(targetKeys)];
|
selectedUserIds.value = [...new Set(targetKeys)];
|
||||||
emit('update:value', selectedUserIds.value.map(Number));
|
emit('update:value', selectedUserIds.value.map(Number));
|
||||||
updateRightListData();
|
updateRightListData();
|
||||||
};
|
}
|
||||||
|
|
||||||
// 重置数据
|
// 重置数据
|
||||||
const resetData = () => {
|
function resetData() {
|
||||||
userList.value = [];
|
userList.value = [];
|
||||||
selectedUserIds.value = [];
|
selectedUserIds.value = [];
|
||||||
|
|
||||||
|
@ -249,7 +295,6 @@ const resetData = () => {
|
||||||
selectedUserIds.value = [];
|
selectedUserIds.value = [];
|
||||||
|
|
||||||
leftListState.value = {
|
leftListState.value = {
|
||||||
loading: false,
|
|
||||||
searchValue: '',
|
searchValue: '',
|
||||||
dataSource: [],
|
dataSource: [],
|
||||||
pagination: {
|
pagination: {
|
||||||
|
@ -268,61 +313,20 @@ const resetData = () => {
|
||||||
total: 0,
|
total: 0,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
// 打开弹窗
|
|
||||||
const open = async (userIds: string[]) => {
|
|
||||||
resetData();
|
|
||||||
loading.value = true;
|
|
||||||
try {
|
|
||||||
// 加载部门数据
|
|
||||||
const deptData = await getSimpleDeptList();
|
|
||||||
deptList.value = deptData;
|
|
||||||
const treeData = handleTree(deptData);
|
|
||||||
deptTree.value = treeData.map((node) => processDeptNode(node));
|
|
||||||
expandedKeys.value = deptTree.value.map((node) => node.key);
|
|
||||||
|
|
||||||
// 加载初始用户数据
|
|
||||||
await loadUserData(1, leftListState.value.pagination.pageSize);
|
|
||||||
|
|
||||||
// 设置已选用户
|
|
||||||
if (userIds?.length) {
|
|
||||||
selectedUserIds.value = userIds.map(String);
|
|
||||||
// 加载已选用户的完整信息 TODO 目前接口暂不支持 多个用户ID 查询, 需要后端支持
|
|
||||||
const { list } = await getUserPage({
|
|
||||||
pageNo: 1,
|
|
||||||
pageSize: 100, // 临时使用固定值确保能加载所有已选用户
|
|
||||||
userIds,
|
|
||||||
});
|
|
||||||
// 使用 Map 来去重,以用户 ID 为 key
|
|
||||||
const userMap = new Map(userList.value.map((user) => [user.id, user]));
|
|
||||||
list.forEach((user) => {
|
|
||||||
if (!userMap.has(user.id)) {
|
|
||||||
userMap.set(user.id, user);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
userList.value = [...userMap.values()];
|
|
||||||
updateRightListData();
|
|
||||||
}
|
|
||||||
|
|
||||||
modalApi.open();
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO 后端接口目前仅支持 username 检索, 筛选条件需要跟后端请求参数保持一致。
|
// TODO 后端接口目前仅支持 username 检索, 筛选条件需要跟后端请求参数保持一致。
|
||||||
const filterOption = (inputValue: string, option: any) => {
|
function filterOption(inputValue: string, option: any) {
|
||||||
return option.username.toLowerCase().includes(inputValue.toLowerCase());
|
return option.username.toLowerCase().includes(inputValue.toLowerCase());
|
||||||
};
|
}
|
||||||
|
|
||||||
// 处理部门树展开/折叠
|
// 处理部门树展开/折叠
|
||||||
const handleExpand = (keys: Key[]) => {
|
function handleExpand(keys: Key[]) {
|
||||||
expandedKeys.value = keys;
|
expandedKeys.value = keys;
|
||||||
};
|
}
|
||||||
|
|
||||||
// 处理部门搜索
|
// 处理部门搜索
|
||||||
const handleDeptSearch = (value: string) => {
|
function handleDeptSearch(value: string) {
|
||||||
deptSearchKeys.value = value;
|
deptSearchKeys.value = value;
|
||||||
|
|
||||||
// 如果有搜索结果,自动展开所有节点
|
// 如果有搜索结果,自动展开所有节点
|
||||||
|
@ -342,10 +346,10 @@ const handleDeptSearch = (value: string) => {
|
||||||
// 清空搜索时,只展开第一级节点
|
// 清空搜索时,只展开第一级节点
|
||||||
expandedKeys.value = deptTree.value.map((node) => node.key);
|
expandedKeys.value = deptTree.value.map((node) => node.key);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// 处理部门选择
|
// 处理部门选择
|
||||||
const handleDeptSelect = async (selectedKeys: Key[], _info: any) => {
|
async function handleDeptSelect(selectedKeys: Key[], _info: any) {
|
||||||
// 更新选中的部门ID
|
// 更新选中的部门ID
|
||||||
const newDeptId =
|
const newDeptId =
|
||||||
selectedKeys.length > 0 ? Number(selectedKeys[0]) : undefined;
|
selectedKeys.length > 0 ? Number(selectedKeys[0]) : undefined;
|
||||||
|
@ -356,10 +360,10 @@ const handleDeptSelect = async (selectedKeys: Key[], _info: any) => {
|
||||||
const { pageSize } = leftListState.value.pagination;
|
const { pageSize } = leftListState.value.pagination;
|
||||||
leftListState.value.pagination.current = 1;
|
leftListState.value.pagination.current = 1;
|
||||||
await loadUserData(1, pageSize);
|
await loadUserData(1, pageSize);
|
||||||
};
|
}
|
||||||
|
|
||||||
// 确认选择
|
// 确认选择
|
||||||
const handleConfirm = () => {
|
function handleConfirm() {
|
||||||
if (selectedUserIds.value.length === 0) {
|
if (selectedUserIds.value.length === 0) {
|
||||||
message.warning('请选择用户');
|
message.warning('请选择用户');
|
||||||
return;
|
return;
|
||||||
|
@ -371,50 +375,37 @@ const handleConfirm = () => {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
};
|
}
|
||||||
|
|
||||||
// 取消选择
|
// 取消选择
|
||||||
const handleCancel = () => {
|
function handleCancel() {
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
// 确保在动画结束后再重置数据
|
// 确保在动画结束后再重置数据
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
resetData();
|
resetData();
|
||||||
}, 300);
|
}, 300);
|
||||||
};
|
}
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
const handleClosed = () => {
|
function handleClosed() {
|
||||||
emit('closed');
|
emit('closed');
|
||||||
resetData();
|
resetData();
|
||||||
};
|
}
|
||||||
|
|
||||||
// 弹窗配置
|
|
||||||
const [ModalComponent, modalApi] = useVbenModal({
|
|
||||||
title: props.title,
|
|
||||||
onCancel: handleCancel,
|
|
||||||
onClosed: handleClosed,
|
|
||||||
destroyOnClose: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 递归处理部门树节点
|
// 递归处理部门树节点
|
||||||
const processDeptNode = (node: any): DeptTreeNode => {
|
function processDeptNode(node: any): DeptTreeNode {
|
||||||
return {
|
return {
|
||||||
key: String(node.id),
|
key: String(node.id),
|
||||||
title: `${node.name} (${node.id})`,
|
title: `${node.name} (${node.id})`,
|
||||||
name: node.name,
|
name: node.name,
|
||||||
children: node.children?.map((child: any) => processDeptNode(child)),
|
children: node.children?.map((child: any) => processDeptNode(child)),
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
open,
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ModalComponent class="w-[1000px]" key="user-select-modal">
|
<Modal class="w-[40%]" key="user-select-modal" :title="title">
|
||||||
<Spin :spinning="loading">
|
|
||||||
<Row :gutter="[16, 16]">
|
<Row :gutter="[16, 16]">
|
||||||
<Col :span="6">
|
<Col :span="6">
|
||||||
<div class="h-[500px] overflow-auto rounded border">
|
<div class="h-[500px] overflow-auto rounded border">
|
||||||
|
@ -479,7 +470,6 @@ defineExpose({
|
||||||
</Transfer>
|
</Transfer>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Spin>
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
@ -490,7 +480,7 @@ defineExpose({
|
||||||
</Button>
|
</Button>
|
||||||
<Button @click="handleCancel">{{ cancelText }}</Button>
|
<Button @click="handleCancel">{{ cancelText }}</Button>
|
||||||
</template>
|
</template>
|
||||||
</ModalComponent>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
Loading…
Reference in New Issue