vben
2023-04-05 8e5a6b7ce547ba8edb1d767bb4d820f3b66ff95a
提交 | 用户 | age
84c9d7 1 import type { ColEx } from '../types';
V 2 import type { AdvanceState } from '../types/hooks';
8e5a6b 3 import { ComputedRef, getCurrentInstance, Ref, shallowReactive, computed, unref, watch } from 'vue';
84c9d7 4 import type { FormProps, FormSchema } from '../types/form';
V 5 import { isBoolean, isFunction, isNumber, isObject } from '/@/utils/is';
6 import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
bcad95 7 import { useDebounceFn } from '@vueuse/core';
84c9d7 8
V 9 const BASIC_COL_LEN = 24;
10
11 interface UseAdvancedContext {
12   advanceState: AdvanceState;
13   emit: EmitType;
14   getProps: ComputedRef<FormProps>;
15   getSchema: ComputedRef<FormSchema[]>;
4ff1c4 16   formModel: Recordable;
V 17   defaultValueRef: Ref<Recordable>;
84c9d7 18 }
V 19
20 export default function ({
21   advanceState,
22   emit,
23   getProps,
24   getSchema,
25   formModel,
26   defaultValueRef,
27 }: UseAdvancedContext) {
20c10d 28   const vm = getCurrentInstance();
W 29
84c9d7 30   const { realWidthRef, screenEnum, screenRef } = useBreakpoint();
4ff1c4 31
V 32   const getEmptySpan = computed((): number => {
84c9d7 33     if (!advanceState.isAdvanced) {
V 34       return 0;
35     }
4ff1c4 36     // For some special cases, you need to manually specify additional blank lines
V 37     const emptySpan = unref(getProps).emptySpan || 0;
84c9d7 38
V 39     if (isNumber(emptySpan)) {
40       return emptySpan;
41     }
42     if (isObject(emptySpan)) {
43       const { span = 0 } = emptySpan;
44       const screen = unref(screenRef) as string;
45
46       const screenSpan = (emptySpan as any)[screen.toLowerCase()];
47       return screenSpan || span || 0;
48     }
49     return 0;
50   });
84b830 51
bcad95 52   const debounceUpdateAdvanced = useDebounceFn(updateAdvanced, 30);
53
84c9d7 54   watch(
480cfb 55     [() => unref(getSchema), () => advanceState.isAdvanced, () => unref(realWidthRef)],
84c9d7 56     () => {
V 57       const { showAdvancedButton } = unref(getProps);
58       if (showAdvancedButton) {
bcad95 59         debounceUpdateAdvanced();
84c9d7 60       }
V 61     },
56a966 62     { immediate: true },
84c9d7 63   );
V 64
65   function getAdvanced(itemCol: Partial<ColEx>, itemColSum = 0, isLastAction = false) {
66     const width = unref(realWidthRef);
67
68     const mdWidth =
69       parseInt(itemCol.md as string) ||
70       parseInt(itemCol.xs as string) ||
71       parseInt(itemCol.sm as string) ||
72       (itemCol.span as number) ||
73       BASIC_COL_LEN;
4ff1c4 74
84c9d7 75     const lgWidth = parseInt(itemCol.lg as string) || mdWidth;
V 76     const xlWidth = parseInt(itemCol.xl as string) || lgWidth;
77     const xxlWidth = parseInt(itemCol.xxl as string) || xlWidth;
78     if (width <= screenEnum.LG) {
79       itemColSum += mdWidth;
80     } else if (width < screenEnum.XL) {
81       itemColSum += lgWidth;
82     } else if (width < screenEnum.XXL) {
83       itemColSum += xlWidth;
84     } else {
85       itemColSum += xxlWidth;
86     }
4ff1c4 87
84c9d7 88     if (isLastAction) {
V 89       advanceState.hideAdvanceBtn = false;
90       if (itemColSum <= BASIC_COL_LEN * 2) {
4ff1c4 91         // When less than or equal to 2 lines, the collapse and expand buttons are not displayed
84c9d7 92         advanceState.hideAdvanceBtn = true;
V 93         advanceState.isAdvanced = true;
94       } else if (
95         itemColSum > BASIC_COL_LEN * 2 &&
4ff1c4 96         itemColSum <= BASIC_COL_LEN * (unref(getProps).autoAdvancedLine || 3)
84c9d7 97       ) {
V 98         advanceState.hideAdvanceBtn = false;
99
46e087 100         // More than 3 lines collapsed by default
84c9d7 101       } else if (!advanceState.isLoad) {
V 102         advanceState.isLoad = true;
103         advanceState.isAdvanced = !advanceState.isAdvanced;
104       }
105       return { isAdvanced: advanceState.isAdvanced, itemColSum };
106     }
93f9a1 107     if (itemColSum > BASIC_COL_LEN * (unref(getProps).alwaysShowLines || 1)) {
84c9d7 108       return { isAdvanced: advanceState.isAdvanced, itemColSum };
V 109     } else {
46e087 110       // The first line is always displayed
84c9d7 111       return { isAdvanced: true, itemColSum };
V 112     }
113   }
114
58b30a 115   const fieldsIsAdvancedMap = shallowReactive({});
116
84c9d7 117   function updateAdvanced() {
V 118     let itemColSum = 0;
119     let realItemColSum = 0;
c8ef82 120     const { baseColProps = {} } = unref(getProps);
V 121
84c9d7 122     for (const schema of unref(getSchema)) {
V 123       const { show, colProps } = schema;
124       let isShow = true;
125
126       if (isBoolean(show)) {
127         isShow = show;
128       }
129
130       if (isFunction(show)) {
131         isShow = show({
132           schema: schema,
133           model: formModel,
134           field: schema.field,
135           values: {
136             ...unref(defaultValueRef),
137             ...formModel,
138           },
139         });
140       }
141
c8ef82 142       if (isShow && (colProps || baseColProps)) {
V 143         const { itemColSum: sum, isAdvanced } = getAdvanced(
144           { ...baseColProps, ...colProps },
56a966 145           itemColSum,
c8ef82 146         );
84c9d7 147
V 148         itemColSum = sum || 0;
149         if (isAdvanced) {
150           realItemColSum = itemColSum;
151         }
58b30a 152         fieldsIsAdvancedMap[schema.field] = isAdvanced;
84c9d7 153       }
V 154     }
155
20c10d 156     // 确保页面发送更新
W 157     vm?.proxy?.$forceUpdate();
158
4ff1c4 159     advanceState.actionSpan = (realItemColSum % BASIC_COL_LEN) + unref(getEmptySpan);
84c9d7 160
4ff1c4 161     getAdvanced(unref(getProps).actionColOptions || { span: BASIC_COL_LEN }, itemColSum, true);
84b830 162
84c9d7 163     emit('advanced-change');
V 164   }
165
166   function handleToggleAdvanced() {
167     advanceState.isAdvanced = !advanceState.isAdvanced;
168   }
4ff1c4 169
58b30a 170   return { handleToggleAdvanced, fieldsIsAdvancedMap };
84c9d7 171 }