wms-antdvue/.svn/pristine/e2/e2343b65112bbdf0fd1b601f1d5d33937030dcd6.svn-base
2024-11-07 16:33:03 +08:00

334 lines
9.7 KiB
Plaintext

<template>
<a-tooltip trigger="hover">
<template #title>
<span>列设置</span>
</template>
<div class="cursor-pointer table-toolbar-right-icon">
<a-popover
:overlayStyle="{ width: getPopoverWidth, maxHeight: '50vh', padding: 0 }"
overlayClassName="toolbar-popover"
placement="rightBottom"
trigger="click"
>
<SettingOutlined />
<template #content>
<div class="table-toolbar-inner-popover-title">
<div class="w-full flex justify-between items-center">
<a-checkbox
v-model:checked="checkAll"
:indeterminate="!checkAll && checkPart"
@change="onCheckAll"
>列展示
</a-checkbox>
<!-- <a-checkbox v-model:checked="selection" @update:checked="onSelection"-->
<!-- >勾选列-->
<!-- </a-checkbox>-->
<a-button class="mt-1" size="small" type="link" @click="resetColumns">重置 </a-button>
</div>
</div>
<div class="table-toolbar-inner">
<a-checkbox-group v-model:value="checkList" @change="onChange">
<Draggable
v-model="basicColumns"
animation="300"
item-key="key"
filter=".no-draggable"
:move="onMove"
@end="draggableEnd"
>
<template #item="{ element }">
<div
v-if="element.type != 'selection' && element.type != 'expand'"
:class="{
'table-toolbar-inner-checkbox-dark': getDarkTheme === true,
'no-draggable': element.draggable === false,
}"
class="table-toolbar-inner-checkbox"
>
<span class="drag-icon">
<DragOutlined style="font-size: 18px" />
</span>
<a-checkbox :value="element.key">{{ element.title }}</a-checkbox>
<div class="fixed-item">
<a-tooltip placement="top" trigger="hover">
<template #title>
<span>固定到左侧</span>
</template>
<span
:color="element.fixed === 'left' ? '#1e6fff' : undefined"
class="cursor-pointer"
size="18"
@click="fixedColumn(element, 'left')"
>
<VerticalRightOutlined />
</span>
</a-tooltip>
<a-divider type="vertical" />
<a-tooltip placement="top" trigger="hover">
<template #title>
<span>固定到右侧</span>
</template>
<span
:color="element.fixed === 'right' ? '#1e6fff' : undefined"
class="cursor-pointer"
size="18"
@click="fixedColumn(element, 'right')"
>
<VerticalLeftOutlined />
</span>
</a-tooltip>
</div>
</div>
</template>
</Draggable>
</a-checkbox-group>
</div>
</template>
</a-popover>
</div>
</a-tooltip>
</template>
<script lang="ts" setup>
import { ref, unref, toRaw, watchEffect, computed } from 'vue';
import { useTableContext } from '../../hooks/useTableContext';
import { cloneDeep } from 'lodash-es';
import {
SettingOutlined,
DragOutlined,
VerticalRightOutlined,
VerticalLeftOutlined,
} from '@ant-design/icons-vue';
import Draggable from 'vuedraggable/src/vuedraggable';
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
import type { TableSetting } from '../../types/table';
interface Options {
title: string;
key: string;
fixed?: boolean | 'left' | 'right';
}
const props = defineProps({
tableSetting: {
type: Object as PropType<TableSetting>,
},
});
const emit = defineEmits(['columnsChange']);
const getPopoverWidth = computed(() => {
return props.tableSetting?.width + 'px';
});
const { getDarkTheme } = useProjectSetting();
const table: any = useTableContext();
const basicColumns = ref<Options[]>([]);
const cacheColumnsList = ref<Options[]>([]);
const selection = ref(false);
const checkAll = ref(true);
const checkPart = ref(false);
const checkList = ref<string[]>([]);
const defaultCheckList = ref([]);
watchEffect(() => {
const columns = table.getColumns();
if (columns.length) {
init();
}
});
//初始化
function init() {
const columns: any[] = getColumns();
//同时兼容 全选 反选,单选
const checkListArr: any =
!checkAll.value && !checkPart.value && checkList.value.length
? checkList.value
: columns.map((item) => item.key);
//重新赋值
checkList.value = !checkAll.value && !checkPart.value ? [] : checkListArr;
defaultCheckList.value = !checkAll.value && !checkPart.value ? [] : checkListArr;
const newColumns = columns.filter(
(item) => item.type != 'selection' && item.key != 'action' && item.title != '操作',
);
if (!basicColumns.value.length) {
basicColumns.value = cloneDeep(newColumns);
cacheColumnsList.value = cloneDeep(newColumns);
}
}
//切换
function onChange(list) {
if (selection.value) {
list.unshift('selection');
}
const filterColumns = basicColumns.value.filter((item) => {
return list.includes(item.key);
});
const isAction = list.includes('action');
const len = isAction ? list.length - 1 : list.length;
checkPart.value = basicColumns.value.length != len;
checkAll.value = basicColumns.value.length == len;
setColumns(filterColumns);
table.isShowTable.value = true;
emit('columnsChange', table.getColumns());
}
//设置
function setColumns(columns) {
table.setColumns(columns);
}
//获取
function getColumns() {
let newRet: any[] = [];
table.getColumns().forEach((item) => {
item.key = item.key || item.dataIndex;
newRet.push({ ...item });
});
return newRet;
}
function onMove(e) {
if (e.draggedContext.element.draggable === false) return false;
return true;
}
//重置
function resetColumns() {
checkList.value = [...defaultCheckList.value];
checkAll.value = true;
let cacheColumnsKeys: any[] = table.getCacheColumns();
let newColumns = cacheColumnsKeys.map((item) => {
return {
...item,
fixed: undefined,
};
});
setColumns(newColumns);
basicColumns.value = newColumns;
table.isShowTable.value = true;
emit('columnsChange', table.getColumns());
}
//全选
function onCheckAll(e) {
let checkList = table.getCacheColumns();
checkPart.value = false;
if (e.target.checked) {
setColumns(checkList);
checkAll.value = true;
checkList.value = checkList;
table.isShowTable.value = true;
} else {
table.isShowTable.value = false;
checkList.value = [];
checkAll.value = false;
setColumns([]);
}
emit('columnsChange', table.getColumns());
}
//拖拽排序
function draggableEnd() {
const newColumns = toRaw(unref(basicColumns));
basicColumns.value = newColumns;
const filterColumns = newColumns.filter((item) => {
return checkList.value.includes(item.key);
});
checkList.value = filterColumns.map((item) => item.key);
setColumns(filterColumns);
emit('columnsChange', table.getColumns());
}
//勾选列
// function onSelection(e) {
// let checkList = table.getCacheColumns();
// if (e) {
// checkList.unshift({ type: 'selection', key: 'selection' });
// setColumns(checkList);
// } else {
// checkList.splice(0, 1);
// setColumns(checkList);
// }
// }
//固定
function fixedColumn(item, fixed) {
if (!unref(checkList).includes(item.key as never)) return;
let columns = getColumns();
const isFixed = item.fixed === fixed ? undefined : fixed;
let index = columns.findIndex((res) => res.key === item.key);
if (index !== -1) {
columns[index].fixed = isFixed;
}
table.setCacheColumnsField(item.key, { fixed: isFixed });
basicColumns.value[index].fixed = isFixed;
setColumns(columns);
emit('columnsChange', table.getColumns());
}
</script>
<style lang="less" scoped>
.table-toolbar {
&-inner-popover-title {
border-bottom: 1px solid #eee;
padding-bottom: 10px;
}
&-right {
&-icon {
margin-left: 12px;
font-size: 16px;
color: var(--text-color);
cursor: pointer;
}
}
&-inner {
margin-top: 5px;
.ant-checkbox-group {
width: 100%;
}
&-checkbox {
display: flex;
align-items: center;
padding: 10px;
&:hover {
background: #e6f7ff;
border-radius: 4px;
}
.drag-icon {
display: inline-flex;
margin-right: 8px;
cursor: move;
}
.fixed-item {
display: flex;
align-items: center;
justify-content: flex-end;
margin-left: auto;
}
.ant-checkbox-wrapper {
flex: 1;
}
}
&-checkbox-dark {
&:hover {
background: hsla(0, 0%, 100%, 0.08);
}
}
}
}
</style>