Blame view

Yi.Vben5.Vue3/apps/web-antd/src/utils/popup.ts 3.19 KB
515fceeb   “wangming”   框架初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  import type { ExtendedFormApi } from '@vben/common-ui';
  import type { MaybePromise } from '@vben/types';
  
  import { ref } from 'vue';
  
  import { $t } from '@vben/locales';
  
  import { Modal } from 'ant-design-vue';
  import { isFunction } from 'lodash-es';
  
  interface BeforeCloseDiffProps {
    /**
     * 初始化值如何获取
     * @returns Promise<string>
     */
    initializedGetter: () => MaybePromise<string>;
    /**
     * 当前值如何获取
     * @returns Promise<string>
     */
    currentGetter: () => MaybePromise<string>;
    /**
     * 自定义比较函数
     * @param init 初始值
     * @param current 当前值
     * @returns boolean
     */
    compare?: (init: string, current: string) => boolean;
  }
  
  /**
   * 用于Drawer/Modal使用 判断表单是否有变动来决定是否弹窗提示
   * @param props props
   * @returns hook
   */
  export function useBeforeCloseDiff(props: BeforeCloseDiffProps) {
    const { initializedGetter, currentGetter, compare } = props;
    /**
     * 记录初始值 json
     */
    const initialized = ref<string>('');
    /**
     * 是否已经初始化了 通过这个值判断是否需要进行对比 为false直接关闭 不弹窗
     */
    const isInitialized = ref(false);
  
    /**
     * 标记是否已经完成初始化 后续需要进行对比
     * @param data 自定义初始化数据 可选
     */
    async function markInitialized(data?: string) {
      initialized.value = data || (await initializedGetter());
      isInitialized.value = true;
    }
  
    /**
     * 重置初始化状态 需要在closed前调用 或者打开窗口时
     */
    function resetInitialized() {
      initialized.value = '';
      isInitialized.value = false;
    }
  
    /**
     * 提供给useVbenForm/useVbenDrawer使用
     * @returns 是否允许关闭
     */
    async function onBeforeClose(): Promise<boolean> {
      // 如果还未初始化,直接允许关闭
      if (!isInitialized.value) {
        return true;
      }
  
      try {
        // 获取当前表单数据
        const current = await currentGetter();
        // 自定义比较的情况
        if (isFunction(compare) && compare(initialized.value, current)) {
          return true;
        } else {
          // 如果数据没有变化,直接允许关闭
          if (current === initialized.value) {
            return true;
          }
        }
  
        // 数据有变化,显示确认对话框
        return new Promise<boolean>((resolve) => {
          Modal.confirm({
            title: $t('pages.common.tip'),
            content: $t('pages.common.beforeCloseTip'),
            centered: true,
            okButtonProps: { danger: true },
            cancelText: $t('common.cancel'),
            okText: $t('common.confirm'),
            onOk: () => {
              resolve(true);
              isInitialized.value = false;
            },
            onCancel: () => resolve(false),
          });
        });
      } catch (error) {
        console.error('Failed to compare data:', error);
        return true;
      }
    }
  
    return {
      onBeforeClose,
      markInitialized,
      resetInitialized,
    };
  }
  
  /**
   * 给useVbenForm使用的 封装函数
   * @param formApi 表单实例
   * @returns getter
   */
  export function defaultFormValueGetter(formApi: ExtendedFormApi) {
    return async () => {
      const v = await formApi.getValues();
      return JSON.stringify(v);
    };
  }