提交 661c380f authored 作者: lidongxu's avatar lidongxu

refactor(promotion/display): 调整:切换展示列方式和列选择对应问题

上级 31a19c40
...@@ -39,14 +39,35 @@ ...@@ -39,14 +39,35 @@
<template v-for="item in columns" <template v-for="item in columns"
:key="item.key"> :key="item.key">
<el-dropdown-item> <el-dropdown-item>
<el-checkbox :checked="item.visible" <el-checkbox v-model="item.visible"
@change="checkboxChange($event, item.label)"
:label="item.label" /> :label="item.label" />
</el-dropdown-item> </el-dropdown-item>
</template> </template>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
<!-- 树结构选择方式 -->
<el-dropdown trigger="click"
:hide-on-click="false"
style="padding-left: 12px"
v-if="showColumnsType == 'tree'">
<el-button circle
icon="Menu" />
<template #dropdown>
<el-dropdown-menu class="tree-dropdown-menu">
<el-tree
:data="treeData"
show-checkbox
node-key="prop"
ref="columnTree"
:props="treeProps"
default-expand-all
check-on-click-node
:default-checked-keys="defaultCheckedKeys"
@check="handleTreeCheck" />
</el-dropdown-menu>
</template>
</el-dropdown>
</el-tooltip> </el-tooltip>
<!-- 自定义功能 --> <!-- 自定义功能 -->
<slot></slot> <slot></slot>
...@@ -79,7 +100,7 @@ const props = defineProps({ ...@@ -79,7 +100,7 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
/* 显隐列类型(transfer穿梭框、checkbox复选框) */ /* 显隐列类型(transfer穿梭框、checkbox复选框、tree树形结构) */
showColumnsType: { showColumnsType: {
type: String, type: String,
default: "checkbox", default: "checkbox",
...@@ -89,6 +110,19 @@ const props = defineProps({ ...@@ -89,6 +110,19 @@ const props = defineProps({
type: Number, type: Number,
default: 10, default: 10,
}, },
/* 树形结构配置(可选) */
treeConfig: {
type: Object,
default: () => ({
labelKey: 'label',
childrenKey: 'children'
})
},
/* 树形结构默认选中的节点 */
defaultCheckedKeys: {
type: Array,
default: () => []
}
}) })
const emits = defineEmits(['update:showSearch', 'queryTable']); const emits = defineEmits(['update:showSearch', 'queryTable']);
...@@ -99,6 +133,15 @@ const value = ref([]); ...@@ -99,6 +133,15 @@ const value = ref([]);
const title = ref("显示/隐藏"); const title = ref("显示/隐藏");
// 是否显示弹出层 // 是否显示弹出层
const open = ref(false); const open = ref(false);
// 树结构数据
const treeData = ref([]);
// 树结构配置
const treeProps = {
label: props.treeConfig.labelKey || 'label',
children: props.treeConfig.childrenKey || 'children'
};
// 树引用
const columnTree = ref(null);
const style = computed(() => { const style = computed(() => {
const ret = {}; const ret = {};
...@@ -131,6 +174,80 @@ function showColumn() { ...@@ -131,6 +174,80 @@ function showColumn() {
open.value = true; open.value = true;
} }
// 树形结构节点勾选变化
function handleTreeCheck(currentNode, checkedInfo) {
const node = currentNode;
// 判断当前节点是否被勾选(检查当前节点prop是否在checkedKeys中)
const isChecked = checkedInfo.checkedKeys.includes(node.prop);
// 处理父节点的特殊情况:如果是父节点(有children),则更新其所有子节点
if (node.children && node.children.length > 0) {
// 获取该父节点下的所有子节点prop
const allChildProps = [];
const collectChildProps = (nodes) => {
nodes.forEach(child => {
if (child.children && child.children.length > 0) {
collectChildProps(child.children);
} else {
allChildProps.push(child.prop);
}
});
};
collectChildProps(node.children);
// 更新所有子节点的visible属性
allChildProps.forEach(prop => {
updateColumnVisibilityByProp(prop, isChecked);
});
} else {
// 对于单个节点,直接更新其visible属性
updateColumnVisibilityByProp(node.prop, isChecked);
}
}
// 新增:根据prop更新对应列的visible属性
function updateColumnVisibilityByProp(prop, visible) {
const updateColumn = (columns) => {
for (let i = 0; i < columns.length; i++) {
const item = columns[i];
if (item.children && item.children.length > 0) {
// 递归查找子节点
const found = updateColumn(item.children);
if (found) return true;
} else if (item.prop === prop) {
// 找到匹配的节点,更新其visible属性
item.visible = visible;
return true;
}
}
return false;
};
// 从props.columns中查找并更新
updateColumn(props.columns);
}
// 3. 修改initTreeData方法,确保正确处理prop字段
function initTreeData() {
if (props.columns && props.showColumnsType === 'tree') {
// 创建树数据但不深拷贝,保持引用关系
treeData.value = props.columns;
}
}
watch(() => props.columns, () => {
initTreeData();
})
// 再添加一个watcher来监听showColumnsType变化
watch(
() => props.showColumnsType,
(newType, oldType) => {
if (newType === 'tree') {
initTreeData();
}
}
)
if (props.showColumnsType == 'transfer') { if (props.showColumnsType == 'transfer') {
// 显隐列初始默认隐藏列 // 显隐列初始默认隐藏列
for (let item in props.columns) { for (let item in props.columns) {
...@@ -138,13 +255,19 @@ if (props.showColumnsType == 'transfer') { ...@@ -138,13 +255,19 @@ if (props.showColumnsType == 'transfer') {
value.value.push(parseInt(item)); value.value.push(parseInt(item));
} }
} }
} else if (props.showColumnsType === 'tree') {
// 初始化树数据
initTreeData();
} }
// 勾选 // 勾选 - 修改为更健壮的实现
function checkboxChange(event, label) { // function checkboxChange(event, label) {
props.columns.filter(item => item.label == label)[0].visible = event; // // 使用find方法而不是filter,更高效
} // const column = props.columns.find(item => item.label === label);
// if (column) {
// column.visible = event;
// }
// }
</script> </script>
<style lang='scss' <style lang='scss'
...@@ -174,4 +297,25 @@ function checkboxChange(event, label) { ...@@ -174,4 +297,25 @@ function checkboxChange(event, label) {
} }
} }
/* 树结构下拉菜单样式 */
.tree-dropdown-menu {
max-height: 400px;
overflow-y: auto;
min-width: 300px;
padding: 10px;
}
:deep(.el-tree) {
max-height: 380px;
overflow-y: auto;
}
/* 添加选中节点文字蓝色样式 */
:deep(.el-tree-node.is-checked > .el-tree-node__content .el-tree-node__label) {
color: #409EFF;
}
:deep(.el-tree-node__content .el-checkbox__input.is-checked + .el-checkbox__label) {
color: #409EFF;
}
</style> </style>
\ No newline at end of file
...@@ -103,14 +103,14 @@ service.interceptors.response.use(async res => { ...@@ -103,14 +103,14 @@ service.interceptors.response.use(async res => {
// PC/移动端刷新 token 有效期 // PC/移动端刷新 token 有效期
// await useUserStore().refreshTokenFn() // await useUserStore().refreshTokenFn()
// return service(res.config) // return service(res.config)
// ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
// isRelogin.show = false; isRelogin.show = false;
// useUserStore().logOut().then(() => { useUserStore().logOut().then(() => {
// location.href = '#/login'; location.href = '#/login';
// }) })
// }).catch(() => { }).catch(() => {
// isRelogin.show = false; isRelogin.show = false;
// }); });
return Promise.reject('无效的会话,或者会话已过期,请重新登录。') return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 403) { } else if (code === 403) {
......
<template>
<div class="app-container">
<div class="container">
卤币明细
</div>
</div>
</template>
<script setup>
</script>
<style scoped
lang="scss"></style>
\ No newline at end of file
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论