|  | @@ -3,7 +3,14 @@
 | 
	
		
			
				|  |  |      <template #title>
 | 
	
		
			
				|  |  |        <span>{{ t('component.table.settingColumn') }}</span>
 | 
	
		
			
				|  |  |      </template>
 | 
	
		
			
				|  |  | -    <Popover placement="bottomLeft" trigger="click" @visibleChange="handleVisibleChange" :overlayClassName="`${prefixCls}__cloumn-list`" :getPopupContainer="getPopupContainer">
 | 
	
		
			
				|  |  | +    <Popover
 | 
	
		
			
				|  |  | +      v-model:visible="popoverVisible"
 | 
	
		
			
				|  |  | +      placement="bottomLeft"
 | 
	
		
			
				|  |  | +      trigger="click"
 | 
	
		
			
				|  |  | +      @visibleChange="handleVisibleChange"
 | 
	
		
			
				|  |  | +      :overlayClassName="`${prefixCls}__cloumn-list`"
 | 
	
		
			
				|  |  | +      :getPopupContainer="getPopupContainer"
 | 
	
		
			
				|  |  | +    >
 | 
	
		
			
				|  |  |        <template #title>
 | 
	
		
			
				|  |  |          <div :class="`${prefixCls}__popover-title`">
 | 
	
		
			
				|  |  |            <Checkbox :indeterminate="indeterminate" v-model:checked="checkAll" @change="onCheckAllChange">
 | 
	
	
		
			
				|  | @@ -21,10 +28,6 @@
 | 
	
		
			
				|  |  |            <!--                    >-->
 | 
	
		
			
				|  |  |            <!--                        {{ t('component.table.settingSelectColumnShow') }}-->
 | 
	
		
			
				|  |  |            <!--                    </Checkbox>-->
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -          <a-button size="small" type="link" @click="reset">
 | 
	
		
			
				|  |  | -            {{ t('common.resetText') }}
 | 
	
		
			
				|  |  | -          </a-button>
 | 
	
		
			
				|  |  |          </div>
 | 
	
		
			
				|  |  |        </template>
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -33,7 +36,7 @@
 | 
	
		
			
				|  |  |            <CheckboxGroup v-model:value="checkedList" @change="onChange" ref="columnListRef">
 | 
	
		
			
				|  |  |              <template v-for="item in plainOptions" :key="item.value">
 | 
	
		
			
				|  |  |                <div :class="`${prefixCls}__check-item`" v-if="!('ifShow' in item && !item.ifShow)">
 | 
	
		
			
				|  |  | -                <DragOutlined class="table-coulmn-drag-icon" />
 | 
	
		
			
				|  |  | +                <DragOutlined class="table-column-drag-icon" />
 | 
	
		
			
				|  |  |                  <Checkbox :value="item.value">
 | 
	
		
			
				|  |  |                    {{ item.label }}
 | 
	
		
			
				|  |  |                  </Checkbox>
 | 
	
	
		
			
				|  | @@ -75,6 +78,12 @@
 | 
	
		
			
				|  |  |              </template>
 | 
	
		
			
				|  |  |            </CheckboxGroup>
 | 
	
		
			
				|  |  |          </ScrollContainer>
 | 
	
		
			
				|  |  | +        <div :class="`${prefixCls}__popover-footer`">
 | 
	
		
			
				|  |  | +          <a-button size="small" @click="reset">
 | 
	
		
			
				|  |  | +            {{ t('common.resetText') }}
 | 
	
		
			
				|  |  | +          </a-button>
 | 
	
		
			
				|  |  | +          <a-button size="small" type="primary" @click="saveSetting"> 保存 </a-button>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  |        </template>
 | 
	
		
			
				|  |  |        <SettingOutlined />
 | 
	
		
			
				|  |  |      </Popover>
 | 
	
	
		
			
				|  | @@ -89,14 +98,18 @@
 | 
	
		
			
				|  |  |    import { ScrollContainer } from '/@/components/Container';
 | 
	
		
			
				|  |  |    import { useI18n } from '/@/hooks/web/useI18n';
 | 
	
		
			
				|  |  |    import { useTableContext } from '../../hooks/useTableContext';
 | 
	
		
			
				|  |  | +  import { useColumnsCache } from '../../hooks/useColumnsCache';
 | 
	
		
			
				|  |  |    import { useDesign } from '/@/hooks/web/useDesign';
 | 
	
		
			
				|  |  | -  import { useSortable } from '/@/hooks/web/useSortable';
 | 
	
		
			
				|  |  | +  // import { useSortable } from '/@/hooks/web/useSortable';
 | 
	
		
			
				|  |  |    import { isFunction, isNullAndUnDef } from '/@/utils/is';
 | 
	
		
			
				|  |  |    import { getPopupContainer as getParentContainer } from '/@/utils';
 | 
	
		
			
				|  |  | -  import { omit } from 'lodash-es';
 | 
	
		
			
				|  |  | +  import { cloneDeep, omit } from 'lodash-es';
 | 
	
		
			
				|  |  | +  import Sortablejs from 'sortablejs';
 | 
	
		
			
				|  |  | +  import type Sortable from 'sortablejs';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    interface State {
 | 
	
		
			
				|  |  |      checkAll: boolean;
 | 
	
		
			
				|  |  | +    isInit?: boolean;
 | 
	
		
			
				|  |  |      checkedList: string[];
 | 
	
		
			
				|  |  |      defaultCheckList: string[];
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -128,12 +141,13 @@
 | 
	
		
			
				|  |  |      setup(props, { emit, attrs }) {
 | 
	
		
			
				|  |  |        const { t } = useI18n();
 | 
	
		
			
				|  |  |        const table = useTableContext();
 | 
	
		
			
				|  |  | +      const popoverVisible = ref(false);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        const defaultRowSelection = omit(table.getRowSelection(), 'selectedRowKeys');
 | 
	
		
			
				|  |  |        let inited = false;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        const cachePlainOptions = ref<Options[]>([]);
 | 
	
		
			
				|  |  | -      const plainOptions = ref<Options[]>([]);
 | 
	
		
			
				|  |  | +      const plainOptions = ref<Options[] | any>([]);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        const plainSortOptions = ref<Options[]>([]);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -162,9 +176,26 @@
 | 
	
		
			
				|  |  |          return obj;
 | 
	
		
			
				|  |  |        });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +      let sortable: Sortable;
 | 
	
		
			
				|  |  | +      const sortableOrder = ref<string[]>();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 列表字段配置缓存
 | 
	
		
			
				|  |  | +      const { saveSetting, resetSetting } = useColumnsCache(
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          state,
 | 
	
		
			
				|  |  | +          popoverVisible,
 | 
	
		
			
				|  |  | +          plainOptions,
 | 
	
		
			
				|  |  | +          plainSortOptions,
 | 
	
		
			
				|  |  | +          sortableOrder,
 | 
	
		
			
				|  |  | +          checkIndex,
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        setColumns,
 | 
	
		
			
				|  |  | +        handleColumnFixed
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |        watchEffect(() => {
 | 
	
		
			
				|  |  |          const columns = table.getColumns();
 | 
	
		
			
				|  |  | -        if (columns.length) {
 | 
	
		
			
				|  |  | +        if (columns.length && !state.isInit) {
 | 
	
		
			
				|  |  |            init();
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |        });
 | 
	
	
		
			
				|  | @@ -217,6 +248,7 @@
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |            });
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        state.isInit = true;
 | 
	
		
			
				|  |  |          state.checkedList = checkList;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -234,16 +266,15 @@
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        const indeterminate = computed(() => {
 | 
	
		
			
				|  |  |          const len = plainOptions.value.length;
 | 
	
		
			
				|  |  | -        let checkdedLen = state.checkedList.length;
 | 
	
		
			
				|  |  | -        unref(checkIndex) && checkdedLen--;
 | 
	
		
			
				|  |  | -        return checkdedLen > 0 && checkdedLen < len;
 | 
	
		
			
				|  |  | +        let checkedLen = state.checkedList.length;
 | 
	
		
			
				|  |  | +        unref(checkIndex) && checkedLen--;
 | 
	
		
			
				|  |  | +        return checkedLen > 0 && checkedLen < len;
 | 
	
		
			
				|  |  |        });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        // Trigger when check/uncheck a column
 | 
	
		
			
				|  |  |        function onChange(checkedList: string[]) {
 | 
	
		
			
				|  |  | -        const len = plainOptions.value.length;
 | 
	
		
			
				|  |  | +        const len = plainSortOptions.value.length;
 | 
	
		
			
				|  |  |          state.checkAll = checkedList.length === len;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |          const sortList = unref(plainSortOptions).map((item) => item.value);
 | 
	
		
			
				|  |  |          checkedList.sort((prev, next) => {
 | 
	
		
			
				|  |  |            return sortList.indexOf(prev) - sortList.indexOf(next);
 | 
	
	
		
			
				|  | @@ -258,6 +289,10 @@
 | 
	
		
			
				|  |  |          plainOptions.value = unref(cachePlainOptions);
 | 
	
		
			
				|  |  |          plainSortOptions.value = unref(cachePlainOptions);
 | 
	
		
			
				|  |  |          setColumns(table.getCacheColumns());
 | 
	
		
			
				|  |  | +        if (sortableOrder.value) {
 | 
	
		
			
				|  |  | +          sortable.sort(sortableOrder.value);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        resetSetting();
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        // Open the pop-up window for drag and drop initialization
 | 
	
	
		
			
				|  | @@ -269,15 +304,18 @@
 | 
	
		
			
				|  |  |            const el = columnListEl.$el as any;
 | 
	
		
			
				|  |  |            if (!el) return;
 | 
	
		
			
				|  |  |            // Drag and drop sort
 | 
	
		
			
				|  |  | -          const { initSortable } = useSortable(el, {
 | 
	
		
			
				|  |  | -            handle: '.table-coulmn-drag-icon ',
 | 
	
		
			
				|  |  | +          sortable = Sortablejs.create(unref(el), {
 | 
	
		
			
				|  |  | +            animation: 500,
 | 
	
		
			
				|  |  | +            delay: 400,
 | 
	
		
			
				|  |  | +            delayOnTouchOnly: true,
 | 
	
		
			
				|  |  | +            handle: '.table-column-drag-icon ',
 | 
	
		
			
				|  |  |              onEnd: (evt) => {
 | 
	
		
			
				|  |  |                const { oldIndex, newIndex } = evt;
 | 
	
		
			
				|  |  |                if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) {
 | 
	
		
			
				|  |  |                  return;
 | 
	
		
			
				|  |  |                }
 | 
	
		
			
				|  |  |                // Sort column
 | 
	
		
			
				|  |  | -              const columns = getColumns();
 | 
	
		
			
				|  |  | +              const columns = cloneDeep(plainSortOptions.value);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                if (oldIndex > newIndex) {
 | 
	
		
			
				|  |  |                  columns.splice(newIndex, 0, columns[oldIndex]);
 | 
	
	
		
			
				|  | @@ -288,11 +326,13 @@
 | 
	
		
			
				|  |  |                }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                plainSortOptions.value = columns;
 | 
	
		
			
				|  |  | -              plainOptions.value = columns;
 | 
	
		
			
				|  |  |                setColumns(columns);
 | 
	
		
			
				|  |  |              },
 | 
	
		
			
				|  |  |            });
 | 
	
		
			
				|  |  | -          initSortable();
 | 
	
		
			
				|  |  | +          // 记录原始 order 序列
 | 
	
		
			
				|  |  | +          if (!sortableOrder.value) {
 | 
	
		
			
				|  |  | +            sortableOrder.value = sortable.toArray();
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  |            inited = true;
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |        }
 | 
	
	
		
			
				|  | @@ -325,13 +365,13 @@
 | 
	
		
			
				|  |  |          if (isFixed && !item.width) {
 | 
	
		
			
				|  |  |            item.width = 100;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        table.setCacheColumnsByField?.(item.dataIndex, { fixed: isFixed });
 | 
	
		
			
				|  |  | +        table.setCacheColumnsByField?.(item.dataIndex as string, { fixed: isFixed });
 | 
	
		
			
				|  |  |          setColumns(columns);
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        function setColumns(columns: BasicColumn[] | string[]) {
 | 
	
		
			
				|  |  |          table.setColumns(columns);
 | 
	
		
			
				|  |  | -        const data: ColumnChangeParam[] = unref(plainOptions).map((col) => {
 | 
	
		
			
				|  |  | +        const data: ColumnChangeParam[] = unref(plainSortOptions).map((col) => {
 | 
	
		
			
				|  |  |            const visible = columns.findIndex((c: BasicColumn | string) => c === col.value || (typeof c !== 'string' && c.dataIndex === col.value)) !== -1;
 | 
	
		
			
				|  |  |            return { dataIndex: col.value, fixed: col.fixed, visible };
 | 
	
		
			
				|  |  |          });
 | 
	
	
		
			
				|  | @@ -347,11 +387,13 @@
 | 
	
		
			
				|  |  |          getBindProps,
 | 
	
		
			
				|  |  |          t,
 | 
	
		
			
				|  |  |          ...toRefs(state),
 | 
	
		
			
				|  |  | +        popoverVisible,
 | 
	
		
			
				|  |  |          indeterminate,
 | 
	
		
			
				|  |  |          onCheckAllChange,
 | 
	
		
			
				|  |  |          onChange,
 | 
	
		
			
				|  |  |          plainOptions,
 | 
	
		
			
				|  |  |          reset,
 | 
	
		
			
				|  |  | +        saveSetting,
 | 
	
		
			
				|  |  |          prefixCls,
 | 
	
		
			
				|  |  |          columnListRef,
 | 
	
		
			
				|  |  |          handleVisibleChange,
 | 
	
	
		
			
				|  | @@ -369,7 +411,7 @@
 | 
	
		
			
				|  |  |  <style lang="less">
 | 
	
		
			
				|  |  |    @prefix-cls: ~'@{namespace}-basic-column-setting';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  .table-coulmn-drag-icon {
 | 
	
		
			
				|  |  | +  .table-column-drag-icon {
 | 
	
		
			
				|  |  |      margin: 0 5px;
 | 
	
		
			
				|  |  |      cursor: move;
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -382,6 +424,19 @@
 | 
	
		
			
				|  |  |        justify-content: space-between;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /* 卡片底部样式 */
 | 
	
		
			
				|  |  | +    &__popover-footer {
 | 
	
		
			
				|  |  | +      position: relative;
 | 
	
		
			
				|  |  | +      top: 7px;
 | 
	
		
			
				|  |  | +      text-align: right;
 | 
	
		
			
				|  |  | +      padding: 4px 0 0;
 | 
	
		
			
				|  |  | +      border-top: 1px solid #f0f0f0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      .ant-btn {
 | 
	
		
			
				|  |  | +        margin-right: 6px;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      &__check-item {
 | 
	
		
			
				|  |  |        display: flex;
 | 
	
		
			
				|  |  |        align-items: center;
 |