refactor(antdv-next): 将message组件调用统一改为window.message

将项目中直接导入的antdv-next的message组件调用改为通过window.message调用,提升代码一致性
移除不再需要的message组件导入
新增api-switch组件用于统一处理状态切换逻辑
This commit is contained in:
dap 2026-01-15 09:35:54 +08:00
parent 2312f438ac
commit ee1b37c787
23 changed files with 211 additions and 90 deletions

View File

@ -1,6 +1,6 @@
import { $t } from '@vben/locales';
import { message, Modal } from 'antdv-next';
import { Modal } from 'antdv-next';
import { useAuthStore } from '#/store';
@ -93,7 +93,7 @@ export function handleUnauthorizedLogout() {
}
})
.finally(() => {
message.error(timeoutMsg);
window.message.error(timeoutMsg);
isLogoutProcessing = false;
});
// 不再执行下面逻辑

View File

@ -27,7 +27,7 @@ import {
RsaEncryption,
} from '@vben/utils';
import { message, Modal } from 'antdv-next';
import { Modal } from 'antdv-next';
import { isEmpty, isNull } from 'lodash-es';
import { useAuthStore } from '#/store';
@ -165,7 +165,7 @@ function createRequestClient(baseURL: string) {
// 通用的错误处理, 如果没有进入上面的错误处理逻辑,就会进入这里
// 主要处理http状态码不为200(如网络异常/离线)的情况 必须放在在下面的响应拦截器之前
client.addResponseInterceptor(
errorMessageResponseInterceptor((msg: string) => message.error(msg)),
errorMessageResponseInterceptor((msg: string) => window.message.error(msg)),
);
client.addResponseInterceptor<HttpResponse>({
@ -258,7 +258,7 @@ function createRequestClient(baseURL: string) {
title: $t('http.successTip'),
});
} else if (response.config.successMessageMode === 'message') {
message.success(successMsg);
window.message.success(successMsg);
}
// 分页情况下为code msg rows total 并没有data字段
// 如果有data 直接返回data 没有data将剩余参数(...other)封装为data返回
@ -293,7 +293,7 @@ function createRequestClient(baseURL: string) {
title: $t('http.errorTip'),
});
} else if (response.config.errorMessageMode === 'message') {
message.error(timeoutMsg);
window.message.error(timeoutMsg);
}
throw new Error(timeoutMsg || $t('http.apiRequestFailed'));

View File

@ -8,8 +8,6 @@ import { computed, ref, unref, watch, watchEffect } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t as t } from '@vben/locales';
import { message } from 'antdv-next';
import cropperModal from './cropper-modal.vue';
defineOptions({ name: 'CropperAvatar' });
@ -74,7 +72,7 @@ watch(
function handleUploadSuccess({ data, source }: any) {
sourceValue.value = source;
emit('change', { data, source });
message.success(t('component.cropper.uploadSuccess'));
window.message.success(t('component.cropper.uploadSuccess'));
}
const closeModal = () => modalApi.close();

View File

@ -8,7 +8,7 @@ import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t as t } from '@vben/locales';
import { Avatar, message, Space, Tooltip, Upload } from 'antdv-next';
import { Avatar, Space, Tooltip, Upload } from 'antdv-next';
import { isFunction } from 'lodash-es';
import { dataURLtoBlob } from '#/utils/file/base64Conver';
@ -102,7 +102,7 @@ async function handleOk() {
const uploadApi = props.uploadApi;
if (uploadApi && isFunction(uploadApi)) {
if (!previewSource.value) {
message.warn('未选择图片');
window.message.warning('未选择图片');
return;
}
const blob = dataURLtoBlob(previewSource.value);

View File

@ -0,0 +1,125 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { $t } from '@vben/locales';
import { Modal, Switch } from 'antdv-next';
import { isFunction } from 'lodash-es';
interface Props {
/**
* 选中的文本
* @default i18n 启用
*/
checkedText?: string;
/**
* 未选中的文本
* @default i18n 禁用
*/
unCheckedText?: string;
disabled?: boolean;
/**
* 需要自己在内部处理更新的逻辑 因为status已经双向绑定了 可以直接获取
*/
api: (checked: boolean) => PromiseLike<void>;
/**
* 更新前是否弹窗确认
* @default false
*/
confirm?: boolean;
/**
* 对应的提示内容
* @param checked 选中的值(更新后的值)
* @default string '确认要更新状态吗?'
*/
confirmText?: (checked: boolean) => string;
}
const props = withDefaults(defineProps<Props>(), {
checkedText: undefined,
unCheckedText: undefined,
confirm: false,
confirmText: undefined,
});
const emit = defineEmits<{ reload: [] }>();
// computed
const checkedTextComputed = computed(() => {
return props.checkedText ?? $t('pages.common.enable');
});
const unCheckedTextComputed = computed(() => {
return props.unCheckedText ?? $t('pages.common.disable');
});
const currentChecked = defineModel<boolean>('value', {
default: false,
});
const loading = ref(false);
function confirmUpdate(checked: boolean, lastStatus: boolean) {
const content = isFunction(props.confirmText)
? props.confirmText(checked)
: `确认要更新状态吗?`;
Modal.confirm({
title: '提示',
content,
centered: true,
onOk: async () => {
try {
loading.value = true;
const { api } = props;
isFunction(api) && (await api(checked));
emit('reload');
} catch {
currentChecked.value = lastStatus;
} finally {
loading.value = false;
}
},
onCancel: () => {
currentChecked.value = lastStatus;
},
});
}
async function handleChange(checked: boolean, e: Event) {
//
e.stopPropagation();
//
const lastStatus = !checked;
//
currentChecked.value = checked;
const { api } = props;
try {
loading.value = true;
if (props.confirm) {
confirmUpdate(checked, lastStatus);
return;
}
isFunction(api) && (await api(checked));
emit('reload');
} catch {
currentChecked.value = lastStatus;
} finally {
loading.value = false;
}
}
</script>
<template>
<Switch
v-bind="$attrs"
:loading="loading"
:disabled="disabled"
:checked="currentChecked"
:checked-children="checkedTextComputed"
:un-checked-children="unCheckedTextComputed"
@change="handleChange"
/>
</template>

View File

@ -12,7 +12,7 @@ import { useTabs } from '@vben/hooks';
import { $t } from '@vben/locales';
import { getPopupContainer } from '@vben/utils';
import { message, Select, Spin } from 'antdv-next';
import { Select, Spin } from 'antdv-next';
import { storeToRefs } from 'pinia';
import { tenantDynamicClear, tenantDynamicToggle } from '#/api/system/tenant';
@ -90,7 +90,7 @@ const onSelected: SelectProps['onSelect'] = async (
// message
messageInstance.value?.();
messageInstance.value = message.success(
messageInstance.value = window.message.success(
`${$t('component.tenantToggle.switch')} ${option.companyName}`,
);
@ -111,7 +111,9 @@ async function onDeselect() {
await tenantDynamicClear();
// message
messageInstance.value?.();
messageInstance.value = message.success($t('component.tenantToggle.reset'));
messageInstance.value = window.message.success(
$t('component.tenantToggle.reset'),
);
lastSelected.value = '';
close(false);

View File

@ -9,7 +9,7 @@ import { ref, toRefs, watch } from 'vue';
import { $t } from '@vben/locales';
import { UploadOutlined } from '@ant-design/icons-vue';
import { message, Upload } from 'antdv-next';
import { Upload } from 'antdv-next';
import { isArray, isFunction, isObject, isString } from 'lodash-es';
import { uploadApi } from '#/api';
@ -129,14 +129,14 @@ const beforeUpload = async (file: File) => {
const { maxSize, accept } = props;
const isAct = await checkFileType(file, accept);
if (!isAct) {
message.error($t('component.upload.acceptUpload', [accept]));
window.message.error($t('component.upload.acceptUpload', [accept]));
isActMsg.value = false;
//
setTimeout(() => (isActMsg.value = true), 1000);
}
const isLt = file.size / 1024 / 1024 > maxSize;
if (isLt) {
message.error($t('component.upload.maxSizeMultiple', [maxSize]));
window.message.error($t('component.upload.maxSizeMultiple', [maxSize]));
isLtMsg.value = false;
//
setTimeout(() => (isLtMsg.value = true), 1000);
@ -165,7 +165,7 @@ async function customRequest(info: UploadRequestOption<any>) {
* 内部的逻辑由requestClient.upload处理 这里不用判断业务状态码 不符合会自动reject
*/
info.onSuccess!(res);
message.success($t('component.upload.uploadSuccess'));
window.message.success($t('component.upload.uploadSuccess'));
//
const value = getValue();
isInnerOperate.value = true;
@ -218,9 +218,9 @@ function getValue() {
</div>
<div v-if="showDescription" class="mt-2 flex flex-wrap items-center">
请上传不超过
<div class="text-primary mx-1 font-bold">{{ maxSize }}MB</div>
<div class="mx-1 font-bold text-primary">{{ maxSize }}MB</div>
<div class="text-primary mx-1 font-bold">{{ accept.join('/') }}</div>
<div class="mx-1 font-bold text-primary">{{ accept.join('/') }}</div>
格式文件
</div>
</Upload>

View File

@ -9,7 +9,7 @@ import { ref, toRefs, watch } from 'vue';
import { $t } from '@vben/locales';
import { PlusOutlined } from '@ant-design/icons-vue';
import { message, Modal, Upload } from 'antdv-next';
import { Modal, Upload } from 'antdv-next';
import { isArray, isFunction, isObject, isString, uniqueId } from 'lodash-es';
import { uploadApi } from '#/api';
@ -30,7 +30,7 @@ const props = withDefaults(
api?: UploadApi;
disabled?: boolean;
helpText?: string;
// eslint-disable-next-line no-use-before-define
listType?: ListType;
// Infinity
maxNumber?: number;
@ -189,14 +189,14 @@ const beforeUpload = async (file: File) => {
const { maxSize, accept } = props;
const isAct = await checkImageFileType(file, accept);
if (!isAct) {
message.error($t('component.upload.acceptUpload', [accept]));
window.message.error($t('component.upload.acceptUpload', [accept]));
isActMsg.value = false;
//
setTimeout(() => (isActMsg.value = true), 1000);
}
const isLt = file.size / 1024 / 1024 > maxSize;
if (isLt) {
message.error($t('component.upload.maxSizeMultiple', [maxSize]));
window.message.error($t('component.upload.maxSizeMultiple', [maxSize]));
isLtMsg.value = false;
//
setTimeout(() => (isLtMsg.value = true), 1000);
@ -225,7 +225,7 @@ async function customRequest(info: UploadRequestOption<any>) {
* 内部的逻辑由requestClient.upload处理 这里不用判断业务状态码 不符合会自动reject
*/
info.onSuccess!(res);
message.success($t('component.upload.uploadSuccess'));
window.message.success($t('component.upload.uploadSuccess'));
//
const value = getValue();
isInnerOperate.value = true;
@ -294,9 +294,9 @@ function getValue() {
class="mt-2 flex flex-wrap items-center text-[14px]"
>
请上传不超过
<div class="text-primary mx-1 font-bold">{{ maxSize }}MB</div>
<div class="mx-1 font-bold text-primary">{{ maxSize }}MB</div>
<div class="text-primary mx-1 font-bold">{{ accept.join('/') }}</div>
<div class="mx-1 font-bold text-primary">{{ accept.join('/') }}</div>
格式文件
</div>
<Modal

View File

@ -22,7 +22,7 @@ import { computed, onUnmounted, ref, watch } from 'vue';
import { $t } from '@vben/locales';
import { message, Modal } from 'antdv-next';
import { Modal } from 'antdv-next';
import { isFunction, isString } from 'lodash-es';
import { ossInfo } from '#/api/system/oss';
@ -270,7 +270,7 @@ export function useUpload(
function beforeUpload(file: FileType) {
const isLtMax = file.size / 1024 / 1024 < props.maxSize!;
if (!isLtMax) {
message.error($t('component.upload.maxSize', [props.maxSize]));
window.message.error($t('component.upload.maxSize', [props.maxSize]));
return false;
}
// 大坑 Safari不支持file-type库 去除文件类型的校验
@ -301,7 +301,7 @@ export function useUpload(
});
info.onSuccess!(res);
if (props.showSuccessMsg) {
message.success($t('component.upload.uploadSuccess'));
window.message.success($t('component.upload.uploadSuccess'));
}
emit('success', info.file as RcFile, res);
} catch (error: any) {

View File

@ -22,8 +22,6 @@ import { preferences } from '@vben/preferences';
import { useAccessStore, useUserStore } from '@vben/stores';
import { openWindow } from '@vben/utils';
import { message } from 'antdv-next';
import { TenantToggle } from '#/components/tenant-toggle';
import { $t } from '#/locales';
import { resetRoutes } from '#/router';
@ -110,7 +108,7 @@ const notifyStore = useNotifyStore();
onMounted(() => notifyStore.startListeningMessage());
function handleViewAll() {
message.warning('暂未开放');
window.message.warning('暂未开放');
}
watch(
() => ({

View File

@ -10,7 +10,6 @@ import type { Menu } from '#/api';
import { generateAccessible } from '@vben/access';
import { preferences } from '@vben/preferences';
import { message } from 'antdv-next';
import { cloneDeep } from 'lodash-es';
import { getAllMenusApi } from '#/api';
@ -241,8 +240,8 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
...options,
fetchMenuListAsync: async () => {
// 清除以前的message
message.destroy();
message.loading({
window.message.destroy();
window.message.loading({
content: `${$t('common.loadingMenu')}...`,
duration: 1,
});

View File

@ -3,7 +3,6 @@ import type { VbenFormProps } from '#/adapter/form';
import { $t } from '@vben/locales';
import { cloneDeep, formatDate } from '@vben/utils';
import { message } from 'antdv-next';
import { isFunction } from 'lodash-es';
import { dataURLtoBlob, urlToBase64 } from './base64Conver';
@ -26,7 +25,10 @@ export async function downloadExcel(
requestData: any = {},
withRandomName = true,
) {
const hideLoading = message.loading($t('pages.common.downloadLoading'), 0);
const hideLoading = window.message.loading(
$t('pages.common.downloadLoading'),
0,
);
try {
const data = await func(requestData);
downloadExcelFile(data, fileName, withRandomName);
@ -114,7 +116,10 @@ export async function commonDownloadExcel(
requestData: any = {},
options: DownloadExcelOptions = {},
) {
const hideLoading = message.loading($t('pages.common.downloadLoading'), 0);
const hideLoading = window.message.loading(
$t('pages.common.downloadLoading'),
0,
);
try {
const { withRandomName = true, fieldMappingTime } = options;
// 需要处理时间字段映射

View File

@ -9,7 +9,7 @@ import { AuthenticationCodeLogin, z } from '@vben/common-ui';
import { DEFAULT_TENANT_ID } from '@vben/constants';
import { $t } from '@vben/locales';
import { Alert, message } from 'antdv-next';
import { Alert } from 'antdv-next';
import { tenantList } from '#/api';
import { sendSmsCode } from '#/api/core/captcha';
@ -96,7 +96,7 @@ const formSchema = computed((): VbenFormSchema[] => {
}
//
await sendSmsCode(value);
message.success('验证码发送成功');
window.message.success('验证码发送成功');
},
};
},

View File

@ -5,8 +5,6 @@ import { computed, ref } from 'vue';
import { ProfilePasswordSetting, z } from '@vben/common-ui';
import { message } from 'antdv-next';
const profilePasswordSettingRef = ref();
const formSchema = computed((): VbenFormSchema[] => {
@ -53,7 +51,7 @@ const formSchema = computed((): VbenFormSchema[] => {
});
function handleSubmit() {
message.success('密码修改成功');
window.message.success('密码修改成功');
}
</script>
<template>

View File

@ -9,7 +9,7 @@ import { preferences } from '@vben/preferences';
import { useAccessStore } from '@vben/stores';
import { cn } from '@vben/utils';
import { message, Spin } from 'antdv-next';
import { Spin } from 'antdv-next';
import { authCallback } from '#/api';
import { useAuthStore } from '#/store';
@ -49,7 +49,7 @@ onMounted(async () => {
(item) => item.source === source,
);
if (!currentClient) {
message.error({ content: `未找到${source}平台` });
window.message.error({ content: `未找到${source}平台` });
return;
}
const data: AuthApi.OAuthLoginParams = {
@ -62,14 +62,14 @@ onMounted(async () => {
// token token
if (accessStore.accessToken) {
await authCallback(data);
message.success(`${source}授权成功`);
window.message.success(`${source}授权成功`);
setTimeout(() => {
router.push(preferences.app.defaultHomePath);
}, 1500);
} else {
//
await authStore.authLogin(data as any);
message.success(`${source}登录成功`);
window.message.success(`${source}登录成功`);
}
} catch (error) {
console.error(error);

View File

@ -6,7 +6,7 @@ import { useVbenDrawer } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { cloneDeep } from '@vben/utils';
import { Button, message, Skeleton } from 'antdv-next';
import { Button, Skeleton } from 'antdv-next';
import { useVbenForm } from '#/adapter/form';
import { tenantAdd, tenantInfo, tenantUpdate } from '#/api/system/tenant';
@ -43,7 +43,7 @@ async function setupPackageSelect() {
* 检测是否存在租户套餐 你也不想表单填完了发现套餐为0无法选中吧
*/
if (tenantPackageList.length === 0) {
const closeMessage = message.error(
const closeMessage = window.message.error(
h('span', {}, [
'请先配置租户套餐',
h(

View File

@ -22,7 +22,7 @@ import {
userRemove,
userStatusChange,
} from '#/api/system/user';
import { TableSwitch } from '#/components/table';
import ApiSwitch from '#/components/global/api-switch.vue';
import { commonDownloadExcel } from '#/utils/file/download';
import { columns, querySchema } from './data';
@ -199,6 +199,14 @@ function handleMenuClick(key: string, row: any) {
}
}
}
async function handleChangeStatus(checked: boolean, row: User) {
console.log(checked);
await userStatusChange({
userId: row.userId,
status: checked ? '0' : '1',
});
}
</script>
<template>
@ -248,9 +256,10 @@ function handleMenuClick(key: string, row: any) {
<Avatar :src="row.avatar || preferences.app.defaultAvatar" />
</template>
<template #status="{ row }">
<TableSwitch
v-model:value="row.status"
:api="() => userStatusChange(row)"
<!-- value只能接收boolean值 -->
<ApiSwitch
:value="row.status === '0'"
:api="(checked) => handleChangeStatus(checked, row)"
:disabled="
row.userId === 1 || !hasAccessByCodes(['system:user:edit'])
"

View File

@ -10,7 +10,7 @@ import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { getVxePopupContainer } from '@vben/utils';
import { message, Modal, Popconfirm, Space } from 'antdv-next';
import { Modal, Popconfirm, Space } from 'antdv-next';
import dayjs from 'dayjs';
import { useVbenVxeGrid, vxeCheckboxChecked } from '#/adapter/vxe-table';
@ -125,10 +125,10 @@ async function handleBatchGen() {
const rows = tableApi.grid.getCheckboxRecords();
const ids = rows.map((row: any) => row.tableId);
if (ids.length === 0) {
message.info('请选择需要生成代码的表');
window.message.info('请选择需要生成代码的表');
return;
}
const hideLoading = message.loading('下载中...');
const hideLoading = window.message.loading('下载中...');
try {
const params = ids.join(',');
const data = await batchGenCode(params);
@ -140,12 +140,12 @@ async function handleBatchGen() {
}
async function handleDownload(record: Recordable<any>) {
const hideLoading = message.loading('加载中...');
const hideLoading = window.message.loading('加载中...');
try {
//
if (record.genType === '1' && record.genPath) {
await genWithPath(record.tableId);
message.success(`生成成功: ${record.genPath}`);
window.message.success(`生成成功: ${record.genPath}`);
return;
}
// zip
@ -196,7 +196,7 @@ function handleImport() {
<BasicTable table-title="代码生成列表">
<template #toolbar-tools>
<a
class="text-primary mr-2"
class="mr-2 text-primary"
href="https://dapdap.top/other/template.html"
target="_blank"
>👉关于代码生成模板

View File

@ -11,7 +11,6 @@ import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { cloneDeep } from '@vben/utils';
import { message } from 'antdv-next';
import { omit } from 'lodash-es';
import { useVbenForm } from '#/adapter/form';
@ -173,7 +172,7 @@ async function handleSubmit() {
//
for (const item of nextNodeInfo.value) {
if (item.selectUserList.length === 0) {
message.warn(`未选择节点[${item.nodeName}]审批人`);
window.message.warning(`未选择节点[${item.nodeName}]审批人`);
return;
}
}

View File

@ -16,7 +16,7 @@ import { cn } from '@vben/utils';
import { CopyOutlined } from '@ant-design/icons-vue';
import { useClipboard } from '@vueuse/core';
import { Card, Divider, message, TabPane, Tabs } from 'antdv-next';
import { Card, Divider, TabPane, Tabs } from 'antdv-next';
import { flowInfo } from '#/api/workflow/instance';
import { getTaskByTaskId } from '#/api/workflow/task';
@ -130,7 +130,7 @@ watch(() => props.task, handleLoadInfo);
const { copy } = useClipboard({ legacy: true });
async function handleCopy(text: string) {
await copy(text);
message.success('复制成功');
window.message.success('复制成功');
}
</script>
@ -153,7 +153,7 @@ async function handleCopy(text: string) {
<template #extra>
<a-button size="small" @click="() => handleLoadInfo(task)">
<div class="flex items-center justify-center">
<span class="icon-[material-symbols--refresh] size-24px"></span>
<span class="size-24px icon-[material-symbols--refresh]"></span>
</div>
</a-button>
</template>
@ -174,7 +174,7 @@ async function handleCopy(text: string) {
<div class="flex items-center gap-2">
<VbenAvatar
:alt="task?.createByName ?? ''"
class="bg-primary size-[28px] rounded-full text-white"
class="size-[28px] rounded-full bg-primary text-white"
src=""
/>

View File

@ -14,14 +14,7 @@ import { Page, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { getVxePopupContainer } from '@vben/utils';
import {
message,
Modal,
Popconfirm,
RadioGroup,
Space,
Switch,
} from 'antdv-next';
import { Modal, Popconfirm, RadioGroup, Space, Switch } from 'antdv-next';
import { useVbenVxeGrid, vxeCheckboxChecked } from '#/adapter/vxe-table';
import {
@ -219,7 +212,10 @@ function handleEdit(row: any) {
* @param row row
*/
async function handleExportXml(row: any) {
const hideLoading = message.loading($t('pages.common.downloadLoading'), 0);
const hideLoading = window.message.loading(
$t('pages.common.downloadLoading'),
0,
);
try {
const blob = await workflowDefinitionExport(row.id);
downloadByData(blob, `${row.flowName}-${Date.now()}.json`);
@ -239,12 +235,12 @@ const [ProcessDefinitionDeployModal, deployModalApi] = useVbenModal({
*/
function handleDeploy() {
if (selectedCode.value.length === 0) {
message.warning('请先选择流程分类');
window.message.warning('请先选择流程分类');
return;
}
const selectedCategory = selectedCode.value[0];
if (selectedCategory === 0) {
message.warning('不可选择根目录进行部署, 请选择子分类');
window.message.warning('不可选择根目录进行部署, 请选择子分类');
return;
}
deployModalApi.setData({ category: selectedCategory });

View File

@ -4,7 +4,7 @@ import { ref } from 'vue';
import { JsonPreview, useVbenModal } from '@vben/common-ui';
import { cn, getPopupContainer } from '@vben/utils';
import { message, Modal, Tag } from 'antdv-next';
import { Modal, Tag } from 'antdv-next';
import { useVbenForm } from '#/adapter/form';
import { instanceVariable, updateFlowVariable } from '#/api/workflow/instance';
@ -168,7 +168,7 @@ async function handleSubmit(values: any) {
} catch (error) {
console.error(error);
if (error instanceof Error) {
message.error(error.message);
window.message.error(error.message);
}
throw error;
}

View File

@ -5,15 +5,7 @@ import { nextTick, onMounted } from 'vue';
import { JsonPreview } from '@vben/common-ui';
import {
Button,
Input,
InputNumber,
message,
Modal,
Select,
Space,
} from 'antdv-next';
import { Button, Input, InputNumber, Modal, Select, Space } from 'antdv-next';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
@ -246,9 +238,9 @@ async function handleValidate() {
const result = await tableApi.grid.validate(true);
console.log(result);
if (result) {
message.error('校验失败');
window.message.error('校验失败');
} else {
message.success('校验成功');
window.message.success('校验成功');
}
}