import { ref, watch, Ref, computed, nextTick } from "vue" import { IColumnConfig, IProps, SettingStorgeConfig } from "../types" interface IViewSettingParams { showingColumns: Ref actualColumns: Ref viewSettingDragSortOptions: Ref props: IProps emit: { (e: 'update:leftFixedColumnCount', val: number): void (e: 'update:showingColumns', val: string[]): void (e: 'update:viewSettingDragSortOptions', val: IColumnConfig[]): void (e: 'tableDoLayout'): void } } /** 默认迁移配置 */ const storgeSchemaMigrationConfig: Record ({ schemaVersion: number, config: any, version?: string }) /** 迁移到的下一个版本号 */ nextSchemaVersion?: number }> = { '0': { migration: (config: { showingColumns: string[], leftFixedColumnCount: number }, columns: IColumnConfig[]) => { return { config: { fields: columns.reduce((acc, curr) => { acc[curr.prop] = { hidden: config.showingColumns.find(v => v === curr.prop) ? false : true, order: config.showingColumns.findIndex(v => v === curr.prop) ?? 0, } return acc; }, {} as Record), leftFixedColumnCount: config.leftFixedColumnCount, }, schemaVersion: 1, } }, nextSchemaVersion: 1, } } export function useViewSetting({ showingColumns, actualColumns, props, viewSettingDragSortOptions, emit }: IViewSettingParams) { const columnsToBeShown = ref([]); // 显示设置弹窗中勾选的列 const viewSettingVisible = ref(false); const leftFixedColumnCount = ref(0); const tempLeftFixedColumnCount = ref(0); const updateShowingColumns = (val: string[]) => emit('update:showingColumns', val); const storageKey = computed(() => `@lx-frontend/wrap-element-ui/table_setting_cloumns/${props.settingStorgeKey || (location.pathname === '/' ? location.hash : location.pathname)}`); const saveSettingToStorge = async() => { await nextTick() const settingStorgeMigrationConfigs = props.settingStorgeMigrationConfigs ?? [] const len = settingStorgeMigrationConfigs.length const version = len ? settingStorgeMigrationConfigs[len - 1].version.to : undefined localStorage.setItem(storageKey.value, JSON.stringify({ config: { fields: props.columnConfig.reduce((acc, curr, index) => { const _index = showingColumns.value.findIndex(v => v === curr.prop) acc[curr.prop] = { hidden: showingColumns.value.find(v => v === curr.prop) ? false : true, order: _index === -1 ? index : _index, } return acc; }, {} as Record), leftFixedColumnCount: leftFixedColumnCount.value, }, version, schemaVersion: 1 })) }; const handleViewSettingShow = () => { emit('update:viewSettingDragSortOptions', [...actualColumns.value.filter(v => v?.prop !== '$$operation')]); tempLeftFixedColumnCount.value = leftFixedColumnCount.value; viewSettingVisible.value = true; columnsToBeShown.value = [...showingColumns.value]; } const handleViewSettingClose = () => { viewSettingVisible.value = false; } const handleViewSettingConfirm = async () => { viewSettingVisible.value = false; updateShowingColumns(viewSettingDragSortOptions.value.map(c => c.prop)); leftFixedColumnCount.value = tempLeftFixedColumnCount.value; await saveSettingToStorge() emit('tableDoLayout') } const handleInputTempLeftFixedColumnCount = (value: string) => { const _value = Number(value) if (isNaN(_value)) return tempLeftFixedColumnCount.value = Math.max(0, Math.min(columnsToBeShown.value.length, Math.floor(_value))) } watch( () => props.columnConfig, async(val) => { const _cache = localStorage.getItem(storageKey.value); const setColumns = () => updateShowingColumns(val.filter(v => !v.defaultHide).map(c => c.prop)); if (!_cache) { setColumns(); leftFixedColumnCount.value = props.leftFixedCount as number; } else { try { const handleMigration = (_cache: any) => { const schemaVersion = _cache?.schemaVersion ?? 0 if (!storgeSchemaMigrationConfig[schemaVersion]) { // 没有 schema 变动时,查找需要处理的业务迁移配置 const bizMigrationConfigs = (props.settingStorgeMigrationConfigs ?? []).filter(v => (v.schemaVersion ?? 1) === _cache.schemaVersion) const _versionIndex = bizMigrationConfigs.findIndex(v => v.version.form === _cache.version) if (_versionIndex > -1) { for (let i = _versionIndex; i < bizMigrationConfigs.length; i++) { const curr = bizMigrationConfigs[i] _cache = curr.migration(_cache.config, val) } } return _cache } else { let __cache = storgeSchemaMigrationConfig[schemaVersion].migration(_cache, val) // 处理当前schema版本需要处理的变更 const bizMigrationConfigs = (props.settingStorgeMigrationConfigs ?? []).filter(v => (v.schemaVersion ?? 1) === __cache.schemaVersion) if (bizMigrationConfigs.length) { __cache = bizMigrationConfigs.reduce((acc, curr) => ({ ...curr.migration(acc.config, val), schemaVersion: __cache.schemaVersion, }), __cache) } return storgeSchemaMigrationConfig[schemaVersion].nextSchemaVersion ? handleMigration(__cache) : __cache } } const cache = handleMigration(JSON.parse(_cache)) as SettingStorgeConfig; updateShowingColumns( val.filter(v => { return cache.config.fields[v.prop] ? !cache.config.fields[v.prop].hidden : !v.defaultHide }).sort((a, b) => { return (cache.config.fields[a.prop]?.order ?? 0) - (cache.config.fields[b.prop]?.order ?? 0) }).map(v => v.prop) ); const _leftFixedColumnCount = Number(cache?.config?.leftFixedColumnCount) leftFixedColumnCount.value = isNaN(_leftFixedColumnCount) ? (props.leftFixedCount as number) : _leftFixedColumnCount; // 写入清理后的数据 saveSettingToStorge(); } catch (error) { console.error(error); localStorage.removeItem(storageKey.value); setColumns(); } } }, { immediate: true } ) watch(columnsToBeShown, (val, oldVal) => { if (val.length === oldVal?.length) return // 排序调整时不做处理,避免出现死循环 const _map = new Map() props.columnConfig.forEach(c => _map.set(c.prop, c)) // 展示时保留顺序 emit('update:viewSettingDragSortOptions', val.map(prop => _map.get(prop)!)) if (tempLeftFixedColumnCount.value > val.length) tempLeftFixedColumnCount.value = val.length }, { immediate: true }) // 拖拽调整排序时,同时更新勾选数组的顺序,避免出现拖拽排序操作过程后再勾选新列时被还原成拖拽前的顺序的问题 watch(viewSettingDragSortOptions, (val, oldVal) => { if (!val.length || val.length !== oldVal?.length) return // 不是排序调整 columnsToBeShown.value = val.map(c => c.prop) }, { deep: true }) watch(leftFixedColumnCount, (val) => emit('update:leftFixedColumnCount', val), { immediate: true }); return { columnsToBeShown, viewSettingVisible, leftFixedColumnCount, tempLeftFixedColumnCount, handleInputTempLeftFixedColumnCount, handleViewSettingShow, handleViewSettingClose, handleViewSettingConfirm, } }