update: 弹窗表单数据更改关闭时的提示框(可能最终不会加入) 测试页面: 参数管理
This commit is contained in:
parent
b4d038e22f
commit
26587ac09a
@ -26,11 +26,15 @@
|
|||||||
- TableSwitch组件重构
|
- TableSwitch组件重构
|
||||||
- 管理员租户切换不再返回首页 直接刷新当前页(除特殊页面外会回到首页)
|
- 管理员租户切换不再返回首页 直接刷新当前页(除特殊页面外会回到首页)
|
||||||
- 租户切换Select增加loading
|
- 租户切换Select增加loading
|
||||||
- modalLoading/drawerLoading改为调用内部的lock/unlock方法
|
- ~~modalLoading/drawerLoading改为调用内部的lock/unlock方法~~ 有待商榷暂时按老版本逻辑不变
|
||||||
- 登录验证码 增加loading
|
- 登录验证码 增加loading
|
||||||
- DictEnum使用const代替enum
|
- DictEnum使用const代替enum
|
||||||
- TinyMCE组件重构 移除冗余代码/功能 增加loading
|
- TinyMCE组件重构 移除冗余代码/功能 增加loading
|
||||||
|
|
||||||
|
**ALPHA功能**
|
||||||
|
|
||||||
|
- 弹窗表单数据更改关闭时的提示框(可能最终不会加入) 测试页面: 参数管理
|
||||||
|
|
||||||
**BUG FIX**
|
**BUG FIX**
|
||||||
|
|
||||||
- 重新登录 字典会unknown的情况[详细分析](https://gitee.com/dapppp/ruoyi-plus-vben5/issues/IBY27D)
|
- 重新登录 字典会unknown的情况[详细分析](https://gitee.com/dapppp/ruoyi-plus-vben5/issues/IBY27D)
|
||||||
|
117
apps/web-antd/src/utils/popup.ts
Normal file
117
apps/web-antd/src/utils/popup.ts
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated 注意为实验性功能 可能有api变动/被移除
|
||||||
|
* @param props props
|
||||||
|
* @returns hook
|
||||||
|
*
|
||||||
|
* 待解决问题: 网速慢情况直接关闭 会导致数据不一致问题
|
||||||
|
* 但是使用api.lock会导致在报错情况无法关闭(因为目前代码没有finally)
|
||||||
|
*/
|
||||||
|
export function useBeforeCloseDiff(props: BeforeCloseDiffProps) {
|
||||||
|
const { initializedGetter, currentGetter, compare } = props;
|
||||||
|
const initialized = ref<string>('');
|
||||||
|
const isInitialized = ref(false);
|
||||||
|
const isSubmitted = ref(false);
|
||||||
|
|
||||||
|
async function updateInitialized(data?: string) {
|
||||||
|
initialized.value = data || (await initializedGetter());
|
||||||
|
isInitialized.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSubmitted() {
|
||||||
|
isSubmitted.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onBeforeClose(): Promise<boolean> {
|
||||||
|
// 如果还未初始化,直接允许关闭
|
||||||
|
if (!isInitialized.value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 如果已经提交过,直接允许关闭
|
||||||
|
if (isSubmitted.value) {
|
||||||
|
// 重置状态
|
||||||
|
isSubmitted.value = false;
|
||||||
|
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('您有未保存的更改,确认要退出吗?'),
|
||||||
|
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,
|
||||||
|
updateInitialized,
|
||||||
|
setSubmitted,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给useVbenForm使用的 封装函数
|
||||||
|
* @param formApi 表单实例
|
||||||
|
* @returns getter
|
||||||
|
*/
|
||||||
|
export function defaultFormValueGetter(formApi: ExtendedFormApi) {
|
||||||
|
return async () => {
|
||||||
|
const v = await formApi.getValues();
|
||||||
|
return JSON.stringify(v);
|
||||||
|
};
|
||||||
|
}
|
@ -7,6 +7,7 @@ import { cloneDeep } from '@vben/utils';
|
|||||||
|
|
||||||
import { useVbenForm } from '#/adapter/form';
|
import { useVbenForm } from '#/adapter/form';
|
||||||
import { configAdd, configInfo, configUpdate } from '#/api/system/config';
|
import { configAdd, configInfo, configUpdate } from '#/api/system/config';
|
||||||
|
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
|
||||||
|
|
||||||
import { modalSchema } from './data';
|
import { modalSchema } from './data';
|
||||||
|
|
||||||
@ -25,9 +26,15 @@ const [BasicForm, formApi] = useVbenForm({
|
|||||||
showDefaultActions: false,
|
showDefaultActions: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { onBeforeClose, updateInitialized, setSubmitted } = useBeforeCloseDiff({
|
||||||
|
initializedGetter: defaultFormValueGetter(formApi),
|
||||||
|
currentGetter: defaultFormValueGetter(formApi),
|
||||||
|
});
|
||||||
|
|
||||||
const [BasicModal, modalApi] = useVbenModal({
|
const [BasicModal, modalApi] = useVbenModal({
|
||||||
fullscreenButton: false,
|
fullscreenButton: false,
|
||||||
onCancel: handleCancel,
|
onBeforeClose,
|
||||||
|
onClosed: handleClosed,
|
||||||
onConfirm: handleConfirm,
|
onConfirm: handleConfirm,
|
||||||
onOpenChange: async (isOpen) => {
|
onOpenChange: async (isOpen) => {
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
@ -42,6 +49,7 @@ const [BasicModal, modalApi] = useVbenModal({
|
|||||||
const record = await configInfo(id);
|
const record = await configInfo(id);
|
||||||
await formApi.setValues(record);
|
await formApi.setValues(record);
|
||||||
}
|
}
|
||||||
|
await updateInitialized();
|
||||||
|
|
||||||
modalApi.modalLoading(false);
|
modalApi.modalLoading(false);
|
||||||
},
|
},
|
||||||
@ -56,8 +64,9 @@ async function handleConfirm() {
|
|||||||
}
|
}
|
||||||
const data = cloneDeep(await formApi.getValues());
|
const data = cloneDeep(await formApi.getValues());
|
||||||
await (isUpdate.value ? configUpdate(data) : configAdd(data));
|
await (isUpdate.value ? configUpdate(data) : configAdd(data));
|
||||||
|
setSubmitted();
|
||||||
emit('reload');
|
emit('reload');
|
||||||
await handleCancel();
|
modalApi.close();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
@ -65,14 +74,13 @@ async function handleConfirm() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleCancel() {
|
async function handleClosed() {
|
||||||
modalApi.close();
|
|
||||||
await formApi.resetForm();
|
await formApi.resetForm();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<BasicModal :close-on-click-modal="false" :title="title" class="w-[550px]">
|
<BasicModal :title="title" class="w-[550px]">
|
||||||
<BasicForm />
|
<BasicForm />
|
||||||
</BasicModal>
|
</BasicModal>
|
||||||
</template>
|
</template>
|
||||||
|
Loading…
Reference in New Issue
Block a user