feat: 表单编辑器magic-api调用不会弹框,而是以图标闪烁的形式显示
This commit is contained in:
@ -22,6 +22,7 @@ export const requestMagicApi = (
|
||||
},
|
||||
{
|
||||
errorMessageMode: mode,
|
||||
ignoreErrorInEditor: true
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
37
src/components/SecondDev/AjaxErrorIcon.vue
Normal file
37
src/components/SecondDev/AjaxErrorIcon.vue
Normal file
@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<WarningOutlined class="alert-icon" v-show="hasAjaxError" :style="{ color: '#c00', cursor: 'pointer' }" @click.native="showHint" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@keyframes opacityChange {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.alert-icon{
|
||||
animation: opacityChange 3s infinite;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script setup>
|
||||
import { WarningOutlined } from '@ant-design/icons-vue';
|
||||
import { Modal } from 'ant-design-vue';
|
||||
import useGlobalFlag from '/@/hooks/core/useGlobalFlag';
|
||||
|
||||
const globalFlag = useGlobalFlag();
|
||||
const { hasAjaxError } = globalFlag;
|
||||
|
||||
function showHint() {
|
||||
Modal.error({
|
||||
title: '接口调用错误',
|
||||
content: 'magic-api调用出现错误,为了避免干扰正常操作,这些操作不会在表单设计器中显式提示,请使用浏览器的调试工具查看具体报错信息。'
|
||||
});
|
||||
}
|
||||
</script>
|
||||
20
src/hooks/core/useGlobalFlag.ts
Normal file
20
src/hooks/core/useGlobalFlag.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { ref } from 'vue';
|
||||
|
||||
const isEditorOpen = ref(false);
|
||||
const hasAjaxError = ref(false);
|
||||
|
||||
function ajaxError() {
|
||||
hasAjaxError.value = true;
|
||||
setTimeout(() => {
|
||||
hasAjaxError.value = false;
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
export default function() {
|
||||
return {
|
||||
isEditorOpen,
|
||||
hasAjaxError,
|
||||
ajaxError
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,10 +22,12 @@ import { useGo } from '/@/hooks/web/usePage';
|
||||
import { validateScript } from '/@/utils/event/design';
|
||||
import { notification } from 'ant-design-vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
import useGlobalFlag from '/@/hooks/core/useGlobalFlag';
|
||||
|
||||
const globSetting = useGlobSetting();
|
||||
const urlPrefix = globSetting.urlPrefix;
|
||||
const { createMessage, createErrorModal } = useMessage();
|
||||
const { isEditorOpen, ajaxError } = useGlobalFlag();
|
||||
|
||||
const showNetworkError = function() {
|
||||
notification.error({
|
||||
@ -92,10 +94,14 @@ const transform: AxiosTransform = {
|
||||
|
||||
// errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
|
||||
// errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
|
||||
if (options.errorMessageMode === 'modal') {
|
||||
createErrorModal({ title: t('错误提示'), content: timeoutMsg });
|
||||
} else if (options.errorMessageMode === 'message') {
|
||||
createMessage.error(timeoutMsg);
|
||||
if (options.ignoreErrorInEditor && isEditorOpen.value) {
|
||||
ajaxError();
|
||||
} else {
|
||||
if (options.errorMessageMode === 'modal') {
|
||||
createErrorModal({ title: t('错误提示'), content: timeoutMsg });
|
||||
} else if (options.errorMessageMode === 'message') {
|
||||
createMessage.error(timeoutMsg);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(timeoutMsg || t('请求出错,请稍候重试'));
|
||||
@ -187,6 +193,7 @@ const transform: AxiosTransform = {
|
||||
let errMessage = '';
|
||||
|
||||
try {
|
||||
|
||||
if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
|
||||
trNetworkError();
|
||||
} else if (err?.includes('Network Error')) {
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
<a-step :title="t('表单事件')" />
|
||||
</a-steps>
|
||||
<div class="btn-box">
|
||||
<ajax-error-icon />
|
||||
<a-button type="primary" @click="handleStepPrev" v-show="current !== 0">{{
|
||||
t('上一步')
|
||||
}}</a-button>
|
||||
@ -34,12 +35,13 @@
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, provide, watch, Ref, toRaw } from 'vue';
|
||||
import { ref, reactive, provide, watch, Ref, toRaw, onUnmounted } from 'vue';
|
||||
import BasicConfigStep from '../BasicConfigStep.vue';
|
||||
import { FormDesignStep, FormEventStep } from '/@/components/CreateCodeStep';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { CustomFormConfig, GeneratorConfig } from '/@/model/generator/generatorConfig';
|
||||
import { TableInfo } from '/@/components/Designer';
|
||||
import AjaxErrorIcon from '/@/components/SecondDev/AjaxErrorIcon.vue';
|
||||
import {
|
||||
addDataFirstFormTemplate,
|
||||
updateDataFirstFormTemplate,
|
||||
@ -49,6 +51,8 @@
|
||||
import * as antd from '/@/components/Designer/src/types';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import DesignLogo from '/@/components/ModalPanel/src/DesignLogo.vue';
|
||||
import useGlobalFlag from '/@/hooks/core/useGlobalFlag';
|
||||
|
||||
const { t } = useI18n();
|
||||
const current = ref(0);
|
||||
|
||||
@ -61,6 +65,16 @@
|
||||
const isUpdate = ref<boolean>(false);
|
||||
const formId = ref<string>('');
|
||||
const emits = defineEmits(['success', 'register', 'close']);
|
||||
const globalFlag = useGlobalFlag();
|
||||
const { isEditorOpen } = globalFlag;
|
||||
|
||||
watch(current, () => {
|
||||
isEditorOpen.value = current.value === 1;
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
isEditorOpen.value = false;
|
||||
});
|
||||
|
||||
let generatorConfig = reactive<GeneratorConfig>({
|
||||
databaseId: '', //数据库id
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
<a-step :title="t('菜单设置')" />
|
||||
</a-steps>
|
||||
<div class="btn-box">
|
||||
<ajax-error-icon />
|
||||
<a-button @click="handleStepPrev" v-show="current !== 0">{{ t('上一步') }}</a-button>
|
||||
<a-button type="primary" @click="handleSaveDraft" v-show="current > 3">{{
|
||||
t('保存草稿')
|
||||
@ -47,7 +48,7 @@
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, provide, Ref, defineAsyncComponent } from 'vue';
|
||||
import { ref, reactive, provide, Ref, defineAsyncComponent, watch, onUnmounted } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { GeneratorConfig } from '/@/model/generator/generatorConfig';
|
||||
import { TableInfo, noHaveTableAndField } from '/@/components/Designer';
|
||||
@ -70,6 +71,8 @@
|
||||
import { MenuConfig } from '/@/model/generator/menuConfig';
|
||||
import { FormJson } from '/@/model/generator/codeGenerator';
|
||||
import DesignLogo from '/@/components/ModalPanel/src/DesignLogo.vue';
|
||||
import AjaxErrorIcon from '/@/components/SecondDev/AjaxErrorIcon.vue';
|
||||
import useGlobalFlag from '/@/hooks/core/useGlobalFlag';
|
||||
const { t } = useI18n();
|
||||
const StructureConfigStep = defineAsyncComponent({
|
||||
loader: () => import('/@/components/CreateCodeStep/src/StructureConfigStep.vue'),
|
||||
@ -96,6 +99,8 @@
|
||||
loadingComponent: LoadingBox,
|
||||
});
|
||||
|
||||
const globalFlag = useGlobalFlag();
|
||||
const { isEditorOpen } = globalFlag;
|
||||
const userStore = useUserStore();
|
||||
const templateId = ref();
|
||||
const current = ref(0);
|
||||
@ -110,6 +115,14 @@
|
||||
const mainTableName = ref('table_' + random(10000, 99999));
|
||||
const emit = defineEmits(['close', 'register', 'success']);
|
||||
|
||||
watch(current, () => {
|
||||
isEditorOpen.value = current.value === 0;
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
isEditorOpen.value = false;
|
||||
});
|
||||
|
||||
const tableInfo = ref<TableInfo[]>([]);
|
||||
let generatorConfig = reactive<GeneratorConfig>({
|
||||
databaseId: '', //数据库id
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
<a-step :title="t('菜单设置')" />
|
||||
</a-steps>
|
||||
<div class="btn-box">
|
||||
<ajax-error-icon />
|
||||
<a-button @click="handleStepPrev" v-show="current !== 0">{{ t('上一步') }}</a-button>
|
||||
<a-button type="primary" @click="handleSaveDraft" v-show="current > 3">{{
|
||||
t('保存草稿')
|
||||
@ -41,7 +42,7 @@
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, provide, Ref, defineAsyncComponent } from 'vue';
|
||||
import { ref, reactive, provide, Ref, defineAsyncComponent, watch, onUnmounted } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { GeneratorConfig } from '/@/model/generator/generatorConfig';
|
||||
import { TableInfo } from '/@/components/Designer';
|
||||
@ -63,6 +64,8 @@
|
||||
import * as antd from '/@/components/Designer/src/types';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import DesignLogo from '/@/components/ModalPanel/src/DesignLogo.vue';
|
||||
import useGlobalFlag from '/@/hooks/core/useGlobalFlag';
|
||||
import AjaxErrorIcon from '/@/components/SecondDev/AjaxErrorIcon.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const TableConfigStep = defineAsyncComponent({
|
||||
@ -91,6 +94,8 @@
|
||||
});
|
||||
|
||||
const userStore = useUserStore();
|
||||
const globalFlag = useGlobalFlag();
|
||||
const { isEditorOpen } = globalFlag;
|
||||
const templateId = ref();
|
||||
const current = ref(0);
|
||||
const isUpdate = ref(false);
|
||||
@ -103,6 +108,14 @@
|
||||
const widgetForm = ref(JSON.parse(JSON.stringify(antd.widgetForm))); //FormDesignStep -> designer和StructureConfigStep页面使用
|
||||
const tableInfo = ref<TableInfo[]>([]);
|
||||
|
||||
watch(current, () => {
|
||||
isEditorOpen.value = current.value === 1;
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
isEditorOpen.value = false;
|
||||
});
|
||||
|
||||
const emit = defineEmits(['close', 'register', 'success']);
|
||||
let generatorConfig = reactive<GeneratorConfig>({
|
||||
databaseId: null, //数据库id
|
||||
|
||||
2
types/axios.d.ts
vendored
2
types/axios.d.ts
vendored
@ -25,6 +25,8 @@ export interface RequestOptions {
|
||||
withToken?: boolean;
|
||||
// 请求重试机制
|
||||
retryRequest?: RetryRequest;
|
||||
// 在表单设计器中隐藏错误信息
|
||||
ignoreErrorInEditor?: boolean;
|
||||
}
|
||||
|
||||
export interface RetryRequest {
|
||||
|
||||
Reference in New Issue
Block a user