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